Jump to content

To JSON in lua editor


GhostXoP

Recommended Posts

If your like me, and open your data base to add buildngs, or accounts manually you may need a way to take arrays and convert them to JSON without using MTA. I figured id share this

json.encode works like toJSON

json.decode works like fromJSON

I use this to create and print json strings to then set in my database, you could use this too.

Source: http://hg.prosody.im/trunk/file/tip/util/json.lua#l1

Modfied Line 378

If used in any MTA Scripts for servers, please cite in comment at the top of the script, the website and line numbers containing lines from this script. I state that, because i do not enjoy the fact that some take code and mark it as theirs. This Code Is Not Mine.

Enjoy

local type = type; 
local t_insert, t_concat, t_remove, t_sort = table.insert, table.concat, table.remove, table.sort;
local s_char = string.char;
local tostring, tonumber = tostring, tonumber;
local pairs, ipairs = pairs, ipairs;
local next = next;
local error = error;
local newproxy, getmetatable = newproxy, getmetatable;
local print = print;
 
--module("json")
local json = {};
 
local null = newproxy and newproxy(true) or {};
if getmetatable and getmetatable(null) then
    getmetatable(null).__tostring = function() return "null"; end;
end
json.null = null;
 
local escapes = {
    ["\""] = "\\\"", ["\\"] = "\\\\", ["\b"] = "\\b",
    ["\f"] = "\\f", ["\n"] = "\\n", ["\r"] = "\\r", ["\t"] = "\\t"};
local unescapes = {
    ["\""] = "\"", ["\\"] = "\\", ["/"] = "/",
    b = "\b", f = "\f", n = "\n", r = "\r", t = "\t"};
for i=0,31 do
    local ch = s_char(i);
    if not escapes[ch] then escapes[ch] = ("\\u%.4X"):format(i); end
end
 
local valid_types = {
    number  = true,
    string  = true,
    table   = true,
    boolean = true
};
local special_keys = {
    __array = true;
    __hash  = true;
};
 
local simplesave, tablesave, arraysave, stringsave;
 
function stringsave(o, buffer)
    -- FIXME do proper utf-8 and binary data detection
    t_insert(buffer, "\""..(o:gsub(".", escapes)).."\"");
end
 
function arraysave(o, buffer)
    t_insert(buffer, "[");
    if next(o) then
        for i,v in ipairs(o) do
            simplesave(v, buffer);
            t_insert(buffer, ",");
        end
        t_remove(buffer);
    end
    t_insert(buffer, "]");
end
 
function tablesave(o, buffer)
    local __array = {};
    local __hash = {};
    local hash = {};
    for i,v in ipairs(o) do
        __array[i] = v;
    end
    for k,v in pairs(o) do
        local ktype, vtype = type(k), type(v);
        if valid_types[vtype] or v == null then
            if ktype == "string" and not special_keys[k] then
                hash[k] = v;
            elseif (valid_types[ktype] or k == null) and __array[k] == nil then
                __hash[k] = v;
            end
        end
    end
    if next(__hash) ~= nil or next(hash) ~= nil or next(__array) == nil then
        t_insert(buffer, "{");
        local mark = #buffer;
        if buffer.ordered then
            local keys = {};
            for k in pairs(hash) do
                t_insert(keys, k);
            end
            t_sort(keys);
            for _,k in ipairs(keys) do
                stringsave(k, buffer);
                t_insert(buffer, ":");
                simplesave(hash[k], buffer);
                t_insert(buffer, ",");
            end
        else
            for k,v in pairs(hash) do
                stringsave(k, buffer);
                t_insert(buffer, ":");
                simplesave(v, buffer);
                t_insert(buffer, ",");
            end
        end
        if next(__hash) ~= nil then
            t_insert(buffer, "\"__hash\":[");
            for k,v in pairs(__hash) do
                simplesave(k, buffer);
                t_insert(buffer, ",");
                simplesave(v, buffer);
                t_insert(buffer, ",");
            end
            t_remove(buffer);
            t_insert(buffer, "]");
            t_insert(buffer, ",");
        end
        if next(__array) then
            t_insert(buffer, "\"__array\":");
            arraysave(__array, buffer);
            t_insert(buffer, ",");
        end
        if mark ~= #buffer then t_remove(buffer); end
        t_insert(buffer, "}");
    else
        arraysave(__array, buffer);
    end
