mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-22 02:53:09 +00:00
merge sproto
This commit is contained in:
@@ -166,10 +166,16 @@ encode(const struct sproto_arg *args) {
|
||||
lua_Integer v;
|
||||
lua_Integer vh;
|
||||
int isnum;
|
||||
v = lua_tointegerx(L, -1, &isnum);
|
||||
if(!isnum) {
|
||||
return luaL_error(L, ".%s[%d] is not an integer (Is a %s)",
|
||||
args->tagname, args->index, lua_typename(L, lua_type(L, -1)));
|
||||
if (args->extra) {
|
||||
// It's decimal.
|
||||
lua_Number vn = lua_tonumber(L, -1);
|
||||
v = (lua_Integer)(vn * args->extra + 0.5);
|
||||
} else {
|
||||
v = lua_tointegerx(L, -1, &isnum);
|
||||
if(!isnum) {
|
||||
return luaL_error(L, ".%s[%d] is not an integer (Is a %s)",
|
||||
args->tagname, args->index, lua_typename(L, lua_type(L, -1)));
|
||||
}
|
||||
}
|
||||
lua_pop(L,1);
|
||||
// notice: in lua 5.2, lua_Integer maybe 52bit
|
||||
@@ -332,8 +338,15 @@ decode(const struct sproto_arg *args) {
|
||||
switch (args->type) {
|
||||
case SPROTO_TINTEGER: {
|
||||
// notice: in lua 5.2, 52bit integer support (not 64)
|
||||
lua_Integer v = *(uint64_t*)args->value;
|
||||
lua_pushinteger(L, v);
|
||||
if (args->extra) {
|
||||
lua_Integer v = *(uint64_t*)args->value;
|
||||
lua_Number vn = (lua_Number)v;
|
||||
vn /= args->extra;
|
||||
lua_pushnumber(L, vn);
|
||||
} else {
|
||||
lua_Integer v = *(uint64_t*)args->value;
|
||||
lua_pushinteger(L, v);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPROTO_TBOOLEAN: {
|
||||
@@ -660,7 +673,7 @@ ldefault(lua_State *L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
LUAMOD_API int
|
||||
luaopen_sproto_core(lua_State *L) {
|
||||
#ifdef luaL_checkversion
|
||||
luaL_checkversion(L);
|
||||
|
||||
@@ -18,6 +18,7 @@ struct field {
|
||||
const char * name;
|
||||
struct sproto_type * st;
|
||||
int key;
|
||||
int extra;
|
||||
};
|
||||
|
||||
struct sproto_type {
|
||||
@@ -177,6 +178,18 @@ import_string(struct sproto *s, const uint8_t * stream) {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static int
|
||||
calc_pow(int base, int n) {
|
||||
int r;
|
||||
if (n == 0)
|
||||
return 1;
|
||||
r = calc_pow(base * base , n / 2);
|
||||
if (n&1) {
|
||||
r *= base;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static const uint8_t *
|
||||
import_field(struct sproto *s, struct field *f, const uint8_t * stream) {
|
||||
uint32_t sz;
|
||||
@@ -190,6 +203,7 @@ import_field(struct sproto *s, struct field *f, const uint8_t * stream) {
|
||||
f->name = NULL;
|
||||
f->st = NULL;
|
||||
f->key = -1;
|
||||
f->extra = 0;
|
||||
|
||||
sz = todword(stream);
|
||||
stream += SIZEOF_LENGTH;
|
||||
@@ -222,12 +236,18 @@ import_field(struct sproto *s, struct field *f, const uint8_t * stream) {
|
||||
f->type = value;
|
||||
break;
|
||||
case 2: // type index
|
||||
if (value >= s->type_n)
|
||||
return NULL; // invalid type index
|
||||
if (f->type >= 0)
|
||||
return NULL;
|
||||
f->type = SPROTO_TSTRUCT;
|
||||
f->st = &s->type[value];
|
||||
if (f->type == SPROTO_TINTEGER) {
|
||||
f->extra = calc_pow(10, value);
|
||||
} else if (f->type == SPROTO_TSTRING) {
|
||||
f->extra = value; // string if 0 ; binary is 1
|
||||
} else {
|
||||
if (value >= s->type_n)
|
||||
return NULL; // invalid type index
|
||||
if (f->type >= 0)
|
||||
return NULL;
|
||||
f->type = SPROTO_TSTRUCT;
|
||||
f->st = &s->type[value];
|
||||
}
|
||||
break;
|
||||
case 3: // tag
|
||||
f->tag = value;
|
||||
@@ -463,11 +483,6 @@ sproto_release(struct sproto * s) {
|
||||
void
|
||||
sproto_dump(struct sproto *s) {
|
||||
int i,j;
|
||||
static const char * buildin[] = {
|
||||
"integer",
|
||||
"boolean",
|
||||
"string",
|
||||
};
|
||||
printf("=== %d types ===\n", s->type_n);
|
||||
for (i=0;i<s->type_n;i++) {
|
||||
struct sproto_type *t = &s->type[i];
|
||||
@@ -476,25 +491,45 @@ sproto_dump(struct sproto *s) {
|
||||
char array[2] = { 0, 0 };
|
||||
const char * type_name = NULL;
|
||||
struct field *f = &t->f[j];
|
||||
int type = f->type & ~SPROTO_TARRAY;
|
||||
if (f->type & SPROTO_TARRAY) {
|
||||
array[0] = '*';
|
||||
} else {
|
||||
array[0] = 0;
|
||||
}
|
||||
{
|
||||
int t = f->type & ~SPROTO_TARRAY;
|
||||
if (t == SPROTO_TSTRUCT) {
|
||||
type_name = f->st->name;
|
||||
} else {
|
||||
assert(t<SPROTO_TSTRUCT);
|
||||
type_name = buildin[t];
|
||||
if (type == SPROTO_TSTRUCT) {
|
||||
type_name = f->st->name;
|
||||
} else {
|
||||
switch(type) {
|
||||
case SPROTO_TINTEGER:
|
||||
if (f->extra) {
|
||||
type_name = "decimal";
|
||||
} else {
|
||||
type_name = "integer";
|
||||
}
|
||||
break;
|
||||
case SPROTO_TBOOLEAN:
|
||||
type_name = "boolean";
|
||||
break;
|
||||
case SPROTO_TSTRING:
|
||||
if (f->extra == SPROTO_TSTRING_BINARY)
|
||||
type_name = "binary";
|
||||
else
|
||||
type_name = "string";
|
||||
break;
|
||||
default:
|
||||
type_name = "invalid";
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (f->key >= 0) {
|
||||
printf("\t%s (%d) %s%s(%d)\n", f->name, f->tag, array, type_name, f->key);
|
||||
} else {
|
||||
printf("\t%s (%d) %s%s\n", f->name, f->tag, array, type_name);
|
||||
printf("\t%s (%d) %s%s", f->name, f->tag, array, type_name);
|
||||
if (type == SPROTO_TINTEGER && f->extra > 0) {
|
||||
printf("(%d)", f->extra);
|
||||
}
|
||||
if (f->key >= 0) {
|
||||
printf("[%d]", f->key);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
printf("=== %d protocol ===\n", s->protocol_n);
|
||||
@@ -884,6 +919,7 @@ sproto_encode(const struct sproto_type *st, void * buffer, int size, sproto_call
|
||||
args.tagid = f->tag;
|
||||
args.subtype = f->st;
|
||||
args.mainindex = f->key;
|
||||
args.extra = f->extra;
|
||||
if (type & SPROTO_TARRAY) {
|
||||
args.type = type & ~SPROTO_TARRAY;
|
||||
sz = encode_array(cb, &args, data, size);
|
||||
@@ -1116,6 +1152,7 @@ sproto_decode(const struct sproto_type *st, const void * data, int size, sproto_
|
||||
args.subtype = f->st;
|
||||
args.index = 0;
|
||||
args.mainindex = f->key;
|
||||
args.extra = f->extra;
|
||||
if (value < 0) {
|
||||
if (f->type & SPROTO_TARRAY) {
|
||||
if (decode_array(cb, &args, currentdata)) {
|
||||
|
||||
@@ -9,11 +9,16 @@ struct sproto_type;
|
||||
#define SPROTO_REQUEST 0
|
||||
#define SPROTO_RESPONSE 1
|
||||
|
||||
// type (sproto_arg.type)
|
||||
#define SPROTO_TINTEGER 0
|
||||
#define SPROTO_TBOOLEAN 1
|
||||
#define SPROTO_TSTRING 2
|
||||
#define SPROTO_TSTRUCT 3
|
||||
|
||||
// sub type of string (sproto_arg.extra)
|
||||
#define SPROTO_TSTRING_STRING 0
|
||||
#define SPROTO_TSTRING_BINARY 1
|
||||
|
||||
#define SPROTO_CB_ERROR -1
|
||||
#define SPROTO_CB_NIL -2
|
||||
#define SPROTO_CB_NOARRAY -3
|
||||
@@ -41,6 +46,7 @@ struct sproto_arg {
|
||||
int length;
|
||||
int index; // array base 1
|
||||
int mainindex; // for map
|
||||
int extra; // SPROTO_TINTEGER: decimal ; SPROTO_TSTRING 0:utf8 string 1:binary
|
||||
};
|
||||
|
||||
typedef int (*sproto_callback)(const struct sproto_arg *args);
|
||||
|
||||
@@ -70,6 +70,7 @@ local name = C(word)
|
||||
local typename = C(word * ("." * word) ^ 0)
|
||||
local tag = R"09" ^ 1 / tonumber
|
||||
local mainkey = "(" * blank0 * name * blank0 * ")"
|
||||
local decimal = "(" * blank0 * C(tag) * blank0 * ")"
|
||||
|
||||
local function multipat(pat)
|
||||
return Ct(blank0 * (pat * blanks) ^ 0 * pat^0 * blank0)
|
||||
@@ -81,7 +82,7 @@ end
|
||||
|
||||
local typedef = P {
|
||||
"ALL",
|
||||
FIELD = namedpat("field", (name * blanks * tag * blank0 * ":" * blank0 * (C"*")^-1 * typename * mainkey^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")),
|
||||
@@ -134,8 +135,12 @@ function convert.type(all, obj)
|
||||
end
|
||||
local mainkey = f[5]
|
||||
if mainkey then
|
||||
assert(field.array)
|
||||
field.key = mainkey
|
||||
if fieldtype == "integer" then
|
||||
field.decimal = mainkey
|
||||
else
|
||||
assert(field.array)
|
||||
field.key = mainkey
|
||||
end
|
||||
end
|
||||
field.typename = fieldtype
|
||||
else
|
||||
@@ -167,6 +172,7 @@ local buildin_types = {
|
||||
integer = 0,
|
||||
boolean = 1,
|
||||
string = 2,
|
||||
binary = 2, -- binary is a sub type of string
|
||||
}
|
||||
|
||||
local function checktype(types, ptype, t)
|
||||
@@ -275,7 +281,11 @@ local function packfield(f)
|
||||
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)
|
||||
if f.extra then
|
||||
table.insert(strtbl, packvalue(f.extra)) -- f.buildin can be integer or string
|
||||
else
|
||||
table.insert(strtbl, "\1\0") -- skip (tag = 2)
|
||||
end
|
||||
table.insert(strtbl, packvalue(f.tag)) -- tag (tag = 3)
|
||||
else
|
||||
table.insert(strtbl, "\1\0") -- skip (tag = 1)
|
||||
@@ -299,8 +309,12 @@ local function packtype(name, t, alltypes)
|
||||
tmp.array = f.array
|
||||
tmp.name = f.name
|
||||
tmp.tag = f.tag
|
||||
tmp.extra = f.decimal
|
||||
|
||||
tmp.buildin = buildin_types[f.typename]
|
||||
if f.typename == "binary" then
|
||||
tmp.extra = 1 -- binary is sub type of string
|
||||
end
|
||||
local subtype
|
||||
if not tmp.buildin then
|
||||
subtype = assert(alltypes[f.typename])
|
||||
|
||||
Reference in New Issue
Block a user