mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-24 20:23:06 +00:00
Add map for sproto
This commit is contained in:
@@ -4,7 +4,7 @@ local table = require "table"
|
||||
local packbytes
|
||||
local packvalue
|
||||
|
||||
if _VERSION == "Lua 5.4" then
|
||||
if _VERSION == "Lua 5.3" then
|
||||
function packbytes(str)
|
||||
return string.pack("<s4",str)
|
||||
end
|
||||
@@ -69,7 +69,7 @@ local word = alpha * alnum ^ 0
|
||||
local name = C(word)
|
||||
local typename = C(word * ("." * word) ^ 0)
|
||||
local tag = R"09" ^ 1 / tonumber
|
||||
local mainkey = "(" * blank0 * name * blank0 * ")"
|
||||
local mainkey = "(" * blank0 * C((word ^ 0)) * blank0 * ")"
|
||||
local decimal = "(" * blank0 * C(tag) * blank0 * ")"
|
||||
|
||||
local function multipat(pat)
|
||||
@@ -82,7 +82,7 @@ end
|
||||
|
||||
local typedef = P {
|
||||
"ALL",
|
||||
FIELD = namedpat("field", (name * blanks * tag * blank0 * ":" * blank0 * (C"*")^-1 * typename * (mainkey + decimal)^0)),
|
||||
FIELD = namedpat("field", name * blanks * tag * blank0 * ":" * blank0 * (C"*")^-1 * typename * (mainkey + decimal)^0),
|
||||
STRUCT = P"{" * multipat(V"FIELD" + V"TYPE") * P"}",
|
||||
TYPE = namedpat("type", P"." * name * blank0 * V"STRUCT" ),
|
||||
SUBPROTO = Ct((C"request" + C"response") * blanks * (typename + V"STRUCT")),
|
||||
@@ -118,6 +118,11 @@ function convert.protocol(all, obj)
|
||||
return result
|
||||
end
|
||||
|
||||
local map_keytypes = {
|
||||
integer = true,
|
||||
string = true,
|
||||
}
|
||||
|
||||
function convert.type(all, obj)
|
||||
local result = {}
|
||||
local typename = obj[1]
|
||||
@@ -258,7 +263,8 @@ end
|
||||
type 2 : integer
|
||||
tag 3 : integer
|
||||
array 4 : boolean
|
||||
key 5 : integer # If key exists, array must be true, and it's a map.
|
||||
key 5 : integer # If key exists, array must be true
|
||||
map 6 : boolean # Interpret two fields struct as map when decoding
|
||||
}
|
||||
name 0 : string
|
||||
fields 1 : *field
|
||||
@@ -282,7 +288,11 @@ local function packfield(f)
|
||||
local strtbl = {}
|
||||
if f.array then
|
||||
if f.key then
|
||||
table.insert(strtbl, "\6\0") -- 6 fields
|
||||
if f.map then
|
||||
table.insert(strtbl, "\7\0") -- 7 fields
|
||||
else
|
||||
table.insert(strtbl, "\6\0") -- 6 fields
|
||||
end
|
||||
else
|
||||
table.insert(strtbl, "\5\0") -- 5 fields
|
||||
end
|
||||
@@ -305,9 +315,12 @@ local function packfield(f)
|
||||
end
|
||||
if f.array then
|
||||
table.insert(strtbl, packvalue(1)) -- array = true (tag = 4)
|
||||
end
|
||||
if f.key then
|
||||
table.insert(strtbl, packvalue(f.key)) -- key tag (tag = 5)
|
||||
if f.key then
|
||||
table.insert(strtbl, packvalue(f.key)) -- key tag (tag = 5)
|
||||
if f.map then
|
||||
table.insert(strtbl, packvalue(f.map)) -- map tag (tag = 6)
|
||||
end
|
||||
end
|
||||
end
|
||||
table.insert(strtbl, packbytes(f.name)) -- external object (name)
|
||||
return packbytes(table.concat(strtbl))
|
||||
@@ -334,10 +347,27 @@ local function packtype(name, t, alltypes)
|
||||
tmp.type = nil
|
||||
end
|
||||
if f.key then
|
||||
tmp.key = subtype.fields[f.key]
|
||||
if not tmp.key then
|
||||
assert(f.array)
|
||||
if f.key == "" then
|
||||
tmp.map = 1
|
||||
local c = 0
|
||||
local min_t = math.maxinteger
|
||||
for n, t in pairs(subtype.fields) do
|
||||
c = c + 1
|
||||
if t.tag < min_t then
|
||||
min_t = t.tag
|
||||
f.key = n
|
||||
end
|
||||
end
|
||||
if c ~= 2 then
|
||||
error(string.format("Invalid map definition: %s, must only have two fields", tmp.name))
|
||||
end
|
||||
end
|
||||
local stfield = subtype.fields[f.key]
|
||||
if not stfield or not stfield.buildin then
|
||||
error("Invalid map index :" .. f.key)
|
||||
end
|
||||
tmp.key = stfield.tag
|
||||
else
|
||||
tmp.key = nil
|
||||
end
|
||||
@@ -415,9 +445,10 @@ local function packgroup(t,p)
|
||||
for idx, name in ipairs(alltypes) do
|
||||
local fields = {}
|
||||
for _, type_fields in ipairs(t[name]) do
|
||||
if buildin_types[type_fields.typename] then
|
||||
fields[type_fields.name] = type_fields.tag
|
||||
end
|
||||
fields[type_fields.name] = {
|
||||
tag = type_fields.tag,
|
||||
buildin = buildin_types[type_fields.typename]
|
||||
}
|
||||
end
|
||||
alltypes[name] = { id = idx - 1, fields = fields }
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user