[PATCH] osmo-gsm-tester[master]: ms: Add lua script support utilities
Hello Pau Espin Pedrol, Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/6915 to look at the new patch set (#4). ms: Add lua script support utilities Add a JSON encoder and a small module to sent registration and other events per unix datagram socket. json.lua fetched using: $ wget -O src/osmo_ms_driver/lua/json.lua \ https://raw.githubusercontent.com/rxi/json.lua/master/json.lua Change-Id: I43ae84a944c7f33e41d5de0880d4aaab3378809b --- A src/osmo_ms_driver/lua/json.lua A src/osmo_ms_driver/lua/ms_support.lua 2 files changed, 411 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-gsm-tester refs/changes/15/6915/4 diff --git a/src/osmo_ms_driver/lua/json.lua b/src/osmo_ms_driver/lua/json.lua new file mode 100644 index 000..dda6193 --- /dev/null +++ b/src/osmo_ms_driver/lua/json.lua @@ -0,0 +1,380 @@ +-- +-- json.lua +-- +-- Copyright (c) 2015 rxi +-- +-- This library is free software; you can redistribute it and/or modify it +-- under the terms of the MIT license. See LICENSE for details. +-- + +local json = { _version = "0.1.0" } + +--- +-- Encode +--- + +local encode + +local escape_char_map = { + [ "\\" ] = "", + [ "\"" ] = "\\\"", + [ "\b" ] = "\\b", + [ "\f" ] = "\\f", + [ "\n" ] = "\\n", + [ "\r" ] = "\\r", + [ "\t" ] = "\\t", +} + +local escape_char_map_inv = { [ "\\/" ] = "/" } +for k, v in pairs(escape_char_map) do + escape_char_map_inv[v] = k +end + + +local function escape_char(c) + return escape_char_map[c] or string.format("\\u%04x", c:byte()) +end + + +local function encode_nil(val) + return "null" +end + + +local function encode_table(val, stack) + local res = {} + stack = stack or {} + + -- Circular reference? + if stack[val] then error("circular reference") end + + stack[val] = true + + if val[1] ~= nil or next(val) == nil then +-- Treat as array -- check keys are valid and it is not sparse +local n = 0 +for k in pairs(val) do + if type(k) ~= "number" then +error("invalid table: mixed or invalid key types") + end + n = n + 1 +end +if n ~= #val then + error("invalid table: sparse array") +end +-- Encode +for i, v in ipairs(val) do + table.insert(res, encode(v, stack)) +end +stack[val] = nil +return "[" .. table.concat(res, ",") .. "]" + + else +-- Treat as an object +for k, v in pairs(val) do + if type(k) ~= "string" then +error("invalid table: mixed or invalid key types") + end + table.insert(res, encode(k, stack) .. ":" .. encode(v, stack)) +end +stack[val] = nil +return "{" .. table.concat(res, ",") .. "}" + end +end + + +local function encode_string(val) + return '"' .. val:gsub('[%z\1-\31\\"]', escape_char) .. '"' +end + + +local function encode_number(val) + -- Check for NaN, -inf and inf + if val ~= val or val <= -math.huge or val >= math.huge then +error("unexpected number value '" .. tostring(val) .. "'") + end + return string.format("%.14g", val) +end + + +local type_func_map = { + [ "nil" ] = encode_nil, + [ "table" ] = encode_table, + [ "string" ] = encode_string, + [ "number" ] = encode_number, + [ "boolean" ] = tostring, +} + + +encode = function(val, stack) + local t = type(val) + local f = type_func_map[t] + if f then +return f(val, stack) + end + error("unexpected type '" .. t .. "'") +end + + +function json.encode(val) + return ( encode(val) ) +end + + +--- +-- Decode +--- + +local parse + +local function create_set(...) + local res = {} + for i = 1, select("#", ...) do +res[ select(i, ...) ] = true + end + return res +end + +local space_chars = create_set(" ", "\t", "\r", "\n") +local delim_chars = create_set(" ", "\t", "\r", "\n", "]", "}", ",") +local escape_chars = create_set("\\", "/", '"', "b", "f", "n", "r", "t", "u") +local literals = create_set("true", "false", "null") + +local literal_map = { + [ "true" ] = true, + [ "false" ] = false, + [ "null" ] = nil, +} + + +local function next_char(str, idx, set, negate) + for i = idx, #str do +if set[str:sub(i, i)] ~= negate then + return i +end + end + return #str + 1 +end + + +local function decode_error(str, idx, msg) + local line_count = 1 + local col_count = 1 + for i = 1, idx - 1 do +col_count = col_count + 1 +if str:sub(i, i) == "\n" then + line_count = line_count + 1 + col_count = 1 +end + end + error( string.format("%s at line %d col %d", msg, line_count, col_count) ) +end + + +local function codepoint_to_utf8(n) + --
[PATCH] osmo-gsm-tester[master]: ms: Add lua script support utilities
ms: Add lua script support utilities Add a JSON encoder and a small module to sent registration and other events per unix datagram socket. Change-Id: I43ae84a944c7f33e41d5de0880d4aaab3378809b --- A src/osmo_ms_driver/lua/json.lua A src/osmo_ms_driver/lua/ms_support.lua 2 files changed, 411 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-gsm-tester refs/changes/15/6915/3 diff --git a/src/osmo_ms_driver/lua/json.lua b/src/osmo_ms_driver/lua/json.lua new file mode 100644 index 000..dda6193 --- /dev/null +++ b/src/osmo_ms_driver/lua/json.lua @@ -0,0 +1,380 @@ +-- +-- json.lua +-- +-- Copyright (c) 2015 rxi +-- +-- This library is free software; you can redistribute it and/or modify it +-- under the terms of the MIT license. See LICENSE for details. +-- + +local json = { _version = "0.1.0" } + +--- +-- Encode +--- + +local encode + +local escape_char_map = { + [ "\\" ] = "", + [ "\"" ] = "\\\"", + [ "\b" ] = "\\b", + [ "\f" ] = "\\f", + [ "\n" ] = "\\n", + [ "\r" ] = "\\r", + [ "\t" ] = "\\t", +} + +local escape_char_map_inv = { [ "\\/" ] = "/" } +for k, v in pairs(escape_char_map) do + escape_char_map_inv[v] = k +end + + +local function escape_char(c) + return escape_char_map[c] or string.format("\\u%04x", c:byte()) +end + + +local function encode_nil(val) + return "null" +end + + +local function encode_table(val, stack) + local res = {} + stack = stack or {} + + -- Circular reference? + if stack[val] then error("circular reference") end + + stack[val] = true + + if val[1] ~= nil or next(val) == nil then +-- Treat as array -- check keys are valid and it is not sparse +local n = 0 +for k in pairs(val) do + if type(k) ~= "number" then +error("invalid table: mixed or invalid key types") + end + n = n + 1 +end +if n ~= #val then + error("invalid table: sparse array") +end +-- Encode +for i, v in ipairs(val) do + table.insert(res, encode(v, stack)) +end +stack[val] = nil +return "[" .. table.concat(res, ",") .. "]" + + else +-- Treat as an object +for k, v in pairs(val) do + if type(k) ~= "string" then +error("invalid table: mixed or invalid key types") + end + table.insert(res, encode(k, stack) .. ":" .. encode(v, stack)) +end +stack[val] = nil +return "{" .. table.concat(res, ",") .. "}" + end +end + + +local function encode_string(val) + return '"' .. val:gsub('[%z\1-\31\\"]', escape_char) .. '"' +end + + +local function encode_number(val) + -- Check for NaN, -inf and inf + if val ~= val or val <= -math.huge or val >= math.huge then +error("unexpected number value '" .. tostring(val) .. "'") + end + return string.format("%.14g", val) +end + + +local type_func_map = { + [ "nil" ] = encode_nil, + [ "table" ] = encode_table, + [ "string" ] = encode_string, + [ "number" ] = encode_number, + [ "boolean" ] = tostring, +} + + +encode = function(val, stack) + local t = type(val) + local f = type_func_map[t] + if f then +return f(val, stack) + end + error("unexpected type '" .. t .. "'") +end + + +function json.encode(val) + return ( encode(val) ) +end + + +--- +-- Decode +--- + +local parse + +local function create_set(...) + local res = {} + for i = 1, select("#", ...) do +res[ select(i, ...) ] = true + end + return res +end + +local space_chars = create_set(" ", "\t", "\r", "\n") +local delim_chars = create_set(" ", "\t", "\r", "\n", "]", "}", ",") +local escape_chars = create_set("\\", "/", '"', "b", "f", "n", "r", "t", "u") +local literals = create_set("true", "false", "null") + +local literal_map = { + [ "true" ] = true, + [ "false" ] = false, + [ "null" ] = nil, +} + + +local function next_char(str, idx, set, negate) + for i = idx, #str do +if set[str:sub(i, i)] ~= negate then + return i +end + end + return #str + 1 +end + + +local function decode_error(str, idx, msg) + local line_count = 1 + local col_count = 1 + for i = 1, idx - 1 do +col_count = col_count + 1 +if str:sub(i, i) == "\n" then + line_count = line_count + 1 + col_count = 1 +end + end + error( string.format("%s at line %d col %d", msg, line_count, col_count) ) +end + + +local function codepoint_to_utf8(n) + -- http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi=iws-appendixa + local f = math.floor + if n <= 0x7f then +return string.char(n) + elseif n <= 0x7ff then +return string.char(f(n / 64) + 192, n % 64 + 128) + elseif n <= 0x then +return string.char(f(n / 4096) + 224, f(n % 4096 / 64) + 128, n % 64 + 128) + elseif n <= 0x10 then +
[PATCH] osmo-gsm-tester[master]: ms: Add lua script support utilities
Review at https://gerrit.osmocom.org/6915 ms: Add lua script support utilities Add a JSON encoder and a small module to sent registration and other events per unix datagram socket. Change-Id: I43ae84a944c7f33e41d5de0880d4aaab3378809b --- A src/osmo_ms_driver/lua/json.lua A src/osmo_ms_driver/lua/ms_support.lua 2 files changed, 411 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-gsm-tester refs/changes/15/6915/1 diff --git a/src/osmo_ms_driver/lua/json.lua b/src/osmo_ms_driver/lua/json.lua new file mode 100644 index 000..dda6193 --- /dev/null +++ b/src/osmo_ms_driver/lua/json.lua @@ -0,0 +1,380 @@ +-- +-- json.lua +-- +-- Copyright (c) 2015 rxi +-- +-- This library is free software; you can redistribute it and/or modify it +-- under the terms of the MIT license. See LICENSE for details. +-- + +local json = { _version = "0.1.0" } + +--- +-- Encode +--- + +local encode + +local escape_char_map = { + [ "\\" ] = "", + [ "\"" ] = "\\\"", + [ "\b" ] = "\\b", + [ "\f" ] = "\\f", + [ "\n" ] = "\\n", + [ "\r" ] = "\\r", + [ "\t" ] = "\\t", +} + +local escape_char_map_inv = { [ "\\/" ] = "/" } +for k, v in pairs(escape_char_map) do + escape_char_map_inv[v] = k +end + + +local function escape_char(c) + return escape_char_map[c] or string.format("\\u%04x", c:byte()) +end + + +local function encode_nil(val) + return "null" +end + + +local function encode_table(val, stack) + local res = {} + stack = stack or {} + + -- Circular reference? + if stack[val] then error("circular reference") end + + stack[val] = true + + if val[1] ~= nil or next(val) == nil then +-- Treat as array -- check keys are valid and it is not sparse +local n = 0 +for k in pairs(val) do + if type(k) ~= "number" then +error("invalid table: mixed or invalid key types") + end + n = n + 1 +end +if n ~= #val then + error("invalid table: sparse array") +end +-- Encode +for i, v in ipairs(val) do + table.insert(res, encode(v, stack)) +end +stack[val] = nil +return "[" .. table.concat(res, ",") .. "]" + + else +-- Treat as an object +for k, v in pairs(val) do + if type(k) ~= "string" then +error("invalid table: mixed or invalid key types") + end + table.insert(res, encode(k, stack) .. ":" .. encode(v, stack)) +end +stack[val] = nil +return "{" .. table.concat(res, ",") .. "}" + end +end + + +local function encode_string(val) + return '"' .. val:gsub('[%z\1-\31\\"]', escape_char) .. '"' +end + + +local function encode_number(val) + -- Check for NaN, -inf and inf + if val ~= val or val <= -math.huge or val >= math.huge then +error("unexpected number value '" .. tostring(val) .. "'") + end + return string.format("%.14g", val) +end + + +local type_func_map = { + [ "nil" ] = encode_nil, + [ "table" ] = encode_table, + [ "string" ] = encode_string, + [ "number" ] = encode_number, + [ "boolean" ] = tostring, +} + + +encode = function(val, stack) + local t = type(val) + local f = type_func_map[t] + if f then +return f(val, stack) + end + error("unexpected type '" .. t .. "'") +end + + +function json.encode(val) + return ( encode(val) ) +end + + +--- +-- Decode +--- + +local parse + +local function create_set(...) + local res = {} + for i = 1, select("#", ...) do +res[ select(i, ...) ] = true + end + return res +end + +local space_chars = create_set(" ", "\t", "\r", "\n") +local delim_chars = create_set(" ", "\t", "\r", "\n", "]", "}", ",") +local escape_chars = create_set("\\", "/", '"', "b", "f", "n", "r", "t", "u") +local literals = create_set("true", "false", "null") + +local literal_map = { + [ "true" ] = true, + [ "false" ] = false, + [ "null" ] = nil, +} + + +local function next_char(str, idx, set, negate) + for i = idx, #str do +if set[str:sub(i, i)] ~= negate then + return i +end + end + return #str + 1 +end + + +local function decode_error(str, idx, msg) + local line_count = 1 + local col_count = 1 + for i = 1, idx - 1 do +col_count = col_count + 1 +if str:sub(i, i) == "\n" then + line_count = line_count + 1 + col_count = 1 +end + end + error( string.format("%s at line %d col %d", msg, line_count, col_count) ) +end + + +local function codepoint_to_utf8(n) + -- http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi=iws-appendixa + local f = math.floor + if n <= 0x7f then +return string.char(n) + elseif n <= 0x7ff then +return string.char(f(n / 64) + 192, n % 64 + 128) + elseif n <= 0x then +return string.char(f(n / 4096) + 224, f(n % 4096 / 64) + 128, n % 64 +