mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-25 04:33:05 +00:00
sproto update
This commit is contained in:
@@ -1,6 +1,40 @@
|
||||
local lpeg = require "lpeg"
|
||||
local table = require "table"
|
||||
|
||||
local packbytes
|
||||
local packvalue
|
||||
|
||||
if _VERSION == "Lua 5.3" then
|
||||
function packbytes(str)
|
||||
return string.pack("<s4",str)
|
||||
end
|
||||
|
||||
function packvalue(id)
|
||||
id = (id + 1) * 2
|
||||
return string.pack("<I2",id)
|
||||
end
|
||||
else
|
||||
function packbytes(str)
|
||||
local size = #str
|
||||
local a = size % 256
|
||||
size = math.floor(size / 256)
|
||||
local b = size % 256
|
||||
size = math.floor(size / 256)
|
||||
local c = size % 256
|
||||
size = math.floor(size / 256)
|
||||
local d = size
|
||||
return string.char(a)..string.char(b)..string.char(c)..string.char(d) .. str
|
||||
end
|
||||
|
||||
function packvalue(id)
|
||||
id = (id + 1) * 2
|
||||
assert(id >=0 and id < 65536)
|
||||
local a = id % 256
|
||||
local b = math.floor(id / 256)
|
||||
return string.char(a) .. string.char(b)
|
||||
end
|
||||
end
|
||||
|
||||
local P = lpeg.P
|
||||
local S = lpeg.S
|
||||
local R = lpeg.R
|
||||
@@ -35,6 +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 function multipat(pat)
|
||||
return Ct(blank0 * (pat * blanks) ^ 0 * pat^0 * blank0)
|
||||
@@ -46,7 +81,7 @@ end
|
||||
|
||||
local typedef = P {
|
||||
"ALL",
|
||||
FIELD = namedpat("field", (name * blanks * tag * blank0 * ":" * blank0 * (C"*")^0 * typename)),
|
||||
FIELD = namedpat("field", (name * blanks * tag * blank0 * ":" * blank0 * (C"*")^0 * typename * mainkey^0)),
|
||||
STRUCT = P"{" * multipat(V"FIELD" + V"TYPE") * P"}",
|
||||
TYPE = namedpat("type", P"." * name * blank0 * V"STRUCT" ),
|
||||
SUBPROTO = Ct((C"request" + C"response") * blanks * (name + V"STRUCT")),
|
||||
@@ -97,6 +132,11 @@ function convert.type(all, obj)
|
||||
field.array = true
|
||||
fieldtype = f[4]
|
||||
end
|
||||
local mainkey = f[5]
|
||||
if mainkey then
|
||||
assert(field.array)
|
||||
field.key = mainkey
|
||||
end
|
||||
field.typename = fieldtype
|
||||
else
|
||||
assert(f.type == "type") -- nest type
|
||||
@@ -176,6 +216,7 @@ 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.
|
||||
}
|
||||
name 0 : string
|
||||
fields 1 : *field
|
||||
@@ -194,25 +235,18 @@ end
|
||||
}
|
||||
]]
|
||||
|
||||
local function packbytes(str)
|
||||
str = string.pack("<s4",str)
|
||||
return str
|
||||
end
|
||||
|
||||
local function packvalue(id)
|
||||
id = (id + 1) * 2
|
||||
local str = string.pack("<I2", id)
|
||||
return str
|
||||
end
|
||||
|
||||
local function packfield(f)
|
||||
local strtbl = {}
|
||||
if f.array then
|
||||
table.insert(strtbl, "\5\0") -- 5 fields
|
||||
if f.key then
|
||||
table.insert(strtbl, "\6\0") -- 6 fields
|
||||
else
|
||||
table.insert(strtbl, "\5\0") -- 5 fields
|
||||
end
|
||||
else
|
||||
table.insert(strtbl, "\4\0") -- 4 fields
|
||||
end
|
||||
table.insert(strtbl, "\0\0") -- name (tag = 0, ref =0)
|
||||
table.insert(strtbl, "\0\0") -- name (tag = 0, ref an object)
|
||||
if f.buildin then
|
||||
table.insert(strtbl, packvalue(f.buildin)) -- buildin (tag = 1)
|
||||
table.insert(strtbl, "\1\0") -- skip (tag = 2)
|
||||
@@ -225,7 +259,10 @@ local function packfield(f)
|
||||
if f.array then
|
||||
table.insert(strtbl, packvalue(1)) -- array = true (tag = 4)
|
||||
end
|
||||
table.insert(strtbl, packbytes(f.name))
|
||||
if f.key then
|
||||
table.insert(strtbl, packvalue(f.key)) -- key tag (tag = 5)
|
||||
end
|
||||
table.insert(strtbl, packbytes(f.name)) -- external object (name)
|
||||
return packbytes(table.concat(strtbl))
|
||||
end
|
||||
|
||||
@@ -238,11 +275,22 @@ local function packtype(name, t, alltypes)
|
||||
tmp.tag = f.tag
|
||||
|
||||
tmp.buildin = buildin_types[f.typename]
|
||||
local subtype
|
||||
if not tmp.buildin then
|
||||
tmp.type = assert(alltypes[f.typename])
|
||||
subtype = assert(alltypes[f.typename])
|
||||
tmp.type = subtype.id
|
||||
else
|
||||
tmp.type = nil
|
||||
end
|
||||
if f.key then
|
||||
tmp.key = subtype.fields[f.key]
|
||||
if not tmp.key then
|
||||
error("Invalid map index :" .. f.key)
|
||||
end
|
||||
else
|
||||
tmp.key = nil
|
||||
end
|
||||
|
||||
table.insert(fields, packfield(tmp))
|
||||
end
|
||||
local data
|
||||
@@ -274,6 +322,7 @@ local function packproto(name, p, alltypes)
|
||||
if request == nil then
|
||||
error(string.format("Protocol %s request type %s not found", name, p.request))
|
||||
end
|
||||
request = request.id
|
||||
end
|
||||
local tmp = {
|
||||
"\4\0", -- 4 fields
|
||||
@@ -284,12 +333,12 @@ local function packproto(name, p, alltypes)
|
||||
tmp[1] = "\2\0"
|
||||
else
|
||||
if p.request then
|
||||
table.insert(tmp, packvalue(alltypes[p.request])) -- request typename (tag=2)
|
||||
table.insert(tmp, packvalue(alltypes[p.request].id)) -- request typename (tag=2)
|
||||
else
|
||||
table.insert(tmp, "\1\0")
|
||||
end
|
||||
if p.response then
|
||||
table.insert(tmp, packvalue(alltypes[p.response])) -- request typename (tag=3)
|
||||
table.insert(tmp, packvalue(alltypes[p.response].id)) -- request typename (tag=3)
|
||||
else
|
||||
tmp[1] = "\3\0"
|
||||
end
|
||||
@@ -312,7 +361,13 @@ local function packgroup(t,p)
|
||||
end
|
||||
table.sort(alltypes) -- make result stable
|
||||
for idx, name in ipairs(alltypes) do
|
||||
alltypes[name] = idx - 1
|
||||
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
|
||||
end
|
||||
alltypes[name] = { id = idx - 1, fields = fields }
|
||||
end
|
||||
tt = {}
|
||||
for _,name in ipairs(alltypes) do
|
||||
|
||||
Reference in New Issue
Block a user