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