Module:User:Surjection/packer
Appearance
- This module sandbox lacks a documentation subpage. Please create it.
- Useful links: root page • root page’s subpages • links • transclusions • testcases • sandbox
local export = {}
-- see [[Module:User:Surjection/unpacker]] for format
local common_keys = {
"from", "remove_diacritics",
"type", "ancestors", "wikimedia_codes", "wikipedia_article", "translit",
"link_tr", "display_text", "entry_name", "sort_key", "dotted_dotless_i",
"standardChars"
}
local pack_table = nil
local function trim31(s)
local trim = #s
while trim > 0 and s:byte(trim) == 31 do trim = trim - 1 end
if trim < #s then return s:sub(1, trim) end
return s
end
local function pack_table_value(v, common_keys, implicit)
local t = type(v)
if v == nil then
return "\016"
elseif t == "boolean" then
return string.char(17, v and 1 or 0)
elseif t == "number" then
return "\018" .. tostring(v) .. "\031"
elseif t == "string" then
return "\019" .. v .. "\031"
elseif t == "table" then
return trim31("\020" .. pack_table(v, common_keys)) .. "\003"
else
error("cannot encode '" .. t .. "")
end
end
pack_table = function (tbl, common_keys)
local max_index = 0
local s = ""
for index, value in ipairs(tbl) do
s = trim31(s)
s = s .. pack_table_value(value, common_keys)
max_index = index
end
for key, value in pairs(tbl) do
if type(key) == "number" then
if key <= 0 or key > max_index then
s = trim31(s)
s = string.char(2) .. tostring(key) .. pack_table_value(value, common_keys)
end
elseif type(key) == "string" then
local compression = common_keys[key]
local skey
if compression ~= nil and compression <= 255 and #key > 2 then
s = trim31(s)
key = string.char(5, compression)
elseif #key == 0 then
s = trim31(s)
key = string.char(2)
end
s = s .. key .. pack_table_value(value, common_keys)
end
end
return s
end
function export.pack_rows(list, common_keys)
local s = ""
local common_key_indexes = {}
for index, key in ipairs(common_keys) do
common_key_indexes[key] = index
end
for top_key, top_value in pairs(list) do
s = s .. string.char(1) .. top_key .. string.char(4) .. pack_table(top_value, common_key_indexes)
local trim = #s
while trim > 0 and (s:byte(trim) == 3 or s:byte(trim) == 31) do trim = trim - 1 end
if trim < #s then s = s:sub(1, trim) end
end
return s .. string.char(1)
end
export.common_keys = common_keys
return export