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).
* `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.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: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.
@@ -217,7 +217,7 @@ Types
* **string** : 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.
* **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
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?
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.
@@ -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.
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 {
@@ -277,6 +278,9 @@ Notice: If the tag is not declared in schema, the decoder will simply ignore the
bools 1 : *boolean
number 2 : 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)
```
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
=======

View File

@@ -84,14 +84,16 @@ lua_seti(lua_State *L, int index, lua_Integer n) {
#if defined(SPROTO_WEAK_TYPE)
static int64_t
tointegerx (lua_State *L, int idx, int *isnum) {
int64_t v;
if (lua_isnumber(L, idx)) {
v = (int64_t)(round(lua_tonumber(L, idx)));
if (isnum) *isnum = 1;
return v;
} else {
return lua_tointegerx(L, idx, isnum);
int _isnum = 0;
int64_t v = lua_tointegerx(L, idx, &_isnum);
if (!_isnum){
double num = lua_tonumberx(L, idx, &_isnum);
if(_isnum) {
v = (int64_t)llround(num);
}
}
if(isnum) *isnum = _isnum;
return v;
}
static int
@@ -613,7 +615,7 @@ getbuffer(lua_State *L, int index, size_t *sz) {
/*
lightuserdata sproto_type
string source / (lightuserdata , integer)
return table
return table, sz(decoded bytes)
*/
static int
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);
if (buffer == NULL)
return -1;
if (noarray) {
return 0;
}
@@ -1088,26 +1088,33 @@ expand64(uint32_t v) {
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
decode_array(sproto_callback cb, struct sproto_arg *args, uint8_t * stream) {
uint32_t sz = todword(stream);
int type = args->type;
int i;
if (sz == 0) {
// It's empty array, call cb with index == -1 to create the empty array.
args->index = -1;
args->value = NULL;
args->length = 0;
cb(args);
return 0;
}
return decode_empty_array(cb, args);
}
stream += SIZEOF_LENGTH;
switch (type) {
case SPROTO_TDOUBLE:
case SPROTO_TINTEGER: {
if (--sz == 0) {
// An empty array but with a len prefix
return decode_empty_array(cb, args);
}
int len = *stream;
++stream;
--sz;
if (len == SIZEOF_INT32) {
if (sz % SIZEOF_INT32 != 0)
return -1;