update sproto (#1720)

Co-authored-by: zixun <lb151450@alibaba-inc.com>
This commit is contained in:
子熏
2023-03-21 21:37:03 +08:00
committed by GitHub
parent 1e45d4a9be
commit b9a5cec191
3 changed files with 66 additions and 20 deletions

View File

@@ -104,7 +104,7 @@ local sprotocore = require "sproto.core" -- optional
* `sproto.new(spbin)` creates a sproto object by a schema binary string (generates by parser). * `sproto.new(spbin)` creates a sproto object by a schema binary string (generates by parser).
* `sprotocore.newproto(spbin)` creates a sproto c object by a schema binary string (generates by parser). * `sprotocore.newproto(spbin)` creates a sproto c object by a schema binary string (generates by parser).
* `sproto.sharenew(spbin)` share a sproto object from a sproto c object (generates by sprotocore.newproto). * `sproto.sharenew(spbin)` share a sproto object from a sproto c object (generates by sprotocore.newproto).
* `sproto.parse(schema)` creares a sproto object by a schema text string (by calling parser.parse) * `sproto.parse(schema)` creates a sproto object by a schema text string (by calling parser.parse)
* `sproto:exist_type(typename)` detect whether a type exist in sproto object. * `sproto:exist_type(typename)` detect whether a type exist in sproto object.
* `sproto:encode(typename, luatable)` encodes a lua table with typename into a binary string. * `sproto:encode(typename, luatable)` encodes a lua table with typename into a binary string.
* `sproto:decode(typename, blob [,sz])` decodes a binary string generated by sproto.encode with typename. If blob is a lightuserdata (C ptr), sz (integer) is needed. * `sproto:decode(typename, blob [,sz])` decodes a binary string generated by sproto.encode with typename. If blob is a lightuserdata (C ptr), sz (integer) is needed.
@@ -217,7 +217,7 @@ Types
* **string** : string * **string** : string
* **binary** : binary string (it's a sub type of string) * **binary** : binary string (it's a sub type of string)
* **integer** : integer, the max length of an integer is signed 64bit. It can be a fixed-point number with specified precision. * **integer** : integer, the max length of an integer is signed 64bit. It can be a fixed-point number with specified precision.
* **double** : double, floating-point number. * **double** : double precision floating-point number, satisfy [the IEEE 754 standard](https://en.wikipedia.org/wiki/Double-precision_floating-point_format).
* **boolean** : true or false * **boolean** : true or false
You can add * before the typename to declare an array. You can add * before the typename to declare an array.
@@ -230,7 +230,7 @@ User defined type can be any name in alphanumeric characters except the build-in
* Where are double or real types? * Where are double or real types?
I have been using Google protocol buffers for many years in many projects, and I found the real types were seldom used. If you really need it, you can use string to serialize the double numbers. When you need decimal, you can specify the fixed-point presision. I have been using Google protocol buffers for many years in many projects, and I found the real types were seldom used. If you really need it, you can use string to serialize the double numbers. When you need decimal, you can specify the fixed-point precision.
**NOTE** : `double` is supported now. **NOTE** : `double` is supported now.
@@ -263,6 +263,7 @@ For integer array, an additional byte (4 or 8) to indicate the value is 32bit or
Read the examples below to see more details. Read the examples below to see more details.
Notice: If the tag is not declared in schema, the decoder will simply ignore the field for protocol version compatibility. Notice: If the tag is not declared in schema, the decoder will simply ignore the field for protocol version compatibility.
Notice more: all examples are tested in `test_wire_protocol.lua`, update `test_wire_protocol.lua` when update examples.
``` ```
.Person { .Person {
@@ -277,6 +278,9 @@ Notice: If the tag is not declared in schema, the decoder will simply ignore the
bools 1 : *boolean bools 1 : *boolean
number 2 : integer number 2 : integer
bignumber 3 : integer bignumber 3 : integer
double 4 : double
doubles 5 : *double
fpn 6 : integer(2)
} }
``` ```
@@ -405,6 +409,39 @@ A0 86 01 00 (100000, 32bit integer)
00 1C F4 AB FD FF FF FF (-10000000000, 64bit integer) 00 1C F4 AB FD FF FF FF (-10000000000, 64bit integer)
``` ```
Example 7:
```
data {
double = 0.01171875,
doubles = {0.01171875, 23, 4}
}
03 00 (fn = 3)
07 00 (skip id = 3)
00 00 (id = 4, value in data part)
00 00 (id = 5, value in data part)
08 00 00 00 (sizeof number, data part)
00 00 00 00 00 00 88 3f (0.01171875, 64bit double)
19 00 00 00 (sizeof doubles)
08 (sizeof double)
00 00 00 00 00 00 88 3f (0.01171875, 64bit double)
00 00 00 00 00 00 37 40 (23, 64bit double)
00 00 00 00 00 00 10 40 (4, 64bit double)
```
Example 8:
```
data {
fpn = 1.82,
}
02 00 (fn = 2)
0b 00 (skip id = 5)
6e 01 (id = 6, value = 0x16e/2 - 1 = 182)
```
0 Packing 0 Packing
======= =======

View File

@@ -84,14 +84,16 @@ lua_seti(lua_State *L, int index, lua_Integer n) {
#if defined(SPROTO_WEAK_TYPE) #if defined(SPROTO_WEAK_TYPE)
static int64_t static int64_t
tointegerx (lua_State *L, int idx, int *isnum) { tointegerx (lua_State *L, int idx, int *isnum) {
int64_t v; int _isnum = 0;
if (lua_isnumber(L, idx)) { int64_t v = lua_tointegerx(L, idx, &_isnum);
v = (int64_t)(round(lua_tonumber(L, idx))); if (!_isnum){
if (isnum) *isnum = 1; double num = lua_tonumberx(L, idx, &_isnum);
return v; if(_isnum) {
} else { v = (int64_t)llround(num);
return lua_tointegerx(L, idx, isnum); }
} }
if(isnum) *isnum = _isnum;
return v;
} }
static int static int
@@ -613,7 +615,7 @@ getbuffer(lua_State *L, int index, size_t *sz) {
/* /*
lightuserdata sproto_type lightuserdata sproto_type
string source / (lightuserdata , integer) string source / (lightuserdata , integer)
return table return table, sz(decoded bytes)
*/ */
static int static int
ldecode(lua_State *L) { ldecode(lua_State *L) {

View File

@@ -898,7 +898,7 @@ encode_array(sproto_callback cb, struct sproto_arg *args, uint8_t *data, int siz
buffer = encode_integer_array(cb,args,buffer,size, &noarray); buffer = encode_integer_array(cb,args,buffer,size, &noarray);
if (buffer == NULL) if (buffer == NULL)
return -1; return -1;
if (noarray) { if (noarray) {
return 0; return 0;
} }
@@ -1088,26 +1088,33 @@ expand64(uint32_t v) {
return value; return value;
} }
static int
decode_empty_array(sproto_callback cb, struct sproto_arg *args) {
// It's empty array, call cb with index == -1 to create the empty array.
args->index = -1;
args->value = NULL;
args->length = 0;
return cb(args);
}
static int static int
decode_array(sproto_callback cb, struct sproto_arg *args, uint8_t * stream) { decode_array(sproto_callback cb, struct sproto_arg *args, uint8_t * stream) {
uint32_t sz = todword(stream); uint32_t sz = todword(stream);
int type = args->type; int type = args->type;
int i; int i;
if (sz == 0) { if (sz == 0) {
// It's empty array, call cb with index == -1 to create the empty array. return decode_empty_array(cb, args);
args->index = -1; }
args->value = NULL;
args->length = 0;
cb(args);
return 0;
}
stream += SIZEOF_LENGTH; stream += SIZEOF_LENGTH;
switch (type) { switch (type) {
case SPROTO_TDOUBLE: case SPROTO_TDOUBLE:
case SPROTO_TINTEGER: { case SPROTO_TINTEGER: {
if (--sz == 0) {
// An empty array but with a len prefix
return decode_empty_array(cb, args);
}
int len = *stream; int len = *stream;
++stream; ++stream;
--sz;
if (len == SIZEOF_INT32) { if (len == SIZEOF_INT32) {
if (sz % SIZEOF_INT32 != 0) if (sz % SIZEOF_INT32 != 0)
return -1; return -1;