end
 
function simplesave(o, buffer)
    local t = type(o);
    if t == "number" then
        t_insert(buffer, tostring(o));
    elseif t == "string" then
        stringsave(o, buffer);
    elseif t == "table" then
        tablesave(o, buffer);
    elseif t == "boolean" then
        t_insert(buffer, (o and "true" or "false"));
    else
        t_insert(buffer, "null");
    end
end
 
function json.encode(obj)
    local t = {};
    simplesave(obj, t);
    return t_concat(t);
end
function json.encode_ordered(obj)
    local t = { ordered = true };
    simplesave(obj, t);
    return t_concat(t);
end
 
-----------------------------------
 
 
function json.decode(json)
    json = json.." "; -- appending a space ensures valid json wouldn't touch EOF
    local pos = 1;
    local current = {};
    local stack = {};
    local ch, peek;
    local function next()
        ch = json:sub(pos, pos);
        if ch == "" then error("Unexpected EOF"); end
        pos = pos+1;
        peek = json:sub(pos, pos);
        return ch;
    end
 
    local function skipwhitespace()
        while ch and (ch == "\r" or ch == "\n" or ch == "\t" or ch == " ") do
            next();
        end
    end
    local function skiplinecomment()
        repeat next(); until not(ch) or ch == "\r" or ch == "\n";
        skipwhitespace();
    end
    local function skipstarcomment()
        next(); next(); -- skip '/', '*'
        while peek and ch ~= "*" and peek ~= "/" do next(); end
        if not peek then error("eof in star comment") end
        next(); next(); -- skip '*', '/'
        skipwhitespace();
    end
    local function skipstuff()
        while true do
            skipwhitespace();
            if ch == "/" and peek == "*" then
                skipstarcomment();
            elseif ch == "/" and peek == "/" then
                skiplinecomment();
            else
                return;
            end
        end
    end
 
    local readvalue;
    local function readarray()
        local t = {};
        next(); -- skip '['
        skipstuff();
        if ch == "]" then next(); return t; end
        t_insert(t, readvalue());
        while true do
            skipstuff();
            if ch == "]" then next(); return t; end
            if not ch then error("eof while reading array");
            elseif ch == "," then next();
            elseif ch then error("unexpected character in array, comma expected"); end
            if not ch then error("eof while reading array"); end
            t_insert(t, readvalue());
        end
    end
 
    local function checkandskip(c)
        local x = ch or "eof";
        if x ~= c then error("unexpected "..x..", '"..c.."' expected"); end
        next();
    end
    local function readliteral(lit, val)
        for c in lit:gmatch(".") do
            checkandskip(c);
        end
        return val;
    end
    local function readstring()
        local s = "";
        checkandskip("\"");
        while ch do
            while ch and ch ~= "\\" and ch ~= "\"" do
                s = s..ch; next();
            end
            if ch == "\\" then
                next();
                if unescapes[ch] then
                    s = s..unescapes[ch];
                    next();
                elseif ch == "u" then
                    local seq = "";
                    for i=1,4 do
                        next();
                        if not ch then error("unexpected eof in string"); end
                        if not ch:match("[0-9a-fA-F]") then error("invalid unicode escape sequence in string"); end
                        seq = seq..ch;
                    end
                    s = s..s.char(tonumber(seq, 16)); -- FIXME do proper utf-8
                    next();
                else error("invalid escape sequence in string"); end
            end
            if ch == "\"" then
               
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...