Skip to content
Permalink
master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
local M = {}
M.decoder = function (callbacks)
local pos, level = 1, 0
local s, machine, emb_any
local str_length = 0
local function to_state(f)
machine = f
return machine()
end
local accum_number = 0
local function emb_int()
if pos > #s then return end
local ch = s:sub(pos, pos)
pos = pos + 1
if ch == 'e' then
callbacks.push_number(level, accum_number)
accum_number = 0
return to_state(emb_any);
end
accum_number = 10*accum_number + ch:byte() - 48 --tonumber(ch)
return emb_int()
end
local function emb_str ()
if pos > #s then return end
if str_length > #s-pos+1 then
local fragment = s:sub(pos, -1)
callbacks.push_string_fragment(level, fragment)
str_length = str_length - #fragment
pos = #s+1
return emb_str()
else
callbacks.push_string_fragment(level, s:sub(pos, pos+str_length-1))
callbacks.push_string_fragment(level, nil)
pos = pos + str_length
return to_state(emb_any)
end
end
--local buf_length = ''
local function emb_len()
if pos > #s then return end
local ch = s:sub(pos, pos)
pos = pos + 1
if ch == ':' then
callbacks.push_string_len(level, str_length)
return to_state(emb_str)
end
str_length = 10*str_length + ch:byte() - 48 --tonumber(ch)
return emb_len()
end
local function emb_list ()
callbacks.push_list(level)
level = level + 1
return to_state(emb_any)
end
local function emb_dict ()
callbacks.push_dict(level)
level = level + 1
return to_state(emb_any)
end
emb_any = function ()
if pos > #s then return end
local ch = s:sub(pos, pos)
if ch == 'i' then
pos = pos + 1
return to_state(emb_int)
elseif ch == 'd' then
pos = pos + 1
return to_state(emb_dict)
elseif ch == 'l' then
pos = pos + 1
return to_state(emb_list)
elseif ch == 'e' then
pos, level = pos + 1, level - 1
callbacks.push_pop(level)
return to_state(emb_any)
elseif ch>='0' and ch<='9' then
str_length = 0
return to_state(emb_len)
end
error() --TODO
end
machine = emb_any
return function (in_s)
s, pos = in_s, 1
return machine(callbacks)
end
end
M.encoder = function (callback)
return {
push_number = function (n)
callback('i')
callback(tostring(n))
callback('e')
end,
push_dict = function ()
callback('d')
end,
push_list = function ()
callback('l')
end,
push_string = function (s)
callback(tostring(#s))
callback(':')
callback(tostring(s))
end,
push_string_length = function (n)
callback(tostring(n))
callback(':')
end,
push_string_fragment = function (s)
callback(s)
end,
pop = function ()
callback('e')
end,
}
end
return M