commit b5103027386a74d2b929689d2f74f4541e2b0b76
parent 94e2e6ea19317dc809ba386684a7569b5d65f42c
Author: Remy Noulin <loader2x@gmail.com>
Date: Sat, 13 Oct 2018 20:30:16 +0200
add netSerial level 0, 1, 2 and 3 (default)
README.md | 106 +
memTest.c.template | 23 +
memcheckNetSerial.c | 1537 ++++++++++
netSerial.c | 5260 +++++++++++++++++++++++++++++++++++
netSerial.c.gcov | 7713 +++++++++++++++++++++++++++++++++++++++++++++++++++
netSerial.h | 106 +
netSerialInternal.h | 61 +
package.yml | 28 +
runMemtest.c | 108 +
test.c | 95 +
testNetSerial.c | 1565 +++++++++++
testNetSerial.sh | 5 +
testNetSerialMem.sh | 2 +
13 files changed, 16609 insertions(+)
Diffstat:
| A | README.md | | | 106 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | memTest.c.template | | | 24 | ++++++++++++++++++++++++ |
| A | memcheckNetSerial.c | | | 1537 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | netSerial.c | | | 5260 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | netSerial.c.gcov | | | 7713 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | netSerial.h | | | 106 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | netSerialInternal.h | | | 61 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | package.yml | | | 28 | ++++++++++++++++++++++++++++ |
| A | runMemtest.c | | | 109 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | test.c | | | 95 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | testNetSerial.c | | | 1565 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | testNetSerial.sh | | | 5 | +++++ |
| A | testNetSerialMem.sh | | | 3 | +++ |
13 files changed, 16612 insertions(+), 0 deletions(-)
diff --git a/README.md b/README.md
@@ -0,0 +1,106 @@
+# Sheepy
+This is a sheepy package for [sheepy](https://github.com/RemyNoulin/sheepy) and using [libsheepy](https://github.com/RemyNoulin/libsheepy)
+
+# netSerial
+
+netSerial is a serializer/deserializer for JSON data structures that has compact binary format.
+
+In general, it gives smaller bitstreams than JSON strings and smallJson serializer bitstream.
+
+The netSerial serializer is in average 1.5 times slower than the smallJson serializer.
+
+# Usage
+
+Install with spm: `spm install netSerial`
+
+Include netSerial: `#include "shpPackages/netSerial/netSerial.h"`, then:
+
+```c
+// create a netSerial object:
+createNetSerial(n);
+
+// create a JSON
+parseG(&n, "[3,270,-86942]");
+
+smallBytest *bitstream = serialG(&n);
+```
+
+# Encoding
+
+Data types are encoding on 4 bits:
+- undefined
+- bool
+- dict
+- double
+- varint
+- string
+- array
+- bytes = faststring
+- packed dict
+- packed double
+- packed varint
+- packed string
+- packed array
+- packed bytes
+- dict - all elements have same type
+- array - all elements have same type
+
+Integers are encoded as varint (n <<1 ^ n >> 63, see [protobuf](https://developers.google.com/protocol-buffers/docs/encoding)) and lengths (array, dictionary) are encoded as varuint.
+
+The integer _150_ is encoded as `0xc4 0x25`.
+
+- 0xc_4_ is integer type
+- 0x_c_4 are the first 3 bits in 150, bit 7 is set so next byte represents the 7 next bits in 150
+- _0x25_ are last bits in 150
+
+The encoding of `[3,270,-86942]` gives:
+```
+0x4f - uniform array of varint elements
+0x03 - 3 elements
+0x06 - int 3
+0x9c 0x04 - int 270
+0xbb 0xce 0x0a - int -86942
+```
+
+The arrays have 2 variants: normal and uniform.
+
+Normal arrays have elements of any types whereas uniform arrays have only one type of elements.
+
+For example, `[null,null,null]` is an uniform array of undefined values, encoded as:
+```
+0x0f - uniform array of undefined(null) elements
+0x03 - 3 elements
+```
+
+undefined is a type without data, only the element count is needed to represent an array of null elements.
+
+The bool type is encoded in 4bits type + 1 bit data and are packed by default:
+
+```
+{"sdf":true,"0":null,"1":null,"2":true,"3":true}
+
+0x52 - dictionary with 5 elements
+0x73 0x64 0x66 0x00 - "sdf" string
+0x71 - bool type and bool data for bool 1,2 and 3 (true)
+0x30 0x00 - "0" string
+0x00 - undefined 1 and 2
+0x31 0x00 - "1" string
+0x32 0x00 - "2" string
+0x11 - bool type 2 and 3
+0x33 0x00 - "3" string
+```
+
+Encoding a dictionary and an array:
+```
+{"a":[3,270,-86942]}
+
+0xfe - uniform dictionary of uniform arrays
+0x01 - 1 element
+0x61 0x00 - "a" string
+0x34 - int type and 3 elements
+0x06 - int 3
+0x9c 0x04 - int 270
+0xbb 0xce 0x0a - int -86942
+```
+
+-
diff --git a/memTest.c.template b/memTest.c.template
@@ -0,0 +1,23 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define ck_assert_str_eq(a,b) a;b;
+#define ck_assert_str_ne(a,b) a;b;
+#define ck_assert_ptr_eq(a,b) a;b;
+#define ck_assert_ptr_ne(a,b) a;b;
+#define ck_assert_uint_eq(a,b) a;b;
+#define ck_assert_uint_ne(a,b) a;b;
+#define ck_assert_int_eq(a,b) a;b;
+#define ck_assert_int_ne(a,b) a;b;
+#define ck_assert(a) a;
+
+__tests
+
+int main(int n, char**v) {
+
+initLibsheepy(v[0]);
+setLogMode(LOG_FUNC);
+
+__calls
+}+
\ No newline at end of file
diff --git a/memcheckNetSerial.c b/memcheckNetSerial.c
@@ -0,0 +1,1537 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define ck_assert_str_eq(a,b) a;b;
+#define ck_assert_str_ne(a,b) a;b;
+#define ck_assert_ptr_eq(a,b) a;b;
+#define ck_assert_ptr_ne(a,b) a;b;
+#define ck_assert_uint_eq(a,b) a;b;
+#define ck_assert_uint_ne(a,b) a;b;
+#define ck_assert_int_eq(a,b) a;b;
+#define ck_assert_int_ne(a,b) a;b;
+#define ck_assert(a) a;
+
+
+#include "libsheepyObject.h"
+#include "netSerial.h"
+
+int argc; char **argv;
+
+/* enable/disable logging */
+/* #undef pLog */
+/* #define pLog(...) */
+
+
+void topT(void) {
+
+ // STEPS
+ // init
+ // init allocate
+ // terminate
+ // allocate
+ // string
+ // duplicate
+
+ createNetSerial(n);
+ createNetSerial(ds);
+ char *s;
+ smallBytest *B;
+ createSmallDict(d);
+ createSmallArray(a);
+
+ // undefined
+ undefinedt *oU = allocUndefined();
+ setTopNFreeG(&n, (baset *)oU);
+ B = serialG(&n);
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "null");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // bool
+ setTopG(&n, TRUE);
+ B = serialG(&n);
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[17]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "true");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // double
+ setTopG(&n, 1.2);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s", toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[3,51,51,51,51,51,51,-13,63]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "1.200000e+00");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // int
+ setTopG(&n, 120);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[-12,30]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "120");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // string
+ setTopG(&n, "string");
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[5,115,116,114,105,110,103,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "string");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // dict
+ setG(&d, "k", 4);
+ setTopG(&n, &d);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[78,1,107,0,8]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"k\":4}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // array
+ pushG(&a, "k");
+ pushG(&a, 4);
+ setTopG(&n, &a);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[38,69,107,0,8]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[\"k\",4]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+}
+
+
+
+void uniformDictT(void) {
+
+ // STEPS
+ // init
+ // init allocate
+ // terminate
+ // allocate
+ // string
+ // duplicate
+
+ createNetSerial(n);
+ createNetSerial(ds);
+ char *s;
+ smallBytest *B;
+ createSmallDict(d);
+ createSmallDict(dd);
+ createSmallArray(a);
+
+ // undefined
+ undefinedt *oU = allocUndefined();
+ setG(&d, "0", oU);
+ setG(&d, "1", oU);
+ setG(&d, "2", oU);
+ setG(&d, "3", oU);
+ setG(&d, "4", oU);
+ setNFreeG(&d, "5", oU);
+ setTopG(&n, &d);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[14,6,48,0,49,0,50,0,51,0,52,0,53,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":null,\"1\":null,\"2\":null,\"3\":null,\"4\":null,\"5\":null}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // empty dict
+ initiateG(&d);
+ setTopG(&n, &d);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[14,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // bool
+ initiateG(&d);
+ setG(&d, "0", TRUE);
+ setG(&d, "1", TRUE);
+ setG(&d, "2", TRUE);
+ setG(&d, "3", TRUE);
+ setTopG(&n, &d);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[30,4,48,0,15,49,0,50,0,51,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":true,\"1\":true,\"2\":true,\"3\":true}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // 9 bools
+ initiateG(&d);
+ setG(&d, "0", TRUE);
+ setG(&d, "1", TRUE);
+ setG(&d, "2", TRUE);
+ setG(&d, "3", TRUE);
+ setG(&d, "4", TRUE);
+ setG(&d, "5", TRUE);
+ setG(&d, "6", TRUE);
+ setG(&d, "7", TRUE);
+ setG(&d, "8", TRUE);
+ setTopG(&n, &d);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[30,9,48,0,-1,49,0,50,0,51,0,52,0,53,0,54,0,55,0,56,0,1]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":true,\"1\":true,\"2\":true,\"3\":true,\"4\":true,\"5\":true,\"6\":true,\"7\":true,\"8\":true}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+
+ // double
+ initiateG(&d);
+ setG(&d, "0", 1.1);
+ setG(&d, "1", 2.2);
+ setG(&d, "2", 3.3);
+ setTopG(&n, &d);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[62,3,48,0,-10,-10,-10,-10,-10,-10,-15,63,49,0,-10,-10,-10,-10,-10,-10,1,64,50,0,102,102,102,102,102,102,10,64]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":1.100000e+00,\"1\":2.200000e+00,\"2\":3.300000e+00}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // int
+ initiateG(&d);
+ setG(&d, "0", 1);
+ setG(&d, "1", 2);
+ setTopG(&n, &d);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[78,2,48,0,2,49,0,4]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":1,\"1\":2}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // string
+ initiateG(&d);
+ setG(&d, "0", "a");
+ setG(&d, "1", "A");
+ setG(&d, "2", "z");
+ setTopG(&n, &d);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[94,3,48,0,97,0,49,0,65,0,50,0,122,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":\"a\",\"1\":\"A\",\"2\":\"z\"}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // dict
+ initiateG(&d);
+ setG(&dd, "9", "z");
+ setG(&dd, "1", 1);
+ setG(&d, "0", &dd);
+ initiateG(&dd);
+ setG(&dd, "Z", "-");
+ setG(&dd, "A", 234);
+ setG(&d, "1", &dd);
+ setTopG(&n, &d);
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[46,2,48,0,2,57,0,69,122,0,49,0,2,49,0,2,90,0,69,45,0,65,0,-44,3]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":{\"9\":\"z\",\"1\":1},\"1\":{\"Z\":\"-\",\"A\":234}}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // uniform dict
+ initiateG(&dd);
+ initiateG(&d);
+ setG(&dd, "9", 1);
+ setG(&dd, "1", 2);
+ setG(&d, "0", &dd);
+ initiateG(&dd);
+ setG(&dd, "Z", "-");
+ setG(&dd, "A", "+");
+ setG(&d, "1", &dd);
+ setTopG(&n, &d);
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[-18,2,48,0,36,57,0,2,49,0,4,49,0,37,90,0,45,0,65,0,43,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":{\"9\":1,\"1\":2},\"1\":{\"Z\":\"-\",\"A\":\"+\"}}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // array
+ initiateG(&d);
+ pushG(&a, "k");
+ pushG(&a, 4);
+ setG(&d, "0", &a);
+ setTopG(&n, &d);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[110,1,48,0,2,69,107,0,8]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":[\"k\",4]}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // uniform array
+ initiateG(&d);
+ initiateG(&a);
+ pushG(&a, 1);
+ pushG(&a, 2);
+ pushG(&a, 3);
+ pushG(&a, 4);
+ setG(&d, "0", &a);
+ setTopG(&n, &d);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[-2,1,48,0,68,2,4,6,8]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":[1,2,3,4]}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+}
+
+
+// uniformArray
+void uniformArrayT(void) {
+
+ // STEPS
+ // init
+ // init allocate
+ // terminate
+ // allocate
+ // string
+ // duplicate
+
+ createNetSerial(n);
+ createNetSerial(ds);
+ char *s;
+ smallBytest *B;
+ createSmallArray(A);
+ createSmallDict(dd);
+ createSmallArray(a);
+
+ // undefined
+ undefinedt *oU = allocUndefined();
+ pushG(&A, oU);
+ pushG(&A, oU);
+ pushG(&A, oU);
+ pushG(&A, oU);
+ pushG(&A, oU);
+ pushNFreeG(&A, oU);
+ setTopG(&n, &A);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[15,6]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[null,null,null,null,null,null]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // empty dict
+ initiateG(&A);
+ setTopG(&n, &A);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[15,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // bool
+ initiateG(&A);
+ pushG(&A, TRUE);
+ pushG(&A, TRUE);
+ pushG(&A, TRUE);
+ pushG(&A, TRUE);
+ setTopG(&n, &A);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[31,4,15]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[true,true,true,true]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // double
+ initiateG(&A);
+ pushG(&A, 1.1);
+ pushG(&A, 2.2);
+ pushG(&A, 3.3);
+ setTopG(&n, &A);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[63,3,-10,-10,-10,-10,-10,-10,-15,63,-10,-10,-10,-10,-10,-10,1,64,102,102,102,102,102,102,10,64]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[1.100000e+00,2.200000e+00,3.300000e+00]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // int
+ initiateG(&A);
+ pushG(&A, 1);
+ pushG(&A, 2);
+ setTopG(&n, &A);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[79,2,2,4]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[1,2]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // string
+ initiateG(&A);
+ pushG(&A, "a");
+ pushG(&A, "A");
+ pushG(&A, "z");
+ setTopG(&n, &A);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[95,3,97,0,65,0,122,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[\"a\",\"A\",\"z\"]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // dict
+ initiateG(&A);
+ setG(&dd, "9", "z");
+ setG(&dd, "1", 1);
+ pushG(&A, &dd);
+ initiateG(&dd);
+ setG(&dd, "Z", "-");
+ setG(&dd, "A", 234);
+ pushG(&A, &dd);
+ setTopG(&n, &A);
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[47,2,2,57,0,69,122,0,49,0,2,2,90,0,69,45,0,65,0,-44,3]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[{\"9\":\"z\",\"1\":1},{\"Z\":\"-\",\"A\":234}]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // uniform dict
+ initiateG(&dd);
+ initiateG(&A);
+ setG(&dd, "9", 1);
+ setG(&dd, "1", 2);
+ pushG(&A, &dd);
+ initiateG(&dd);
+ setG(&dd, "Z", "-");
+ setG(&dd, "A", "+");
+ pushG(&A, &dd);
+ setTopG(&n, &A);
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[-17,2,36,57,0,2,49,0,4,37,90,0,45,0,65,0,43,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[{\"9\":1,\"1\":2},{\"Z\":\"-\",\"A\":\"+\"}]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // array
+ initiateG(&A);
+ pushG(&a, "k");
+ pushG(&a, 4);
+ pushG(&A, &a);
+ setTopG(&n, &A);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[111,1,2,69,107,0,8]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[[\"k\",4]]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ initiateG(&A);
+ initiateG(&a);
+ pushG(&a, 1);
+ pushG(&a, 2);
+ pushG(&a, 3);
+ pushG(&a, 4);
+ pushG(&A, &a);
+ setTopG(&n, &A);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[-1,1,68,2,4,6,8]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[[1,2,3,4]]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // many bools in uniform array
+ parseG(&n, "[true,true,true,true,true,true,true,true,false,true]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[31,10,-1,2]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[true,true,true,true,true,true,true,true,false,true]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+}
+
+
+// dict with values, dict, array, uniforms, packed test high/low nibbles
+void dictT(void) {
+
+ // STEPS
+ // init
+ // init allocate
+ // terminate
+ // allocate
+ // string
+ // duplicate
+
+ createNetSerial(n);
+ createNetSerial(ds);
+ char *s;
+ smallBytest *B;
+ createSmallDict(d);
+ createSmallDict(dd);
+ createSmallArray(a);
+
+ // null and uniform dict
+ initiateG(&d);
+ setG(&d, "0", NULL);
+ initiateG(&dd);
+ setG(&dd, "Z", "-");
+ setG(&dd, "A", "+");
+ setG(&d, "1", &dd);
+ setTopG(&n, &d);
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[34,48,0,-32,49,0,37,90,0,45,0,65,0,43,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":null,\"1\":{\"Z\":\"-\",\"A\":\"+\"}}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // null and dict
+ initiateG(&d);
+ setG(&d, "0", NULL);
+ initiateG(&dd);
+ setG(&dd, "Z", "-");
+ setG(&dd, "A", 1);
+ setG(&d, "1", &dd);
+ setTopG(&n, &d);
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[34,48,0,32,49,0,2,90,0,69,45,0,65,0,2]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":null,\"1\":{\"Z\":\"-\",\"A\":1}}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // bool and uniform dict
+ initiateG(&d);
+ setG(&d, "0", TRUE);
+ initiateG(&dd);
+ setG(&dd, "Z", "-");
+ setG(&dd, "A", "+");
+ setG(&d, "1", &dd);
+ setTopG(&n, &d);
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[34,48,0,17,49,0,94,2,90,0,45,0,65,0,43,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":true,\"1\":{\"Z\":\"-\",\"A\":\"+\"}}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // null element and uniform array
+ initiateG(&d);
+ setG(&d, "1", NULL);
+ initiateG(&a);
+ pushG(&a, 1);
+ pushG(&a, 2);
+ pushG(&a, 3);
+ pushG(&a, 4);
+ setG(&d, "0", &a);
+ setTopG(&n, &d);
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[34,49,0,-16,48,0,68,2,4,6,8]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"1\":null,\"0\":[1,2,3,4]}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // uniform array high nibble
+ initiateG(&d);
+ setG(&d, "1", TRUE);
+ initiateG(&a);
+ pushG(&a, 1);
+ pushG(&a, 2);
+ pushG(&a, 3);
+ pushG(&a, 4);
+ setG(&d, "0", &a);
+ setTopG(&n, &d);
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[34,49,0,17,48,0,79,4,2,4,6,8]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"1\":true,\"0\":[1,2,3,4]}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // uniform array in high nibble
+ initiateG(&d);
+ setG(&d, "1", "1");
+ initiateG(&a);
+ pushG(&a, 1);
+ pushG(&a, 2);
+ pushG(&a, 3);
+ pushG(&a, 4);
+ setG(&d, "0", &a);
+ setTopG(&n, &d);
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[34,49,0,-11,49,0,48,0,68,2,4,6,8]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"1\":\"1\",\"0\":[1,2,3,4]}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // low and high nibble undefined
+ parseG(&n, "{"_"0"_":null,"_"1"_":null, "_"2"_":1}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[50,48,0,0,49,0,50,0,36]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":null,\"1\":null,\"2\":1}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // low and high nibble bool
+ parseG(&n, "{"_"z"_":null,"_"0"_":true,"_"1"_":true, "_"2"_":true, "_"3"_":true"_"4"_":true"_"5"_":true, "_"6"_":true, "_"7"_":true, "_"8"_":true, "_"9"_":true, "_"a"_":true, "_"b"_":true, "_"c"_":true, "_"d"_":true}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[-14,1,122,0,16,48,0,-1,49,0,17,50,0,51,0,17,52,0,53,0,17,54,0,55,0,17,56,0,63,57,0,17,97,0,98,0,17,99,0,100,0,1]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"z\":null,\"0\":true,\"1\":true,\"2\":true,\"3\":true,\"4\":true,\"5\":true,\"6\":true,\"7\":true,\"8\":true,\"9\":true,\"a\":true,\"b\":true,\"c\":true,\"d\":true}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // low and high nibble bool - deserialDict ctx->nibble == lowNbl and ctx->boolShift == 8
+ parseG(&n, "{"_"z"_":null,"_"0"_":true,"_"1"_":true, "_"2"_":true, "_"3"_":true, "_"4"_":true, "_"5"_":true, "_"6"_":true, "_"7"_":true, \"Z\": null, "_"8"_":true, "_"9"_":true, "_"a"_":true, "_"b"_":true, "_"c"_":true, "_"d"_":true}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[-12,2,122,0,16,48,0,-1,49,0,17,50,0,51,0,17,52,0,53,0,17,54,0,55,0,1,90,0,56,0,-15,57,0,17,97,0,98,0,17,99,0,3,100,0,1]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"z\":null,\"0\":true,\"1\":true,\"2\":true,\"3\":true,\"4\":true,\"5\":true,\"6\":true,\"7\":true,\"Z\":null,\"8\":true,\"9\":true,\"a\":true,\"b\":true,\"c\":true,\"d\":true}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // dict in dict
+ parseG(&n, "{"_"0"_":{\"0\":true}, "_"2"_":{\"0\":false},\"z\":null}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[50,48,0,30,1,48,0,1,50,0,30,1,48,0,122,0,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":{\"0\":true},\"2\":{\"0\":false},\"z\":null}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+
+ // low and high nibble double
+ parseG(&n, "{"_"0"_":0.0, "_"2"_":2.0,\"z\":null}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[50,48,0,51,0,0,0,0,0,0,0,0,50,0,0,0,0,0,0,0,0,64,122,0,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":0.000000e+00,\"2\":2.000000e+00,\"z\":null}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // high nibble string
+ parseG(&n, "{"_"0"_":null, "_"2"_":\"2.0\",\"z\":null}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[50,48,0,80,50,0,50,46,48,0,122,0,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":null,\"2\":\"2.0\",\"z\":null}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // array in dict
+ parseG(&n, "{"_"0"_":null, "_"2"_":[1,2],\"z\":[true,3]}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[50,48,0,-16,50,0,36,2,4,122,0,38,17,100]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":null,\"2\":[1,2],\"z\":[true,3]}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+
+
+ // packed dicts
+ parseG(&n, "{"_"0"_":{},"_"1"_":{}, "_"2"_":{}, "_"3"_":{}, "_"4"_":{}, "_"5"_": 1}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[98,48,0,88,0,49,0,0,50,0,0,51,0,0,52,0,0,53,0,36]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":{},\"1\":{},\"2\":{},\"3\":{},\"4\":{},\"5\":1}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ parseG(&n, "{"_"0"_":{"_"0"_":null,"_"1"_":1},"_"1"_":{"_"0"_":"_"0"_","_"1"_":1}, "_"2"_":{"_"0"_":"_"0"_","_"1"_":1}, "_"3"_":{"_"0"_":"_"0"_","_"1"_":1}, "_"4"_":{"_"0"_":"_"0"_","_"1"_":1}, "_"5"_": 1}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[98,48,0,88,2,48,0,64,49,0,2,49,0,2,48,0,69,48,0,49,0,2,50,0,2,48,0,69,48,0,49,0,2,51,0,2,48,0,69,48,0,49,0,2,52,0,2,48,0,69,48,0,49,0,2,53,0,36]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":{\"0\":null,\"1\":1},\"1\":{\"0\":\"0\",\"1\":1},\"2\":{\"0\":\"0\",\"1\":1},\"3\":{\"0\":\"0\",\"1\":1},\"4\":{\"0\":\"0\",\"1\":1},\"5\":1}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // high nibble packed dicts
+ parseG(&n, "{\"a\": null,"_"0"_":{},"_"1"_":{}, "_"2"_":{}, "_"3"_":{}, "_"4"_":{}, "_"5"_": 1}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[114,97,0,-12,48,0,5,0,49,0,0,50,0,0,51,0,0,52,0,0,53,0,36]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"a\":null,\"0\":{},\"1\":{},\"2\":{},\"3\":{},\"4\":{},\"5\":1}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+
+ // packed doubles
+ parseG(&n, "{"_"0"_":0.0,"_"1"_":1.0, "_"2"_":2.0, "_"3"_":3.0, "_"4"_":4.0, "_"5"_": null}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[98,48,0,89,0,0,0,0,0,0,0,0,49,0,0,0,0,0,0,0,-16,63,50,0,0,0,0,0,0,0,0,64,51,0,0,0,0,0,0,0,8,64,52,0,0,0,0,0,0,0,16,64,53,0,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":0.000000e+00,\"1\":1.000000e+00,\"2\":2.000000e+00,\"3\":3.000000e+00,\"4\":4.000000e+00,\"5\":null}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // high nibble packed doubles
+ parseG(&n, "{\"a\": null, "_"0"_":0.0,"_"1"_":1.0, "_"2"_":2.0, "_"3"_":3.0, "_"4"_":4.0, "_"5"_": null}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[114,97,0,-11,48,0,5,0,0,0,0,0,0,0,0,49,0,0,0,0,0,0,0,-16,63,50,0,0,0,0,0,0,0,0,64,51,0,0,0,0,0,0,0,8,64,52,0,0,0,0,0,0,0,16,64,53,0,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"a\":null,\"0\":0.000000e+00,\"1\":1.000000e+00,\"2\":2.000000e+00,\"3\":3.000000e+00,\"4\":4.000000e+00,\"5\":null}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+
+ // packed ints
+ parseG(&n, "{\"1\":1,\"2\":2,\"3\":3,\"4\":4,\"Z\":\"l\"}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[82,49,0,74,2,50,0,4,51,0,6,52,0,8,90,0,5,108,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"1\":1,\"2\":2,\"3\":3,\"4\":4,\"Z\":\"l\"}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // high nibble packed ints
+ parseG(&n, "{\"0\":null,\"1\":1,\"2\":2,\"3\":3,\"4\":4,\"Z\":\"l\"}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[98,48,0,-96,49,0,4,2,50,0,4,51,0,6,52,0,8,90,0,5,108,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":null,\"1\":1,\"2\":2,\"3\":3,\"4\":4,\"Z\":\"l\"}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+
+ // packed strings
+ parseG(&n, "{\"1\":\"1\",\"2\":\"2\",\"3\":\"3\",\"4\":\"4\",\"Z\":null}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[82,49,0,75,49,0,50,0,50,0,51,0,51,0,52,0,52,0,90,0,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"1\":\"1\",\"2\":\"2\",\"3\":\"3\",\"4\":\"4\",\"Z\":null}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // high nibble packed strings
+ parseG(&n, "{\"0\":null,\"1\":\"1\",\"2\":\"2\",\"3\":\"3\",\"4\":\"4\",\"Z\":null}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[98,48,0,-80,49,0,4,49,0,50,0,50,0,51,0,51,0,52,0,52,0,90,0,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":null,\"1\":\"1\",\"2\":\"2\",\"3\":\"3\",\"4\":\"4\",\"Z\":null}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // packed arrays
+ parseG(&n, "{\"1\":[],\"2\":[1],\"3\":[\"3r\"],\"4\":[true],\"Z\":null}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[82,49,0,76,0,50,0,1,36,51,0,1,21,51,114,0,52,0,1,1,90,0,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"1\":[],\"2\":[1],\"3\":[\"3r\"],\"4\":[true],\"Z\":null}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // high nibble packed arrays
+ parseG(&n, "{\"0\":null,\"1\":[],\"2\":[1],\"3\":[\"3r\"],\"4\":[true],\"Z\":null}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[98,48,0,-64,49,0,4,0,50,0,1,36,51,0,1,21,51,114,0,52,0,1,1,90,0,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":null,\"1\":[],\"2\":[1],\"3\":[\"3r\"],\"4\":[true],\"Z\":null}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+}
+
+
+// array with values, dict, array, uniforms, packed test high/low nibbles
+void arrayT(void) {
+
+ // STEPS
+ // init
+ // init allocate
+ // terminate
+ // allocate
+ // string
+ // duplicate
+
+ createNetSerial(n);
+ createNetSerial(ds);
+ char *s;
+ smallBytest *B;
+ createSmallArray(A);
+ createSmallArray(a);
+
+ // null and uniform array
+ initiateG(&A);
+ pushG(&A, NULL);
+ initiateG(&a);
+ pushG(&a, 1);
+ pushG(&a, 2);
+ pushG(&a, 3);
+ pushG(&a, 4);
+ pushG(&A, &a);
+ setTopG(&n, &A);
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[38,-16,68,2,4,6,8]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ //ck_assert_str_eq(s, "[null,null]");
+ ck_assert_str_eq(s, "[null,[1,2,3,4]]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // uniform array in high low
+ initiateG(&A);
+ pushG(&A, FALSE);
+ initiateG(&a);
+ pushG(&a, 1);
+ pushG(&a, 2);
+ pushG(&a, 3);
+ pushG(&a, 4);
+ pushG(&A, &a);
+ setTopG(&n, &A);
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[38,1,79,4,2,4,6,8]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ //ck_assert_str_eq(s, "[null,null]");
+ ck_assert_str_eq(s, "[false,[1,2,3,4]]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // uniform array in high nibble
+ initiateG(&A);
+ pushG(&A, "1");
+ initiateG(&a);
+ pushG(&a, 1);
+ pushG(&a, 2);
+ pushG(&a, 3);
+ pushG(&a, 4);
+ pushG(&A, &a);
+ setTopG(&n, &A);
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[38,-11,49,0,68,2,4,6,8]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[\"1\",[1,2,3,4]]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // high nibble array
+ parseG(&n, "[null, [1,null]]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[38,96,2,36,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[null,[1,null]]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // low and high undefined
+ parseG(&n, "[null,null,1]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[54,0,36]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[null,null,1]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // low and high nibble bool
+ parseG(&n, "[null,true,false,false,true,true,false,true,false,true,true,true,true,true]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[-26,1,16,89,17,17,17,17,31,17,17]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[null,true,false,false,true,true,false,true,false,true,true,true,true,true]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // low and high nibble bool - ctx->boolOffset != 0 ctx->nibble == lowNbl ctx->boolShift == 8
+ parseG(&n, "[true,false,false,true,null,true,false,true,false,true,true,true,true,true]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[-26,1,-11,17,1,81,17,17,31,17,17]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[true,false,false,true,null,true,false,true,false,true,true,true,true,true]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+
+ // dict in array
+ parseG(&n, "[{\"0\":null,\"1\":1},{\"2\":2},{\"3\":3},null]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[70,34,48,0,64,49,0,2,78,1,50,0,4,78,1,51,0,6,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[{\"0\":null,\"1\":1},{\"2\":2},{\"3\":3},null]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // double in array
+ parseG(&n, "[1.0,2.0,null]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[54,51,0,0,0,0,0,0,-16,63,0,0,0,0,0,0,0,64,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[1.000000e+00,2.000000e+00,null]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // int in array
+ parseG(&n, "[1,2,null]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[54,36,68,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[1,2,null]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // string in array
+ parseG(&n, "[\"1\",\"2\",null]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[54,85,49,0,50,0,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[\"1\",\"2\",null]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // array in array
+ parseG(&n, "[[],[1,2],null]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[54,15,0,79,2,2,4,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[[],[1,2],null]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+
+ // packed dicts
+ parseG(&n, "[{\"1\":1},{\"2\":2},{\"3\":3},{\"4\":4},null]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[86,72,1,49,0,36,1,50,0,68,1,51,0,100,1,52,0,-12,1,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[{\"1\":1},{\"2\":2},{\"3\":3},{\"4\":4},null]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // high nibble packed dicts
+ parseG(&n, "[null,{\"1\":1},{\"2\":2},{\"3\":3},{\"4\":4},null]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[102,-12,4,1,49,0,36,1,50,0,68,1,51,0,100,1,52,0,-12,1,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[null,{\"1\":1},{\"2\":2},{\"3\":3},{\"4\":4},null]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // packed doubles
+ parseG(&n, "[1.0,2.0,3.0,4.0,null]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[86,73,0,0,0,0,0,0,-16,63,0,0,0,0,0,0,0,64,0,0,0,0,0,0,8,64,0,0,0,0,0,0,16,64,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[1.000000e+00,2.000000e+00,3.000000e+00,4.000000e+00,null]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // high nibble packed doubles
+ parseG(&n, "[null,1.0,2.0,3.0,4.0,null]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[102,-11,4,0,0,0,0,0,0,-16,63,0,0,0,0,0,0,0,64,0,0,0,0,0,0,8,64,0,0,0,0,0,0,16,64,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[null,1.000000e+00,2.000000e+00,3.000000e+00,4.000000e+00,null]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // packed ints
+ parseG(&n, "[1,2,3,4,null]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[86,74,2,4,6,8,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[1,2,3,4,null]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // high nibble packed ints
+ parseG(&n, "[null,1,2,3,4,null]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[102,-96,4,2,4,6,8,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[null,1,2,3,4,null]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // packed strings
+ parseG(&n, "[\"1\",\"2\",\"3\",\"4\",null]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[86,75,49,0,50,0,51,0,52,0,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[\"1\",\"2\",\"3\",\"4\",null]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // high nibble packed strings
+ parseG(&n, "[null,\"1\",\"2\",\"3\",\"4\",null]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[102,-80,4,49,0,50,0,51,0,52,0,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[null,\"1\",\"2\",\"3\",\"4\",null]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // packed arrays
+ parseG(&n, "[[1],[2],[3],[4],null]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[86,76,1,36,1,68,1,100,1,-12,1,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[[1],[2],[3],[4],null]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // high nibble packed arrays
+ parseG(&n, "[null,[1],[2],[3],[4],null]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[102,-64,4,1,36,1,68,1,100,1,-12,1,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[null,[1],[2],[3],[4],null]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+}
+
+
+void variousT(void) {
+
+ createNetSerial(n);
+ createNetSerial(ds);
+ char *s;
+ smallBytest *B;
+
+
+ // array dict int bool string
+ parseG(&n, "[0, \"asd\", {\"rpc\":\"ds\", \"id\":1, \"p\":true}, [true, \"user\", [[false,\"name\",1], [true, \"name2\", 12340], [false, \"zxc\", 234]]]]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[70,4,37,97,115,100,0,3,114,112,99,0,69,100,115,0,105,100,0,2,112,0,-79,54,81,117,115,101,114,0,111,3,3,81,110,97,109,101,0,36,3,81,110,97,109,101,50,0,-12,-11,24,3,1,69,122,120,99,0,-44,3]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[0,\"asd\",{\"rpc\":\"ds\",\"id\":1,\"p\":true},[true,\"user\",[[false,\"name\",1],[true,\"name2\",12340],[false,\"zxc\",234]]]]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+
+}
+
+
+int main(int n, char**v) {
+
+initLibsheepy(v[0]);
+setLogMode(LOG_FUNC);
+
+topT();
+uniformDictT();
+uniformArrayT();
+dictT();
+arrayT();
+variousT();
+}
diff --git a/netSerial.c b/netSerial.c
@@ -0,0 +1,5260 @@
+
+#include "libsheepyObject.h"
+#include "netSerial.h"
+#include "netSerialInternal.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#define lv logVarG
+
+void initiateNetSerialLevel0(smallJsont *self);
+void initiateNetSerialLevel1(smallJsont *self);
+void initiateNetSerialLevel2(smallJsont *self);
+void initiateNetSerial(smallJsont *self);
+void registerMethodsNetSerialLevel0(smallJsonFunctionst *f);
+void registerMethodsNetSerialLevel1(smallJsonFunctionst *f);
+void registerMethodsNetSerialLevel2(smallJsonFunctionst *f);
+void registerMethodsNetSerial(smallJsonFunctionst *f);
+void initiateAllocateNetSerialLevel0(smallJsont **self);
+void initiateAllocateNetSerialLevel1(smallJsont **self);
+void initiateAllocateNetSerialLevel2(smallJsont **self);
+void initiateAllocateNetSerial(smallJsont **self);
+void finalizeNetSerial(void);
+smallJsont* allocNetSerialLevel0(void);
+smallJsont* allocNetSerialLevel1(void);
+smallJsont* allocNetSerialLevel2(void);
+smallJsont* allocNetSerial(void);
+internal const char* helpNetSerial(smallJsont *self);
+internal smallBytest* serialNetSerialLevel0(smallJsont *self);
+internal smallBytest* serialNetSerialLevel1(smallJsont *self);
+internal smallBytest* serialNetSerialLevel2(smallJsont *self);
+internal smallBytest* serialNetSerial(smallJsont *self);
+internal smallJsont* deserialNetSerialLevel0(smallJsont *self, smallBytest *data);
+internal smallJsont* deserialNetSerialLevel1(smallJsont *self, smallBytest *data);
+internal smallJsont* deserialNetSerialLevel2(smallJsont *self, smallBytest *data);
+internal smallJsont* deserialNetSerial(smallJsont *self, smallBytest *data);
+
+internal void uintToNetTypeVarint(sBytest **buf, u8 type, u64 value);
+internal void uintToVarint(sBytest **buf, u64 value);
+internal u64 netTypeVarintToUint(u8 **buf);
+internal u64 varintToUint(u8 **buf);
+
+internal sBytest* netSerialLevel0(smallt *o);
+internal void dictNetSerialLevel0(sBytest **r, sDictt *dict);
+internal void arrayNetSerialLevel0(sBytest **r, sArrayt *array);
+internal sBytest* netSerialLevel1(smallt *o);
+internal void dictNetSerialLevel1(sBytest **r, sDictt *dict, contextt *ctx);
+internal void arrayNetSerialLevel1(sBytest **r, sArrayt *array, contextt *ctx);
+internal sBytest* netSerialLevel2(smallt *o);
+internal void dictNetSerialLevel2(sBytest **r, sDictt *dict, contextt *ctx, bool packed);
+internal void arrayNetSerialLevel2(sBytest **r, sArrayt *array, contextt *ctx, bool packed);
+internal sBytest* netSerial(smallt *o);
+internal void dictNetSerial(sBytest **r, sDictt *dict, contextt *ctx, packingT packing);
+internal void arrayNetSerial(sBytest **r, sArrayt *array, contextt *ctx, packingT packing);
+
+internal smallt* netDeserialLevel0(sBytest *obj);
+internal void dictNetDeserialLevel0(sDictt **dict, char **data);
+internal void arrayNetDeserialLevel0(sArrayt **array, char **data);
+internal smallt* netDeserialLevel1(sBytest *obj);
+internal void dictNetDeserialLevel1(sDictt **dict, u8 **data, contextt *ctx);
+internal void arrayNetDeserialLevel1(sArrayt **array, u8 **data, contextt *ctx);
+internal smallt* netDeserialLevel2(sBytest *obj);
+internal void dictNetDeserialLevel2(sDictt **dict, u8 **data, contextt *ctx, bool packed);
+internal u8 isDictUniform(sDictt *dict);
+internal u8 isArrayUniform(sArrayt *array);
+internal void uniformDictNetDeserialLevel2(sDictt **dict, u8 **data, contextt *ctx, bool packed);
+internal void arrayNetDeserialLevel2(sArrayt **array, u8 **data, contextt *ctx, bool packed);
+internal void uniformArrayNetDeserialLevel2(sArrayt **array, u8 **data, contextt *ctx, bool packed);
+internal smallt* netDeserial(sBytest *obj);
+internal void dictNetDeserial(sDictt **dict, u8 **data, contextt *ctx, bool packed);
+internal void uniformDictNetDeserial(sDictt **dict, u8 **data, contextt *ctx, bool packed);
+internal void arrayNetDeserial(sArrayt **array, u8 **data, contextt *ctx, bool packed);
+internal void uniformArrayNetDeserial(sArrayt **array, u8 **data, contextt *ctx, bool packed);
+
+/* enable/disable logging */
+/* #undef pLog */
+/* #define pLog(...) */
+
+void initiateNetSerialLevel0(smallJsont *self) {
+
+ initiateSmallJson(self);
+
+ self->type = "netSerial";
+ if (!netSerialF) {
+ netSerialF = malloc(sizeof(smallJsonFunctionst));
+ registerMethodsNetSerialLevel0(netSerialF);
+ pErrorNot0(atexit(finalizeNetSerial));
+ }
+ self->f = netSerialF;
+}
+
+void initiateNetSerialLevel1(smallJsont *self) {
+
+ initiateSmallJson(self);
+
+ self->type = "netSerial";
+ if (!netSerialF) {
+ netSerialF = malloc(sizeof(smallJsonFunctionst));
+ registerMethodsNetSerialLevel1(netSerialF);
+ pErrorNot0(atexit(finalizeNetSerial));
+ }
+ self->f = netSerialF;
+}
+
+void initiateNetSerialLevel2(smallJsont *self) {
+
+ initiateSmallJson(self);
+
+ self->type = "netSerial";
+ if (!netSerialF) {
+ netSerialF = malloc(sizeof(smallJsonFunctionst));
+ registerMethodsNetSerialLevel2(netSerialF);
+ pErrorNot0(atexit(finalizeNetSerial));
+ }
+ self->f = netSerialF;
+}
+
+void initiateNetSerial(smallJsont *self) {
+
+ initiateSmallJson(self);
+
+ self->type = "netSerial";
+ if (!netSerialF) {
+ netSerialF = malloc(sizeof(smallJsonFunctionst));
+ registerMethodsNetSerial(netSerialF);
+ pErrorNot0(atexit(finalizeNetSerial));
+ }
+ self->f = netSerialF;
+}
+
+void registerMethodsNetSerialLevel0(smallJsonFunctionst *f) {
+
+ registerMethodsSmallJson(f);
+ f->help = helpNetSerial;
+ f->serial = serialNetSerialLevel0;
+ f->deserial = deserialNetSerialLevel0;
+}
+
+void registerMethodsNetSerialLevel1(smallJsonFunctionst *f) {
+
+ registerMethodsSmallJson(f);
+ f->help = helpNetSerial;
+ f->serial = serialNetSerialLevel1;
+ f->deserial = deserialNetSerialLevel1;
+}
+
+void registerMethodsNetSerialLevel2(smallJsonFunctionst *f) {
+
+ registerMethodsSmallJson(f);
+ f->help = helpNetSerial;
+ f->serial = serialNetSerialLevel2;
+ f->deserial = deserialNetSerialLevel2;
+}
+
+void registerMethodsNetSerial(smallJsonFunctionst *f) {
+
+ registerMethodsSmallJson(f);
+ f->help = helpNetSerial;
+ f->serial = serialNetSerial;
+ f->deserial = deserialNetSerial;
+}
+
+void initiateAllocateNetSerialLevel0(smallJsont **self) {
+
+ if (self) {
+ (*self) = malloc(sizeof(smallJsont));
+ if (*self) {
+ initiateNetSerialLevel0(*self);
+ }
+ }
+}
+
+void initiateAllocateNetSerialLevel1(smallJsont **self) {
+
+ if (self) {
+ (*self) = malloc(sizeof(smallJsont));
+ if (*self) {
+ initiateNetSerialLevel1(*self);
+ }
+ }
+}
+
+void initiateAllocateNetSerialLevel2(smallJsont **self) {
+
+ if (self) {
+ (*self) = malloc(sizeof(smallJsont));
+ if (*self) {
+ initiateNetSerialLevel2(*self);
+ }
+ }
+}
+
+void initiateAllocateNetSerial(smallJsont **self) {
+
+ if (self) {
+ (*self) = malloc(sizeof(smallJsont));
+ if (*self) {
+ initiateNetSerial(*self);
+ }
+ }
+}
+
+void finalizeNetSerial(void) {
+
+ if (netSerialF) {
+ free(netSerialF);
+ netSerialF = NULL;
+ }
+}
+
+smallJsont* allocNetSerialLevel0(void) {
+ smallJsont *r = NULL;
+
+ initiateAllocateNetSerialLevel0(&r);
+ ret r;
+}
+
+smallJsont* allocNetSerialLevel1(void) {
+ smallJsont *r = NULL;
+
+ initiateAllocateNetSerialLevel1(&r);
+ ret r;
+}
+
+smallJsont* allocNetSerialLevel2(void) {
+ smallJsont *r = NULL;
+
+ initiateAllocateNetSerialLevel2(&r);
+ ret r;
+}
+
+smallJsont* allocNetSerial(void) {
+ smallJsont *r = NULL;
+
+ initiateAllocateNetSerial(&r);
+ ret r;
+}
+
+
+internal const char* helpNetSerial(smallJsont UNUSED *self) {
+ ret "TODO helpNetSerial \n" helpTextSmallJson;
+}
+
+/**
+ * encode type in lower nibble, uint value in high nibble and next bytes as varuint
+ */
+internal void uintToNetTypeVarint(sBytest **buf, u8 type, u64 value) {
+ u64 c = value;
+ /* encode b0..2 */
+ u8 b = type + ((c & 0x7) << 4);
+ if (c & 0xFFFFFFFFFFFFFFF8) {
+ b |= 0x80;
+ sBytesPush(buf, b);
+ c >>=3;
+ /* encode b3..9 ...*/
+ while(c) {
+ b = c & 0x7F;
+ if (c & 0xFFFFFFFFFFFFFF80)
+ b |= 0x80;
+ sBytesPush(buf, b);
+ c >>=7;
+ }
+ }
+ else
+ sBytesPush(buf, b);
+}
+
+/**
+ * encode uint as varuint
+ */
+internal void uintToVarint(sBytest **buf, u64 value) {
+ u64 c = value;
+ u8 b = c & 0x7F;
+ if (c & 0xFFFFFFFFFFFFFF80) {
+ b |= 0x80;
+ sBytesPush(buf, b);
+ c >>=7;
+ /* encode b7..14 ...*/
+ while(c) {
+ b = c & 0x7F;
+ if (c & 0xFFFFFFFFFFFFFF80)
+ b |= 0x80;
+ sBytesPush(buf, b);
+ c >>=7;
+ }
+ }
+ else
+ sBytesPush(buf, b);
+}
+
+/**
+ * decode type and varuint to uint
+ */
+internal u64 netTypeVarintToUint(u8 **buf) {
+ u64 r = 0;
+
+ r = (**buf >> 4) & 0x7;
+
+ u8 c = 0;
+ while (**buf & 0x80) {
+ (*buf)++;
+ r |= (**buf & 0x7F) << (7*c+3);
+ c++;
+ }
+ (*buf)++;
+ ret r;
+}
+
+/**
+ * decode varuint to uint
+ */
+internal u64 varintToUint(u8 **buf) {
+ u64 r = 0;
+
+ r = (**buf) & 0x7F;
+ u8 c = 1;
+ while (**buf & 0x80) {
+ (*buf)++;
+ r |= (**buf & 0x7F) << (7*c);
+ c++;
+ }
+ (*buf)++;
+ ret r;
+}
+
+// -------------------------------------
+// Serializers
+
+// level 0
+// like smallJson with ints and length encoded as varints
+
+/**
+ * serializer top function
+ */
+internal sBytest* netSerialLevel0(smallt *o) {
+ sBytest *r = NULL;
+ sBytest *B = NULL;
+
+ switch(o->type) {
+ case UNDEFINED:
+ sBytesPush(&r, NET_SERIAL_TYPES[(u8)o->type]);
+ break;
+ case BOOL: {
+ u8 c = NET_SERIAL_TYPES[(u8)o->type];
+ // set bit 4 when true
+ if (((sBoolt *)&(o->type))->value)
+ c |= (1<<4);
+ sBytesPush(&r, c);
+ }
+ break;
+ case CONTAINER:
+ // undefined
+ sBytesPush(&r, NET_SERIAL_TYPES[(u8)o->type]);
+ break;
+ case DICT:
+ dictNetSerialLevel0(&r, (sDictt *)&(o->type));
+ break;
+ case DOUBLE:
+ sBytesPush(&r, NET_SERIAL_TYPES[(u8)o->type]);
+ sBytesPushBuffer(&r, &((sDoublet *)&(o->type))->value, sizeof(double));
+ break;
+ case INT: {
+ // encode int to varint
+ // v is int64_t to convert to varint
+ i64 v = ((sIntt *)&(o->type))->value;
+ // encode v with arithmetic shifts
+ uintToNetTypeVarint(&r, NET_SERIAL_TYPES[(u8)o->type], (v << 1) ^ (v >> 63));
+ }
+ break;
+ case STRING:
+ sBytesPush(&r, NET_SERIAL_TYPES[(u8)o->type]);
+ sBytesPushBuffer(&r, &((sStringt *)&(o->type))->data, sizeof(sStringt) + strlen(&(((sStringt *)&(o->type))->data)) -1);
+ break;
+ case ARRAY:
+ arrayNetSerialLevel0(&r, (sArrayt *)&(o->type));
+ break;
+ case BYTES:
+ B = (sBytest *)&(o->type);
+ uintToNetTypeVarint(&r, NET_SERIAL_TYPES[(u8)o->type], B->count);
+ sBytesPushBuffer(&r, &(B->data), B->count);
+ break;
+ }
+ ret r;
+}
+
+/**
+ * serialize dictionary
+ *
+ * the serialized dict is pushed to r.
+ * All elements are serialized recursively
+ *
+ * the data in containers is not serialized
+ *
+ * \param
+ * r small bytes object
+ * dict dictionary to serialize
+ */
+internal void dictNetSerialLevel0(sBytest **r, sDictt *dict) {
+ sBytest *B = NULL;
+
+ uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)dict->type], dict->count);
+
+ forEachSDict(dict, e) {
+ if (e->key) {
+ sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+
+ switch(e->data->type) {
+ case UNDEFINED:
+ sBytesPush(r, NET_SERIAL_TYPES[(u8)e->data->type]);
+ break;
+ case BOOL: {
+ u8 c = NET_SERIAL_TYPES[(u8)e->data->type];
+ // set bit 4 when true
+ if (((sBoolt *)(e->data))->value)
+ c |= (1<<4);
+ sBytesPush(r, c);
+ }
+ break;
+ case CONTAINER:
+ // undefined
+ sBytesPush(r, NET_SERIAL_TYPES[(u8)e->data->type]);
+ break;
+ case DICT:
+ dictNetSerialLevel0(r, (sDictt *)(e->data));
+ break;
+ case DOUBLE:
+ sBytesPush(r, NET_SERIAL_TYPES[(u8)e->data->type]);
+ sBytesPushBuffer(r, &((sDoublet *)(e->data))->value, sizeof(double));
+ break;
+ case INT: {
+ // encode int to varint
+ // v is int64_t to convert to varint
+ i64 v = ((sIntt *)(e->data))->value;
+ // encode v with arithmetic shifts
+ uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)e->data->type], (v << 1) ^ (v >> 63));
+ }
+ break;
+ case STRING:
+ sBytesPush(r, NET_SERIAL_TYPES[(u8)e->data->type]);
+ sBytesPushBuffer(r, &((sStringt *)(e->data))->data, sizeof(sStringt) + strlen(&(((sStringt *)(e->data))->data)) -1);
+ break;
+ case ARRAY:
+ arrayNetSerialLevel0(r, (sArrayt *)(e->data));
+ break;
+ case BYTES:
+ B = (sBytest *)(e->data);
+ uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)e->data->type], B->count);
+ sBytesPushBuffer(r, &(B->data), B->count);
+ break;
+ }
+ }
+ }
+ ret;
+}
+
+/**
+ * serialize array
+ *
+ * the serialized array is pushed to r.
+ * All elements are serialized recursively
+ *
+ * the data in containers is not serialized
+ *
+ * \param
+ * r small bytes object
+ * array to serialize
+ */
+internal void arrayNetSerialLevel0(sBytest **r, sArrayt *array) {
+ sBytest *B = NULL;
+
+ uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)array->type], array->count);
+
+ forEachSArray(array, e) {
+ if (!e) {
+ // empty slots are represented as undefined elements
+ sBytesPush(r, NET_SERIAL_TYPES[UNDEFINED]);
+ }
+ else {
+ switch(e->type) {
+ case UNDEFINED:
+ sBytesPush(r, NET_SERIAL_TYPES[(u8)e->type]);
+ break;
+ case BOOL: {
+ u8 c = NET_SERIAL_TYPES[(u8)e->type];
+ // set bit 4 when true
+ if (((sBoolt *)&(e->type))->value)
+ c |= (1<<4);
+ sBytesPush(r, c);
+ }
+ break;
+ case CONTAINER:
+ // undefined
+ sBytesPush(r, NET_SERIAL_TYPES[(u8)e->type]);
+ break;
+ case DICT:
+ dictNetSerialLevel0(r, (sDictt *)e);
+ break;
+ case DOUBLE:
+ sBytesPush(r, NET_SERIAL_TYPES[(u8)e->type]);
+ sBytesPushBuffer(r, &((sDoublet *)e)->value, sizeof(double));
+ break;
+ case INT: {
+ // encode int to varint
+ // v is int64_t to convert to varint
+ i64 v = ((sIntt *)&(e->type))->value;
+ // encode v with arithmetic shifts
+ uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)e->type], (v << 1) ^ (v >> 63));
+ }
+ break;
+ case STRING:
+ sBytesPush(r, NET_SERIAL_TYPES[(u8)e->type]);
+ sBytesPushBuffer(r, &((sStringt *)e)->data, sizeof(sStringt) + strlen(&(((sStringt *)e)->data)) -1);
+ break;
+ case ARRAY:
+ arrayNetSerialLevel0(r, (sArrayt *)e);
+ break;
+ case BYTES:
+ B = (sBytest *)e;
+ uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)e->type], B->count);
+ sBytesPushBuffer(r, &(B->data), B->count);
+ break;
+ }
+ }
+ }
+ ret;
+}
+
+internal smallBytest* serialNetSerialLevel0(smallJsont *self) {
+
+ smallt *o = getsoG(self);
+
+ if (o == NULL)
+ ret NULL;
+
+ sBytest *B = netSerialLevel0(o);
+
+ if (!B) {
+ ret NULL;
+ }
+
+ createAllocateSmallBytes(r);
+ r->B = B;
+ ret r;
+}
+
+// level 1
+// like level 0 with type encoded in nibbles and bools are packed
+
+/**
+ * serializer top function
+ */
+internal sBytest* netSerialLevel1(smallt *o) {
+ sBytest *r = NULL;
+ sBytest *B = NULL;
+ contextt ctx = {.nibble=lowNbl, .nblOffset=0, .boolShift = 0, .boolOffset=0};
+
+ switch(o->type) {
+ case UNDEFINED:
+ case CONTAINER:
+ sBytesPush(&r, NET_SERIAL_TYPES[(u8)o->type]);
+ break;
+ case BOOL: {
+ u8 c = NET_SERIAL_TYPES[(u8)o->type];
+ // set bit 4 when true
+ if (((sBoolt *)&(o->type))->value)
+ c |= (1<<4);
+ sBytesPush(&r, c);
+ }
+ break;
+ case DICT:
+ dictNetSerialLevel1(&r, (sDictt *)&(o->type), &ctx);
+ break;
+ case DOUBLE:
+ sBytesPush(&r, NET_SERIAL_TYPES[(u8)o->type]);
+ sBytesPushBuffer(&r, &((sDoublet *)&(o->type))->value, sizeof(double));
+ break;
+ case INT: {
+ // encode int to varint
+ // v is int64_t to convert to varint
+ i64 v = ((sIntt *)&(o->type))->value;
+ // encode v with arithmetic shifts
+ uintToNetTypeVarint(&r, NET_SERIAL_TYPES[(u8)o->type], (v << 1) ^ (v >> 63));
+ }
+ break;
+ case STRING:
+ sBytesPush(&r, NET_SERIAL_TYPES[(u8)o->type]);
+ sBytesPushBuffer(&r, &((sStringt *)&(o->type))->data, sizeof(sStringt) + strlen(&(((sStringt *)&(o->type))->data)) -1);
+ break;
+ case ARRAY:
+ arrayNetSerialLevel1(&r, (sArrayt *)&(o->type), &ctx);
+ break;
+ case BYTES:
+ B = (sBytest *)&(o->type);
+ uintToNetTypeVarint(&r, NET_SERIAL_TYPES[(u8)o->type], B->count);
+ sBytesPushBuffer(&r, &(B->data), B->count);
+ break;
+ }
+ ret r;
+}
+
+/**
+ * serialize dictionary
+ *
+ * the serialized dict is pushed to r.
+ * All elements are serialized recursively
+ *
+ * the data in containers is not serialized
+ *
+ * \param
+ * r small bytes object
+ * dict dictionary to serialize
+ */
+internal void dictNetSerialLevel1(sBytest **r, sDictt *dict, contextt *ctx) {
+ sBytest *B = NULL;
+ char *data = NULL;
+
+ if (ctx->nibble == lowNbl) {
+ uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)dict->type], dict->count);
+ }
+ else {
+ // high nibble
+ #define storeTypeInHighNbl(o)\
+ ctx->nibble = lowNbl;\
+ data = (char *)&((*r)->data) + ctx->nblOffset;\
+ *data |= NET_SERIAL_TYPES[(u8)o->type] << 4
+ storeTypeInHighNbl(dict);
+ uintToVarint(r, dict->count);
+ }
+
+ forEachSDict(dict, e) {
+ if (e->key) {
+ sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+
+ switch(e->data->type) {
+ case UNDEFINED:
+ case CONTAINER:
+ if (ctx->nibble == lowNbl) {
+ #define storeTypeOnly(o)\
+ sBytesPush(r, NET_SERIAL_TYPES[(u8)o->type]);\
+ ctx->nibble = highNbl;\
+ ctx->nblOffset = (*r)->count -1
+ storeTypeOnly(e->data);
+ }
+ else {
+ storeTypeInHighNbl(e->data);
+ }
+ break;
+ case BOOL:
+ if (!ctx->boolOffset) {
+ // new packed bools
+ if (ctx->nibble == lowNbl) {
+ #define storeNew4bPackedBool(o)\
+ u8 c = NET_SERIAL_TYPES[(u8)o->type];\
+ /* set bit 4 when true */\
+ if (((sBoolt *)(o))->value)\
+ c |= (1<<4);\
+ sBytesPush(r, c);\
+ ctx->boolShift = 5;\
+ ctx->boolOffset = (*r)->count -1
+ storeNew4bPackedBool(e->data);
+ }
+ else {
+ // high nibble, next byte is packed bools
+ storeTypeInHighNbl(e->data);
+ #define storeNew8bPackedBool(o)\
+ u8 c = 0;\
+ if (((sBoolt *)(o))->value)\
+ c = 1;\
+ sBytesPush(r, c);\
+ ctx->boolShift = 1;\
+ ctx->boolOffset = (*r)->count -1
+ storeNew8bPackedBool(e->data);
+ }
+ }
+ else {
+ // there was a bool before this one, fill bits in nibbles
+ if (ctx->nibble == lowNbl) {
+ if (ctx->boolShift == 8) {
+ // previous packed bool is full
+ // this byte is the new packed bools
+ storeNew4bPackedBool(e->data);
+ }
+ else {
+ storeTypeOnly(e->data);
+ #define storeBool(o)\
+ data = (char *)&((*r)->data) + ctx->boolOffset;\
+ if (((sBoolt *)(o))->value)\
+ *data |= 1 << ctx->boolShift;\
+ ctx->boolShift++
+ storeBool(e->data);
+ }
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(e->data);
+ if (ctx->boolShift == 8) {
+ // previous packed bool is full
+ // next byte is the new packed bools
+ storeNew8bPackedBool(e->data);
+ }
+ else {
+ storeBool(e->data);
+ }
+ }
+ }
+ break;
+ case DICT:
+ dictNetSerialLevel1(r, (sDictt *)(e->data), ctx);
+ break;
+ case DOUBLE:
+ if (ctx->nibble == lowNbl) {
+ storeTypeOnly(e->data);
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(e->data);
+ }
+ sBytesPushBuffer(r, &((sDoublet *)(e->data))->value, sizeof(double));
+ break;
+ case INT: {
+ // encode int to varint
+ // v is int64_t to convert to varint
+ i64 v = ((sIntt *)(e->data))->value;
+ if (ctx->nibble == lowNbl) {
+ // encode v with arithmetic shifts
+ uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)e->data->type], (v << 1) ^ (v >> 63));
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(e->data);
+ uintToVarint(r, (v << 1) ^ (v >> 63));
+ }
+ }
+ break;
+ case STRING:
+ if (ctx->nibble == lowNbl) {
+ storeTypeOnly(e->data);
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(e->data);
+ }
+ sBytesPushBuffer(r, &((sStringt *)(e->data))->data, sizeof(sStringt) + strlen(&(((sStringt *)(e->data))->data)) -1);
+ break;
+ case ARRAY:
+ arrayNetSerialLevel1(r, (sArrayt *)(e->data), ctx);
+ break;
+ case BYTES:
+ B = (sBytest *)(e->data);
+ if (ctx->nibble == lowNbl) {
+ uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)e->data->type], B->count);
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(e->data);
+ uintToVarint(r, B->count);
+ }
+ sBytesPushBuffer(r, &(B->data), B->count);
+ break;
+ }
+ }
+ }
+ ret;
+}
+
+/**
+ * serialize array
+ *
+ * the serialized array is pushed to r.
+ * All elements are serialized recursively
+ *
+ * the data in containers is not serialized
+ *
+ * \param
+ * r small bytes object
+ * array to serialize
+ */
+internal void arrayNetSerialLevel1(sBytest **r, sArrayt *array, contextt *ctx) {
+ sBytest *B = NULL;
+ char *data = NULL;
+
+ if (ctx->nibble == lowNbl) {
+ uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)array->type], array->count);
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(array);
+ uintToVarint(r, array->count);
+ }
+
+ forEachSArray(array, e) {
+ if (!e) {
+ // empty slots are represented as undefined elements
+ if (ctx->nibble == lowNbl) {
+ sBytesPush(r, NET_SERIAL_TYPES[UNDEFINED]);
+ ctx->nibble = highNbl;
+ ctx->nblOffset = (*r)->count -1;
+ }
+ else {
+ // high nibble
+ ctx->nibble = lowNbl;
+ data = (char *)&((*r)->data) + ctx->nblOffset;
+ *data |= NET_SERIAL_TYPES[UNDEFINED] << 4;
+ }
+ }
+ else {
+ switch(e->type) {
+ case UNDEFINED:
+ case CONTAINER:
+ if (ctx->nibble == lowNbl) {
+ storeTypeOnly(e);
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(e);
+ }
+ break;
+ case BOOL:
+ if (!ctx->boolOffset) {
+ // new packed bools
+ if (ctx->nibble == lowNbl) {
+ storeNew4bPackedBool(e);
+ }
+ else {
+ // high nibble, next byte is packed bools
+ storeTypeInHighNbl(e);
+ storeNew8bPackedBool(e);
+ }
+ }
+ else {
+ // there was a bool before this one, fill bits in nibbles
+ if (ctx->nibble == lowNbl) {
+ if (ctx->boolShift == 8) {
+ // previous packed bool is full
+ // this byte is the new packed bools
+ storeNew4bPackedBool(e);
+ }
+ else {
+ storeTypeOnly(e);
+ storeBool(e);
+ }
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(e);
+ if (ctx->boolShift == 8) {
+ // previous packed bool is full
+ // next byte is the new packed bools
+ storeNew8bPackedBool(e);
+ }
+ else {
+ storeBool(e);
+ }
+ }
+ }
+ break;
+ case DICT:
+ dictNetSerialLevel1(r, (sDictt *)e, ctx);
+ break;
+ case DOUBLE:
+ if (ctx->nibble == lowNbl) {
+ storeTypeOnly(e);
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(e);
+ }
+ sBytesPushBuffer(r, &((sDoublet *)e)->value, sizeof(double));
+ break;
+ case INT: {
+ // encode int to varint
+ // v is int64_t to convert to varint
+ i64 v = ((sIntt *)&(e->type))->value;
+ if (ctx->nibble == lowNbl) {
+ // encode v with arithmetic shifts
+ uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)e->type], (v << 1) ^ (v >> 63));
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(e);
+ uintToVarint(r, (v << 1) ^ (v >> 63));
+ }
+ }
+ break;
+ case STRING:
+ if (ctx->nibble == lowNbl) {
+ storeTypeOnly(e);
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(e);
+ }
+ sBytesPushBuffer(r, &((sStringt *)e)->data, sizeof(sStringt) + strlen(&(((sStringt *)e)->data)) -1);
+ break;
+ case ARRAY:
+ arrayNetSerialLevel1(r, (sArrayt *)e, ctx);
+ break;
+ case BYTES:
+ B = (sBytest *)e;
+ if (ctx->nibble == lowNbl) {
+ uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)e->type], B->count);
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(e);
+ uintToVarint(r, B->count);
+ }
+ sBytesPushBuffer(r, &(B->data), B->count);
+ break;
+ }
+ }
+ }
+ ret;
+}
+
+internal smallBytest* serialNetSerialLevel1(smallJsont *self) {
+
+ smallt *o = getsoG(self);
+
+ if (o == NULL)
+ ret NULL;
+
+ sBytest *B = netSerialLevel1(o);
+
+ if (!B) {
+ ret NULL;
+ }
+
+ createAllocateSmallBytes(r);
+ r->B = B;
+ ret r;
+}
+
+// level 2
+// like level 1, arrays are set to uniform when all elements are same type
+
+/**
+ * serializer top function
+ */
+internal sBytest* netSerialLevel2(smallt *o) {
+ sBytest *r = NULL;
+ sBytest *B = NULL;
+ contextt ctx = {.nibble=lowNbl, .nblOffset=0, .boolShift = 0, .boolOffset=0};
+
+ switch(o->type) {
+ case UNDEFINED:
+ case CONTAINER:
+ sBytesPush(&r, NET_SERIAL_TYPES[(u8)o->type]);
+ break;
+ case BOOL: {
+ u8 c = NET_SERIAL_TYPES[(u8)o->type];
+ // set bit 4 when true
+ if (((sBoolt *)&(o->type))->value)
+ c |= (1<<4);
+ sBytesPush(&r, c);
+ }
+ break;
+ case DICT:
+ dictNetSerialLevel2(&r, (sDictt *)&(o->type), &ctx, /*packed=*/false);
+ break;
+ case DOUBLE:
+ sBytesPush(&r, NET_SERIAL_TYPES[(u8)o->type]);
+ sBytesPushBuffer(&r, &((sDoublet *)&(o->type))->value, sizeof(double));
+ break;
+ case INT: {
+ // encode int to varint
+ // v is int64_t to convert to varint
+ i64 v = ((sIntt *)&(o->type))->value;
+ // encode v with arithmetic shifts
+ uintToNetTypeVarint(&r, NET_SERIAL_TYPES[(u8)o->type], (v << 1) ^ (v >> 63));
+ }
+ break;
+ case STRING:
+ sBytesPush(&r, NET_SERIAL_TYPES[(u8)o->type]);
+ sBytesPushBuffer(&r, &((sStringt *)&(o->type))->data, sizeof(sStringt) + strlen(&(((sStringt *)&(o->type))->data)) -1);
+ break;
+ case ARRAY:
+ arrayNetSerialLevel2(&r, (sArrayt *)&(o->type), &ctx, /*packed=*/false);
+ break;
+ case BYTES:
+ B = (sBytest *)&(o->type);
+ uintToNetTypeVarint(&r, NET_SERIAL_TYPES[(u8)o->type], B->count);
+ sBytesPushBuffer(&r, &(B->data), B->count);
+ break;
+ }
+ ret r;
+}
+
+internal u8 isDictUniform(sDictt *dict) {
+ bool allElementsHaveSameType = true;
+ bool foundFirstType = false;
+ u8 type = 0;
+ forEachSDict(dict, e) {
+ if (e->key) {
+ if (foundFirstType) {
+ u8 nextType;
+ switch(e->data->type) {
+ case DICT:
+ nextType = isDictUniform((sDictt*)e->data);
+ break;
+ case ARRAY:
+ nextType = isArrayUniform((sArrayt*)e->data);
+ break;
+ default:
+ nextType = NET_SERIAL_TYPES[(u8)e->data->type];
+ }
+ if (nextType != type) {
+ allElementsHaveSameType = false;
+ break;
+ }
+ }
+ else {
+ switch(e->data->type) {
+ case DICT:
+ type = isDictUniform((sDictt*)e->data);
+ break;
+ case ARRAY:
+ type = isArrayUniform((sArrayt*)e->data);
+ break;
+ default:
+ type = NET_SERIAL_TYPES[(u8)e->data->type];
+ }
+ foundFirstType = true;
+ }
+ }
+ }
+ if (allElementsHaveSameType)
+ type = UNIFORM_DICT;
+ else
+ type = S_DICT;
+ ret type;
+}
+
+internal u8 isArrayUniform(sArrayt *array) {
+ bool allElementsHaveSameType = true;
+ bool foundFirstType = false;
+ char type = 0;
+ forEachSArray(array, e) {
+ if (!e) {
+ if (foundFirstType) {
+ if (type != S_UNDEFINED) {
+ allElementsHaveSameType = false;
+ break;
+ }
+ }
+ else {
+ type = S_UNDEFINED;
+ foundFirstType = true;
+ }
+ }
+ else {
+ if (foundFirstType) {
+ u8 nextType;
+ switch(e->type) {
+ case DICT:
+ nextType = isDictUniform((sDictt*)e);
+ break;
+ case ARRAY:
+ nextType = isArrayUniform((sArrayt*)e);
+ break;
+ default:
+ nextType = NET_SERIAL_TYPES[(u8)e->type];
+ }
+ if (nextType != type) {
+ allElementsHaveSameType = false;
+ break;
+ }
+ }
+ else {
+ switch(e->type) {
+ case DICT:
+ type = isDictUniform((sDictt*)e);
+ break;
+ case ARRAY:
+ type = isArrayUniform((sArrayt*)e);
+ break;
+ default:
+ type = NET_SERIAL_TYPES[(u8)e->type];
+ }
+ foundFirstType = true;
+ }
+ }
+ }
+ if (allElementsHaveSameType)
+ type = UNIFORM_ARRAY;
+ else
+ type = S_ARRAY;
+ ret type;
+}
+
+/**
+ * serialize dictionary
+ *
+ * the serialized dict is pushed to r.
+ * All elements are serialized recursively
+ *
+ * the data in containers is not serialized
+ *
+ * \param
+ * r small bytes object
+ * dict dictionary to serialize
+ */
+internal void dictNetSerialLevel2(sBytest **r, sDictt *dict, contextt *ctx, bool packed) {
+ sBytest *B = NULL;
+ char *data = NULL;
+
+ // check if all elements have same type
+ bool allElementsHaveSameType = true;
+ bool foundFirstType = false;
+ char type = 0;
+ {forEachSDict(dict, e) {
+ if (e->key) {
+ if (foundFirstType) {
+ u8 nextType;
+ switch(e->data->type) {
+ case DICT:
+ nextType = isDictUniform((sDictt*)e->data);
+ break;
+ case ARRAY:
+ nextType = isArrayUniform((sArrayt*)e->data);
+ break;
+ default:
+ nextType = NET_SERIAL_TYPES[(u8)e->data->type];
+ }
+ if (nextType != type) {
+ allElementsHaveSameType = false;
+ break;
+ }
+ }
+ else {
+ switch(e->data->type) {
+ case DICT:
+ type = isDictUniform((sDictt*)e->data);
+ break;
+ case ARRAY:
+ type = isArrayUniform((sArrayt*)e->data);
+ break;
+ default:
+ type = NET_SERIAL_TYPES[(u8)e->data->type];
+ }
+ foundFirstType = true;
+ }
+ }
+ }}
+
+ if (allElementsHaveSameType) {
+ // pack dictionary
+ if (packed) {
+ uintToNetTypeVarint(r, type, dict->count);
+ }
+ else {
+ if (ctx->nibble == lowNbl) {
+ sBytesPush(r, (type << 4) + UNIFORM_DICT);
+ uintToVarint(r, dict->count);
+ }
+ else {
+ // high nibble
+ ctx->nibble = lowNbl;
+ data = (char *)&((*r)->data) + ctx->nblOffset;
+ *data |= UNIFORM_DICT << 4;
+ uintToNetTypeVarint(r, type, dict->count);
+ }
+ }
+
+ switch(type) {
+ case S_UNDEFINED:
+ {forEachSDict(dict, e) {
+ if (e->key) {
+ sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+ }
+ }}
+
+ break;
+ case S_BOOL:
+ {forEachSDict(dict, e) {
+ if (e->key) {
+ sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+
+ if (!ctx->boolOffset) {
+ // new packed bools
+ storeNew8bPackedBool(e->data);
+ }
+ else {
+ // there was a bool before this one, fill bits in nibbles
+ if (ctx->boolShift == 8) {
+ // previous packed bool is full
+ // next byte is the new packed bools
+ storeNew8bPackedBool(e->data);
+ }
+ else {
+ storeBool(e->data);
+ }
+ }
+ }
+ }}
+ break;
+ case S_DICT:
+ case UNIFORM_DICT:
+ {forEachSDict(dict, e) {
+ if (e->key) {
+ sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+ dictNetSerialLevel2(r, (sDictt *)(e->data), ctx, /*packed=*/true);
+ }
+ }}
+ break;
+ case S_DOUBLE:
+ {forEachSDict(dict, e) {
+ if (e->key) {
+ sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+ sBytesPushBuffer(r, &((sDoublet *)(e->data))->value, sizeof(double));
+ }
+ }}
+ break;
+ case S_INT:
+ {forEachSDict(dict, e) {
+ if (e->key) {
+ sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+ i64 v = ((sIntt *)(e->data))->value;
+ uintToVarint(r, (v << 1) ^ (v >> 63));
+ }
+ }}
+ break;
+ case S_STRING:
+ {forEachSDict(dict, e) {
+ if (e->key) {
+ sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+ sBytesPushBuffer(r, &((sStringt *)(e->data))->data, sizeof(sStringt) + strlen(&(((sStringt *)(e->data))->data)) -1);
+ }
+ }}
+ break;
+ case S_ARRAY:
+ case UNIFORM_ARRAY:
+ {forEachSDict(dict, e) {
+ if (e->key) {
+ sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+ arrayNetSerialLevel2(r, (sArrayt *)(e->data), ctx, /*packed=*/true);
+ }
+ }}
+ break;
+ case S_BYTES:
+ {forEachSDict(dict, e) {
+ if (e->key) {
+ sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+ B = (sBytest *)(e->data);
+ uintToVarint(r, B->count);
+ sBytesPushBuffer(r, &(B->data), B->count);
+ }
+ }}
+ break;
+ }
+ ret;
+ }
+
+ if (packed) {
+ uintToVarint(r, dict->count);
+ }
+ else {
+ if (ctx->nibble == lowNbl) {
+ uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)dict->type], dict->count);
+ }
+ else {
+ // high nibble
+#define storeTypeInHighNbl(o)\
+ ctx->nibble = lowNbl;\
+ data = (char *)&((*r)->data) + ctx->nblOffset;\
+ *data |= NET_SERIAL_TYPES[(u8)o->type] << 4
+ storeTypeInHighNbl(dict);
+ uintToVarint(r, dict->count);
+ }
+ }
+
+ forEachSDict(dict, e) {
+ if (e->key) {
+ sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+
+ switch(e->data->type) {
+ case UNDEFINED:
+ case CONTAINER:
+ if (ctx->nibble == lowNbl) {
+ #define storeTypeOnly(o)\
+ sBytesPush(r, NET_SERIAL_TYPES[(u8)o->type]);\
+ ctx->nibble = highNbl;\
+ ctx->nblOffset = (*r)->count -1
+ storeTypeOnly(e->data);
+ }
+ else {
+ storeTypeInHighNbl(e->data);
+ }
+ break;
+ case BOOL:
+ if (!ctx->boolOffset) {
+ // new packed bools
+ if (ctx->nibble == lowNbl) {
+ #define storeNew4bPackedBool(o)\
+ u8 c = NET_SERIAL_TYPES[(u8)o->type];\
+ /* set bit 4 when true */\
+ if (((sBoolt *)(o))->value)\
+ c |= (1<<4);\
+ sBytesPush(r, c);\
+ ctx->boolShift = 5;\
+ ctx->boolOffset = (*r)->count -1
+ storeNew4bPackedBool(e->data);
+ }
+ else {
+ // high nibble, next byte is packed bools
+ storeTypeInHighNbl(e->data);
+ #define storeNew8bPackedBool(o)\
+ u8 c = 0;\
+ if (((sBoolt *)(o))->value)\
+ c = 1;\
+ sBytesPush(r, c);\
+ ctx->boolShift = 1;\
+ ctx->boolOffset = (*r)->count -1
+ storeNew8bPackedBool(e->data);
+ }
+ }
+ else {
+ // there was a bool before this one, fill bits in nibbles
+ if (ctx->nibble == lowNbl) {
+ if (ctx->boolShift == 8) {
+ // previous packed bool is full
+ // this byte is the new packed bools
+ storeNew4bPackedBool(e->data);
+ }
+ else {
+ storeTypeOnly(e->data);
+ #define storeBool(o)\
+ data = (char *)&((*r)->data) + ctx->boolOffset;\
+ if (((sBoolt *)(o))->value)\
+ *data |= 1 << ctx->boolShift;\
+ ctx->boolShift++
+ storeBool(e->data);
+ }
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(e->data);
+ if (ctx->boolShift == 8) {
+ // previous packed bool is full
+ // next byte is the new packed bools
+ storeNew8bPackedBool(e->data);
+ }
+ else {
+ storeBool(e->data);
+ }
+ }
+ }
+ break;
+ case DICT:
+ dictNetSerialLevel2(r, (sDictt *)(e->data), ctx, /*packed=*/false);
+ break;
+ case DOUBLE:
+ if (ctx->nibble == lowNbl) {
+ storeTypeOnly(e->data);
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(e->data);
+ }
+ sBytesPushBuffer(r, &((sDoublet *)(e->data))->value, sizeof(double));
+ break;
+ case INT: {
+ // encode int to varint
+ // v is int64_t to convert to varint
+ i64 v = ((sIntt *)(e->data))->value;
+ if (ctx->nibble == lowNbl) {
+ // encode v with arithmetic shifts
+ uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)e->data->type], (v << 1) ^ (v >> 63));
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(e->data);
+ uintToVarint(r, (v << 1) ^ (v >> 63));
+ }
+ }
+ break;
+ case STRING:
+ if (ctx->nibble == lowNbl) {
+ storeTypeOnly(e->data);
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(e->data);
+ }
+ sBytesPushBuffer(r, &((sStringt *)(e->data))->data, sizeof(sStringt) + strlen(&(((sStringt *)(e->data))->data)) -1);
+ break;
+ case ARRAY:
+ arrayNetSerialLevel2(r, (sArrayt *)(e->data), ctx, /*packed=*/false);
+ break;
+ case BYTES:
+ B = (sBytest *)(e->data);
+ if (ctx->nibble == lowNbl) {
+ uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)e->data->type], B->count);
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(e->data);
+ uintToVarint(r, B->count);
+ }
+ sBytesPushBuffer(r, &(B->data), B->count);
+ break;
+ }
+ }
+ }
+ ret;
+}
+
+/**
+ * serialize array
+ *
+ * the serialized array is pushed to r.
+ * All elements are serialized recursively
+ *
+ * the data in containers is not serialized
+ *
+ * \param
+ * r small bytes object
+ * array to serialize
+ */
+internal void arrayNetSerialLevel2(sBytest **r, sArrayt *array, contextt *ctx, bool packed) {
+ sBytest *B = NULL;
+ char *data = NULL;
+
+ // check if all elements have same type
+ bool allElementsHaveSameType = true;
+ bool foundFirstType = false;
+ char type = 0;
+
+ {forEachSArray(array, e) {
+ if (!e) {
+ if (foundFirstType) {
+ if (type != S_UNDEFINED) {
+ allElementsHaveSameType = false;
+ break;
+ }
+ }
+ else {
+ type = S_UNDEFINED;
+ foundFirstType = true;
+ }
+ }
+ else {
+ if (foundFirstType) {
+ u8 nextType;
+ switch(e->type) {
+ case DICT:
+ nextType = isDictUniform((sDictt*)e);
+ break;
+ case ARRAY:
+ nextType = isArrayUniform((sArrayt*)e);
+ break;
+ default:
+ nextType = NET_SERIAL_TYPES[(u8)e->type];
+ }
+ if (nextType != type) {
+ allElementsHaveSameType = false;
+ break;
+ }
+ }
+ else {
+ switch(e->type) {
+ case DICT:
+ type = isDictUniform((sDictt*)e);
+ break;
+ case ARRAY:
+ type = isArrayUniform((sArrayt*)e);
+ break;
+ default:
+ type = NET_SERIAL_TYPES[(u8)e->type];
+ }
+ foundFirstType = true;
+ }
+ }
+ }}
+
+ if (allElementsHaveSameType) {
+ // pack array
+ if (packed) {
+ uintToNetTypeVarint(r, type, array->count);
+ }
+ else {
+ if (ctx->nibble == lowNbl) {
+ sBytesPush(r, (type << 4) + UNIFORM_ARRAY);
+ uintToVarint(r, array->count);
+ }
+ else {
+ // high nibble
+ ctx->nibble = lowNbl;
+ data = (char *)&((*r)->data) + ctx->nblOffset;
+ *data |= UNIFORM_ARRAY << 4;
+ uintToNetTypeVarint(r, type, array->count);
+ }
+ }
+
+ switch(type) {
+ case S_BOOL:
+ {forEachSArray(array, e) {
+ if (!ctx->boolOffset) {
+ // new packed bools
+ storeNew8bPackedBool(e);
+ }
+ else {
+ // there was a bool before this one, fill bits in nibbles
+ if (ctx->boolShift == 8) {
+ // previous packed bool is full
+ // next byte is the new packed bools
+ storeNew8bPackedBool(e);
+ }
+ else {
+ storeBool(e);
+ }
+ }
+ }}
+ break;
+ case S_DICT:
+ case UNIFORM_DICT:
+ {forEachSArray(array, e) {
+ dictNetSerialLevel2(r, (sDictt *)e, ctx, /*packed=*/true);
+ }}
+ break;
+ case S_DOUBLE:
+ {forEachSArray(array, e) {
+ sBytesPushBuffer(r, &((sDoublet *)e)->value, sizeof(double));
+ }}
+ break;
+ case S_INT:
+ {forEachSArray(array, e) {
+ i64 v = ((sIntt *)e)->value;
+ uintToVarint(r, (v << 1) ^ (v >> 63));
+ }}
+ break;
+ case S_STRING:
+ {forEachSArray(array, e) {
+ sBytesPushBuffer(r, &((sStringt *)e)->data, sizeof(sStringt) + strlen(&(((sStringt *)e)->data)) -1);
+ }}
+ break;
+ case S_ARRAY:
+ case UNIFORM_ARRAY:
+ {forEachSArray(array, e) {
+ arrayNetSerialLevel2(r, (sArrayt *)e, ctx, /*packed=*/true);
+ }}
+ break;
+ case S_BYTES:
+ {forEachSArray(array, e) {
+ B = (sBytest *)e;
+ uintToVarint(r, B->count);
+ sBytesPushBuffer(r, &(B->data), B->count);
+ }}
+ break;
+ }
+ ret;
+ }
+
+ if (packed) {
+ uintToVarint(r, array->count);
+ }
+ else {
+ if (ctx->nibble == lowNbl) {
+ uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)array->type], array->count);
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(array);
+ uintToVarint(r, array->count);
+ }
+ }
+
+ forEachSArray(array, e) {
+ if (!e) {
+ // empty slots are represented as undefined elements
+ if (ctx->nibble == lowNbl) {
+ sBytesPush(r, NET_SERIAL_TYPES[UNDEFINED]);
+ ctx->nibble = highNbl;
+ ctx->nblOffset = (*r)->count -1;
+ }
+ else {
+ // high nibble
+ ctx->nibble = lowNbl;
+ data = (char *)&((*r)->data) + ctx->nblOffset;
+ *data |= NET_SERIAL_TYPES[UNDEFINED] << 4;
+ }
+ }
+ else {
+ switch(e->type) {
+ case UNDEFINED:
+ case CONTAINER:
+ if (ctx->nibble == lowNbl) {
+ storeTypeOnly(e);
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(e);
+ }
+ break;
+ case BOOL:
+ if (!ctx->boolOffset) {
+ // new packed bools
+ if (ctx->nibble == lowNbl) {
+ storeNew4bPackedBool(e);
+ }
+ else {
+ // high nibble, next byte is packed bools
+ storeTypeInHighNbl(e);
+ storeNew8bPackedBool(e);
+ }
+ }
+ else {
+ // there was a bool before this one, fill bits in nibbles
+ if (ctx->nibble == lowNbl) {
+ if (ctx->boolShift == 8) {
+ // previous packed bool is full
+ // this byte is the new packed bools
+ storeNew4bPackedBool(e);
+ }
+ else {
+ storeTypeOnly(e);
+ storeBool(e);
+ }
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(e);
+ if (ctx->boolShift == 8) {
+ // previous packed bool is full
+ // next byte is the new packed bools
+ storeNew8bPackedBool(e);
+ }
+ else {
+ storeBool(e);
+ }
+ }
+ }
+ break;
+ case DICT:
+ dictNetSerialLevel2(r, (sDictt *)e, ctx, /*packed=*/false);
+ break;
+ case DOUBLE:
+ if (ctx->nibble == lowNbl) {
+ storeTypeOnly(e);
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(e);
+ }
+ sBytesPushBuffer(r, &((sDoublet *)e)->value, sizeof(double));
+ break;
+ case INT: {
+ // encode int to varint
+ // v is int64_t to convert to varint
+ i64 v = ((sIntt *)&(e->type))->value;
+ if (ctx->nibble == lowNbl) {
+ // encode v with arithmetic shifts
+ uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)e->type], (v << 1) ^ (v >> 63));
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(e);
+ uintToVarint(r, (v << 1) ^ (v >> 63));
+ }
+ }
+ break;
+ case STRING:
+ if (ctx->nibble == lowNbl) {
+ storeTypeOnly(e);
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(e);
+ }
+ sBytesPushBuffer(r, &((sStringt *)e)->data, sizeof(sStringt) + strlen(&(((sStringt *)e)->data)) -1);
+ break;
+ case ARRAY:
+ arrayNetSerialLevel2(r, (sArrayt *)e, ctx, /*packed=*/false);
+ break;
+ case BYTES:
+ B = (sBytest *)e;
+ if (ctx->nibble == lowNbl) {
+ uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)e->type], B->count);
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(e);
+ uintToVarint(r, B->count);
+ }
+ sBytesPushBuffer(r, &(B->data), B->count);
+ break;
+ }
+ }
+ }
+ ret;
+}
+
+internal smallBytest* serialNetSerialLevel2(smallJsont *self) {
+
+ smallt *o = getsoG(self);
+
+ if (o == NULL)
+ ret NULL;
+
+ sBytest *B = netSerialLevel2(o);
+
+ if (!B) {
+ ret NULL;
+ }
+
+ createAllocateSmallBytes(r);
+ r->B = B;
+ ret r;
+}
+
+// level 3
+// like level 2, elements of identical type in a row are packed
+
+/**
+ * serializer top function
+ */
+internal sBytest* netSerial(smallt *o) {
+ sBytest *r = NULL;
+ sBytest *B = NULL;
+ contextt ctx = {.nibble=lowNbl, .nblOffset=0, .boolShift = 0, .boolOffset=0};
+
+ switch(o->type) {
+ case UNDEFINED:
+ case CONTAINER:
+ sBytesPush(&r, NET_SERIAL_TYPES[(u8)o->type]);
+ break;
+ case BOOL: {
+ u8 c = NET_SERIAL_TYPES[(u8)o->type];
+ // set bit 4 when true
+ if (((sBoolt *)&(o->type))->value)
+ c |= (1<<4);
+ sBytesPush(&r, c);
+ }
+ break;
+ case DICT:
+ dictNetSerial(&r, (sDictt *)&(o->type), &ctx, /*packing=*/NOPACKING);
+ break;
+ case DOUBLE:
+ sBytesPush(&r, NET_SERIAL_TYPES[(u8)o->type]);
+ sBytesPushBuffer(&r, &((sDoublet *)&(o->type))->value, sizeof(double));
+ break;
+ case INT: {
+ // encode int to varint
+ // v is int64_t to convert to varint
+ i64 v = ((sIntt *)&(o->type))->value;
+ // encode v with arithmetic shifts
+ uintToNetTypeVarint(&r, NET_SERIAL_TYPES[(u8)o->type], (v << 1) ^ (v >> 63));
+ }
+ break;
+ case STRING:
+ sBytesPush(&r, NET_SERIAL_TYPES[(u8)o->type]);
+ sBytesPushBuffer(&r, &((sStringt *)&(o->type))->data, sizeof(sStringt) + strlen(&(((sStringt *)&(o->type))->data)) -1);
+ break;
+ case ARRAY:
+ arrayNetSerial(&r, (sArrayt *)&(o->type), &ctx, /*packing=*/NOPACKING);
+ break;
+ case BYTES:
+ B = (sBytest *)&(o->type);
+ uintToNetTypeVarint(&r, NET_SERIAL_TYPES[(u8)o->type], B->count);
+ sBytesPushBuffer(&r, &(B->data), B->count);
+ break;
+ }
+ ret r;
+}
+
+/**
+ * serialize dictionary
+ *
+ * the serialized dict is pushed to r.
+ * All elements are serialized recursively
+ *
+ * the data in containers is not serialized
+ *
+ * \param
+ * r small bytes object
+ * dict dictionary to serialize
+ */
+internal void dictNetSerial(sBytest **r, sDictt *dict, contextt *ctx, packingT packing) {
+ sBytest *B = NULL;
+ char *data = NULL;
+
+ // check if all elements have same type
+ // then set dict type normal or uniform
+ // array and dict have to be checked recursively to know if they are normal or uniform
+ bool allElementsHaveSameType = true;
+ bool foundFirstType = false;
+ char type = 0;
+ // get first element type
+ // compare to other element type
+ {forEachSDict(dict, e) {
+ if (e->key) {
+ if (foundFirstType) {
+ u8 nextType;
+ switch(e->data->type) {
+ case DICT:
+ nextType = isDictUniform((sDictt*)e->data);
+ break;
+ case ARRAY:
+ nextType = isArrayUniform((sArrayt*)e->data);
+ break;
+ default:
+ nextType = NET_SERIAL_TYPES[(u8)e->data->type];
+ }
+ if (nextType != type) {
+ allElementsHaveSameType = false;
+ break;
+ }
+ }
+ else {
+ switch(e->data->type) {
+ case DICT:
+ type = isDictUniform((sDictt*)e->data);
+ break;
+ case ARRAY:
+ type = isArrayUniform((sArrayt*)e->data);
+ break;
+ default:
+ type = NET_SERIAL_TYPES[(u8)e->data->type];
+ }
+ foundFirstType = true;
+ }
+ }
+ }}
+
+ if (allElementsHaveSameType) {
+ // uniform dict
+ // encode type and element count
+
+ // in pack dictionary
+ if (packing == PACKED) {
+ // uniform dict can't be packed
+ // because there is only one type of packed arrays
+ goto normalDict;
+ }
+ elif (packing == UNIFORM) {
+ // when the packing is uniform, there is no need to encode UNIFORM_DICT since all elements have this type
+ uintToNetTypeVarint(r, type, dict->count);
+ }
+ else {
+ if (ctx->nibble == lowNbl) {
+ sBytesPush(r, (type << 4) + UNIFORM_DICT);
+ uintToVarint(r, dict->count);
+ }
+ else {
+ // high nibble
+ ctx->nibble = lowNbl;
+ data = (char *)&((*r)->data) + ctx->nblOffset;
+ *data |= UNIFORM_DICT << 4;
+ uintToNetTypeVarint(r, type, dict->count);
+ }
+ }
+
+ // encode all element keys and values
+ switch(type) {
+ case S_UNDEFINED:
+ {forEachSDict(dict, e) {
+ if (e->key) {
+ sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+ }
+ }}
+
+ break;
+ case S_BOOL:
+ {forEachSDict(dict, e) {
+ if (e->key) {
+ sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+
+ if (!ctx->boolOffset) {
+ // new packed bools
+ storeNew8bPackedBool(e->data);
+ }
+ else {
+ // there was a bool before this one, fill bits in nibbles
+ if (ctx->boolShift == 8) {
+ // previous packed bool is full
+ // next byte is the new packed bools
+ storeNew8bPackedBool(e->data);
+ }
+ else {
+ storeBool(e->data);
+ }
+ }
+ }
+ }}
+ break;
+ case S_DICT:
+ case UNIFORM_DICT:
+ {forEachSDict(dict, e) {
+ if (e->key) {
+ sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+ dictNetSerial(r, (sDictt *)(e->data), ctx, /*packing=*/UNIFORM);
+ }
+ }}
+ break;
+ case S_DOUBLE:
+ {forEachSDict(dict, e) {
+ if (e->key) {
+ sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+ sBytesPushBuffer(r, &((sDoublet *)(e->data))->value, sizeof(double));
+ }
+ }}
+ break;
+ case S_INT:
+ {forEachSDict(dict, e) {
+ if (e->key) {
+ sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+ i64 v = ((sIntt *)(e->data))->value;
+ uintToVarint(r, (v << 1) ^ (v >> 63));
+ }
+ }}
+ break;
+ case S_STRING:
+ {forEachSDict(dict, e) {
+ if (e->key) {
+ sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+ sBytesPushBuffer(r, &((sStringt *)(e->data))->data, sizeof(sStringt) + strlen(&(((sStringt *)(e->data))->data)) -1);
+ }
+ }}
+ break;
+ case S_ARRAY:
+ case UNIFORM_ARRAY:
+ {forEachSDict(dict, e) {
+ if (e->key) {
+ sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+ arrayNetSerial(r, (sArrayt *)(e->data), ctx, /*packing=*/UNIFORM);
+ }
+ }}
+ break;
+ case S_BYTES:
+ {forEachSDict(dict, e) {
+ if (e->key) {
+ sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+ B = (sBytest *)(e->data);
+ uintToVarint(r, B->count);
+ sBytesPushBuffer(r, &(B->data), B->count);
+ }
+ }}
+ break;
+ }
+ ret;
+ }
+
+ normalDict:
+ // encode type and element count
+ if (packing == PACKED or packing == UNIFORM) {
+ // when the packing is packed or uniform, there is no need to encode DICT type since all elements have this type
+ uintToVarint(r, dict->count);
+ }
+ else {
+ if (ctx->nibble == lowNbl) {
+ uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)dict->type], dict->count);
+ }
+ else {
+ // high nibble
+ #define storeTypeInHighNbl(o)\
+ ctx->nibble = lowNbl;\
+ data = (char *)&((*r)->data) + ctx->nblOffset;\
+ *data |= NET_SERIAL_TYPES[(u8)o->type] << 4
+ storeTypeInHighNbl(dict);
+ uintToVarint(r, dict->count);
+ }
+ }
+
+ bool pack = false;
+ size_t packCount;
+ enumerateSDict(dict, e, eIdx) {
+ if (e->key) {
+ if (!pack) {
+ // scan dict for packing
+ if ((dict->count - eIdx) > 3) {
+ // at least 4 elements, less than that is not worth it
+ if ( e->data->type == DICT
+ or e->data->type == DOUBLE
+ or e->data->type == INT
+ or e->data->type == STRING
+ or e->data->type == ARRAY
+ or e->data->type == BYTES) {
+ type = e->data->type;
+ packCount = 1;
+ sDictElemt *element = &((dict)->elements) + eIdx;
+ for (size_t i = eIdx+1; i < (dict)->count ; i++, element = &((dict)->elements) + i) {
+ if (element->key) {
+ if (element->data->type != type) {
+ break;
+ }
+ packCount++;
+ } // element->key
+ } // for
+ if (packCount > 3) {
+ type = PACKED_NET_SERIAL_TYPES[(u8)type];
+ pack = true;
+ }
+ } // test current element type
+ } // is dict big enough
+ } // not already packing
+
+ // encode key
+ sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+
+ // encode value
+ switch(e->data->type) {
+ case UNDEFINED:
+ case CONTAINER:
+ if (ctx->nibble == lowNbl) {
+ #define storeTypeOnly(o)\
+ sBytesPush(r, NET_SERIAL_TYPES[(u8)o->type]);\
+ ctx->nibble = highNbl;\
+ ctx->nblOffset = (*r)->count -1
+ storeTypeOnly(e->data);
+ }
+ else {
+ storeTypeInHighNbl(e->data);
+ }
+ break;
+ case BOOL:
+ if (!ctx->boolOffset) {
+ // new packed bools
+ if (ctx->nibble == lowNbl) {
+ #define storeNew4bPackedBool(o)\
+ u8 c = NET_SERIAL_TYPES[(u8)o->type];\
+ /* set bit 4 when true */\
+ if (((sBoolt *)(o))->value)\
+ c |= (1<<4);\
+ sBytesPush(r, c);\
+ ctx->boolShift = 5;\
+ ctx->boolOffset = (*r)->count -1
+ storeNew4bPackedBool(e->data);
+ }
+ else {
+ // high nibble, next byte is packed bools
+ storeTypeInHighNbl(e->data);
+ #define storeNew8bPackedBool(o)\
+ u8 c = 0;\
+ if (((sBoolt *)(o))->value)\
+ c = 1;\
+ sBytesPush(r, c);\
+ ctx->boolShift = 1;\
+ ctx->boolOffset = (*r)->count -1
+ storeNew8bPackedBool(e->data);
+ }
+ }
+ else {
+ // there was a bool before this one, fill bits in nibbles
+ if (ctx->nibble == lowNbl) {
+ if (ctx->boolShift == 8) {
+ // previous packed bool is full
+ // this byte is the new packed bools
+ storeNew4bPackedBool(e->data);
+ }
+ else {
+ storeTypeOnly(e->data);
+ #define storeBool(o)\
+ data = (char *)&((*r)->data) + ctx->boolOffset;\
+ if (((sBoolt *)(o))->value)\
+ *data |= 1 << ctx->boolShift;\
+ ctx->boolShift++
+ storeBool(e->data);
+ }
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(e->data);
+ if (ctx->boolShift == 8) {
+ // previous packed bool is full
+ // next byte is the new packed bools
+ storeNew8bPackedBool(e->data);
+ }
+ else {
+ storeBool(e->data);
+ }
+ }
+ }
+ break;
+ case DICT:
+ if (pack) {
+ if (type) {
+ // this is the first packed element
+ if (ctx->nibble == lowNbl) {
+ uintToNetTypeVarint(r, type, packCount);
+ }
+ else {
+ // high nibble
+ // store type in high nibble
+ ctx->nibble = lowNbl;
+ data = (char *)&((*r)->data) + ctx->nblOffset;
+ *data |= type << 4;
+ uintToVarint(r, packCount);
+ }
+ type = 0;
+ } // if type
+
+ dictNetSerial(r, (sDictt *)(e->data), ctx, /*packing=*/PACKED);
+ // stop packing when packCount == 0
+ packCount--;
+ if (!packCount) pack = false;
+ } // if pack
+ else
+ dictNetSerial(r, (sDictt *)(e->data), ctx, /*packing=*/NOPACKING);
+ break;
+ case DOUBLE:
+ if (pack) {
+ if (type) {
+ // this is the first packed element
+ if (ctx->nibble == lowNbl) {
+ uintToNetTypeVarint(r, type, packCount);
+ }
+ else {
+ // high nibble
+ // store type in high nibble
+ ctx->nibble = lowNbl;
+ data = (char *)&((*r)->data) + ctx->nblOffset;
+ *data |= type << 4;
+ uintToVarint(r, packCount);
+ }
+ type = 0;
+ } // if type
+
+ sBytesPushBuffer(r, &((sDoublet *)(e->data))->value, sizeof(double));
+ // stop packing when packCount == 0
+ packCount--;
+ if (!packCount) pack = false;
+ } // if pack
+ else {
+ if (ctx->nibble == lowNbl) {
+ storeTypeOnly(e->data);
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(e->data);
+ }
+ sBytesPushBuffer(r, &((sDoublet *)(e->data))->value, sizeof(double));
+ }
+ break;
+ case INT:
+ if (pack) {
+ if (type) {
+ // this is the first packed element
+ if (ctx->nibble == lowNbl) {
+ uintToNetTypeVarint(r, type, packCount);
+ }
+ else {
+ // high nibble
+ // store type in high nibble
+ ctx->nibble = lowNbl;
+ data = (char *)&((*r)->data) + ctx->nblOffset;
+ *data |= type << 4;
+ uintToVarint(r, packCount);
+ }
+ type = 0;
+ } // if type
+
+ i64 v = ((sIntt *)(e->data))->value;
+ uintToVarint(r, (v << 1) ^ (v >> 63));
+ // stop packing when packCount == 0
+ packCount--;
+ if (!packCount) pack = false;
+ } // if pack
+ else {
+ // encode int to varint
+ // v is int64_t to convert to varint
+ i64 v = ((sIntt *)(e->data))->value;
+ if (ctx->nibble == lowNbl) {
+ // encode v with arithmetic shifts
+ uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)e->data->type], (v << 1) ^ (v >> 63));
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(e->data);
+ uintToVarint(r, (v << 1) ^ (v >> 63));
+ }
+ }
+ break;
+ case STRING:
+ if (pack) {
+ if (type) {
+ // this is the first packed element
+ if (ctx->nibble == lowNbl) {
+ uintToNetTypeVarint(r, type, packCount);
+ }
+ else {
+ // high nibble
+ // store type in high nibble
+ ctx->nibble = lowNbl;
+ data = (char *)&((*r)->data) + ctx->nblOffset;
+ *data |= type << 4;
+ uintToVarint(r, packCount);
+ }
+ type = 0;
+ } // if type
+
+ sBytesPushBuffer(r, &((sStringt *)(e->data))->data, sizeof(sStringt) + strlen(&(((sStringt *)(e->data))->data)) -1);
+ // stop packing when packCount == 0
+ packCount--;
+ if (!packCount) pack = false;
+ } // if pack
+ else {
+ if (ctx->nibble == lowNbl) {
+ storeTypeOnly(e->data);
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(e->data);
+ }
+ sBytesPushBuffer(r, &((sStringt *)(e->data))->data, sizeof(sStringt) + strlen(&(((sStringt *)(e->data))->data)) -1);
+ }
+ break;
+ case ARRAY:
+ if (pack) {
+ if (type) {
+ // this is the first packed element
+ if (ctx->nibble == lowNbl) {
+ uintToNetTypeVarint(r, type, packCount);
+ }
+ else {
+ // high nibble
+ // store type in high nibble
+ ctx->nibble = lowNbl;
+ data = (char *)&((*r)->data) + ctx->nblOffset;
+ *data |= type << 4;
+ uintToVarint(r, packCount);
+ }
+ type = 0;
+ } // if type
+
+ arrayNetSerial(r, (sArrayt *)(e->data), ctx, /*packing=*/PACKED);
+ // stop packing when packCount == 0
+ packCount--;
+ if (!packCount) pack = false;
+ } // if pack
+ else
+ arrayNetSerial(r, (sArrayt *)(e->data), ctx, /*packing=*/NOPACKING);
+ break;
+ case BYTES:
+ if (pack) {
+ if (type) {
+ // this is the first packed element
+ if (ctx->nibble == lowNbl) {
+ uintToNetTypeVarint(r, type, packCount);
+ }
+ else {
+ // high nibble
+ // store type in high nibble
+ ctx->nibble = lowNbl;
+ data = (char *)&((*r)->data) + ctx->nblOffset;
+ *data |= type << 4;
+ uintToVarint(r, packCount);
+ }
+ type = 0;
+ } // if type
+
+ B = (sBytest *)(e->data);
+ uintToVarint(r, B->count);
+ sBytesPushBuffer(r, &(B->data), B->count);
+ // stop packing when packCount == 0
+ packCount--;
+ if (!packCount) pack = false;
+ } // if pack
+ else {
+ B = (sBytest *)(e->data);
+ if (ctx->nibble == lowNbl) {
+ uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)e->data->type], B->count);
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(e->data);
+ uintToVarint(r, B->count);
+ }
+ sBytesPushBuffer(r, &(B->data), B->count);
+ }
+ break;
+ }
+ }
+ }
+ ret;
+}
+
+/**
+ * serialize array
+ *
+ * the serialized array is pushed to r.
+ * All elements are serialized recursively
+ *
+ * the data in containers is not serialized
+ *
+ * \param
+ * r small bytes object
+ * array to serialize
+ */
+internal void arrayNetSerial(sBytest **r, sArrayt *array, contextt *ctx, packingT packing) {
+ sBytest *B = NULL;
+ char *data = NULL;
+
+ // check if all elements have same type
+ // then set array type normal or uniform
+ // array and dict have to be checked recursively to know if they are normal or uniform
+ bool allElementsHaveSameType = true;
+ bool foundFirstType = false;
+ char type = 0;
+
+ // get first element type
+ // compare to other element type
+ // null element are interpreted as undefined
+ {forEachSArray(array, e) {
+ if (!e) {
+ if (foundFirstType) {
+ if (type != S_UNDEFINED) {
+ allElementsHaveSameType = false;
+ break;
+ }
+ }
+ else {
+ type = S_UNDEFINED;
+ foundFirstType = true;
+ }
+ }
+ else {
+ if (foundFirstType) {
+ u8 nextType;
+ switch(e->type) {
+ case DICT:
+ nextType = isDictUniform((sDictt*)e);
+ break;
+ case ARRAY:
+ nextType = isArrayUniform((sArrayt*)e);
+ break;
+ default:
+ nextType = NET_SERIAL_TYPES[(u8)e->type];
+ }
+ if (nextType != type) {
+ allElementsHaveSameType = false;
+ break;
+ }
+ }
+ else {
+ switch(e->type) {
+ case DICT:
+ type = isDictUniform((sDictt*)e);
+ break;
+ case ARRAY:
+ type = isArrayUniform((sArrayt*)e);
+ break;
+ default:
+ type = NET_SERIAL_TYPES[(u8)e->type];
+ }
+ foundFirstType = true;
+ }
+ }
+ }}
+
+ if (allElementsHaveSameType) {
+ // uniform array
+ // encode type and element count
+
+ // in pack array
+ if (packing == PACKED) {
+ // uniform array can't be packed
+ // because there is only one type of packed arrays
+ goto normalArray;
+ }
+ elif (packing == UNIFORM) {
+ // when the packing is uniform, there is no need to encode UNIFORM_ARRAY since all elements have this type
+ uintToNetTypeVarint(r, type, array->count);
+ }
+ else {
+ if (ctx->nibble == lowNbl) {
+ sBytesPush(r, (type << 4) + UNIFORM_ARRAY);
+ uintToVarint(r, array->count);
+ }
+ else {
+ // high nibble
+ ctx->nibble = lowNbl;
+ data = (char *)&((*r)->data) + ctx->nblOffset;
+ *data |= UNIFORM_ARRAY << 4;
+ uintToNetTypeVarint(r, type, array->count);
+ }
+ }
+
+ // encode all element values
+ switch(type) {
+ case S_BOOL:
+ {forEachSArray(array, e) {
+ if (!ctx->boolOffset) {
+ // new packed bools
+ storeNew8bPackedBool(e);
+ }
+ else {
+ // there was a bool before this one, fill bits in nibbles
+ if (ctx->boolShift == 8) {
+ // previous packed bool is full
+ // next byte is the new packed bools
+ storeNew8bPackedBool(e);
+ }
+ else {
+ storeBool(e);
+ }
+ }
+ }}
+ break;
+ case S_DICT:
+ case UNIFORM_DICT:
+ {forEachSArray(array, e) {
+ dictNetSerial(r, (sDictt *)e, ctx, /*packing=*/UNIFORM);
+ }}
+ break;
+ case S_DOUBLE:
+ {forEachSArray(array, e) {
+ sBytesPushBuffer(r, &((sDoublet *)e)->value, sizeof(double));
+ }}
+ break;
+ case S_INT:
+ {forEachSArray(array, e) {
+ i64 v = ((sIntt *)e)->value;
+ uintToVarint(r, (v << 1) ^ (v >> 63));
+ }}
+ break;
+ case S_STRING:
+ {forEachSArray(array, e) {
+ sBytesPushBuffer(r, &((sStringt *)e)->data, sizeof(sStringt) + strlen(&(((sStringt *)e)->data)) -1);
+ }}
+ break;
+ case S_ARRAY:
+ case UNIFORM_ARRAY:
+ {forEachSArray(array, e) {
+ arrayNetSerial(r, (sArrayt *)e, ctx, /*packing=*/UNIFORM);
+ }}
+ break;
+ case S_BYTES:
+ {forEachSArray(array, e) {
+ B = (sBytest *)e;
+ uintToVarint(r, B->count);
+ sBytesPushBuffer(r, &(B->data), B->count);
+ }}
+ break;
+ }
+ ret;
+ }
+
+ normalArray:
+ // encode type and element count
+ if (packing == PACKED or packing == UNIFORM) {
+ // when the packing is packed or uniform, there is no need to encode ARRAY type since all elements have this type
+ uintToVarint(r, array->count);
+ }
+ else {
+ if (ctx->nibble == lowNbl) {
+ uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)array->type], array->count);
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(array);
+ uintToVarint(r, array->count);
+ }
+ }
+
+ bool pack = false;
+ size_t packCount;
+ enumerateSArray(array, e, eIdx) {
+ if (!e) {
+ // empty slots are represented as undefined elements
+ if (ctx->nibble == lowNbl) {
+ sBytesPush(r, NET_SERIAL_TYPES[UNDEFINED]);
+ ctx->nibble = highNbl;
+ ctx->nblOffset = (*r)->count -1;
+ }
+ else {
+ // high nibble
+ ctx->nibble = lowNbl;
+ data = (char *)&((*r)->data) + ctx->nblOffset;
+ *data |= NET_SERIAL_TYPES[UNDEFINED] << 4;
+ }
+ }
+ else {
+ if (!pack) {
+ // scan array for packing
+ if ((array->count - eIdx) > 3) {
+ // at least 4 elements, less than that is not worth it
+ if ( e->type == DICT
+ or e->type == DOUBLE
+ or e->type == INT
+ or e->type == STRING
+ or e->type == ARRAY
+ or e->type == BYTES) {
+ type = e->type;
+ packCount = 1;
+ smallt *element = ((smallt **) &((array)->data))[eIdx];
+ for (size_t i = eIdx+1; i < (array)->count ; i++, element = ((smallt **) &((array)->data))[i]) {
+ if (!element) {
+ // null element are undefined
+ break;
+ }
+ else {
+ if (element->type != type) {
+ break;
+ }
+ packCount++;
+ } // if element
+ } // for
+ if (packCount > 3) {
+ type = PACKED_NET_SERIAL_TYPES[(u8)type];
+ pack = true;
+ }
+ } // test current element type
+ } // is array big enough
+ } // not already packing
+
+ // encode element value
+ switch(e->type) {
+ case UNDEFINED:
+ case CONTAINER:
+ if (ctx->nibble == lowNbl) {
+ storeTypeOnly(e);
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(e);
+ }
+ break;
+ case BOOL:
+ if (!ctx->boolOffset) {
+ // new packed bools
+ if (ctx->nibble == lowNbl) {
+ storeNew4bPackedBool(e);
+ }
+ else {
+ // high nibble, next byte is packed bools
+ storeTypeInHighNbl(e);
+ storeNew8bPackedBool(e);
+ }
+ }
+ else {
+ // there was a bool before this one, fill bits in nibbles
+ if (ctx->nibble == lowNbl) {
+ if (ctx->boolShift == 8) {
+ // previous packed bool is full
+ // this byte is the new packed bools
+ storeNew4bPackedBool(e);
+ }
+ else {
+ storeTypeOnly(e);
+ storeBool(e);
+ }
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(e);
+ if (ctx->boolShift == 8) {
+ // previous packed bool is full
+ // next byte is the new packed bools
+ storeNew8bPackedBool(e);
+ }
+ else {
+ storeBool(e);
+ }
+ }
+ }
+ break;
+ case DICT:
+ if (pack) {
+ if (type) {
+ // this is the first packed element
+ if (ctx->nibble == lowNbl) {
+ uintToNetTypeVarint(r, type, packCount);
+ }
+ else {
+ // high nibble
+ // store type in high nibble
+ ctx->nibble = lowNbl;
+ data = (char *)&((*r)->data) + ctx->nblOffset;
+ *data |= type << 4;
+ uintToVarint(r, packCount);
+ }
+ type = 0;
+ } // if type
+
+ dictNetSerial(r, (sDictt *)e, ctx, /*packing=*/PACKED);
+ // stop packing when packCount == 0
+ packCount--;
+ if (!packCount) pack = false;
+ } // if pack
+ else
+ dictNetSerial(r, (sDictt *)e, ctx, /*packing=*/NOPACKING);
+ break;
+ case DOUBLE:
+ if (pack) {
+ if (type) {
+ // this is the first packed element
+ if (ctx->nibble == lowNbl) {
+ uintToNetTypeVarint(r, type, packCount);
+ }
+ else {
+ // high nibble
+ // store type in high nibble
+ ctx->nibble = lowNbl;
+ data = (char *)&((*r)->data) + ctx->nblOffset;
+ *data |= type << 4;
+ uintToVarint(r, packCount);
+ }
+ type = 0;
+ } // if type
+
+ sBytesPushBuffer(r, &((sDoublet *)e)->value, sizeof(double));
+ // stop packing when packCount == 0
+ packCount--;
+ if (!packCount) pack = false;
+ } // if pack
+ else {
+ if (ctx->nibble == lowNbl) {
+ storeTypeOnly(e);
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(e);
+ }
+ sBytesPushBuffer(r, &((sDoublet *)e)->value, sizeof(double));
+ }
+ break;
+ case INT:
+ if (pack) {
+ if (type) {
+ // this is the first packed element
+ if (ctx->nibble == lowNbl) {
+ uintToNetTypeVarint(r, type, packCount);
+ }
+ else {
+ // high nibble
+ // store type in high nibble
+ ctx->nibble = lowNbl;
+ data = (char *)&((*r)->data) + ctx->nblOffset;
+ *data |= type << 4;
+ uintToVarint(r, packCount);
+ }
+ type = 0;
+ } // if type
+
+ i64 v = ((sIntt *)&(e->type))->value;
+ uintToVarint(r, (v << 1) ^ (v >> 63));
+ // stop packing when packCount == 0
+ packCount--;
+ if (!packCount) pack = false;
+ } // if pack
+ else {
+ // encode int to varint
+ // v is int64_t to convert to varint
+ i64 v = ((sIntt *)&(e->type))->value;
+ if (ctx->nibble == lowNbl) {
+ // encode v with arithmetic shifts
+ uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)e->type], (v << 1) ^ (v >> 63));
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(e);
+ uintToVarint(r, (v << 1) ^ (v >> 63));
+ }
+ }
+ break;
+ case STRING:
+ if (pack) {
+ if (type) {
+ // this is the first packed element
+ if (ctx->nibble == lowNbl) {
+ uintToNetTypeVarint(r, type, packCount);
+ }
+ else {
+ // high nibble
+ // store type in high nibble
+ ctx->nibble = lowNbl;
+ data = (char *)&((*r)->data) + ctx->nblOffset;
+ *data |= type << 4;
+ uintToVarint(r, packCount);
+ }
+ type = 0;
+ } // if type
+
+ sBytesPushBuffer(r, &((sStringt *)e)->data, sizeof(sStringt) + strlen(&(((sStringt *)e)->data)) -1);
+ // stop packing when packCount == 0
+ packCount--;
+ if (!packCount) pack = false;
+ } // if pack
+ else {
+ if (ctx->nibble == lowNbl) {
+ storeTypeOnly(e);
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(e);
+ }
+ sBytesPushBuffer(r, &((sStringt *)e)->data, sizeof(sStringt) + strlen(&(((sStringt *)e)->data)) -1);
+ }
+ break;
+ case ARRAY:
+ if (pack) {
+ if (type) {
+ // this is the first packed element
+ if (ctx->nibble == lowNbl) {
+ uintToNetTypeVarint(r, type, packCount);
+ }
+ else {
+ // high nibble
+ // store type in high nibble
+ ctx->nibble = lowNbl;
+ data = (char *)&((*r)->data) + ctx->nblOffset;
+ *data |= type << 4;
+ uintToVarint(r, packCount);
+ }
+ type = 0;
+ } // if type
+
+ arrayNetSerial(r, (sArrayt *)e, ctx, /*packing=*/PACKED);
+ // stop packing when packCount == 0
+ packCount--;
+ if (!packCount) pack = false;
+ } // if pack
+ else
+ arrayNetSerial(r, (sArrayt *)e, ctx, /*packing=*/NOPACKING);
+ break;
+ case BYTES:
+ if (pack) {
+ if (type) {
+ // this is the first packed element
+ if (ctx->nibble == lowNbl) {
+ uintToNetTypeVarint(r, type, packCount);
+ }
+ else {
+ // high nibble
+ // store type in high nibble
+ ctx->nibble = lowNbl;
+ data = (char *)&((*r)->data) + ctx->nblOffset;
+ *data |= type << 4;
+ uintToVarint(r, packCount);
+ }
+ type = 0;
+ } // if type
+
+ B = (sBytest *)e;
+ uintToVarint(r, B->count);
+ sBytesPushBuffer(r, &(B->data), B->count);
+ // stop packing when packCount == 0
+ packCount--;
+ if (!packCount) pack = false;
+ } // if pack
+ else {
+ B = (sBytest *)e;
+ if (ctx->nibble == lowNbl) {
+ uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)e->type], B->count);
+ }
+ else {
+ // high nibble
+ storeTypeInHighNbl(e);
+ uintToVarint(r, B->count);
+ }
+ sBytesPushBuffer(r, &(B->data), B->count);
+ }
+ break;
+ }
+ }
+ }
+ ret;
+}
+
+internal smallBytest* serialNetSerial(smallJsont *self) {
+
+ smallt *o = getsoG(self);
+
+ if (o == NULL)
+ ret NULL;
+
+ sBytest *B = netSerial(o);
+
+ if (!B) {
+ ret NULL;
+ }
+
+ createAllocateSmallBytes(r);
+ r->B = B;
+ ret r;
+}
+
+// -------------------------------------
+// Deserializers
+
+// level 0
+// like smallJson with ints and length encoded as varints
+
+/**
+ * deserializer top function
+ */
+internal smallt* netDeserialLevel0(sBytest *obj) {
+ smallt *r = NULL;
+ double *D = NULL;
+ char *s = NULL;
+ sBytest *B = NULL;
+ uint32_t count;
+ char *data = NULL;
+
+ switch(obj->data & 0xF) {
+ case S_UNDEFINED:
+ r = (smallt *) allocSUndefined();
+ break;
+ case S_BOOL:
+ r = (smallt *) allocSBool(obj->data & 0x10);
+ break;
+ case S_DICT:
+ data = (char *)&(obj->data);
+ dictNetDeserialLevel0((sDictt **)&r, &data);
+ break;
+ case S_DOUBLE:
+ data = &(obj->data)+1;
+ D = (double *)data;
+ r = (smallt *) allocSDouble(*D);
+ break;
+ case S_INT:
+ data = &(obj->data);
+ i64 v = netTypeVarintToUint((u8**)&data);
+ v = (v >> 1) ^ ((v << 63) >> 63);
+ r = (smallt *) allocSInt(v);
+ break;
+ case S_STRING:
+ s = (char *)&(obj->data)+1;
+ r = (smallt *) allocSStringTiny(s);
+ break;
+ case S_ARRAY:
+ data = (char *)&(obj->data);
+ arrayNetDeserialLevel0((sArrayt **)&r, &data);
+ break;
+ case S_BYTES:
+ B = allocSBytes();
+ data = &(obj->data);
+ count = netTypeVarintToUint((u8**)&data);
+ sBytesPushBuffer(&B, data, count);
+ r = (smallt *)B;
+ break;
+ }
+
+ ret r;
+}
+
+/**
+ * deserialize dictionary from data
+ *
+ * a new dictionary is allocated
+ *
+ * \param
+ * dict dictionary holding the elements
+ * data serialized dictionary
+ */
+internal void dictNetDeserialLevel0(sDictt **dict, char **data) {
+ sUndefinedt *u = NULL;
+ sBoolt *bo = NULL;
+ double *D = NULL;
+ sDoublet *Do = NULL;
+ sDictt *d = NULL;
+ sIntt *io = NULL;
+ char *s = NULL;
+ sStringt *so = NULL;
+ sArrayt *a = NULL;
+ sBytest *B = NULL;
+ uint32_t count;
+ uint32_t dictCount;
+
+ dictCount = netTypeVarintToUint((u8**)data);
+
+ if (!dictCount) {
+ *dict = allocSDict();
+ ret;
+ }
+
+ loop(dictCount) {
+ char type;
+ char *key;
+ key = *data;
+ *data += strlen(key)+1;
+ type = **data;
+
+ switch(type & 0xF) {
+ case S_UNDEFINED:
+ (*data)++;
+ u = allocSUndefined();
+ sDictPushTiny(dict, key, (smallt *) u);
+ break;
+ case S_BOOL:
+ (*data)++;
+ bo = allocSBool(type & 0x10);
+ sDictPushTiny(dict, key, (smallt *) bo);
+ break;
+ case S_DICT:
+ d = NULL;
+ dictNetDeserialLevel0(&d, data);
+ sDictPushTiny(dict, key, (smallt *) d);
+ break;
+ case S_DOUBLE:
+ (*data)++;
+ D = (double *)(*data);
+ *data += sizeof(double);
+ Do = allocSDouble(*D);
+ sDictPushTiny(dict, key, (smallt *) Do);
+ break;
+ case S_INT: {
+ i64 v = netTypeVarintToUint((u8**)data);
+ v = (v >> 1) ^ ((v << 63) >> 63);
+ io = allocSInt(v);
+ sDictPushTiny(dict, key, (smallt *) io);
+ }
+ break;
+ case S_STRING:
+ (*data)++;
+ s = (char *)(*data);
+ *data += strlen(s)+1;
+ so = allocSStringTiny(s);
+ sDictPushTiny(dict, key, (smallt *) so);
+ break;
+ case S_ARRAY:
+ a = NULL;
+ arrayNetDeserialLevel0(&a, data);
+ sDictPushTiny(dict, key, (smallt *) a);
+ break;
+ case S_BYTES:
+ B = allocSBytes();
+ count = netTypeVarintToUint((u8**)data);
+ sBytesPushBuffer(&B, data, count);
+ *data += count;
+ sDictPushTiny(dict, key, (smallt *) B);
+ break;
+ }
+ }
+}
+
+/**
+ * deserialize array from data
+ *
+ * a new array is allocated
+ *
+ * \param
+ * array holding the elements
+ * data serialized dictionary
+ */
+internal void arrayNetDeserialLevel0(sArrayt **array, char **data) {
+ sUndefinedt *u = NULL;
+ sBoolt *bo = NULL;
+ double *D = NULL;
+ sDoublet *Do = NULL;
+ sDictt *d = NULL;
+ sIntt *io = NULL;
+ char *s = NULL;
+ sStringt *so = NULL;
+ sArrayt *a = NULL;
+ sBytest *B = NULL;
+ uint32_t count;
+ uint32_t arrayCount;
+
+ arrayCount = netTypeVarintToUint((u8**)data);
+
+ if (!arrayCount) {
+ *array = allocSArray();;
+ ret;
+ }
+
+ loop(arrayCount) {
+ char type;
+ type = **data;
+
+ switch(type & 0xF) {
+ case S_UNDEFINED:
+ (*data)++;
+ u = allocSUndefined();
+ sArrayPushTiny(array, (smallt *) u);
+ break;
+ case S_BOOL:
+ (*data)++;
+ bo = allocSBool(type & 0x10);
+ sArrayPushTiny(array, (smallt *) bo);
+ break;
+ case S_DICT:
+ d = NULL;
+ dictNetDeserialLevel0(&d, data);
+ sArrayPushTiny(array, (smallt *) d);
+ break;
+ case S_DOUBLE:
+ (*data)++;
+ D = (double *)(*data);
+ *data += sizeof(double);
+ Do = allocSDouble(*D);
+ sArrayPushTiny(array, (smallt *) Do);
+ break;
+ case S_INT: {
+ i64 v = netTypeVarintToUint((u8**)data);
+ v = (v >> 1) ^ ((v << 63) >> 63);
+ io = allocSInt(v);
+ sArrayPushTiny(array, (smallt *) io);
+ }
+ break;
+ case S_STRING:
+ (*data)++;
+ s = (char *)(*data);
+ *data += strlen(s)+1;
+ so = allocSStringTiny(s);
+ sArrayPushTiny(array, (smallt *) so);
+ break;
+ case S_ARRAY:
+ a = NULL;
+ arrayNetDeserialLevel0(&a, data);
+ sArrayPushTiny(array, (smallt *) a);
+ break;
+ case S_BYTES:
+ B = allocSBytes();
+ count = netTypeVarintToUint((u8**)data);
+ sBytesPushBuffer(&B, data, count);
+ *data += count;
+ sArrayPushTiny(array, (smallt *) B);
+ break;
+ }
+ }
+}
+
+internal smallJsont* deserialNetSerialLevel0(smallJsont *self, smallBytest *data) {
+
+ if (!data) {
+ ret self;
+ }
+
+ smallt *o = netDeserialLevel0(data->B);
+
+ if (!o) {
+ ret self;
+ }
+
+ freeG(self);
+
+ setsoG(self, o);
+
+ ret self;
+}
+
+// level 1
+// like level 0 with type encoded in nibbles and bools are packed
+
+/**
+ * deserializer top function
+ */
+internal smallt* netDeserialLevel1(sBytest *obj) {
+ smallt *r = NULL;
+ double *D = NULL;
+ char *s = NULL;
+ sBytest *B = NULL;
+ uint32_t count;
+ char *data = NULL;
+ contextt ctx = {.nibble=lowNbl, .nblAddr=NULL, .boolShift = 0, .boolAddr=NULL};
+
+ switch(obj->data & 0xF) {
+ case S_UNDEFINED:
+ r = (smallt *) allocSUndefined();
+ break;
+ case S_BOOL:
+ r = (smallt *) allocSBool(obj->data & 0x10);
+ break;
+ case S_DICT:
+ data = (char *)&(obj->data);
+ //debug - ctx.dbuf = (u8*) data;
+ dictNetDeserialLevel1((sDictt **)&r, (u8**)&data, &ctx);
+ break;
+ case S_DOUBLE:
+ data = &(obj->data)+1;
+ D = (double *)data;
+ r = (smallt *) allocSDouble(*D);
+ break;
+ case S_INT:
+ data = &(obj->data);
+ i64 v = netTypeVarintToUint((u8**)&data);
+ v = (v >> 1) ^ ((v << 63) >> 63);
+ r = (smallt *) allocSInt(v);
+ break;
+ case S_STRING:
+ s = (char *)&(obj->data)+1;
+ r = (smallt *) allocSStringTiny(s);
+ break;
+ case S_ARRAY:
+ data = (char *)&(obj->data);
+ //debug - ctx.dbuf = (u8*) data;
+ arrayNetDeserialLevel1((sArrayt **)&r, (u8**)&data, &ctx);
+ break;
+ case S_BYTES:
+ B = allocSBytes();
+ data = &(obj->data);
+ count = netTypeVarintToUint((u8**)&data);
+ sBytesPushBuffer(&B, data, count);
+ r = (smallt *)B;
+ break;
+ }
+
+ ret r;
+}
+
+/**
+ * deserialize dictionary from data
+ *
+ * a new dictionary is allocated
+ *
+ * \param
+ * dict dictionary holding the elements
+ * data serialized dictionary
+ */
+internal void dictNetDeserialLevel1(sDictt **dict, u8 **data, contextt *ctx) {
+ sUndefinedt *u = NULL;
+ sBoolt *bo = NULL;
+ double *D = NULL;
+ sDoublet *Do = NULL;
+ sDictt *d = NULL;
+ sIntt *io = NULL;
+ char *s = NULL;
+ sStringt *so = NULL;
+ sArrayt *a = NULL;
+ sBytest *B = NULL;
+ uint32_t count;
+ uint32_t dictCount;
+
+ if (ctx->nibble == lowNbl) {
+ dictCount = netTypeVarintToUint(data);
+ }
+ else {
+ // high nibble
+ // type = *(ctx->dbuf + ctx->nblOffset) >> 4;
+ #define readTypeInHighNbl\
+ ctx->nibble = lowNbl;\
+ if (ctx->nblAddr == *data)\
+ /* data points to the type, next byte is count */\
+ (*data)++
+ readTypeInHighNbl;
+ dictCount = varintToUint(data);
+ }
+
+ if (!dictCount) {
+ *dict = allocSDict();
+ ret;
+ }
+
+ loop(dictCount) {
+ char *key = (char*)*data;
+ *data += strlen(key)+1;
+ char type;
+ if (ctx->nibble == lowNbl) {
+ type = (**data) & 0xF;
+ }
+ else {
+ // high nibble
+ type = (*ctx->nblAddr) >> 4;
+ }
+
+ switch(type) {
+ case S_UNDEFINED:
+ if (ctx->nibble == lowNbl) {
+ #define readTypeOnly\
+ ctx->nibble = highNbl;\
+ ctx->nblAddr = *data;\
+ (*data)++
+ readTypeOnly;
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ }
+ u = allocSUndefined();
+ sDictPushTiny(dict, key, (smallt *) u);
+ break;
+ case S_BOOL:
+ if (!ctx->boolAddr) {
+ // new packed bools
+ if (ctx->nibble == lowNbl) {
+ #define read4bPackedBool\
+ ctx->boolShift = 5;\
+ ctx->boolAddr = *data;\
+ (*data)++
+ read4bPackedBool;
+ bo = allocSBool((*ctx->boolAddr) & 0x10);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ #define read8bPackedBool\
+ ctx->boolShift = 1;\
+ ctx->boolAddr = *data;\
+ (*data)++
+ read8bPackedBool;
+ bo = allocSBool((*ctx->boolAddr) & 0x1);
+ }
+ }
+ else {
+ // there was a bool before this one, read bits in nibbles
+ if (ctx->nibble == lowNbl) {
+ if (ctx->boolShift == 8) {
+ read4bPackedBool;
+ bo = allocSBool((*ctx->boolAddr) & 0x10);
+ }
+ else {
+ readTypeOnly;
+ bo = allocSBool((*ctx->boolAddr) & (0x1 << (ctx->boolShift++)));
+ }
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ if (ctx->boolShift == 8) {
+ read8bPackedBool;
+ bo = allocSBool((*ctx->boolAddr) & 0x1);
+ }
+ else {
+ // high nibble
+ bo = allocSBool((*ctx->boolAddr) & (0x1 << (ctx->boolShift++)));
+ }
+ }
+ }
+ sDictPushTiny(dict, key, (smallt *) bo);
+ break;
+ case S_DICT:
+ d = NULL;
+ dictNetDeserialLevel1(&d, data, ctx);
+ sDictPushTiny(dict, key, (smallt *) d);
+ break;
+ case S_DOUBLE:
+ if (ctx->nibble == lowNbl) {
+ readTypeOnly;
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ }
+ D = (double *)(*data);
+ *data += sizeof(double);
+ Do = allocSDouble(*D);
+ sDictPushTiny(dict, key, (smallt *) Do);
+ break;
+ case S_INT: {
+ i64 v;
+ if (ctx->nibble == lowNbl) {
+ v = netTypeVarintToUint((u8**)data);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ v = varintToUint(data);
+ }
+ v = (v >> 1) ^ ((v << 63) >> 63);
+ io = allocSInt(v);
+ sDictPushTiny(dict, key, (smallt *) io);
+ }
+ break;
+ case S_STRING:
+ if (ctx->nibble == lowNbl) {
+ readTypeOnly;
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ }
+ s = (char *)(*data);
+ *data += strlen(s)+1;
+ so = allocSStringTiny(s);
+ sDictPushTiny(dict, key, (smallt *) so);
+ break;
+ case S_ARRAY:
+ a = NULL;
+ arrayNetDeserialLevel1(&a, data, ctx);
+ sDictPushTiny(dict, key, (smallt *) a);
+ break;
+ case S_BYTES:
+ B = allocSBytes();
+ if (ctx->nibble == lowNbl) {
+ count = netTypeVarintToUint((u8**)data);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ count = varintToUint((u8**)data);
+ }
+ sBytesPushBuffer(&B, data, count);
+ *data += count;
+ sDictPushTiny(dict, key, (smallt *) B);
+ break;
+ }
+ }
+}
+
+/**
+ * deserialize array from data
+ *
+ * a new array is allocated
+ *
+ * \param
+ * array holding the elements
+ * data serialized dictionary
+ */
+internal void arrayNetDeserialLevel1(sArrayt **array, u8 **data, contextt *ctx) {
+ sUndefinedt *u = NULL;
+ sBoolt *bo = NULL;
+ double *D = NULL;
+ sDoublet *Do = NULL;
+ sDictt *d = NULL;
+ sIntt *io = NULL;
+ char *s = NULL;
+ sStringt *so = NULL;
+ sArrayt *a = NULL;
+ sBytest *B = NULL;
+ uint32_t count;
+ uint32_t arrayCount;
+
+ if (ctx->nibble == lowNbl) {
+ arrayCount = netTypeVarintToUint(data);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ arrayCount = varintToUint(data);
+ }
+
+ if (!arrayCount) {
+ *array = allocSArray();;
+ ret;
+ }
+
+ loop(arrayCount) {
+ char type;
+ if (ctx->nibble == lowNbl) {
+ type = (**data) & 0xF;
+ }
+ else {
+ // high nibble
+ type = (*ctx->nblAddr) >> 4;
+ }
+
+ switch(type) {
+ case S_UNDEFINED:
+ if (ctx->nibble == lowNbl) {
+ readTypeOnly;
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ }
+ u = allocSUndefined();
+ sArrayPushTiny(array, (smallt *) u);
+ break;
+ case S_BOOL:
+ if (!ctx->boolAddr) {
+ // new packed bools
+ if (ctx->nibble == lowNbl) {
+ read4bPackedBool;
+ bo = allocSBool((*ctx->boolAddr) & 0x10);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ read8bPackedBool;
+ bo = allocSBool((*ctx->boolAddr) & 0x1);
+ }
+ }
+ else {
+ // there was a bool before this one, read bits in nibbles
+ if (ctx->nibble == lowNbl) {
+ if (ctx->boolShift == 8) {
+ read4bPackedBool;
+ bo = allocSBool((*ctx->boolAddr) & 0x10);
+ }
+ else {
+ readTypeOnly;
+ bo = allocSBool((*ctx->boolAddr) & (0x1 << (ctx->boolShift++)));
+ }
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ if (ctx->boolShift == 8) {
+ read8bPackedBool;
+ bo = allocSBool((*ctx->boolAddr) & 0x1);
+ }
+ else {
+ bo = allocSBool((*ctx->boolAddr) & (0x1 << (ctx->boolShift++)));
+ }
+ }
+ }
+ sArrayPushTiny(array, (smallt *) bo);
+ break;
+ case S_DICT:
+ d = NULL;
+ dictNetDeserialLevel1(&d, data, ctx);
+ sArrayPushTiny(array, (smallt *) d);
+ break;
+ case S_DOUBLE:
+ if (ctx->nibble == lowNbl) {
+ readTypeOnly;
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ }
+ D = (double *)(*data);
+ *data += sizeof(double);
+ Do = allocSDouble(*D);
+ sArrayPushTiny(array, (smallt *) Do);
+ break;
+ case S_INT: {
+ i64 v;
+ if (ctx->nibble == lowNbl) {
+ v = netTypeVarintToUint((u8**)data);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ v = varintToUint(data);
+ }
+ v = (v >> 1) ^ ((v << 63) >> 63);
+ io = allocSInt(v);
+ sArrayPushTiny(array, (smallt *) io);
+ }
+ break;
+ case S_STRING:
+ if (ctx->nibble == lowNbl) {
+ readTypeOnly;
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ }
+ s = (char *)(*data);
+ *data += strlen(s)+1;
+ so = allocSStringTiny(s);
+ sArrayPushTiny(array, (smallt *) so);
+ break;
+ case S_ARRAY:
+ a = NULL;
+ arrayNetDeserialLevel1(&a, data, ctx);
+ sArrayPushTiny(array, (smallt *) a);
+ break;
+ case S_BYTES:
+ B = allocSBytes();
+ if (ctx->nibble == lowNbl) {
+ count = netTypeVarintToUint((u8**)data);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ count = varintToUint((u8**)data);
+ }
+ sBytesPushBuffer(&B, data, count);
+ *data += count;
+ sArrayPushTiny(array, (smallt *) B);
+ break;
+ }
+ }
+}
+
+internal smallJsont* deserialNetSerialLevel1(smallJsont *self, smallBytest *data) {
+
+ if (!data) {
+ ret self;
+ }
+
+ smallt *o = netDeserialLevel1(data->B);
+
+ if (!o) {
+ ret self;
+ }
+
+ freeG(self);
+
+ setsoG(self, o);
+
+ ret self;
+}
+
+// level 2
+// like level 1, arrays are set to uniform when all elements are same type
+
+/**
+ * deserializer top function
+ */
+internal smallt* netDeserialLevel2(sBytest *obj) {
+ smallt *r = NULL;
+ double *D = NULL;
+ char *s = NULL;
+ sBytest *B = NULL;
+ uint32_t count;
+ char *data = NULL;
+ contextt ctx = {.nibble=lowNbl, .nblAddr=NULL, .boolShift = 0, .boolAddr=NULL};
+
+ switch(obj->data & 0xF) {
+ case S_UNDEFINED:
+ r = (smallt *) allocSUndefined();
+ break;
+ case S_BOOL:
+ r = (smallt *) allocSBool(obj->data & 0x10);
+ break;
+ case S_DICT:
+ data = (char *)&(obj->data);
+ //debug - ctx.dbuf = (u8*) data;
+ dictNetDeserialLevel2((sDictt **)&r, (u8**)&data, &ctx, /*packed=*/false);
+ break;
+ case S_DOUBLE:
+ data = &(obj->data)+1;
+ D = (double *)data;
+ r = (smallt *) allocSDouble(*D);
+ break;
+ case S_INT:
+ data = &(obj->data);
+ i64 v = netTypeVarintToUint((u8**)&data);
+ v = (v >> 1) ^ ((v << 63) >> 63);
+ r = (smallt *) allocSInt(v);
+ break;
+ case S_STRING:
+ s = (char *)&(obj->data)+1;
+ r = (smallt *) allocSStringTiny(s);
+ break;
+ case S_ARRAY:
+ data = (char *)&(obj->data);
+ //debug - ctx.dbuf = (u8*) data;
+ arrayNetDeserialLevel2((sArrayt **)&r, (u8**)&data, &ctx, /*packed=*/false);
+ break;
+ case S_BYTES:
+ B = allocSBytes();
+ data = &(obj->data);
+ count = netTypeVarintToUint((u8**)&data);
+ sBytesPushBuffer(&B, data, count);
+ r = (smallt *)B;
+ break;
+ case UNIFORM_DICT:
+ data = (char *)&(obj->data);
+ //debug - ctx.dbuf = (u8*) data;
+ uniformDictNetDeserialLevel2((sDictt **)&r, (u8**)&data, &ctx, /*packed=*/false);
+ break;
+ case UNIFORM_ARRAY:
+ data = (char *)&(obj->data);
+ //debug - ctx.dbuf = (u8*) data;
+ uniformArrayNetDeserialLevel2((sArrayt **)&r, (u8**)&data, &ctx, /*packed=*/false);
+ break;
+ }
+
+ ret r;
+}
+
+/**
+ * deserialize dictionary from data
+ *
+ * a new dictionary is allocated
+ *
+ * \param
+ * dict dictionary holding the elements
+ * data serialized dictionary
+ */
+internal void dictNetDeserialLevel2(sDictt **dict, u8 **data, contextt *ctx, bool packed) {
+ sUndefinedt *u = NULL;
+ sBoolt *bo = NULL;
+ double *D = NULL;
+ sDoublet *Do = NULL;
+ sDictt *d = NULL;
+ sIntt *io = NULL;
+ char *s = NULL;
+ sStringt *so = NULL;
+ sArrayt *a = NULL;
+ sBytest *B = NULL;
+ uint32_t count;
+ uint32_t dictCount;
+
+ if (packed) {
+ dictCount = varintToUint(data);
+ }
+ else {
+ if (ctx->nibble == lowNbl) {
+ dictCount = netTypeVarintToUint(data);
+ }
+ else {
+ // high nibble
+ // type = *(ctx->dbuf + ctx->nblOffset) >> 4;
+ #define readTypeInHighNbl\
+ ctx->nibble = lowNbl;\
+ if (ctx->nblAddr == *data)\
+ /* data points to the type, next byte is count */\
+ (*data)++
+ readTypeInHighNbl;
+ dictCount = varintToUint(data);
+ }
+ }
+
+ if (!dictCount) {
+ *dict = allocSDict();
+ ret;
+ }
+
+ loop(dictCount) {
+ char *key = (char*)*data;
+ *data += strlen(key)+1;
+ char type;
+ if (ctx->nibble == lowNbl) {
+ type = (**data) & 0xF;
+ }
+ else {
+ // high nibble
+ type = (*ctx->nblAddr) >> 4;
+ }
+
+ switch(type) {
+ case S_UNDEFINED:
+ if (ctx->nibble == lowNbl) {
+ #define readTypeOnly\
+ ctx->nibble = highNbl;\
+ ctx->nblAddr = *data;\
+ (*data)++
+ readTypeOnly;
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ }
+ u = allocSUndefined();
+ sDictPushTiny(dict, key, (smallt *) u);
+ break;
+ case S_BOOL:
+ if (!ctx->boolAddr) {
+ // new packed bools
+ if (ctx->nibble == lowNbl) {
+ #define read4bPackedBool\
+ ctx->boolShift = 5;\
+ ctx->boolAddr = *data;\
+ (*data)++
+ read4bPackedBool;
+ bo = allocSBool((*ctx->boolAddr) & 0x10);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ #define read8bPackedBool\
+ ctx->boolShift = 1;\
+ ctx->boolAddr = *data;\
+ (*data)++
+ read8bPackedBool;
+ bo = allocSBool((*ctx->boolAddr) & 0x1);
+ }
+ }
+ else {
+ // there was a bool before this one, read bits in nibbles
+ if (ctx->nibble == lowNbl) {
+ if (ctx->boolShift == 8) {
+ read4bPackedBool;
+ bo = allocSBool((*ctx->boolAddr) & 0x10);
+ }
+ else {
+ readTypeOnly;
+ bo = allocSBool((*ctx->boolAddr) & (0x1 << (ctx->boolShift++)));
+ }
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ if (ctx->boolShift == 8) {
+ read8bPackedBool;
+ bo = allocSBool((*ctx->boolAddr) & 0x1);
+ }
+ else {
+ // high nibble
+ bo = allocSBool((*ctx->boolAddr) & (0x1 << (ctx->boolShift++)));
+ }
+ }
+ }
+ sDictPushTiny(dict, key, (smallt *) bo);
+ break;
+ case S_DICT:
+ d = NULL;
+ dictNetDeserialLevel2(&d, data, ctx, /*packed=*/false);
+ sDictPushTiny(dict, key, (smallt *) d);
+ break;
+ case S_DOUBLE:
+ if (ctx->nibble == lowNbl) {
+ readTypeOnly;
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ }
+ D = (double *)(*data);
+ *data += sizeof(double);
+ Do = allocSDouble(*D);
+ sDictPushTiny(dict, key, (smallt *) Do);
+ break;
+ case S_INT: {
+ i64 v;
+ if (ctx->nibble == lowNbl) {
+ v = netTypeVarintToUint((u8**)data);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ v = varintToUint(data);
+ }
+ v = (v >> 1) ^ ((v << 63) >> 63);
+ io = allocSInt(v);
+ sDictPushTiny(dict, key, (smallt *) io);
+ }
+ break;
+ case S_STRING:
+ if (ctx->nibble == lowNbl) {
+ readTypeOnly;
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ }
+ s = (char *)(*data);
+ *data += strlen(s)+1;
+ so = allocSStringTiny(s);
+ sDictPushTiny(dict, key, (smallt *) so);
+ break;
+ case S_ARRAY:
+ a = NULL;
+ arrayNetDeserialLevel2(&a, data, ctx, /*packed=*/false);
+ sDictPushTiny(dict, key, (smallt *) a);
+ break;
+ case S_BYTES:
+ B = allocSBytes();
+ if (ctx->nibble == lowNbl) {
+ count = netTypeVarintToUint((u8**)data);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ count = varintToUint((u8**)data);
+ }
+ sBytesPushBuffer(&B, data, count);
+ *data += count;
+ sDictPushTiny(dict, key, (smallt *) B);
+ break;
+ case UNIFORM_DICT:
+ d = NULL;
+ uniformDictNetDeserialLevel2(&d, data, ctx, /*packed=*/false);
+ sDictPushTiny(dict, key, (smallt *) d);
+ break;
+ case UNIFORM_ARRAY:
+ a = NULL;
+ uniformArrayNetDeserialLevel2(&a, data, ctx, /*packed=*/false);
+ sDictPushTiny(dict, key, (smallt *) a);
+ break;
+ }
+ }
+}
+
+/**
+ * deserialize dictionary from data
+ *
+ * a new dictionary is allocated
+ *
+ * \param
+ * dict dictionary holding the elements
+ * data serialized dictionary
+ */
+internal void uniformDictNetDeserialLevel2(sDictt **dict, u8 **data, contextt *ctx, bool packed) {
+ sUndefinedt *u = NULL;
+ sBoolt *bo = NULL;
+ double *D = NULL;
+ sDoublet *Do = NULL;
+ sDictt *d = NULL;
+ sIntt *io = NULL;
+ char *s = NULL;
+ sStringt *so = NULL;
+ sArrayt *a = NULL;
+ sBytest *B = NULL;
+ uint32_t count;
+ uint32_t dictCount;
+ u8 type;
+
+ if (packed) {
+ type = (**data) & 0xF;
+ dictCount = netTypeVarintToUint(data);
+ }
+ else {
+ if (ctx->nibble == lowNbl) {
+ type = (**data) >> 4;
+ (*data)++;
+ dictCount = varintToUint(data);
+ }
+ else {
+ readTypeInHighNbl;
+ type = (**data) & 0xF;
+ dictCount = netTypeVarintToUint(data);
+ }
+ }
+
+ if (!dictCount) {
+ *dict = allocSDict();
+ ret;
+ }
+
+
+ switch(type) {
+ case S_UNDEFINED:
+ loop(dictCount) {
+ char *key = (char*)*data;
+ *data += strlen(key)+1;
+ u = allocSUndefined();
+ sDictPushTiny(dict, key, (smallt *) u);
+ }
+ break;
+ case S_BOOL:
+ loop(dictCount) {
+ char *key = (char*)*data;
+ *data += strlen(key)+1;
+ if (!ctx->boolAddr) {
+ read8bPackedBool;
+ ctx->boolShift = 0;
+ }
+ if (ctx->boolShift == 8) {
+ readTypeInHighNbl;
+ read8bPackedBool;
+ bo = allocSBool((*ctx->boolAddr) & 0x1);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ bo = allocSBool((*ctx->boolAddr) & (0x1 << (ctx->boolShift++)));
+ }
+ sDictPushTiny(dict, key, (smallt *) bo);
+ }
+ break;
+ case S_DICT:
+ loop(dictCount) {
+ char *key = (char*)*data;
+ *data += strlen(key)+1;
+ d = NULL;
+ dictNetDeserialLevel2(&d, data, ctx, /*packed=*/true);
+ sDictPushTiny(dict, key, (smallt *) d);
+ }
+ break;
+ case S_DOUBLE:
+ loop(dictCount) {
+ char *key = (char*)*data;
+ *data += strlen(key)+1;
+ D = (double *)(*data);
+ *data += sizeof(double);
+ Do = allocSDouble(*D);
+ sDictPushTiny(dict, key, (smallt *) Do);
+ }
+ break;
+ case S_INT:
+ loop(dictCount) {
+ char *key = (char*)*data;
+ *data += strlen(key)+1;
+ i64 v = varintToUint(data);
+ v = (v >> 1) ^ ((v << 63) >> 63);
+ io = allocSInt(v);
+ sDictPushTiny(dict, key, (smallt *) io);
+ }
+ break;
+ case S_STRING:
+ loop(dictCount) {
+ char *key = (char*)*data;
+ *data += strlen(key)+1;
+ s = (char *)(*data);
+ *data += strlen(s)+1;
+ so = allocSStringTiny(s);
+ sDictPushTiny(dict, key, (smallt *) so);
+ }
+ break;
+ case S_ARRAY:
+ loop(dictCount) {
+ char *key = (char*)*data;
+ *data += strlen(key)+1;
+ a = NULL;
+ arrayNetDeserialLevel2(&a, data, ctx, /*packed=*/true);
+ sDictPushTiny(dict, key, (smallt *) a);
+ }
+ break;
+ case S_BYTES:
+ loop(dictCount) {
+ char *key = (char*)*data;
+ *data += strlen(key)+1;
+ B = allocSBytes();
+ count = varintToUint((u8**)data);
+ sBytesPushBuffer(&B, data, count);
+ *data += count;
+ sDictPushTiny(dict, key, (smallt *) B);
+ }
+ break;
+ case UNIFORM_DICT:
+ loop(dictCount) {
+ char *key = (char*)*data;
+ *data += strlen(key)+1;
+ d = NULL;
+ uniformDictNetDeserialLevel2(&d, data, ctx, /*packed=*/true);
+ sDictPushTiny(dict, key, (smallt *) d);
+ }
+ break;
+ case UNIFORM_ARRAY:
+ loop(dictCount) {
+ char *key = (char*)*data;
+ *data += strlen(key)+1;
+ a = NULL;
+ uniformArrayNetDeserialLevel2(&a, data, ctx, /*packed=*/true);
+ sDictPushTiny(dict, key, (smallt *) a);
+ }
+ break;
+ }
+}
+
+/**
+ * deserialize array from data
+ *
+ * a new array is allocated
+ *
+ * \param
+ * array holding the elements
+ * data serialized dictionary
+ */
+internal void arrayNetDeserialLevel2(sArrayt **array, u8 **data, contextt *ctx, bool packed) {
+ sUndefinedt *u = NULL;
+ sBoolt *bo = NULL;
+ double *D = NULL;
+ sDoublet *Do = NULL;
+ sDictt *d = NULL;
+ sIntt *io = NULL;
+ char *s = NULL;
+ sStringt *so = NULL;
+ sArrayt *a = NULL;
+ sBytest *B = NULL;
+ uint32_t count;
+ uint32_t arrayCount;
+
+ if (packed) {
+ arrayCount = varintToUint(data);
+ }
+ else {
+ if (ctx->nibble == lowNbl) {
+ arrayCount = netTypeVarintToUint(data);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ arrayCount = varintToUint(data);
+ }
+ }
+
+ if (!arrayCount) {
+ *array = allocSArray();;
+ ret;
+ }
+
+ loop(arrayCount) {
+ char type;
+ if (ctx->nibble == lowNbl) {
+ type = (**data) & 0xF;
+ }
+ else {
+ // high nibble
+ type = (*ctx->nblAddr) >> 4;
+ }
+
+ switch(type) {
+ case S_UNDEFINED:
+ if (ctx->nibble == lowNbl) {
+ readTypeOnly;
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ }
+ u = allocSUndefined();
+ sArrayPushTiny(array, (smallt *) u);
+ break;
+ case S_BOOL:
+ if (!ctx->boolAddr) {
+ // new packed bools
+ if (ctx->nibble == lowNbl) {
+ read4bPackedBool;
+ bo = allocSBool((*ctx->boolAddr) & 0x10);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ read8bPackedBool;
+ bo = allocSBool((*ctx->boolAddr) & 0x1);
+ }
+ }
+ else {
+ // there was a bool before this one, read bits in nibbles
+ if (ctx->nibble == lowNbl) {
+ if (ctx->boolShift == 8) {
+ read4bPackedBool;
+ bo = allocSBool((*ctx->boolAddr) & 0x10);
+ }
+ else {
+ readTypeOnly;
+ bo = allocSBool((*ctx->boolAddr) & (0x1 << (ctx->boolShift++)));
+ }
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ if (ctx->boolShift == 8) {
+ read8bPackedBool;
+ bo = allocSBool((*ctx->boolAddr) & 0x1);
+ }
+ else {
+ bo = allocSBool((*ctx->boolAddr) & (0x1 << (ctx->boolShift++)));
+ }
+ }
+ }
+ sArrayPushTiny(array, (smallt *) bo);
+ break;
+ case S_DICT:
+ d = NULL;
+ dictNetDeserialLevel2(&d, data, ctx, /*packed=*/false);
+ sArrayPushTiny(array, (smallt *) d);
+ break;
+ case S_DOUBLE:
+ if (ctx->nibble == lowNbl) {
+ readTypeOnly;
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ }
+ D = (double *)(*data);
+ *data += sizeof(double);
+ Do = allocSDouble(*D);
+ sArrayPushTiny(array, (smallt *) Do);
+ break;
+ case S_INT: {
+ i64 v;
+ if (ctx->nibble == lowNbl) {
+ v = netTypeVarintToUint((u8**)data);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ v = varintToUint(data);
+ }
+ v = (v >> 1) ^ ((v << 63) >> 63);
+ io = allocSInt(v);
+ sArrayPushTiny(array, (smallt *) io);
+ }
+ break;
+ case S_STRING:
+ if (ctx->nibble == lowNbl) {
+ readTypeOnly;
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ }
+ s = (char *)(*data);
+ *data += strlen(s)+1;
+ so = allocSStringTiny(s);
+ sArrayPushTiny(array, (smallt *) so);
+ break;
+ case S_ARRAY:
+ a = NULL;
+ arrayNetDeserialLevel2(&a, data, ctx, /*packed=*/false);
+ sArrayPushTiny(array, (smallt *) a);
+ break;
+ case S_BYTES:
+ B = allocSBytes();
+ if (ctx->nibble == lowNbl) {
+ count = netTypeVarintToUint((u8**)data);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ count = varintToUint((u8**)data);
+ }
+ sBytesPushBuffer(&B, data, count);
+ *data += count;
+ sArrayPushTiny(array, (smallt *) B);
+ break;
+ case UNIFORM_DICT:
+ d = NULL;
+ uniformDictNetDeserialLevel2(&d, data, ctx, /*packed=*/false);
+ sArrayPushTiny(array, (smallt *) d);
+ break;
+ case UNIFORM_ARRAY:
+ a = NULL;
+ uniformArrayNetDeserialLevel2(&a, data, ctx, /*packed=*/false);
+ sArrayPushTiny(array, (smallt *) a);
+ break;
+ }
+ }
+}
+
+internal void uniformArrayNetDeserialLevel2(sArrayt **array, u8 **data, contextt *ctx, bool packed) {
+ sUndefinedt *u = NULL;
+ sBoolt *bo = NULL;
+ double *D = NULL;
+ sDoublet *Do = NULL;
+ sDictt *d = NULL;
+ sIntt *io = NULL;
+ char *s = NULL;
+ sStringt *so = NULL;
+ sArrayt *a = NULL;
+ sBytest *B = NULL;
+ uint32_t count;
+ uint32_t arrayCount;
+ u8 type;
+
+ if (packed) {
+ type = (**data) & 0xF;
+ arrayCount = netTypeVarintToUint(data);
+ }
+ else {
+ if (ctx->nibble == lowNbl) {
+ type = (**data) >> 4;
+ (*data)++;
+ arrayCount = varintToUint(data);
+ }
+ else {
+ readTypeInHighNbl;
+ type = (**data) & 0xF;
+ arrayCount = netTypeVarintToUint(data);
+ }
+ }
+
+ if (!arrayCount) {
+ *array = allocSArray();;
+ ret;
+ }
+
+ switch(type) {
+ case S_UNDEFINED:
+ loop(arrayCount) {
+ u = allocSUndefined();
+ sArrayPushTiny(array, (smallt *) u);
+ }
+ break;
+ case S_BOOL:
+ loop(arrayCount) {
+ if (!ctx->boolAddr) {
+ read8bPackedBool;
+ ctx->boolShift = 0;
+ }
+ if (ctx->boolShift == 8) {
+ read8bPackedBool;
+ bo = allocSBool((*ctx->boolAddr) & 0x1);
+ }
+ else {
+ bo = allocSBool((*ctx->boolAddr) & (0x1 << (ctx->boolShift++)));
+ }
+ sArrayPushTiny(array, (smallt *) bo);
+ }
+ break;
+ case S_DICT:
+ loop(arrayCount) {
+ d = NULL;
+ dictNetDeserialLevel2(&d, data, ctx, /*packed=*/true);
+ sArrayPushTiny(array, (smallt *) d);
+ }
+ break;
+ case S_DOUBLE:
+ loop(arrayCount) {
+ D = (double *)(*data);
+ *data += sizeof(double);
+ Do = allocSDouble(*D);
+ sArrayPushTiny(array, (smallt *) Do);
+ }
+ break;
+ case S_INT:
+ loop(arrayCount) {
+ i64 v = varintToUint(data);
+ v = (v >> 1) ^ ((v << 63) >> 63);
+ io = allocSInt(v);
+ sArrayPushTiny(array, (smallt *) io);
+ }
+ break;
+ case S_STRING:
+ loop(arrayCount) {
+ s = (char *)(*data);
+ *data += strlen(s)+1;
+ so = allocSStringTiny(s);
+ sArrayPushTiny(array, (smallt *) so);
+ }
+ break;
+ case S_ARRAY:
+ loop(arrayCount) {
+ a = NULL;
+ arrayNetDeserialLevel2(&a, data, ctx, /*packed=*/true);
+ sArrayPushTiny(array, (smallt *) a);
+ }
+ break;
+ case S_BYTES:
+ loop(arrayCount) {
+ B = allocSBytes();
+ count = varintToUint((u8**)data);
+ sBytesPushBuffer(&B, data, count);
+ *data += count;
+ sArrayPushTiny(array, (smallt *) B);
+ }
+ break;
+ case UNIFORM_DICT:
+ loop(arrayCount) {
+ d = NULL;
+ uniformDictNetDeserialLevel2(&d, data, ctx, /*packed=*/true);
+ sArrayPushTiny(array, (smallt *) d);
+ }
+ break;
+ case UNIFORM_ARRAY:
+ loop(arrayCount) {
+ a = NULL;
+ uniformArrayNetDeserialLevel2(&a, data, ctx, /*packed=*/true);
+ sArrayPushTiny(array, (smallt *) a);
+ }
+ break;
+ }
+}
+
+internal smallJsont* deserialNetSerialLevel2(smallJsont *self, smallBytest *data) {
+
+ if (!data) {
+ ret self;
+ }
+
+ smallt *o = netDeserialLevel2(data->B);
+
+ if (!o) {
+ ret self;
+ }
+
+ freeG(self);
+
+ setsoG(self, o);
+
+ ret self;
+}
+
+// level 3
+// like level 2, elements of identical type in a row are packed
+
+/**
+ * deserializer top function
+ */
+internal smallt* netDeserial(sBytest *obj) {
+ smallt *r = NULL;
+ double *D = NULL;
+ char *s = NULL;
+ sBytest *B = NULL;
+ uint32_t count;
+ char *data = NULL;
+ contextt ctx = {.nibble=lowNbl, .nblAddr=NULL, .boolShift = 0, .boolAddr=NULL};
+
+ switch(obj->data & 0xF) {
+ case S_UNDEFINED:
+ r = (smallt *) allocSUndefined();
+ break;
+ case S_BOOL:
+ r = (smallt *) allocSBool(obj->data & 0x10);
+ break;
+ case S_DICT:
+ data = (char *)&(obj->data);
+ //debug - ctx.dbuf = (u8*) data;
+ dictNetDeserial((sDictt **)&r, (u8**)&data, &ctx, /*packed=*/false);
+ break;
+ case S_DOUBLE:
+ data = &(obj->data)+1;
+ D = (double *)data;
+ r = (smallt *) allocSDouble(*D);
+ break;
+ case S_INT:
+ data = &(obj->data);
+ i64 v = netTypeVarintToUint((u8**)&data);
+ v = (v >> 1) ^ ((v << 63) >> 63);
+ r = (smallt *) allocSInt(v);
+ break;
+ case S_STRING:
+ s = (char *)&(obj->data)+1;
+ r = (smallt *) allocSStringTiny(s);
+ break;
+ case S_ARRAY:
+ data = (char *)&(obj->data);
+ //debug - ctx.dbuf = (u8*) data;
+ arrayNetDeserial((sArrayt **)&r, (u8**)&data, &ctx, /*packed=*/false);
+ break;
+ case S_BYTES:
+ B = allocSBytes();
+ data = &(obj->data);
+ count = netTypeVarintToUint((u8**)&data);
+ sBytesPushBuffer(&B, data, count);
+ r = (smallt *)B;
+ break;
+ case UNIFORM_DICT:
+ data = (char *)&(obj->data);
+ //debug - ctx.dbuf = (u8*) data;
+ uniformDictNetDeserial((sDictt **)&r, (u8**)&data, &ctx, /*packed=*/false);
+ break;
+ case UNIFORM_ARRAY:
+ data = (char *)&(obj->data);
+ //debug - ctx.dbuf = (u8*) data;
+ uniformArrayNetDeserial((sArrayt **)&r, (u8**)&data, &ctx, /*packed=*/false);
+ break;
+ }
+
+ ret r;
+}
+
+/**
+ * deserialize dictionary from data
+ *
+ * a new dictionary is allocated
+ *
+ * \param
+ * dict dictionary holding the elements
+ * data serialized dictionary
+ */
+internal void dictNetDeserial(sDictt **dict, u8 **data, contextt *ctx, bool packed) {
+ sUndefinedt *u = NULL;
+ sBoolt *bo = NULL;
+ double *D = NULL;
+ sDoublet *Do = NULL;
+ sDictt *d = NULL;
+ sIntt *io = NULL;
+ char *s = NULL;
+ sStringt *so = NULL;
+ sArrayt *a = NULL;
+ sBytest *B = NULL;
+ uint32_t count;
+ uint32_t dictCount;
+
+ if (packed) {
+ dictCount = varintToUint(data);
+ }
+ else {
+ if (ctx->nibble == lowNbl) {
+ dictCount = netTypeVarintToUint(data);
+ }
+ else {
+ // high nibble
+ // type = *(ctx->dbuf + ctx->nblOffset) >> 4;
+ #define readTypeInHighNbl\
+ ctx->nibble = lowNbl;\
+ if (ctx->nblAddr == *data)\
+ /* data points to the type, next byte is count */\
+ (*data)++
+ readTypeInHighNbl;
+ dictCount = varintToUint(data);
+ }
+ }
+
+ if (!dictCount) {
+ *dict = allocSDict();
+ ret;
+ }
+
+ bool inPack = false;
+ u8 packedType;
+ size_t packCount;
+ loop(dictCount) {
+ char *key = (char*)*data;
+ *data += strlen(key)+1;
+ char type;
+ if (inPack) {
+ type = packedType;
+ }
+ else {
+ if (ctx->nibble == lowNbl) {
+ type = (**data) & 0xF;
+ }
+ else {
+ // high nibble
+ type = (*ctx->nblAddr) >> 4;
+ }
+ }
+
+ switch(type) {
+ case S_UNDEFINED:
+ if (ctx->nibble == lowNbl) {
+ #define readTypeOnly\
+ ctx->nibble = highNbl;\
+ ctx->nblAddr = *data;\
+ (*data)++
+ readTypeOnly;
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ }
+ u = allocSUndefined();
+ sDictPushTiny(dict, key, (smallt *) u);
+ break;
+ case S_BOOL:
+ if (!ctx->boolAddr) {
+ // new packed bools
+ if (ctx->nibble == lowNbl) {
+ #define read4bPackedBool\
+ ctx->boolShift = 5;\
+ ctx->boolAddr = *data;\
+ (*data)++
+ read4bPackedBool;
+ bo = allocSBool((*ctx->boolAddr) & 0x10);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ #define read8bPackedBool\
+ ctx->boolShift = 1;\
+ ctx->boolAddr = *data;\
+ (*data)++
+ read8bPackedBool;
+ bo = allocSBool((*ctx->boolAddr) & 0x1);
+ }
+ }
+ else {
+ // there was a bool before this one, read bits in nibbles
+ if (ctx->nibble == lowNbl) {
+ if (ctx->boolShift == 8) {
+ read4bPackedBool;
+ bo = allocSBool((*ctx->boolAddr) & 0x10);
+ }
+ else {
+ readTypeOnly;
+ bo = allocSBool((*ctx->boolAddr) & (0x1 << (ctx->boolShift++)));
+ }
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ if (ctx->boolShift == 8) {
+ read8bPackedBool;
+ bo = allocSBool((*ctx->boolAddr) & 0x1);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ bo = allocSBool((*ctx->boolAddr) & (0x1 << (ctx->boolShift++)));
+ }
+ }
+ }
+ sDictPushTiny(dict, key, (smallt *) bo);
+ break;
+ case S_DICT:
+ d = NULL;
+ dictNetDeserial(&d, data, ctx, /*packed=*/false);
+ sDictPushTiny(dict, key, (smallt *) d);
+ break;
+ case S_DOUBLE:
+ if (ctx->nibble == lowNbl) {
+ readTypeOnly;
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ }
+ D = (double *)(*data);
+ *data += sizeof(double);
+ Do = allocSDouble(*D);
+ sDictPushTiny(dict, key, (smallt *) Do);
+ break;
+ case S_INT: {
+ i64 v;
+ if (ctx->nibble == lowNbl) {
+ v = netTypeVarintToUint((u8**)data);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ v = varintToUint(data);
+ }
+ v = (v >> 1) ^ ((v << 63) >> 63);
+ io = allocSInt(v);
+ sDictPushTiny(dict, key, (smallt *) io);
+ }
+ break;
+ case S_STRING:
+ if (ctx->nibble == lowNbl) {
+ readTypeOnly;
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ }
+ s = (char *)(*data);
+ *data += strlen(s)+1;
+ so = allocSStringTiny(s);
+ sDictPushTiny(dict, key, (smallt *) so);
+ break;
+ case S_ARRAY:
+ a = NULL;
+ arrayNetDeserial(&a, data, ctx, /*packed=*/false);
+ sDictPushTiny(dict, key, (smallt *) a);
+ break;
+ case S_BYTES:
+ B = allocSBytes();
+ if (ctx->nibble == lowNbl) {
+ count = netTypeVarintToUint((u8**)data);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ count = varintToUint((u8**)data);
+ }
+ sBytesPushBuffer(&B, data, count);
+ *data += count;
+ sDictPushTiny(dict, key, (smallt *) B);
+ break;
+ case PK_DICT:
+ if (!inPack) {
+ inPack = true;
+ if (ctx->nibble == lowNbl) {
+ packCount = netTypeVarintToUint((u8**)data);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ packCount = varintToUint((u8**)data);
+ }
+ packedType = PK_DICT;
+ }
+
+ d = NULL;
+ dictNetDeserial(&d, data, ctx, /*packed=*/true);
+ sDictPushTiny(dict, key, (smallt *) d);
+ // stop unpacking when packCount == 0
+ packCount--;
+ if (!packCount) inPack = false;
+ break;
+ case PK_DOUBLE:
+ if (!inPack) {
+ inPack = true;
+ if (ctx->nibble == lowNbl) {
+ packCount = netTypeVarintToUint((u8**)data);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ packCount = varintToUint((u8**)data);
+ }
+ packedType = PK_DOUBLE;
+ }
+
+ D = (double *)(*data);
+ *data += sizeof(double);
+ Do = allocSDouble(*D);
+ sDictPushTiny(dict, key, (smallt *) Do);
+ // stop unpacking when packCount == 0
+ packCount--;
+ if (!packCount) inPack = false;
+ break;
+ case PK_INT:
+ if (!inPack) {
+ inPack = true;
+ if (ctx->nibble == lowNbl) {
+ packCount = netTypeVarintToUint((u8**)data);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ packCount = varintToUint((u8**)data);
+ }
+ packedType = PK_INT;
+ }
+
+ i64 v = varintToUint(data);
+ v = (v >> 1) ^ ((v << 63) >> 63);
+ io = allocSInt(v);
+ sDictPushTiny(dict, key, (smallt *) io);
+ // stop unpacking when packCount == 0
+ packCount--;
+ if (!packCount) inPack = false;
+ break;
+ case PK_STRING:
+ if (!inPack) {
+ inPack = true;
+ if (ctx->nibble == lowNbl) {
+ packCount = netTypeVarintToUint((u8**)data);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ packCount = varintToUint((u8**)data);
+ }
+ packedType = PK_STRING;
+ }
+
+ s = (char *)(*data);
+ *data += strlen(s)+1;
+ so = allocSStringTiny(s);
+ sDictPushTiny(dict, key, (smallt *) so);
+ // stop unpacking when packCount == 0
+ packCount--;
+ if (!packCount) inPack = false;
+ break;
+ case PK_ARRAY:
+ if (!inPack) {
+ inPack = true;
+ if (ctx->nibble == lowNbl) {
+ packCount = netTypeVarintToUint((u8**)data);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ packCount = varintToUint((u8**)data);
+ }
+ packedType = PK_ARRAY;
+ }
+
+ a = NULL;
+ arrayNetDeserial(&a, data, ctx, /*packed=*/true);
+ sDictPushTiny(dict, key, (smallt *) a);
+ // stop unpacking when packCount == 0
+ packCount--;
+ if (!packCount) inPack = false;
+ break;
+ case PK_BYTES:
+ if (!inPack) {
+ inPack = true;
+ if (ctx->nibble == lowNbl) {
+ packCount = netTypeVarintToUint((u8**)data);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ packCount = varintToUint((u8**)data);
+ }
+ packedType = PK_BYTES;
+ }
+
+ B = allocSBytes();
+ count = varintToUint((u8**)data);
+ sBytesPushBuffer(&B, data, count);
+ *data += count;
+ sDictPushTiny(dict, key, (smallt *) B);
+ // stop unpacking when packCount == 0
+ packCount--;
+ if (!packCount) inPack = false;
+ break;
+ case UNIFORM_DICT:
+ d = NULL;
+ uniformDictNetDeserial(&d, data, ctx, /*packed=*/false);
+ sDictPushTiny(dict, key, (smallt *) d);
+ break;
+ case UNIFORM_ARRAY:
+ a = NULL;
+ uniformArrayNetDeserial(&a, data, ctx, /*packed=*/false);
+ sDictPushTiny(dict, key, (smallt *) a);
+ break;
+ }
+ }
+}
+
+/**
+ * deserialize dictionary from data
+ *
+ * a new dictionary is allocated
+ *
+ * \param
+ * dict dictionary holding the elements
+ * data serialized dictionary
+ */
+internal void uniformDictNetDeserial(sDictt **dict, u8 **data, contextt *ctx, bool packed) {
+ sUndefinedt *u = NULL;
+ sBoolt *bo = NULL;
+ double *D = NULL;
+ sDoublet *Do = NULL;
+ sDictt *d = NULL;
+ sIntt *io = NULL;
+ char *s = NULL;
+ sStringt *so = NULL;
+ sArrayt *a = NULL;
+ sBytest *B = NULL;
+ uint32_t count;
+ uint32_t dictCount;
+ u8 type;
+
+ if (packed) {
+ type = (**data) & 0xF;
+ dictCount = netTypeVarintToUint(data);
+ }
+ else {
+ if (ctx->nibble == lowNbl) {
+ type = (**data) >> 4;
+ (*data)++;
+ dictCount = varintToUint(data);
+ }
+ else {
+ readTypeInHighNbl;
+ type = (**data) & 0xF;
+ dictCount = netTypeVarintToUint(data);
+ }
+ }
+
+ if (!dictCount) {
+ *dict = allocSDict();
+ ret;
+ }
+
+
+ switch(type) {
+ case S_UNDEFINED:
+ loop(dictCount) {
+ char *key = (char*)*data;
+ *data += strlen(key)+1;
+ u = allocSUndefined();
+ sDictPushTiny(dict, key, (smallt *) u);
+ }
+ break;
+ case S_BOOL:
+ loop(dictCount) {
+ char *key = (char*)*data;
+ *data += strlen(key)+1;
+ if (!ctx->boolAddr) {
+ read8bPackedBool;
+ ctx->boolShift = 0;
+ }
+ if (ctx->boolShift == 8) {
+ readTypeInHighNbl;
+ read8bPackedBool;
+ bo = allocSBool((*ctx->boolAddr) & 0x1);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ bo = allocSBool((*ctx->boolAddr) & (0x1 << (ctx->boolShift++)));
+ }
+ sDictPushTiny(dict, key, (smallt *) bo);
+ }
+ break;
+ case S_DICT:
+ loop(dictCount) {
+ char *key = (char*)*data;
+ *data += strlen(key)+1;
+ d = NULL;
+ dictNetDeserial(&d, data, ctx, /*packed=*/true);
+ sDictPushTiny(dict, key, (smallt *) d);
+ }
+ break;
+ case S_DOUBLE:
+ loop(dictCount) {
+ char *key = (char*)*data;
+ *data += strlen(key)+1;
+ D = (double *)(*data);
+ *data += sizeof(double);
+ Do = allocSDouble(*D);
+ sDictPushTiny(dict, key, (smallt *) Do);
+ }
+ break;
+ case S_INT:
+ loop(dictCount) {
+ char *key = (char*)*data;
+ *data += strlen(key)+1;
+ i64 v = varintToUint(data);
+ v = (v >> 1) ^ ((v << 63) >> 63);
+ io = allocSInt(v);
+ sDictPushTiny(dict, key, (smallt *) io);
+ }
+ break;
+ case S_STRING:
+ loop(dictCount) {
+ char *key = (char*)*data;
+ *data += strlen(key)+1;
+ s = (char *)(*data);
+ *data += strlen(s)+1;
+ so = allocSStringTiny(s);
+ sDictPushTiny(dict, key, (smallt *) so);
+ }
+ break;
+ case S_ARRAY:
+ loop(dictCount) {
+ char *key = (char*)*data;
+ *data += strlen(key)+1;
+ a = NULL;
+ arrayNetDeserial(&a, data, ctx, /*packed=*/true);
+ sDictPushTiny(dict, key, (smallt *) a);
+ }
+ break;
+ case S_BYTES:
+ loop(dictCount) {
+ char *key = (char*)*data;
+ *data += strlen(key)+1;
+ B = allocSBytes();
+ count = varintToUint((u8**)data);
+ sBytesPushBuffer(&B, data, count);
+ *data += count;
+ sDictPushTiny(dict, key, (smallt *) B);
+ }
+ break;
+ case UNIFORM_DICT:
+ loop(dictCount) {
+ char *key = (char*)*data;
+ *data += strlen(key)+1;
+ d = NULL;
+ uniformDictNetDeserial(&d, data, ctx, /*packed=*/true);
+ sDictPushTiny(dict, key, (smallt *) d);
+ }
+ break;
+ case UNIFORM_ARRAY:
+ loop(dictCount) {
+ char *key = (char*)*data;
+ *data += strlen(key)+1;
+ a = NULL;
+ uniformArrayNetDeserial(&a, data, ctx, /*packed=*/true);
+ sDictPushTiny(dict, key, (smallt *) a);
+ }
+ break;
+ }
+}
+
+/**
+ * deserialize array from data
+ *
+ * a new array is allocated
+ *
+ * \param
+ * array holding the elements
+ * data serialized dictionary
+ */
+internal void arrayNetDeserial(sArrayt **array, u8 **data, contextt *ctx, bool packed) {
+ sUndefinedt *u = NULL;
+ sBoolt *bo = NULL;
+ double *D = NULL;
+ sDoublet *Do = NULL;
+ sDictt *d = NULL;
+ sIntt *io = NULL;
+ char *s = NULL;
+ sStringt *so = NULL;
+ sArrayt *a = NULL;
+ sBytest *B = NULL;
+ uint32_t count;
+ uint32_t arrayCount;
+
+ if (packed) {
+ arrayCount = varintToUint(data);
+ }
+ else {
+ if (ctx->nibble == lowNbl) {
+ arrayCount = netTypeVarintToUint(data);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ arrayCount = varintToUint(data);
+ }
+ }
+
+ if (!arrayCount) {
+ *array = allocSArray();;
+ ret;
+ }
+
+ bool inPack = false;
+ u8 packedType;
+ size_t packCount;
+ loop(arrayCount) {
+ char type;
+ if (inPack) {
+ type = packedType;
+ }
+ else {
+ if (ctx->nibble == lowNbl) {
+ type = (**data) & 0xF;
+ }
+ else {
+ // high nibble
+ type = (*ctx->nblAddr) >> 4;
+ }
+ }
+
+ switch(type) {
+ case S_UNDEFINED:
+ if (ctx->nibble == lowNbl) {
+ readTypeOnly;
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ }
+ u = allocSUndefined();
+ sArrayPushTiny(array, (smallt *) u);
+ break;
+ case S_BOOL:
+ if (!ctx->boolAddr) {
+ // new packed bools
+ if (ctx->nibble == lowNbl) {
+ read4bPackedBool;
+ bo = allocSBool((*ctx->boolAddr) & 0x10);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ read8bPackedBool;
+ bo = allocSBool((*ctx->boolAddr) & 0x1);
+ }
+ }
+ else {
+ // there was a bool before this one, read bits in nibbles
+ if (ctx->nibble == lowNbl) {
+ if (ctx->boolShift == 8) {
+ read4bPackedBool;
+ bo = allocSBool((*ctx->boolAddr) & 0x10);
+ }
+ else {
+ readTypeOnly;
+ bo = allocSBool((*ctx->boolAddr) & (0x1 << (ctx->boolShift++)));
+ }
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ if (ctx->boolShift == 8) {
+ read8bPackedBool;
+ bo = allocSBool((*ctx->boolAddr) & 0x1);
+ }
+ else {
+ bo = allocSBool((*ctx->boolAddr) & (0x1 << (ctx->boolShift++)));
+ }
+ }
+ }
+ sArrayPushTiny(array, (smallt *) bo);
+ break;
+ case S_DICT:
+ d = NULL;
+ dictNetDeserial(&d, data, ctx, /*packed=*/false);
+ sArrayPushTiny(array, (smallt *) d);
+ break;
+ case S_DOUBLE:
+ if (ctx->nibble == lowNbl) {
+ readTypeOnly;
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ }
+ D = (double *)(*data);
+ *data += sizeof(double);
+ Do = allocSDouble(*D);
+ sArrayPushTiny(array, (smallt *) Do);
+ break;
+ case S_INT: {
+ i64 v;
+ if (ctx->nibble == lowNbl) {
+ v = netTypeVarintToUint((u8**)data);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ v = varintToUint(data);
+ }
+ v = (v >> 1) ^ ((v << 63) >> 63);
+ io = allocSInt(v);
+ sArrayPushTiny(array, (smallt *) io);
+ }
+ break;
+ case S_STRING:
+ if (ctx->nibble == lowNbl) {
+ readTypeOnly;
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ }
+ s = (char *)(*data);
+ *data += strlen(s)+1;
+ so = allocSStringTiny(s);
+ sArrayPushTiny(array, (smallt *) so);
+ break;
+ case S_ARRAY:
+ a = NULL;
+ arrayNetDeserial(&a, data, ctx, /*packed=*/false);
+ sArrayPushTiny(array, (smallt *) a);
+ break;
+ case S_BYTES:
+ B = allocSBytes();
+ if (ctx->nibble == lowNbl) {
+ count = netTypeVarintToUint((u8**)data);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ count = varintToUint((u8**)data);
+ }
+ sBytesPushBuffer(&B, data, count);
+ *data += count;
+ sArrayPushTiny(array, (smallt *) B);
+ break;
+ case PK_DICT:
+ if (!inPack) {
+ inPack = true;
+ if (ctx->nibble == lowNbl) {
+ packCount = netTypeVarintToUint((u8**)data);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ packCount = varintToUint((u8**)data);
+ }
+ packedType = PK_DICT;
+ }
+
+ d = NULL;
+ dictNetDeserial(&d, data, ctx, /*packed=*/true);
+ sArrayPushTiny(array, (smallt *) d);
+ // stop unpacking when packCount == 0
+ packCount--;
+ if (!packCount) inPack = false;
+ break;
+ case PK_DOUBLE:
+ if (!inPack) {
+ inPack = true;
+ if (ctx->nibble == lowNbl) {
+ packCount = netTypeVarintToUint((u8**)data);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ packCount = varintToUint((u8**)data);
+ }
+ packedType = PK_DOUBLE;
+ }
+
+ D = (double *)(*data);
+ *data += sizeof(double);
+ Do = allocSDouble(*D);
+ sArrayPushTiny(array, (smallt *) Do);
+ // stop unpacking when packCount == 0
+ packCount--;
+ if (!packCount) inPack = false;
+ break;
+ case PK_INT:
+ if (!inPack) {
+ inPack = true;
+ if (ctx->nibble == lowNbl) {
+ packCount = netTypeVarintToUint((u8**)data);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ packCount = varintToUint((u8**)data);
+ }
+ packedType = PK_INT;
+ }
+
+ i64 v = varintToUint(data);
+ v = (v >> 1) ^ ((v << 63) >> 63);
+ io = allocSInt(v);
+ sArrayPushTiny(array, (smallt *) io);
+ // stop unpacking when packCount == 0
+ packCount--;
+ if (!packCount) inPack = false;
+ break;
+ case PK_STRING:
+ if (!inPack) {
+ inPack = true;
+ if (ctx->nibble == lowNbl) {
+ packCount = netTypeVarintToUint((u8**)data);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ packCount = varintToUint((u8**)data);
+ }
+ packedType = PK_STRING;
+ }
+
+ s = (char *)(*data);
+ *data += strlen(s)+1;
+ so = allocSStringTiny(s);
+ sArrayPushTiny(array, (smallt *) so);
+ // stop unpacking when packCount == 0
+ packCount--;
+ if (!packCount) inPack = false;
+ break;
+ case PK_ARRAY:
+ if (!inPack) {
+ inPack = true;
+ if (ctx->nibble == lowNbl) {
+ packCount = netTypeVarintToUint((u8**)data);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ packCount = varintToUint((u8**)data);
+ }
+ packedType = PK_ARRAY;
+ }
+
+ a = NULL;
+ arrayNetDeserial(&a, data, ctx, /*packed=*/true);
+ sArrayPushTiny(array, (smallt *) a);
+ // stop unpacking when packCount == 0
+ packCount--;
+ if (!packCount) inPack = false;
+ break;
+ case PK_BYTES:
+ if (!inPack) {
+ inPack = true;
+ if (ctx->nibble == lowNbl) {
+ packCount = netTypeVarintToUint((u8**)data);
+ }
+ else {
+ // high nibble
+ readTypeInHighNbl;
+ packCount = varintToUint((u8**)data);
+ }
+ packedType = PK_BYTES;
+ }
+
+ B = allocSBytes();
+ count = varintToUint((u8**)data);
+ sBytesPushBuffer(&B, data, count);
+ *data += count;
+ sArrayPushTiny(array, (smallt *) B);
+ // stop unpacking when packCount == 0
+ packCount--;
+ if (!packCount) inPack = false;
+ break;
+ case UNIFORM_DICT:
+ d = NULL;
+ uniformDictNetDeserial(&d, data, ctx, /*packed=*/false);
+ sArrayPushTiny(array, (smallt *) d);
+ break;
+ case UNIFORM_ARRAY:
+ a = NULL;
+ uniformArrayNetDeserial(&a, data, ctx, /*packed=*/false);
+ sArrayPushTiny(array, (smallt *) a);
+ break;
+ }
+ }
+}
+
+internal void uniformArrayNetDeserial(sArrayt **array, u8 **data, contextt *ctx, bool packed) {
+ sUndefinedt *u = NULL;
+ sBoolt *bo = NULL;
+ double *D = NULL;
+ sDoublet *Do = NULL;
+ sDictt *d = NULL;
+ sIntt *io = NULL;
+ char *s = NULL;
+ sStringt *so = NULL;
+ sArrayt *a = NULL;
+ sBytest *B = NULL;
+ uint32_t count;
+ uint32_t arrayCount;
+ u8 type;
+
+ if (packed) {
+ type = (**data) & 0xF;
+ arrayCount = netTypeVarintToUint(data);
+ }
+ else {
+ if (ctx->nibble == lowNbl) {
+ type = (**data) >> 4;
+ (*data)++;
+ arrayCount = varintToUint(data);
+ }
+ else {
+ readTypeInHighNbl;
+ type = (**data) & 0xF;
+ arrayCount = netTypeVarintToUint(data);
+ }
+ }
+
+ if (!arrayCount) {
+ *array = allocSArray();;
+ ret;
+ }
+
+ switch(type) {
+ case S_UNDEFINED:
+ loop(arrayCount) {
+ u = allocSUndefined();
+ sArrayPushTiny(array, (smallt *) u);
+ }
+ break;
+ case S_BOOL:
+ loop(arrayCount) {
+ if (!ctx->boolAddr) {
+ read8bPackedBool;
+ ctx->boolShift = 0;
+ }
+ if (ctx->boolShift == 8) {
+ read8bPackedBool;
+ bo = allocSBool((*ctx->boolAddr) & 0x1);
+ }
+ else {
+ bo = allocSBool((*ctx->boolAddr) & (0x1 << (ctx->boolShift++)));
+ }
+ sArrayPushTiny(array, (smallt *) bo);
+ }
+ break;
+ case S_DICT:
+ loop(arrayCount) {
+ d = NULL;
+ dictNetDeserial(&d, data, ctx, /*packed=*/true);
+ sArrayPushTiny(array, (smallt *) d);
+ }
+ break;
+ case S_DOUBLE:
+ loop(arrayCount) {
+ D = (double *)(*data);
+ *data += sizeof(double);
+ Do = allocSDouble(*D);
+ sArrayPushTiny(array, (smallt *) Do);
+ }
+ break;
+ case S_INT:
+ loop(arrayCount) {
+ i64 v = varintToUint(data);
+ v = (v >> 1) ^ ((v << 63) >> 63);
+ io = allocSInt(v);
+ sArrayPushTiny(array, (smallt *) io);
+ }
+ break;
+ case S_STRING:
+ loop(arrayCount) {
+ s = (char *)(*data);
+ *data += strlen(s)+1;
+ so = allocSStringTiny(s);
+ sArrayPushTiny(array, (smallt *) so);
+ }
+ break;
+ case S_ARRAY:
+ loop(arrayCount) {
+ a = NULL;
+ arrayNetDeserial(&a, data, ctx, /*packed=*/true);
+ sArrayPushTiny(array, (smallt *) a);
+ }
+ break;
+ case S_BYTES:
+ loop(arrayCount) {
+ B = allocSBytes();
+ count = varintToUint((u8**)data);
+ sBytesPushBuffer(&B, data, count);
+ *data += count;
+ sArrayPushTiny(array, (smallt *) B);
+ }
+ break;
+ case UNIFORM_DICT:
+ loop(arrayCount) {
+ d = NULL;
+ uniformDictNetDeserial(&d, data, ctx, /*packed=*/true);
+ sArrayPushTiny(array, (smallt *) d);
+ }
+ break;
+ case UNIFORM_ARRAY:
+ loop(arrayCount) {
+ a = NULL;
+ uniformArrayNetDeserial(&a, data, ctx, /*packed=*/true);
+ sArrayPushTiny(array, (smallt *) a);
+ }
+ break;
+ }
+}
+
+internal smallJsont* deserialNetSerial(smallJsont *self, smallBytest *data) {
+
+ if (!data) {
+ ret self;
+ }
+
+ smallt *o = netDeserial(data->B);
+
+ if (!o) {
+ ret self;
+ }
+
+ freeG(self);
+
+ setsoG(self, o);
+
+ ret self;
+}
+
+// vim: set expandtab ts=2 sw=2:
diff --git a/netSerial.c.gcov b/netSerial.c.gcov
@@ -0,0 +1,7713 @@
+ -: 0:Source:/home/remy/git/sw/sheepyPackagesGitHub/netSerial/netSerial.c
+ -: 0:Graph:netSerial.gcno
+ -: 0:Data:netSerial.gcda
+ -: 0:Runs:7
+ -: 0:Programs:1
+ -: 1:
+ -: 2:#include "libsheepyObject.h"
+ -: 3:#include "netSerial.h"
+ -: 4:#include "netSerialInternal.h"
+ -: 5:
+ -: 6:#include <stdlib.h>
+ -: 7:#include <string.h>
+ -: 8:#include <stdio.h>
+ -: 9:
+ -: 10:#define lv logVarG
+ -: 11:
+ -: 12:void initiateNetSerialLevel0(smallJsont *self);
+ -: 13:void initiateNetSerialLevel1(smallJsont *self);
+ -: 14:void initiateNetSerialLevel2(smallJsont *self);
+ -: 15:void initiateNetSerial(smallJsont *self);
+ -: 16:void registerMethodsNetSerialLevel0(smallJsonFunctionst *f);
+ -: 17:void registerMethodsNetSerialLevel1(smallJsonFunctionst *f);
+ -: 18:void registerMethodsNetSerialLevel2(smallJsonFunctionst *f);
+ -: 19:void registerMethodsNetSerial(smallJsonFunctionst *f);
+ -: 20:void initiateAllocateNetSerialLevel0(smallJsont **self);
+ -: 21:void initiateAllocateNetSerialLevel1(smallJsont **self);
+ -: 22:void initiateAllocateNetSerialLevel2(smallJsont **self);
+ -: 23:void initiateAllocateNetSerial(smallJsont **self);
+ -: 24:void finalizeNetSerial(void);
+ -: 25:smallJsont* allocNetSerialLevel0(void);
+ -: 26:smallJsont* allocNetSerialLevel1(void);
+ -: 27:smallJsont* allocNetSerialLevel2(void);
+ -: 28:smallJsont* allocNetSerial(void);
+ -: 29:internal const char* helpNetSerial(smallJsont *self);
+ -: 30:internal smallBytest* serialNetSerialLevel0(smallJsont *self);
+ -: 31:internal smallBytest* serialNetSerialLevel1(smallJsont *self);
+ -: 32:internal smallBytest* serialNetSerialLevel2(smallJsont *self);
+ -: 33:internal smallBytest* serialNetSerial(smallJsont *self);
+ -: 34:internal smallJsont* deserialNetSerialLevel0(smallJsont *self, smallBytest *data);
+ -: 35:internal smallJsont* deserialNetSerialLevel1(smallJsont *self, smallBytest *data);
+ -: 36:internal smallJsont* deserialNetSerialLevel2(smallJsont *self, smallBytest *data);
+ -: 37:internal smallJsont* deserialNetSerial(smallJsont *self, smallBytest *data);
+ -: 38:
+ -: 39:internal void uintToNetTypeVarint(sBytest **buf, u8 type, u64 value);
+ -: 40:internal void uintToVarint(sBytest **buf, u64 value);
+ -: 41:internal u64 netTypeVarintToUint(u8 **buf);
+ -: 42:internal u64 varintToUint(u8 **buf);
+ -: 43:
+ -: 44:internal sBytest* netSerialLevel0(smallt *o);
+ -: 45:internal void dictNetSerialLevel0(sBytest **r, sDictt *dict);
+ -: 46:internal void arrayNetSerialLevel0(sBytest **r, sArrayt *array);
+ -: 47:internal sBytest* netSerialLevel1(smallt *o);
+ -: 48:internal void dictNetSerialLevel1(sBytest **r, sDictt *dict, contextt *ctx);
+ -: 49:internal void arrayNetSerialLevel1(sBytest **r, sArrayt *array, contextt *ctx);
+ -: 50:internal sBytest* netSerialLevel2(smallt *o);
+ -: 51:internal void dictNetSerialLevel2(sBytest **r, sDictt *dict, contextt *ctx, bool packed);
+ -: 52:internal void arrayNetSerialLevel2(sBytest **r, sArrayt *array, contextt *ctx, bool packed);
+ -: 53:internal sBytest* netSerial(smallt *o);
+ -: 54:internal void dictNetSerial(sBytest **r, sDictt *dict, contextt *ctx, packingT packing);
+ -: 55:internal void arrayNetSerial(sBytest **r, sArrayt *array, contextt *ctx, packingT packing);
+ -: 56:
+ -: 57:internal smallt* netDeserialLevel0(sBytest *obj);
+ -: 58:internal void dictNetDeserialLevel0(sDictt **dict, char **data);
+ -: 59:internal void arrayNetDeserialLevel0(sArrayt **array, char **data);
+ -: 60:internal smallt* netDeserialLevel1(sBytest *obj);
+ -: 61:internal void dictNetDeserialLevel1(sDictt **dict, u8 **data, contextt *ctx);
+ -: 62:internal void arrayNetDeserialLevel1(sArrayt **array, u8 **data, contextt *ctx);
+ -: 63:internal smallt* netDeserialLevel2(sBytest *obj);
+ -: 64:internal void dictNetDeserialLevel2(sDictt **dict, u8 **data, contextt *ctx, bool packed);
+ -: 65:internal u8 isDictUniform(sDictt *dict);
+ -: 66:internal u8 isArrayUniform(sArrayt *array);
+ -: 67:internal void uniformDictNetDeserialLevel2(sDictt **dict, u8 **data, contextt *ctx, bool packed);
+ -: 68:internal void arrayNetDeserialLevel2(sArrayt **array, u8 **data, contextt *ctx, bool packed);
+ -: 69:internal void uniformArrayNetDeserialLevel2(sArrayt **array, u8 **data, contextt *ctx, bool packed);
+ -: 70:internal smallt* netDeserial(sBytest *obj);
+ -: 71:internal void dictNetDeserial(sDictt **dict, u8 **data, contextt *ctx, bool packed);
+ -: 72:internal void uniformDictNetDeserial(sDictt **dict, u8 **data, contextt *ctx, bool packed);
+ -: 73:internal void arrayNetDeserial(sArrayt **array, u8 **data, contextt *ctx, bool packed);
+ -: 74:internal void uniformArrayNetDeserial(sArrayt **array, u8 **data, contextt *ctx, bool packed);
+ -: 75:
+ -: 76:/* enable/disable logging */
+ -: 77:/* #undef pLog */
+ -: 78:/* #define pLog(...) */
+ -: 79:
+function initiateNetSerialLevel0 called 0 returned 0% blocks executed 0%
+ #####: 80:void initiateNetSerialLevel0(smallJsont *self) {
+ -: 81:
+ #####: 82: initiateSmallJson(self);
+call 0 never executed
+ -: 83:
+ #####: 84: self->type = "netSerial";
+ #####: 85: if (!netSerialF) {
+branch 0 never executed
+branch 1 never executed
+ #####: 86: netSerialF = malloc(sizeof(smallJsonFunctionst));
+ #####: 87: registerMethodsNetSerialLevel0(netSerialF);
+call 0 never executed
+ #####: 88: pErrorNot0(atexit(finalizeNetSerial));
+call 0 never executed
+branch 1 never executed
+branch 2 never executed
+call 3 never executed
+branch 4 never executed
+branch 5 never executed
+call 6 never executed
+branch 7 never executed
+branch 8 never executed
+call 9 never executed
+call 10 never executed
+call 11 never executed
+call 12 never executed
+ -: 89: }
+ #####: 90: self->f = netSerialF;
+ #####: 91:}
+ -: 92:
+function initiateNetSerialLevel1 called 0 returned 0% blocks executed 0%
+ #####: 93:void initiateNetSerialLevel1(smallJsont *self) {
+ -: 94:
+ #####: 95: initiateSmallJson(self);
+call 0 never executed
+ -: 96:
+ #####: 97: self->type = "netSerial";
+ #####: 98: if (!netSerialF) {
+branch 0 never executed
+branch 1 never executed
+ #####: 99: netSerialF = malloc(sizeof(smallJsonFunctionst));
+ #####: 100: registerMethodsNetSerialLevel1(netSerialF);
+call 0 never executed
+ #####: 101: pErrorNot0(atexit(finalizeNetSerial));
+call 0 never executed
+branch 1 never executed
+branch 2 never executed
+call 3 never executed
+branch 4 never executed
+branch 5 never executed
+call 6 never executed
+branch 7 never executed
+branch 8 never executed
+call 9 never executed
+call 10 never executed
+call 11 never executed
+call 12 never executed
+ -: 102: }
+ #####: 103: self->f = netSerialF;
+ #####: 104:}
+ -: 105:
+function initiateNetSerialLevel2 called 0 returned 0% blocks executed 0%
+ #####: 106:void initiateNetSerialLevel2(smallJsont *self) {
+ -: 107:
+ #####: 108: initiateSmallJson(self);
+call 0 never executed
+ -: 109:
+ #####: 110: self->type = "netSerial";
+ #####: 111: if (!netSerialF) {
+branch 0 never executed
+branch 1 never executed
+ #####: 112: netSerialF = malloc(sizeof(smallJsonFunctionst));
+ #####: 113: registerMethodsNetSerialLevel2(netSerialF);
+call 0 never executed
+ #####: 114: pErrorNot0(atexit(finalizeNetSerial));
+call 0 never executed
+branch 1 never executed
+branch 2 never executed
+call 3 never executed
+branch 4 never executed
+branch 5 never executed
+call 6 never executed
+branch 7 never executed
+branch 8 never executed
+call 9 never executed
+call 10 never executed
+call 11 never executed
+call 12 never executed
+ -: 115: }
+ #####: 116: self->f = netSerialF;
+ #####: 117:}
+ -: 118:
+function initiateNetSerial called 12 returned 100% blocks executed 43%
+ 12: 119:void initiateNetSerial(smallJsont *self) {
+ -: 120:
+ 12: 121: initiateSmallJson(self);
+call 0 returned 100%
+ -: 122:
+ 12: 123: self->type = "netSerial";
+ 12: 124: if (!netSerialF) {
+branch 0 taken 50% (fallthrough)
+branch 1 taken 50%
+ 6: 125: netSerialF = malloc(sizeof(smallJsonFunctionst));
+ 6: 126: registerMethodsNetSerial(netSerialF);
+call 0 returned 100%
+ 6: 127: pErrorNot0(atexit(finalizeNetSerial));
+call 0 returned 100%
+branch 1 taken 0% (fallthrough)
+branch 2 taken 100%
+call 3 never executed
+branch 4 never executed
+branch 5 never executed
+call 6 never executed
+branch 7 never executed
+branch 8 never executed
+call 9 never executed
+call 10 never executed
+call 11 never executed
+call 12 never executed
+ -: 128: }
+ 12: 129: self->f = netSerialF;
+ 12: 130:}
+ -: 131:
+function registerMethodsNetSerialLevel0 called 0 returned 0% blocks executed 0%
+ #####: 132:void registerMethodsNetSerialLevel0(smallJsonFunctionst *f) {
+ -: 133:
+ #####: 134: registerMethodsSmallJson(f);
+call 0 never executed
+ #####: 135: f->help = helpNetSerial;
+ #####: 136: f->serial = serialNetSerialLevel0;
+ #####: 137: f->deserial = deserialNetSerialLevel0;
+ #####: 138:}
+ -: 139:
+function registerMethodsNetSerialLevel1 called 0 returned 0% blocks executed 0%
+ #####: 140:void registerMethodsNetSerialLevel1(smallJsonFunctionst *f) {
+ -: 141:
+ #####: 142: registerMethodsSmallJson(f);
+call 0 never executed
+ #####: 143: f->help = helpNetSerial;
+ #####: 144: f->serial = serialNetSerialLevel1;
+ #####: 145: f->deserial = deserialNetSerialLevel1;
+ #####: 146:}
+ -: 147:
+function registerMethodsNetSerialLevel2 called 0 returned 0% blocks executed 0%
+ #####: 148:void registerMethodsNetSerialLevel2(smallJsonFunctionst *f) {
+ -: 149:
+ #####: 150: registerMethodsSmallJson(f);
+call 0 never executed
+ #####: 151: f->help = helpNetSerial;
+ #####: 152: f->serial = serialNetSerialLevel2;
+ #####: 153: f->deserial = deserialNetSerialLevel2;
+ #####: 154:}
+ -: 155:
+function registerMethodsNetSerial called 6 returned 100% blocks executed 100%
+ 6: 156:void registerMethodsNetSerial(smallJsonFunctionst *f) {
+ -: 157:
+ 6: 158: registerMethodsSmallJson(f);
+call 0 returned 100%
+ 6: 159: f->help = helpNetSerial;
+ 6: 160: f->serial = serialNetSerial;
+ 6: 161: f->deserial = deserialNetSerial;
+ 6: 162:}
+ -: 163:
+function initiateAllocateNetSerialLevel0 called 0 returned 0% blocks executed 0%
+ #####: 164:void initiateAllocateNetSerialLevel0(smallJsont **self) {
+ -: 165:
+ #####: 166: if (self) {
+branch 0 never executed
+branch 1 never executed
+ #####: 167: (*self) = malloc(sizeof(smallJsont));
+ #####: 168: if (*self) {
+branch 0 never executed
+branch 1 never executed
+ #####: 169: initiateNetSerialLevel0(*self);
+call 0 never executed
+ -: 170: }
+ -: 171: }
+ #####: 172:}
+ -: 173:
+function initiateAllocateNetSerialLevel1 called 0 returned 0% blocks executed 0%
+ #####: 174:void initiateAllocateNetSerialLevel1(smallJsont **self) {
+ -: 175:
+ #####: 176: if (self) {
+branch 0 never executed
+branch 1 never executed
+ #####: 177: (*self) = malloc(sizeof(smallJsont));
+ #####: 178: if (*self) {
+branch 0 never executed
+branch 1 never executed
+ #####: 179: initiateNetSerialLevel1(*self);
+call 0 never executed
+ -: 180: }
+ -: 181: }
+ #####: 182:}
+ -: 183:
+function initiateAllocateNetSerialLevel2 called 0 returned 0% blocks executed 0%
+ #####: 184:void initiateAllocateNetSerialLevel2(smallJsont **self) {
+ -: 185:
+ #####: 186: if (self) {
+branch 0 never executed
+branch 1 never executed
+ #####: 187: (*self) = malloc(sizeof(smallJsont));
+ #####: 188: if (*self) {
+branch 0 never executed
+branch 1 never executed
+ #####: 189: initiateNetSerialLevel2(*self);
+call 0 never executed
+ -: 190: }
+ -: 191: }
+ #####: 192:}
+ -: 193:
+function initiateAllocateNetSerial called 0 returned 0% blocks executed 0%
+ #####: 194:void initiateAllocateNetSerial(smallJsont **self) {
+ -: 195:
+ #####: 196: if (self) {
+branch 0 never executed
+branch 1 never executed
+ #####: 197: (*self) = malloc(sizeof(smallJsont));
+ #####: 198: if (*self) {
+branch 0 never executed
+branch 1 never executed
+ #####: 199: initiateNetSerial(*self);
+call 0 never executed
+ -: 200: }
+ -: 201: }
+ #####: 202:}
+ -: 203:
+function finalizeNetSerial called 6 returned 100% blocks executed 100%
+ 6: 204:void finalizeNetSerial(void) {
+ -: 205:
+ 6: 206: if (netSerialF) {
+branch 0 taken 100% (fallthrough)
+branch 1 taken 0%
+ 6: 207: free(netSerialF);
+ 6: 208: netSerialF = NULL;
+ -: 209: }
+ 6: 210:}
+ -: 211:
+function allocNetSerialLevel0 called 0 returned 0% blocks executed 0%
+ #####: 212:smallJsont* allocNetSerialLevel0(void) {
+ #####: 213: smallJsont *r = NULL;
+ -: 214:
+ #####: 215: initiateAllocateNetSerialLevel0(&r);
+call 0 never executed
+ #####: 216: ret r;
+ -: 217:}
+ -: 218:
+function allocNetSerialLevel1 called 0 returned 0% blocks executed 0%
+ #####: 219:smallJsont* allocNetSerialLevel1(void) {
+ #####: 220: smallJsont *r = NULL;
+ -: 221:
+ #####: 222: initiateAllocateNetSerialLevel1(&r);
+call 0 never executed
+ #####: 223: ret r;
+ -: 224:}
+ -: 225:
+function allocNetSerialLevel2 called 0 returned 0% blocks executed 0%
+ #####: 226:smallJsont* allocNetSerialLevel2(void) {
+ #####: 227: smallJsont *r = NULL;
+ -: 228:
+ #####: 229: initiateAllocateNetSerialLevel2(&r);
+call 0 never executed
+ #####: 230: ret r;
+ -: 231:}
+ -: 232:
+function allocNetSerial called 0 returned 0% blocks executed 0%
+ #####: 233:smallJsont* allocNetSerial(void) {
+ #####: 234: smallJsont *r = NULL;
+ -: 235:
+ #####: 236: initiateAllocateNetSerial(&r);
+call 0 never executed
+ #####: 237: ret r;
+ -: 238:}
+ -: 239:
+ -: 240:
+function helpNetSerial called 0 returned 0% blocks executed 0%
+ #####: 241:internal const char* helpNetSerial(smallJsont UNUSED *self) {
+ #####: 242: ret "TODO helpNetSerial \n" helpTextSmallJson;
+ -: 243:}
+ -: 244:
+function uintToNetTypeVarint called 105 returned 100% blocks executed 100%
+ 105: 245:internal void uintToNetTypeVarint(sBytest **buf, u8 type, u64 value) {
+ 105: 246: u64 c = value;
+ -: 247: /* encode b0..2 */
+ 105: 248: u8 b = type + ((c & 0x7) << 4);
+ 105: 249: if (c & 0xFFFFFFFFFFFFFFF8) {
+branch 0 taken 10% (fallthrough)
+branch 1 taken 90%
+ 10: 250: b |= 0x80;
+ 10: 251: sBytesPush(buf, b);
+call 0 returned 100%
+ 10: 252: c >>=3;
+ -: 253: /* encode b3..9 ...*/
+ 31: 254: while(c) {
+branch 0 taken 52%
+branch 1 taken 48%
+ 11: 255: b = c & 0x7F;
+ 11: 256: if (c & 0xFFFFFFFFFFFFFF80)
+branch 0 taken 9% (fallthrough)
+branch 1 taken 91%
+ 1: 257: b |= 0x80;
+ 11: 258: sBytesPush(buf, b);
+call 0 returned 100%
+ 11: 259: c >>=7;
+ -: 260: }
+ -: 261: }
+ -: 262: else
+ 95: 263: sBytesPush(buf, b);
+call 0 returned 100%
+ 105: 264:}
+ -: 265:
+function uintToVarint called 173 returned 100% blocks executed 90%
+ 173: 266:internal void uintToVarint(sBytest **buf, u64 value) {
+ 173: 267: u64 c = value;
+ 173: 268: u8 b = c & 0x7F;
+ 173: 269: if (c & 0xFFFFFFFFFFFFFF80) {
+branch 0 taken 2% (fallthrough)
+branch 1 taken 98%
+ 3: 270: b |= 0x80;
+ 3: 271: sBytesPush(buf, b);
+call 0 returned 100%
+ 3: 272: c >>=7;
+ -: 273: /* encode b7..14 ...*/
+ 9: 274: while(c) {
+branch 0 taken 50%
+branch 1 taken 50%
+ 3: 275: b = c & 0x7F;
+ 3: 276: if (c & 0xFFFFFFFFFFFFFF80)
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ #####: 277: b |= 0x80;
+ 3: 278: sBytesPush(buf, b);
+call 0 returned 100%
+ 3: 279: c >>=7;
+ -: 280: }
+ -: 281: }
+ -: 282: else
+ 170: 283: sBytesPush(buf, b);
+call 0 returned 100%
+ 173: 284:}
+ -: 285:
+function netTypeVarintToUint called 105 returned 100% blocks executed 100%
+ 105: 286:internal u64 netTypeVarintToUint(u8 **buf) {
+ 105: 287: u64 r = 0;
+ -: 288:
+ 105: 289: r = (**buf >> 4) & 0x7;
+ -: 290:
+ 105: 291: u8 c = 0;
+ 221: 292: while (**buf & 0x80) {
+branch 0 taken 9%
+branch 1 taken 91% (fallthrough)
+ 11: 293: (*buf)++;
+ 11: 294: r |= (**buf & 0x7F) << (7*c+3);
+ 11: 295: c++;
+ -: 296: }
+ 105: 297: (*buf)++;
+ 105: 298: ret r;
+ -: 299:}
+ -: 300:
+function varintToUint called 173 returned 100% blocks executed 100%
+ 173: 301:internal u64 varintToUint(u8 **buf) {
+ 173: 302: u64 r = 0;
+ -: 303:
+ 173: 304: r = (**buf) & 0x7F;
+ 173: 305: u8 c = 1;
+ 349: 306: while (**buf & 0x80) {
+branch 0 taken 2%
+branch 1 taken 98% (fallthrough)
+ 3: 307: (*buf)++;
+ 3: 308: r |= (**buf & 0x7F) << (7*c);
+ 3: 309: c++;
+ -: 310: }
+ 173: 311: (*buf)++;
+ 173: 312: ret r;
+ -: 313:}
+ -: 314:
+ -: 315:// -------------------------------------
+ -: 316:// Serializers
+ -: 317:
+function netSerialLevel0 called 0 returned 0% blocks executed 0%
+ #####: 318:internal sBytest* netSerialLevel0(smallt *o) {
+ #####: 319: sBytest *r = NULL;
+ #####: 320: sBytest *B = NULL;
+ -: 321:
+ #####: 322: switch(o->type) {
+branch 0 never executed
+branch 1 never executed
+branch 2 never executed
+branch 3 never executed
+branch 4 never executed
+branch 5 never executed
+branch 6 never executed
+branch 7 never executed
+branch 8 never executed
+branch 9 never executed
+ -: 323: case UNDEFINED:
+ #####: 324: sBytesPush(&r, NET_SERIAL_TYPES[(u8)o->type]);
+call 0 never executed
+ #####: 325: break;
+ -: 326: case BOOL: {
+ #####: 327: u8 c = NET_SERIAL_TYPES[(u8)o->type];
+ -: 328: // set bit 4 when true
+ #####: 329: if (((sBoolt *)&(o->type))->value)
+branch 0 never executed
+branch 1 never executed
+ #####: 330: c |= (1<<4);
+ #####: 331: sBytesPush(&r, c);
+call 0 never executed
+ -: 332: }
+ #####: 333: break;
+ -: 334: case CONTAINER:
+ -: 335: // undefined
+ #####: 336: sBytesPush(&r, NET_SERIAL_TYPES[(u8)o->type]);
+call 0 never executed
+ #####: 337: break;
+ -: 338: case DICT:
+ #####: 339: dictNetSerialLevel0(&r, (sDictt *)&(o->type));
+call 0 never executed
+ #####: 340: break;
+ -: 341: case DOUBLE:
+ #####: 342: sBytesPush(&r, NET_SERIAL_TYPES[(u8)o->type]);
+call 0 never executed
+ #####: 343: sBytesPushBuffer(&r, &((sDoublet *)&(o->type))->value, sizeof(double));
+call 0 never executed
+ #####: 344: break;
+ -: 345: case INT: {
+ -: 346: // encode int to varint
+ -: 347: // v is int64_t to convert to varint
+ #####: 348: i64 v = ((sIntt *)&(o->type))->value;
+ -: 349: // encode v with arithmetic shifts
+ #####: 350: uintToNetTypeVarint(&r, NET_SERIAL_TYPES[(u8)o->type], (v << 1) ^ (v >> 63));
+call 0 never executed
+ -: 351: }
+ #####: 352: break;
+ -: 353: case STRING:
+ #####: 354: sBytesPush(&r, NET_SERIAL_TYPES[(u8)o->type]);
+call 0 never executed
+ #####: 355: sBytesPushBuffer(&r, &((sStringt *)&(o->type))->data, sizeof(sStringt) + strlen(&(((sStringt *)&(o->type))->data)) -1);
+call 0 never executed
+ #####: 356: break;
+ -: 357: case ARRAY:
+ #####: 358: arrayNetSerialLevel0(&r, (sArrayt *)&(o->type));
+call 0 never executed
+ #####: 359: break;
+ -: 360: case BYTES:
+ #####: 361: B = (sBytest *)&(o->type);
+ #####: 362: uintToNetTypeVarint(&r, NET_SERIAL_TYPES[(u8)o->type], B->count);
+call 0 never executed
+ #####: 363: sBytesPushBuffer(&r, &(B->data), B->count);
+call 0 never executed
+ #####: 364: break;
+ -: 365: }
+ #####: 366: ret r;
+ -: 367:}
+ -: 368:
+ -: 369:/**
+ -: 370: * serialize dictionary
+ -: 371: *
+ -: 372: * the serialized dict is pushed to r.
+ -: 373: * All elements are serialized recursively
+ -: 374: *
+ -: 375: * the data in containers is not serialized
+ -: 376: *
+ -: 377: * \param
+ -: 378: * r small bytes object
+ -: 379: * dict dictionary to serialize
+ -: 380: */
+function dictNetSerialLevel0 called 0 returned 0% blocks executed 0%
+ #####: 381:internal void dictNetSerialLevel0(sBytest **r, sDictt *dict) {
+ #####: 382: sBytest *B = NULL;
+ -: 383:
+ #####: 384: uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)dict->type], dict->count);
+call 0 never executed
+ -: 385:
+ #####: 386: forEachSDict(dict, e) {
+branch 0 never executed
+branch 1 never executed
+ #####: 387: if (e->key) {
+branch 0 never executed
+branch 1 never executed
+ #####: 388: sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+call 0 never executed
+ -: 389:
+ #####: 390: switch(e->data->type) {
+branch 0 never executed
+branch 1 never executed
+branch 2 never executed
+branch 3 never executed
+branch 4 never executed
+branch 5 never executed
+branch 6 never executed
+branch 7 never executed
+branch 8 never executed
+branch 9 never executed
+ -: 391: case UNDEFINED:
+ #####: 392: sBytesPush(r, NET_SERIAL_TYPES[(u8)e->data->type]);
+call 0 never executed
+ #####: 393: break;
+ -: 394: case BOOL: {
+ #####: 395: u8 c = NET_SERIAL_TYPES[(u8)e->data->type];
+ -: 396: // set bit 4 when true
+ #####: 397: if (((sBoolt *)(e->data))->value)
+branch 0 never executed
+branch 1 never executed
+ #####: 398: c |= (1<<4);
+ #####: 399: sBytesPush(r, c);
+call 0 never executed
+ -: 400: }
+ #####: 401: break;
+ -: 402: case CONTAINER:
+ -: 403: // undefined
+ #####: 404: sBytesPush(r, NET_SERIAL_TYPES[(u8)e->data->type]);
+call 0 never executed
+ #####: 405: break;
+ -: 406: case DICT:
+ #####: 407: dictNetSerialLevel0(r, (sDictt *)(e->data));
+call 0 never executed
+ #####: 408: break;
+ -: 409: case DOUBLE:
+ #####: 410: sBytesPush(r, NET_SERIAL_TYPES[(u8)e->data->type]);
+call 0 never executed
+ #####: 411: sBytesPushBuffer(r, &((sDoublet *)(e->data))->value, sizeof(double));
+call 0 never executed
+ #####: 412: break;
+ -: 413: case INT: {
+ -: 414: // encode int to varint
+ -: 415: // v is int64_t to convert to varint
+ #####: 416: i64 v = ((sIntt *)(e->data))->value;
+ -: 417: // encode v with arithmetic shifts
+ #####: 418: uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)e->data->type], (v << 1) ^ (v >> 63));
+call 0 never executed
+ -: 419: }
+ #####: 420: break;
+ -: 421: case STRING:
+ #####: 422: sBytesPush(r, NET_SERIAL_TYPES[(u8)e->data->type]);
+call 0 never executed
+ #####: 423: sBytesPushBuffer(r, &((sStringt *)(e->data))->data, sizeof(sStringt) + strlen(&(((sStringt *)(e->data))->data)) -1);
+call 0 never executed
+ #####: 424: break;
+ -: 425: case ARRAY:
+ #####: 426: arrayNetSerialLevel0(r, (sArrayt *)(e->data));
+call 0 never executed
+ #####: 427: break;
+ -: 428: case BYTES:
+ #####: 429: B = (sBytest *)(e->data);
+ #####: 430: uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)e->data->type], B->count);
+call 0 never executed
+ #####: 431: sBytesPushBuffer(r, &(B->data), B->count);
+call 0 never executed
+ #####: 432: break;
+ -: 433: }
+ -: 434: }
+ -: 435: }
+ #####: 436: ret;
+ -: 437:}
+ -: 438:
+ -: 439:/**
+ -: 440: * serialize array
+ -: 441: *
+ -: 442: * the serialized array is pushed to r.
+ -: 443: * All elements are serialized recursively
+ -: 444: *
+ -: 445: * the data in containers is not serialized
+ -: 446: *
+ -: 447: * \param
+ -: 448: * r small bytes object
+ -: 449: * array to serialize
+ -: 450: */
+function arrayNetSerialLevel0 called 0 returned 0% blocks executed 0%
+ #####: 451:internal void arrayNetSerialLevel0(sBytest **r, sArrayt *array) {
+ #####: 452: sBytest *B = NULL;
+ -: 453:
+ #####: 454: uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)array->type], array->count);
+call 0 never executed
+ -: 455:
+ #####: 456: forEachSArray(array, e) {
+branch 0 never executed
+branch 1 never executed
+ #####: 457: if (!e) {
+branch 0 never executed
+branch 1 never executed
+ -: 458: // empty slots are represented as undefined elements
+ #####: 459: sBytesPush(r, NET_SERIAL_TYPES[UNDEFINED]);
+call 0 never executed
+ -: 460: }
+ -: 461: else {
+ #####: 462: switch(e->type) {
+branch 0 never executed
+branch 1 never executed
+branch 2 never executed
+branch 3 never executed
+branch 4 never executed
+branch 5 never executed
+branch 6 never executed
+branch 7 never executed
+branch 8 never executed
+branch 9 never executed
+ -: 463: case UNDEFINED:
+ #####: 464: sBytesPush(r, NET_SERIAL_TYPES[(u8)e->type]);
+call 0 never executed
+ #####: 465: break;
+ -: 466: case BOOL: {
+ #####: 467: u8 c = NET_SERIAL_TYPES[(u8)e->type];
+ -: 468: // set bit 4 when true
+ #####: 469: if (((sBoolt *)&(e->type))->value)
+branch 0 never executed
+branch 1 never executed
+ #####: 470: c |= (1<<4);
+ #####: 471: sBytesPush(r, c);
+call 0 never executed
+ -: 472: }
+ #####: 473: break;
+ -: 474: case CONTAINER:
+ -: 475: // undefined
+ #####: 476: sBytesPush(r, NET_SERIAL_TYPES[(u8)e->type]);
+call 0 never executed
+ #####: 477: break;
+ -: 478: case DICT:
+ #####: 479: dictNetSerialLevel0(r, (sDictt *)e);
+call 0 never executed
+ #####: 480: break;
+ -: 481: case DOUBLE:
+ #####: 482: sBytesPush(r, NET_SERIAL_TYPES[(u8)e->type]);
+call 0 never executed
+ #####: 483: sBytesPushBuffer(r, &((sDoublet *)e)->value, sizeof(double));
+call 0 never executed
+ #####: 484: break;
+ -: 485: case INT: {
+ -: 486: // encode int to varint
+ -: 487: // v is int64_t to convert to varint
+ #####: 488: i64 v = ((sIntt *)&(e->type))->value;
+ -: 489: // encode v with arithmetic shifts
+ #####: 490: uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)e->type], (v << 1) ^ (v >> 63));
+call 0 never executed
+ -: 491: }
+ #####: 492: break;
+ -: 493: case STRING:
+ #####: 494: sBytesPush(r, NET_SERIAL_TYPES[(u8)e->type]);
+call 0 never executed
+ #####: 495: sBytesPushBuffer(r, &((sStringt *)e)->data, sizeof(sStringt) + strlen(&(((sStringt *)e)->data)) -1);
+call 0 never executed
+ #####: 496: break;
+ -: 497: case ARRAY:
+ #####: 498: arrayNetSerialLevel0(r, (sArrayt *)e);
+call 0 never executed
+ #####: 499: break;
+ -: 500: case BYTES:
+ #####: 501: B = (sBytest *)e;
+ #####: 502: uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)e->type], B->count);
+call 0 never executed
+ #####: 503: sBytesPushBuffer(r, &(B->data), B->count);
+call 0 never executed
+ #####: 504: break;
+ -: 505: }
+ -: 506: }
+ -: 507: }
+ #####: 508: ret;
+ -: 509:}
+ -: 510:
+function serialNetSerialLevel0 called 0 returned 0% blocks executed 0%
+ #####: 511:internal smallBytest* serialNetSerialLevel0(smallJsont *self) {
+ -: 512:
+ #####: 513: smallt *o = getsoG(self);
+call 0 never executed
+ -: 514:
+ #####: 515: if (o == NULL)
+branch 0 never executed
+branch 1 never executed
+ #####: 516: ret NULL;
+ -: 517:
+ #####: 518: sBytest *B = netSerialLevel0(o);
+call 0 never executed
+ -: 519:
+ #####: 520: if (!B) {
+branch 0 never executed
+branch 1 never executed
+ #####: 521: ret NULL;
+ -: 522: }
+ -: 523:
+ #####: 524: createAllocateSmallBytes(r);
+call 0 never executed
+ #####: 525: r->B = B;
+ #####: 526: ret r;
+ -: 527:}
+ -: 528:
+ -: 529:// level 1
+ -: 530:
+function netSerialLevel1 called 0 returned 0% blocks executed 0%
+ #####: 531:internal sBytest* netSerialLevel1(smallt *o) {
+ #####: 532: sBytest *r = NULL;
+ #####: 533: sBytest *B = NULL;
+ #####: 534: contextt ctx = {.nibble=lowNbl, .nblOffset=0, .boolShift = 0, .boolOffset=0};
+ -: 535:
+ #####: 536: switch(o->type) {
+branch 0 never executed
+branch 1 never executed
+branch 2 never executed
+branch 3 never executed
+branch 4 never executed
+branch 5 never executed
+branch 6 never executed
+branch 7 never executed
+branch 8 never executed
+ -: 537: case UNDEFINED:
+ -: 538: case CONTAINER:
+ #####: 539: sBytesPush(&r, NET_SERIAL_TYPES[(u8)o->type]);
+call 0 never executed
+ #####: 540: break;
+ -: 541: case BOOL: {
+ #####: 542: u8 c = NET_SERIAL_TYPES[(u8)o->type];
+ -: 543: // set bit 4 when true
+ #####: 544: if (((sBoolt *)&(o->type))->value)
+branch 0 never executed
+branch 1 never executed
+ #####: 545: c |= (1<<4);
+ #####: 546: sBytesPush(&r, c);
+call 0 never executed
+ -: 547: }
+ #####: 548: break;
+ -: 549: case DICT:
+ #####: 550: dictNetSerialLevel1(&r, (sDictt *)&(o->type), &ctx);
+call 0 never executed
+ #####: 551: break;
+ -: 552: case DOUBLE:
+ #####: 553: sBytesPush(&r, NET_SERIAL_TYPES[(u8)o->type]);
+call 0 never executed
+ #####: 554: sBytesPushBuffer(&r, &((sDoublet *)&(o->type))->value, sizeof(double));
+call 0 never executed
+ #####: 555: break;
+ -: 556: case INT: {
+ -: 557: // encode int to varint
+ -: 558: // v is int64_t to convert to varint
+ #####: 559: i64 v = ((sIntt *)&(o->type))->value;
+ -: 560: // encode v with arithmetic shifts
+ #####: 561: uintToNetTypeVarint(&r, NET_SERIAL_TYPES[(u8)o->type], (v << 1) ^ (v >> 63));
+call 0 never executed
+ -: 562: }
+ #####: 563: break;
+ -: 564: case STRING:
+ #####: 565: sBytesPush(&r, NET_SERIAL_TYPES[(u8)o->type]);
+call 0 never executed
+ #####: 566: sBytesPushBuffer(&r, &((sStringt *)&(o->type))->data, sizeof(sStringt) + strlen(&(((sStringt *)&(o->type))->data)) -1);
+call 0 never executed
+ #####: 567: break;
+ -: 568: case ARRAY:
+ #####: 569: arrayNetSerialLevel1(&r, (sArrayt *)&(o->type), &ctx);
+call 0 never executed
+ #####: 570: break;
+ -: 571: case BYTES:
+ #####: 572: B = (sBytest *)&(o->type);
+ #####: 573: uintToNetTypeVarint(&r, NET_SERIAL_TYPES[(u8)o->type], B->count);
+call 0 never executed
+ #####: 574: sBytesPushBuffer(&r, &(B->data), B->count);
+call 0 never executed
+ #####: 575: break;
+ -: 576: }
+ #####: 577: ret r;
+ -: 578:}
+ -: 579:
+ -: 580:/**
+ -: 581: * serialize dictionary
+ -: 582: *
+ -: 583: * the serialized dict is pushed to r.
+ -: 584: * All elements are serialized recursively
+ -: 585: *
+ -: 586: * the data in containers is not serialized
+ -: 587: *
+ -: 588: * \param
+ -: 589: * r small bytes object
+ -: 590: * dict dictionary to serialize
+ -: 591: */
+function dictNetSerialLevel1 called 0 returned 0% blocks executed 0%
+ #####: 592:internal void dictNetSerialLevel1(sBytest **r, sDictt *dict, contextt *ctx) {
+ #####: 593: sBytest *B = NULL;
+ #####: 594: char *data = NULL;
+ -: 595:
+ #####: 596: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 597: uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)dict->type], dict->count);
+call 0 never executed
+ -: 598: }
+ -: 599: else {
+ -: 600: // high nibble
+ -: 601: #define storeTypeInHighNbl(o)\
+ -: 602: ctx->nibble = lowNbl;\
+ -: 603: data = (char *)&((*r)->data) + ctx->nblOffset;\
+ -: 604: *data |= NET_SERIAL_TYPES[(u8)o->type] << 4
+ #####: 605: storeTypeInHighNbl(dict);
+ #####: 606: uintToVarint(r, dict->count);
+call 0 never executed
+ -: 607: }
+ -: 608:
+ #####: 609: forEachSDict(dict, e) {
+branch 0 never executed
+branch 1 never executed
+ #####: 610: if (e->key) {
+branch 0 never executed
+branch 1 never executed
+ #####: 611: sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+call 0 never executed
+ -: 612:
+ #####: 613: switch(e->data->type) {
+branch 0 never executed
+branch 1 never executed
+branch 2 never executed
+branch 3 never executed
+branch 4 never executed
+branch 5 never executed
+branch 6 never executed
+branch 7 never executed
+branch 8 never executed
+ -: 614: case UNDEFINED:
+ -: 615: case CONTAINER:
+ #####: 616: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ -: 617: #define storeTypeOnly(o)\
+ -: 618: sBytesPush(r, NET_SERIAL_TYPES[(u8)o->type]);\
+ -: 619: ctx->nibble = highNbl;\
+ -: 620: ctx->nblOffset = (*r)->count -1
+ #####: 621: storeTypeOnly(e->data);
+call 0 never executed
+ -: 622: }
+ -: 623: else {
+ #####: 624: storeTypeInHighNbl(e->data);
+ -: 625: }
+ #####: 626: break;
+ -: 627: case BOOL:
+ #####: 628: if (!ctx->boolOffset) {
+branch 0 never executed
+branch 1 never executed
+ -: 629: // new packed bools
+ #####: 630: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ -: 631: #define storeNew4bPackedBool(o)\
+ -: 632: u8 c = NET_SERIAL_TYPES[(u8)o->type];\
+ -: 633: /* set bit 4 when true */\
+ -: 634: if (((sBoolt *)(o))->value)\
+ -: 635: c |= (1<<4);\
+ -: 636: sBytesPush(r, c);\
+ -: 637: ctx->boolShift = 5;\
+ -: 638: ctx->boolOffset = (*r)->count -1
+ #####: 639: storeNew4bPackedBool(e->data);
+branch 0 never executed
+branch 1 never executed
+call 2 never executed
+ -: 640: }
+ -: 641: else {
+ -: 642: // high nibble, next byte is packed bools
+ #####: 643: storeTypeInHighNbl(e->data);
+ -: 644: #define storeNew8bPackedBool(o)\
+ -: 645: u8 c = 0;\
+ -: 646: if (((sBoolt *)(o))->value)\
+ -: 647: c = 1;\
+ -: 648: sBytesPush(r, c);\
+ -: 649: ctx->boolShift = 1;\
+ -: 650: ctx->boolOffset = (*r)->count -1
+ #####: 651: storeNew8bPackedBool(e->data);
+branch 0 never executed
+branch 1 never executed
+call 2 never executed
+ -: 652: }
+ -: 653: }
+ -: 654: else {
+ -: 655: // there was a bool before this one, fill bits in nibbles
+ #####: 656: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 657: if (ctx->boolShift == 8) {
+branch 0 never executed
+branch 1 never executed
+ -: 658: // previous packed bool is full
+ -: 659: // this byte is the new packed bools
+ #####: 660: storeNew4bPackedBool(e->data);
+branch 0 never executed
+branch 1 never executed
+call 2 never executed
+ -: 661: }
+ -: 662: else {
+ #####: 663: storeTypeOnly(e->data);
+call 0 never executed
+ -: 664: #define storeBool(o)\
+ -: 665: data = (char *)&((*r)->data) + ctx->boolOffset;\
+ -: 666: if (((sBoolt *)(o))->value)\
+ -: 667: *data |= 1 << ctx->boolShift;\
+ -: 668: ctx->boolShift++
+ #####: 669: storeBool(e->data);
+branch 0 never executed
+branch 1 never executed
+ -: 670: }
+ -: 671: }
+ -: 672: else {
+ -: 673: // high nibble
+ #####: 674: storeTypeInHighNbl(e->data);
+ #####: 675: if (ctx->boolShift == 8) {
+branch 0 never executed
+branch 1 never executed
+ -: 676: // previous packed bool is full
+ -: 677: // next byte is the new packed bools
+ #####: 678: storeNew8bPackedBool(e->data);
+branch 0 never executed
+branch 1 never executed
+call 2 never executed
+ -: 679: }
+ -: 680: else {
+ #####: 681: storeBool(e->data);
+branch 0 never executed
+branch 1 never executed
+ -: 682: }
+ -: 683: }
+ -: 684: }
+ #####: 685: break;
+ -: 686: case DICT:
+ #####: 687: dictNetSerialLevel1(r, (sDictt *)(e->data), ctx);
+call 0 never executed
+ #####: 688: break;
+ -: 689: case DOUBLE:
+ #####: 690: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 691: storeTypeOnly(e->data);
+call 0 never executed
+ -: 692: }
+ -: 693: else {
+ -: 694: // high nibble
+ #####: 695: storeTypeInHighNbl(e->data);
+ -: 696: }
+ #####: 697: sBytesPushBuffer(r, &((sDoublet *)(e->data))->value, sizeof(double));
+call 0 never executed
+ #####: 698: break;
+ -: 699: case INT: {
+ -: 700: // encode int to varint
+ -: 701: // v is int64_t to convert to varint
+ #####: 702: i64 v = ((sIntt *)(e->data))->value;
+ #####: 703: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ -: 704: // encode v with arithmetic shifts
+ #####: 705: uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)e->data->type], (v << 1) ^ (v >> 63));
+call 0 never executed
+ -: 706: }
+ -: 707: else {
+ -: 708: // high nibble
+ #####: 709: storeTypeInHighNbl(e->data);
+ #####: 710: uintToVarint(r, (v << 1) ^ (v >> 63));
+call 0 never executed
+ -: 711: }
+ -: 712: }
+ #####: 713: break;
+ -: 714: case STRING:
+ #####: 715: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 716: storeTypeOnly(e->data);
+call 0 never executed
+ -: 717: }
+ -: 718: else {
+ -: 719: // high nibble
+ #####: 720: storeTypeInHighNbl(e->data);
+ -: 721: }
+ #####: 722: sBytesPushBuffer(r, &((sStringt *)(e->data))->data, sizeof(sStringt) + strlen(&(((sStringt *)(e->data))->data)) -1);
+call 0 never executed
+ #####: 723: break;
+ -: 724: case ARRAY:
+ #####: 725: arrayNetSerialLevel1(r, (sArrayt *)(e->data), ctx);
+call 0 never executed
+ #####: 726: break;
+ -: 727: case BYTES:
+ #####: 728: B = (sBytest *)(e->data);
+ #####: 729: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 730: uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)e->data->type], B->count);
+call 0 never executed
+ -: 731: }
+ -: 732: else {
+ -: 733: // high nibble
+ #####: 734: storeTypeInHighNbl(e->data);
+ #####: 735: uintToVarint(r, B->count);
+call 0 never executed
+ -: 736: }
+ #####: 737: sBytesPushBuffer(r, &(B->data), B->count);
+call 0 never executed
+ #####: 738: break;
+ -: 739: }
+ -: 740: }
+ -: 741: }
+ #####: 742: ret;
+ -: 743:}
+ -: 744:
+ -: 745:/**
+ -: 746: * serialize array
+ -: 747: *
+ -: 748: * the serialized array is pushed to r.
+ -: 749: * All elements are serialized recursively
+ -: 750: *
+ -: 751: * the data in containers is not serialized
+ -: 752: *
+ -: 753: * \param
+ -: 754: * r small bytes object
+ -: 755: * array to serialize
+ -: 756: */
+function arrayNetSerialLevel1 called 0 returned 0% blocks executed 0%
+ #####: 757:internal void arrayNetSerialLevel1(sBytest **r, sArrayt *array, contextt *ctx) {
+ #####: 758: sBytest *B = NULL;
+ #####: 759: char *data = NULL;
+ -: 760:
+ #####: 761: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 762: uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)array->type], array->count);
+call 0 never executed
+ -: 763: }
+ -: 764: else {
+ -: 765: // high nibble
+ #####: 766: storeTypeInHighNbl(array);
+ #####: 767: uintToVarint(r, array->count);
+call 0 never executed
+ -: 768: }
+ -: 769:
+ #####: 770: forEachSArray(array, e) {
+branch 0 never executed
+branch 1 never executed
+ #####: 771: if (!e) {
+branch 0 never executed
+branch 1 never executed
+ -: 772: // empty slots are represented as undefined elements
+ #####: 773: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 774: sBytesPush(r, NET_SERIAL_TYPES[UNDEFINED]);
+call 0 never executed
+ #####: 775: ctx->nibble = highNbl;
+ #####: 776: ctx->nblOffset = (*r)->count -1;
+ -: 777: }
+ -: 778: else {
+ -: 779: // high nibble
+ #####: 780: ctx->nibble = lowNbl;
+ #####: 781: data = (char *)&((*r)->data) + ctx->nblOffset;
+ #####: 782: *data |= NET_SERIAL_TYPES[UNDEFINED] << 4;
+ -: 783: }
+ -: 784: }
+ -: 785: else {
+ #####: 786: switch(e->type) {
+branch 0 never executed
+branch 1 never executed
+branch 2 never executed
+branch 3 never executed
+branch 4 never executed
+branch 5 never executed
+branch 6 never executed
+branch 7 never executed
+branch 8 never executed
+ -: 787: case UNDEFINED:
+ -: 788: case CONTAINER:
+ #####: 789: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 790: storeTypeOnly(e);
+call 0 never executed
+ -: 791: }
+ -: 792: else {
+ -: 793: // high nibble
+ #####: 794: storeTypeInHighNbl(e);
+ -: 795: }
+ #####: 796: break;
+ -: 797: case BOOL:
+ #####: 798: if (!ctx->boolOffset) {
+branch 0 never executed
+branch 1 never executed
+ -: 799: // new packed bools
+ #####: 800: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 801: storeNew4bPackedBool(e);
+branch 0 never executed
+branch 1 never executed
+call 2 never executed
+ -: 802: }
+ -: 803: else {
+ -: 804: // high nibble, next byte is packed bools
+ #####: 805: storeTypeInHighNbl(e);
+ #####: 806: storeNew8bPackedBool(e);
+branch 0 never executed
+branch 1 never executed
+call 2 never executed
+ -: 807: }
+ -: 808: }
+ -: 809: else {
+ -: 810: // there was a bool before this one, fill bits in nibbles
+ #####: 811: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 812: if (ctx->boolShift == 8) {
+branch 0 never executed
+branch 1 never executed
+ -: 813: // previous packed bool is full
+ -: 814: // this byte is the new packed bools
+ #####: 815: storeNew4bPackedBool(e);
+branch 0 never executed
+branch 1 never executed
+call 2 never executed
+ -: 816: }
+ -: 817: else {
+ #####: 818: storeTypeOnly(e);
+call 0 never executed
+ #####: 819: storeBool(e);
+branch 0 never executed
+branch 1 never executed
+ -: 820: }
+ -: 821: }
+ -: 822: else {
+ -: 823: // high nibble
+ #####: 824: storeTypeInHighNbl(e);
+ #####: 825: if (ctx->boolShift == 8) {
+branch 0 never executed
+branch 1 never executed
+ -: 826: // previous packed bool is full
+ -: 827: // next byte is the new packed bools
+ #####: 828: storeNew8bPackedBool(e);
+branch 0 never executed
+branch 1 never executed
+call 2 never executed
+ -: 829: }
+ -: 830: else {
+ #####: 831: storeBool(e);
+branch 0 never executed
+branch 1 never executed
+ -: 832: }
+ -: 833: }
+ -: 834: }
+ #####: 835: break;
+ -: 836: case DICT:
+ #####: 837: dictNetSerialLevel1(r, (sDictt *)e, ctx);
+call 0 never executed
+ #####: 838: break;
+ -: 839: case DOUBLE:
+ #####: 840: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 841: storeTypeOnly(e);
+call 0 never executed
+ -: 842: }
+ -: 843: else {
+ -: 844: // high nibble
+ #####: 845: storeTypeInHighNbl(e);
+ -: 846: }
+ #####: 847: sBytesPushBuffer(r, &((sDoublet *)e)->value, sizeof(double));
+call 0 never executed
+ #####: 848: break;
+ -: 849: case INT: {
+ -: 850: // encode int to varint
+ -: 851: // v is int64_t to convert to varint
+ #####: 852: i64 v = ((sIntt *)&(e->type))->value;
+ #####: 853: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ -: 854: // encode v with arithmetic shifts
+ #####: 855: uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)e->type], (v << 1) ^ (v >> 63));
+call 0 never executed
+ -: 856: }
+ -: 857: else {
+ -: 858: // high nibble
+ #####: 859: storeTypeInHighNbl(e);
+ #####: 860: uintToVarint(r, (v << 1) ^ (v >> 63));
+call 0 never executed
+ -: 861: }
+ -: 862: }
+ #####: 863: break;
+ -: 864: case STRING:
+ #####: 865: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 866: storeTypeOnly(e);
+call 0 never executed
+ -: 867: }
+ -: 868: else {
+ -: 869: // high nibble
+ #####: 870: storeTypeInHighNbl(e);
+ -: 871: }
+ #####: 872: sBytesPushBuffer(r, &((sStringt *)e)->data, sizeof(sStringt) + strlen(&(((sStringt *)e)->data)) -1);
+call 0 never executed
+ #####: 873: break;
+ -: 874: case ARRAY:
+ #####: 875: arrayNetSerialLevel1(r, (sArrayt *)e, ctx);
+call 0 never executed
+ #####: 876: break;
+ -: 877: case BYTES:
+ #####: 878: B = (sBytest *)e;
+ #####: 879: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 880: uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)e->type], B->count);
+call 0 never executed
+ -: 881: }
+ -: 882: else {
+ -: 883: // high nibble
+ #####: 884: storeTypeInHighNbl(e);
+ #####: 885: uintToVarint(r, B->count);
+call 0 never executed
+ -: 886: }
+ #####: 887: sBytesPushBuffer(r, &(B->data), B->count);
+call 0 never executed
+ #####: 888: break;
+ -: 889: }
+ -: 890: }
+ -: 891: }
+ #####: 892: ret;
+ -: 893:}
+ -: 894:
+function serialNetSerialLevel1 called 0 returned 0% blocks executed 0%
+ #####: 895:internal smallBytest* serialNetSerialLevel1(smallJsont *self) {
+ -: 896:
+ #####: 897: smallt *o = getsoG(self);
+call 0 never executed
+ -: 898:
+ #####: 899: if (o == NULL)
+branch 0 never executed
+branch 1 never executed
+ #####: 900: ret NULL;
+ -: 901:
+ #####: 902: sBytest *B = netSerialLevel1(o);
+call 0 never executed
+ -: 903:
+ #####: 904: if (!B) {
+branch 0 never executed
+branch 1 never executed
+ #####: 905: ret NULL;
+ -: 906: }
+ -: 907:
+ #####: 908: createAllocateSmallBytes(r);
+call 0 never executed
+ #####: 909: r->B = B;
+ #####: 910: ret r;
+ -: 911:}
+ -: 912:
+ -: 913:// level 2
+ -: 914:
+function netSerialLevel2 called 0 returned 0% blocks executed 0%
+ #####: 915:internal sBytest* netSerialLevel2(smallt *o) {
+ #####: 916: sBytest *r = NULL;
+ #####: 917: sBytest *B = NULL;
+ #####: 918: contextt ctx = {.nibble=lowNbl, .nblOffset=0, .boolShift = 0, .boolOffset=0};
+ -: 919:
+ #####: 920: switch(o->type) {
+branch 0 never executed
+branch 1 never executed
+branch 2 never executed
+branch 3 never executed
+branch 4 never executed
+branch 5 never executed
+branch 6 never executed
+branch 7 never executed
+branch 8 never executed
+ -: 921: case UNDEFINED:
+ -: 922: case CONTAINER:
+ #####: 923: sBytesPush(&r, NET_SERIAL_TYPES[(u8)o->type]);
+call 0 never executed
+ #####: 924: break;
+ -: 925: case BOOL: {
+ #####: 926: u8 c = NET_SERIAL_TYPES[(u8)o->type];
+ -: 927: // set bit 4 when true
+ #####: 928: if (((sBoolt *)&(o->type))->value)
+branch 0 never executed
+branch 1 never executed
+ #####: 929: c |= (1<<4);
+ #####: 930: sBytesPush(&r, c);
+call 0 never executed
+ -: 931: }
+ #####: 932: break;
+ -: 933: case DICT:
+ #####: 934: dictNetSerialLevel2(&r, (sDictt *)&(o->type), &ctx, /*packed=*/false);
+call 0 never executed
+ #####: 935: break;
+ -: 936: case DOUBLE:
+ #####: 937: sBytesPush(&r, NET_SERIAL_TYPES[(u8)o->type]);
+call 0 never executed
+ #####: 938: sBytesPushBuffer(&r, &((sDoublet *)&(o->type))->value, sizeof(double));
+call 0 never executed
+ #####: 939: break;
+ -: 940: case INT: {
+ -: 941: // encode int to varint
+ -: 942: // v is int64_t to convert to varint
+ #####: 943: i64 v = ((sIntt *)&(o->type))->value;
+ -: 944: // encode v with arithmetic shifts
+ #####: 945: uintToNetTypeVarint(&r, NET_SERIAL_TYPES[(u8)o->type], (v << 1) ^ (v >> 63));
+call 0 never executed
+ -: 946: }
+ #####: 947: break;
+ -: 948: case STRING:
+ #####: 949: sBytesPush(&r, NET_SERIAL_TYPES[(u8)o->type]);
+call 0 never executed
+ #####: 950: sBytesPushBuffer(&r, &((sStringt *)&(o->type))->data, sizeof(sStringt) + strlen(&(((sStringt *)&(o->type))->data)) -1);
+call 0 never executed
+ #####: 951: break;
+ -: 952: case ARRAY:
+ #####: 953: arrayNetSerialLevel2(&r, (sArrayt *)&(o->type), &ctx, /*packed=*/false);
+call 0 never executed
+ #####: 954: break;
+ -: 955: case BYTES:
+ #####: 956: B = (sBytest *)&(o->type);
+ #####: 957: uintToNetTypeVarint(&r, NET_SERIAL_TYPES[(u8)o->type], B->count);
+call 0 never executed
+ #####: 958: sBytesPushBuffer(&r, &(B->data), B->count);
+call 0 never executed
+ #####: 959: break;
+ -: 960: }
+ #####: 961: ret r;
+ -: 962:}
+ -: 963:
+function isDictUniform called 31 returned 100% blocks executed 69%
+ 31: 964:internal u8 isDictUniform(sDictt *dict) {
+ 31: 965: bool allElementsHaveSameType = true;
+ 31: 966: bool foundFirstType = false;
+ 31: 967: u8 type = 0;
+ 62: 968: forEachSDict(dict, e) {
+branch 0 taken 68%
+branch 1 taken 32% (fallthrough)
+ 42: 969: if (e->key) {
+branch 0 taken 100% (fallthrough)
+branch 1 taken 0%
+ 42: 970: if (foundFirstType) {
+branch 0 taken 40% (fallthrough)
+branch 1 taken 60%
+ -: 971: u8 nextType;
+ 17: 972: switch(e->data->type) {
+branch 0 taken 0%
+branch 1 taken 0%
+branch 2 taken 100%
+ -: 973: case DICT:
+ #####: 974: nextType = isDictUniform((sDictt*)e->data);
+call 0 never executed
+ #####: 975: break;
+ -: 976: case ARRAY:
+ #####: 977: nextType = isArrayUniform((sArrayt*)e->data);
+call 0 never executed
+ #####: 978: break;
+ -: 979: default:
+ 17: 980: nextType = NET_SERIAL_TYPES[(u8)e->data->type];
+ -: 981: }
+ 17: 982: if (nextType != type) {
+branch 0 taken 65% (fallthrough)
+branch 1 taken 35%
+ 11: 983: allElementsHaveSameType = false;
+ 11: 984: break;
+ -: 985: }
+ -: 986: }
+ -: 987: else {
+ 25: 988: switch(e->data->type) {
+branch 0 taken 0%
+branch 1 taken 0%
+branch 2 taken 100%
+ -: 989: case DICT:
+ #####: 990: type = isDictUniform((sDictt*)e->data);
+call 0 never executed
+ #####: 991: break;
+ -: 992: case ARRAY:
+ #####: 993: type = isArrayUniform((sArrayt*)e->data);
+call 0 never executed
+ #####: 994: break;
+ -: 995: default:
+ 25: 996: type = NET_SERIAL_TYPES[(u8)e->data->type];
+ -: 997: }
+ 25: 998: foundFirstType = true;
+ -: 999: }
+ -: 1000: }
+ -: 1001: }
+ 31: 1002: if (allElementsHaveSameType)
+branch 0 taken 65% (fallthrough)
+branch 1 taken 35%
+ 20: 1003: type = UNIFORM_DICT;
+ -: 1004: else
+ 11: 1005: type = S_DICT;
+ 31: 1006: ret type;
+ -: 1007:}
+ -: 1008:
+function isArrayUniform called 27 returned 100% blocks executed 58%
+ 27: 1009:internal u8 isArrayUniform(sArrayt *array) {
+ 27: 1010: bool allElementsHaveSameType = true;
+ 27: 1011: bool foundFirstType = false;
+ 27: 1012: char type = 0;
+ 77: 1013: forEachSArray(array, e) {
+branch 0 taken 73%
+branch 1 taken 27% (fallthrough)
+ 56: 1014: if (!e) {
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ #####: 1015: if (foundFirstType) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1016: if (type != S_UNDEFINED) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1017: allElementsHaveSameType = false;
+ #####: 1018: break;
+ -: 1019: }
+ -: 1020: }
+ -: 1021: else {
+ #####: 1022: type = S_UNDEFINED;
+ #####: 1023: foundFirstType = true;
+ -: 1024: }
+ -: 1025: }
+ -: 1026: else {
+ 56: 1027: if (foundFirstType) {
+branch 0 taken 57% (fallthrough)
+branch 1 taken 43%
+ -: 1028: u8 nextType;
+ 32: 1029: switch(e->type) {
+branch 0 taken 0%
+branch 1 taken 0%
+branch 2 taken 100%
+ -: 1030: case DICT:
+ #####: 1031: nextType = isDictUniform((sDictt*)e);
+call 0 never executed
+ #####: 1032: break;
+ -: 1033: case ARRAY:
+ #####: 1034: nextType = isArrayUniform((sArrayt*)e);
+call 0 never executed
+ #####: 1035: break;
+ -: 1036: default:
+ 32: 1037: nextType = NET_SERIAL_TYPES[(u8)e->type];
+ -: 1038: }
+ 32: 1039: if (nextType != type) {
+branch 0 taken 19% (fallthrough)
+branch 1 taken 81%
+ 6: 1040: allElementsHaveSameType = false;
+ 6: 1041: break;
+ -: 1042: }
+ -: 1043: }
+ -: 1044: else {
+ 24: 1045: switch(e->type) {
+branch 0 taken 0%
+branch 1 taken 0%
+branch 2 taken 100%
+ -: 1046: case DICT:
+ #####: 1047: type = isDictUniform((sDictt*)e);
+call 0 never executed
+ #####: 1048: break;
+ -: 1049: case ARRAY:
+ #####: 1050: type = isArrayUniform((sArrayt*)e);
+call 0 never executed
+ #####: 1051: break;
+ -: 1052: default:
+ 24: 1053: type = NET_SERIAL_TYPES[(u8)e->type];
+ -: 1054: }
+ 24: 1055: foundFirstType = true;
+ -: 1056: }
+ -: 1057: }
+ -: 1058: }
+ 27: 1059: if (allElementsHaveSameType)
+branch 0 taken 78% (fallthrough)
+branch 1 taken 22%
+ 21: 1060: type = UNIFORM_ARRAY;
+ -: 1061: else
+ 6: 1062: type = S_ARRAY;
+ 27: 1063: ret type;
+ -: 1064:}
+ -: 1065:
+ -: 1066:/**
+ -: 1067: * serialize dictionary
+ -: 1068: *
+ -: 1069: * the serialized dict is pushed to r.
+ -: 1070: * All elements are serialized recursively
+ -: 1071: *
+ -: 1072: * the data in containers is not serialized
+ -: 1073: *
+ -: 1074: * \param
+ -: 1075: * r small bytes object
+ -: 1076: * dict dictionary to serialize
+ -: 1077: */
+function dictNetSerialLevel2 called 0 returned 0% blocks executed 0%
+ #####: 1078:internal void dictNetSerialLevel2(sBytest **r, sDictt *dict, contextt *ctx, bool packed) {
+ #####: 1079: sBytest *B = NULL;
+ #####: 1080: char *data = NULL;
+ -: 1081:
+ -: 1082: // check if all elements have same type
+ #####: 1083: bool allElementsHaveSameType = true;
+ #####: 1084: bool foundFirstType = false;
+ #####: 1085: char type = 0;
+ #####: 1086: {forEachSDict(dict, e) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1087: if (e->key) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1088: if (foundFirstType) {
+branch 0 never executed
+branch 1 never executed
+ -: 1089: u8 nextType;
+ #####: 1090: switch(e->data->type) {
+branch 0 never executed
+branch 1 never executed
+branch 2 never executed
+ -: 1091: case DICT:
+ #####: 1092: nextType = isDictUniform((sDictt*)e->data);
+call 0 never executed
+ #####: 1093: break;
+ -: 1094: case ARRAY:
+ #####: 1095: nextType = isArrayUniform((sArrayt*)e->data);
+call 0 never executed
+ #####: 1096: break;
+ -: 1097: default:
+ #####: 1098: nextType = NET_SERIAL_TYPES[(u8)e->data->type];
+ -: 1099: }
+ #####: 1100: if (nextType != type) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1101: allElementsHaveSameType = false;
+ #####: 1102: break;
+ -: 1103: }
+ -: 1104: }
+ -: 1105: else {
+ #####: 1106: switch(e->data->type) {
+branch 0 never executed
+branch 1 never executed
+branch 2 never executed
+ -: 1107: case DICT:
+ #####: 1108: type = isDictUniform((sDictt*)e->data);
+call 0 never executed
+ #####: 1109: break;
+ -: 1110: case ARRAY:
+ #####: 1111: type = isArrayUniform((sArrayt*)e->data);
+call 0 never executed
+ #####: 1112: break;
+ -: 1113: default:
+ #####: 1114: type = NET_SERIAL_TYPES[(u8)e->data->type];
+ -: 1115: }
+ #####: 1116: foundFirstType = true;
+ -: 1117: }
+ -: 1118: }
+ -: 1119: }}
+ -: 1120:
+ #####: 1121: if (allElementsHaveSameType) {
+branch 0 never executed
+branch 1 never executed
+ -: 1122: // pack dictionary
+ #####: 1123: if (packed) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1124: uintToNetTypeVarint(r, type, dict->count);
+call 0 never executed
+ -: 1125: }
+ -: 1126: else {
+ #####: 1127: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1128: sBytesPush(r, (type << 4) + UNIFORM_DICT);
+call 0 never executed
+ #####: 1129: uintToVarint(r, dict->count);
+call 0 never executed
+ -: 1130: }
+ -: 1131: else {
+ -: 1132: // high nibble
+ #####: 1133: ctx->nibble = lowNbl;
+ #####: 1134: data = (char *)&((*r)->data) + ctx->nblOffset;
+ #####: 1135: *data |= UNIFORM_DICT << 4;
+ #####: 1136: uintToNetTypeVarint(r, type, dict->count);
+call 0 never executed
+ -: 1137: }
+ -: 1138: }
+ -: 1139:
+ #####: 1140: switch(type) {
+branch 0 never executed
+branch 1 never executed
+branch 2 never executed
+branch 3 never executed
+branch 4 never executed
+branch 5 never executed
+branch 6 never executed
+branch 7 never executed
+branch 8 never executed
+ -: 1141: case S_UNDEFINED:
+ #####: 1142: {forEachSDict(dict, e) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1143: if (e->key) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1144: sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+call 0 never executed
+ -: 1145: }
+ -: 1146: }}
+ -: 1147:
+ #####: 1148: break;
+ -: 1149: case S_BOOL:
+ #####: 1150: {forEachSDict(dict, e) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1151: if (e->key) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1152: sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+call 0 never executed
+ -: 1153:
+ #####: 1154: if (!ctx->boolOffset) {
+branch 0 never executed
+branch 1 never executed
+ -: 1155: // new packed bools
+ #####: 1156: storeNew8bPackedBool(e->data);
+branch 0 never executed
+branch 1 never executed
+call 2 never executed
+ -: 1157: }
+ -: 1158: else {
+ -: 1159: // there was a bool before this one, fill bits in nibbles
+ #####: 1160: if (ctx->boolShift == 8) {
+branch 0 never executed
+branch 1 never executed
+ -: 1161: // previous packed bool is full
+ -: 1162: // next byte is the new packed bools
+ #####: 1163: storeNew8bPackedBool(e->data);
+branch 0 never executed
+branch 1 never executed
+call 2 never executed
+ -: 1164: }
+ -: 1165: else {
+ #####: 1166: storeBool(e->data);
+branch 0 never executed
+branch 1 never executed
+ -: 1167: }
+ -: 1168: }
+ -: 1169: }
+ -: 1170: }}
+ #####: 1171: break;
+ -: 1172: case S_DICT:
+ -: 1173: case UNIFORM_DICT:
+ #####: 1174: {forEachSDict(dict, e) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1175: if (e->key) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1176: sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+call 0 never executed
+ #####: 1177: dictNetSerialLevel2(r, (sDictt *)(e->data), ctx, /*packed=*/true);
+call 0 never executed
+ -: 1178: }
+ -: 1179: }}
+ #####: 1180: break;
+ -: 1181: case S_DOUBLE:
+ #####: 1182: {forEachSDict(dict, e) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1183: if (e->key) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1184: sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+call 0 never executed
+ #####: 1185: sBytesPushBuffer(r, &((sDoublet *)(e->data))->value, sizeof(double));
+call 0 never executed
+ -: 1186: }
+ -: 1187: }}
+ #####: 1188: break;
+ -: 1189: case S_INT:
+ #####: 1190: {forEachSDict(dict, e) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1191: if (e->key) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1192: sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+call 0 never executed
+ #####: 1193: i64 v = ((sIntt *)(e->data))->value;
+ #####: 1194: uintToVarint(r, (v << 1) ^ (v >> 63));
+call 0 never executed
+ -: 1195: }
+ -: 1196: }}
+ #####: 1197: break;
+ -: 1198: case S_STRING:
+ #####: 1199: {forEachSDict(dict, e) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1200: if (e->key) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1201: sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+call 0 never executed
+ #####: 1202: sBytesPushBuffer(r, &((sStringt *)(e->data))->data, sizeof(sStringt) + strlen(&(((sStringt *)(e->data))->data)) -1);
+call 0 never executed
+ -: 1203: }
+ -: 1204: }}
+ #####: 1205: break;
+ -: 1206: case S_ARRAY:
+ -: 1207: case UNIFORM_ARRAY:
+ #####: 1208: {forEachSDict(dict, e) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1209: if (e->key) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1210: sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+call 0 never executed
+ #####: 1211: arrayNetSerialLevel2(r, (sArrayt *)(e->data), ctx, /*packed=*/true);
+call 0 never executed
+ -: 1212: }
+ -: 1213: }}
+ #####: 1214: break;
+ -: 1215: case S_BYTES:
+ #####: 1216: {forEachSDict(dict, e) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1217: if (e->key) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1218: sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+call 0 never executed
+ #####: 1219: B = (sBytest *)(e->data);
+ #####: 1220: uintToVarint(r, B->count);
+call 0 never executed
+ #####: 1221: sBytesPushBuffer(r, &(B->data), B->count);
+call 0 never executed
+ -: 1222: }
+ -: 1223: }}
+ #####: 1224: break;
+ -: 1225: }
+ #####: 1226: ret;
+ -: 1227: }
+ -: 1228:
+ #####: 1229: if (packed) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1230: uintToVarint(r, dict->count);
+call 0 never executed
+ -: 1231: }
+ -: 1232: else {
+ #####: 1233: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1234: uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)dict->type], dict->count);
+call 0 never executed
+ -: 1235: }
+ -: 1236: else {
+ -: 1237: // high nibble
+ -: 1238:#define storeTypeInHighNbl(o)\
+ -: 1239: ctx->nibble = lowNbl;\
+ -: 1240: data = (char *)&((*r)->data) + ctx->nblOffset;\
+ -: 1241: *data |= NET_SERIAL_TYPES[(u8)o->type] << 4
+ #####: 1242: storeTypeInHighNbl(dict);
+ #####: 1243: uintToVarint(r, dict->count);
+call 0 never executed
+ -: 1244: }
+ -: 1245: }
+ -: 1246:
+ #####: 1247: forEachSDict(dict, e) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1248: if (e->key) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1249: sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+call 0 never executed
+ -: 1250:
+ #####: 1251: switch(e->data->type) {
+branch 0 never executed
+branch 1 never executed
+branch 2 never executed
+branch 3 never executed
+branch 4 never executed
+branch 5 never executed
+branch 6 never executed
+branch 7 never executed
+branch 8 never executed
+ -: 1252: case UNDEFINED:
+ -: 1253: case CONTAINER:
+ #####: 1254: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ -: 1255: #define storeTypeOnly(o)\
+ -: 1256: sBytesPush(r, NET_SERIAL_TYPES[(u8)o->type]);\
+ -: 1257: ctx->nibble = highNbl;\
+ -: 1258: ctx->nblOffset = (*r)->count -1
+ #####: 1259: storeTypeOnly(e->data);
+call 0 never executed
+ -: 1260: }
+ -: 1261: else {
+ #####: 1262: storeTypeInHighNbl(e->data);
+ -: 1263: }
+ #####: 1264: break;
+ -: 1265: case BOOL:
+ #####: 1266: if (!ctx->boolOffset) {
+branch 0 never executed
+branch 1 never executed
+ -: 1267: // new packed bools
+ #####: 1268: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ -: 1269: #define storeNew4bPackedBool(o)\
+ -: 1270: u8 c = NET_SERIAL_TYPES[(u8)o->type];\
+ -: 1271: /* set bit 4 when true */\
+ -: 1272: if (((sBoolt *)(o))->value)\
+ -: 1273: c |= (1<<4);\
+ -: 1274: sBytesPush(r, c);\
+ -: 1275: ctx->boolShift = 5;\
+ -: 1276: ctx->boolOffset = (*r)->count -1
+ #####: 1277: storeNew4bPackedBool(e->data);
+branch 0 never executed
+branch 1 never executed
+call 2 never executed
+ -: 1278: }
+ -: 1279: else {
+ -: 1280: // high nibble, next byte is packed bools
+ #####: 1281: storeTypeInHighNbl(e->data);
+ -: 1282: #define storeNew8bPackedBool(o)\
+ -: 1283: u8 c = 0;\
+ -: 1284: if (((sBoolt *)(o))->value)\
+ -: 1285: c = 1;\
+ -: 1286: sBytesPush(r, c);\
+ -: 1287: ctx->boolShift = 1;\
+ -: 1288: ctx->boolOffset = (*r)->count -1
+ #####: 1289: storeNew8bPackedBool(e->data);
+branch 0 never executed
+branch 1 never executed
+call 2 never executed
+ -: 1290: }
+ -: 1291: }
+ -: 1292: else {
+ -: 1293: // there was a bool before this one, fill bits in nibbles
+ #####: 1294: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1295: if (ctx->boolShift == 8) {
+branch 0 never executed
+branch 1 never executed
+ -: 1296: // previous packed bool is full
+ -: 1297: // this byte is the new packed bools
+ #####: 1298: storeNew4bPackedBool(e->data);
+branch 0 never executed
+branch 1 never executed
+call 2 never executed
+ -: 1299: }
+ -: 1300: else {
+ #####: 1301: storeTypeOnly(e->data);
+call 0 never executed
+ -: 1302: #define storeBool(o)\
+ -: 1303: data = (char *)&((*r)->data) + ctx->boolOffset;\
+ -: 1304: if (((sBoolt *)(o))->value)\
+ -: 1305: *data |= 1 << ctx->boolShift;\
+ -: 1306: ctx->boolShift++
+ #####: 1307: storeBool(e->data);
+branch 0 never executed
+branch 1 never executed
+ -: 1308: }
+ -: 1309: }
+ -: 1310: else {
+ -: 1311: // high nibble
+ #####: 1312: storeTypeInHighNbl(e->data);
+ #####: 1313: if (ctx->boolShift == 8) {
+branch 0 never executed
+branch 1 never executed
+ -: 1314: // previous packed bool is full
+ -: 1315: // next byte is the new packed bools
+ #####: 1316: storeNew8bPackedBool(e->data);
+branch 0 never executed
+branch 1 never executed
+call 2 never executed
+ -: 1317: }
+ -: 1318: else {
+ #####: 1319: storeBool(e->data);
+branch 0 never executed
+branch 1 never executed
+ -: 1320: }
+ -: 1321: }
+ -: 1322: }
+ #####: 1323: break;
+ -: 1324: case DICT:
+ #####: 1325: dictNetSerialLevel2(r, (sDictt *)(e->data), ctx, /*packed=*/false);
+call 0 never executed
+ #####: 1326: break;
+ -: 1327: case DOUBLE:
+ #####: 1328: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1329: storeTypeOnly(e->data);
+call 0 never executed
+ -: 1330: }
+ -: 1331: else {
+ -: 1332: // high nibble
+ #####: 1333: storeTypeInHighNbl(e->data);
+ -: 1334: }
+ #####: 1335: sBytesPushBuffer(r, &((sDoublet *)(e->data))->value, sizeof(double));
+call 0 never executed
+ #####: 1336: break;
+ -: 1337: case INT: {
+ -: 1338: // encode int to varint
+ -: 1339: // v is int64_t to convert to varint
+ #####: 1340: i64 v = ((sIntt *)(e->data))->value;
+ #####: 1341: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ -: 1342: // encode v with arithmetic shifts
+ #####: 1343: uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)e->data->type], (v << 1) ^ (v >> 63));
+call 0 never executed
+ -: 1344: }
+ -: 1345: else {
+ -: 1346: // high nibble
+ #####: 1347: storeTypeInHighNbl(e->data);
+ #####: 1348: uintToVarint(r, (v << 1) ^ (v >> 63));
+call 0 never executed
+ -: 1349: }
+ -: 1350: }
+ #####: 1351: break;
+ -: 1352: case STRING:
+ #####: 1353: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1354: storeTypeOnly(e->data);
+call 0 never executed
+ -: 1355: }
+ -: 1356: else {
+ -: 1357: // high nibble
+ #####: 1358: storeTypeInHighNbl(e->data);
+ -: 1359: }
+ #####: 1360: sBytesPushBuffer(r, &((sStringt *)(e->data))->data, sizeof(sStringt) + strlen(&(((sStringt *)(e->data))->data)) -1);
+call 0 never executed
+ #####: 1361: break;
+ -: 1362: case ARRAY:
+ #####: 1363: arrayNetSerialLevel2(r, (sArrayt *)(e->data), ctx, /*packed=*/false);
+call 0 never executed
+ #####: 1364: break;
+ -: 1365: case BYTES:
+ #####: 1366: B = (sBytest *)(e->data);
+ #####: 1367: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1368: uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)e->data->type], B->count);
+call 0 never executed
+ -: 1369: }
+ -: 1370: else {
+ -: 1371: // high nibble
+ #####: 1372: storeTypeInHighNbl(e->data);
+ #####: 1373: uintToVarint(r, B->count);
+call 0 never executed
+ -: 1374: }
+ #####: 1375: sBytesPushBuffer(r, &(B->data), B->count);
+call 0 never executed
+ #####: 1376: break;
+ -: 1377: }
+ -: 1378: }
+ -: 1379: }
+ #####: 1380: ret;
+ -: 1381:}
+ -: 1382:
+ -: 1383:/**
+ -: 1384: * serialize array
+ -: 1385: *
+ -: 1386: * the serialized array is pushed to r.
+ -: 1387: * All elements are serialized recursively
+ -: 1388: *
+ -: 1389: * the data in containers is not serialized
+ -: 1390: *
+ -: 1391: * \param
+ -: 1392: * r small bytes object
+ -: 1393: * array to serialize
+ -: 1394: */
+function arrayNetSerialLevel2 called 0 returned 0% blocks executed 0%
+ #####: 1395:internal void arrayNetSerialLevel2(sBytest **r, sArrayt *array, contextt *ctx, bool packed) {
+ #####: 1396: sBytest *B = NULL;
+ #####: 1397: char *data = NULL;
+ -: 1398:
+ -: 1399: // check if all elements have same type
+ #####: 1400: bool allElementsHaveSameType = true;
+ #####: 1401: bool foundFirstType = false;
+ #####: 1402: char type = 0;
+ -: 1403:
+ #####: 1404: {forEachSArray(array, e) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1405: if (!e) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1406: if (foundFirstType) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1407: if (type != S_UNDEFINED) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1408: allElementsHaveSameType = false;
+ #####: 1409: break;
+ -: 1410: }
+ -: 1411: }
+ -: 1412: else {
+ #####: 1413: type = S_UNDEFINED;
+ #####: 1414: foundFirstType = true;
+ -: 1415: }
+ -: 1416: }
+ -: 1417: else {
+ #####: 1418: if (foundFirstType) {
+branch 0 never executed
+branch 1 never executed
+ -: 1419: u8 nextType;
+ #####: 1420: switch(e->type) {
+branch 0 never executed
+branch 1 never executed
+branch 2 never executed
+ -: 1421: case DICT:
+ #####: 1422: nextType = isDictUniform((sDictt*)e);
+call 0 never executed
+ #####: 1423: break;
+ -: 1424: case ARRAY:
+ #####: 1425: nextType = isArrayUniform((sArrayt*)e);
+call 0 never executed
+ #####: 1426: break;
+ -: 1427: default:
+ #####: 1428: nextType = NET_SERIAL_TYPES[(u8)e->type];
+ -: 1429: }
+ #####: 1430: if (nextType != type) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1431: allElementsHaveSameType = false;
+ #####: 1432: break;
+ -: 1433: }
+ -: 1434: }
+ -: 1435: else {
+ #####: 1436: switch(e->type) {
+branch 0 never executed
+branch 1 never executed
+branch 2 never executed
+ -: 1437: case DICT:
+ #####: 1438: type = isDictUniform((sDictt*)e);
+call 0 never executed
+ #####: 1439: break;
+ -: 1440: case ARRAY:
+ #####: 1441: type = isArrayUniform((sArrayt*)e);
+call 0 never executed
+ #####: 1442: break;
+ -: 1443: default:
+ #####: 1444: type = NET_SERIAL_TYPES[(u8)e->type];
+ -: 1445: }
+ #####: 1446: foundFirstType = true;
+ -: 1447: }
+ -: 1448: }
+ -: 1449: }}
+ -: 1450:
+ #####: 1451: if (allElementsHaveSameType) {
+branch 0 never executed
+branch 1 never executed
+ -: 1452: // pack array
+ #####: 1453: if (packed) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1454: uintToNetTypeVarint(r, type, array->count);
+call 0 never executed
+ -: 1455: }
+ -: 1456: else {
+ #####: 1457: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1458: sBytesPush(r, (type << 4) + UNIFORM_ARRAY);
+call 0 never executed
+ #####: 1459: uintToVarint(r, array->count);
+call 0 never executed
+ -: 1460: }
+ -: 1461: else {
+ -: 1462: // high nibble
+ #####: 1463: ctx->nibble = lowNbl;
+ #####: 1464: data = (char *)&((*r)->data) + ctx->nblOffset;
+ #####: 1465: *data |= UNIFORM_ARRAY << 4;
+ #####: 1466: uintToNetTypeVarint(r, type, array->count);
+call 0 never executed
+ -: 1467: }
+ -: 1468: }
+ -: 1469:
+ #####: 1470: switch(type) {
+branch 0 never executed
+branch 1 never executed
+branch 2 never executed
+branch 3 never executed
+branch 4 never executed
+branch 5 never executed
+branch 6 never executed
+branch 7 never executed
+ -: 1471: case S_BOOL:
+ #####: 1472: {forEachSArray(array, e) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1473: if (!ctx->boolOffset) {
+branch 0 never executed
+branch 1 never executed
+ -: 1474: // new packed bools
+ #####: 1475: storeNew8bPackedBool(e);
+branch 0 never executed
+branch 1 never executed
+call 2 never executed
+ -: 1476: }
+ -: 1477: else {
+ -: 1478: // there was a bool before this one, fill bits in nibbles
+ #####: 1479: if (ctx->boolShift == 8) {
+branch 0 never executed
+branch 1 never executed
+ -: 1480: // previous packed bool is full
+ -: 1481: // next byte is the new packed bools
+ #####: 1482: storeNew8bPackedBool(e);
+branch 0 never executed
+branch 1 never executed
+call 2 never executed
+ -: 1483: }
+ -: 1484: else {
+ #####: 1485: storeBool(e);
+branch 0 never executed
+branch 1 never executed
+ -: 1486: }
+ -: 1487: }
+ -: 1488: }}
+ #####: 1489: break;
+ -: 1490: case S_DICT:
+ -: 1491: case UNIFORM_DICT:
+ #####: 1492: {forEachSArray(array, e) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1493: dictNetSerialLevel2(r, (sDictt *)e, ctx, /*packed=*/true);
+call 0 never executed
+ -: 1494: }}
+ #####: 1495: break;
+ -: 1496: case S_DOUBLE:
+ #####: 1497: {forEachSArray(array, e) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1498: sBytesPushBuffer(r, &((sDoublet *)e)->value, sizeof(double));
+call 0 never executed
+ -: 1499: }}
+ #####: 1500: break;
+ -: 1501: case S_INT:
+ #####: 1502: {forEachSArray(array, e) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1503: i64 v = ((sIntt *)e)->value;
+ #####: 1504: uintToVarint(r, (v << 1) ^ (v >> 63));
+call 0 never executed
+ -: 1505: }}
+ #####: 1506: break;
+ -: 1507: case S_STRING:
+ #####: 1508: {forEachSArray(array, e) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1509: sBytesPushBuffer(r, &((sStringt *)e)->data, sizeof(sStringt) + strlen(&(((sStringt *)e)->data)) -1);
+call 0 never executed
+ -: 1510: }}
+ #####: 1511: break;
+ -: 1512: case S_ARRAY:
+ -: 1513: case UNIFORM_ARRAY:
+ #####: 1514: {forEachSArray(array, e) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1515: arrayNetSerialLevel2(r, (sArrayt *)e, ctx, /*packed=*/true);
+call 0 never executed
+ -: 1516: }}
+ #####: 1517: break;
+ -: 1518: case S_BYTES:
+ #####: 1519: {forEachSArray(array, e) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1520: B = (sBytest *)e;
+ #####: 1521: uintToVarint(r, B->count);
+call 0 never executed
+ #####: 1522: sBytesPushBuffer(r, &(B->data), B->count);
+call 0 never executed
+ -: 1523: }}
+ #####: 1524: break;
+ -: 1525: }
+ #####: 1526: ret;
+ -: 1527: }
+ -: 1528:
+ #####: 1529: if (packed) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1530: uintToVarint(r, array->count);
+call 0 never executed
+ -: 1531: }
+ -: 1532: else {
+ #####: 1533: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1534: uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)array->type], array->count);
+call 0 never executed
+ -: 1535: }
+ -: 1536: else {
+ -: 1537: // high nibble
+ #####: 1538: storeTypeInHighNbl(array);
+ #####: 1539: uintToVarint(r, array->count);
+call 0 never executed
+ -: 1540: }
+ -: 1541: }
+ -: 1542:
+ #####: 1543: forEachSArray(array, e) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1544: if (!e) {
+branch 0 never executed
+branch 1 never executed
+ -: 1545: // empty slots are represented as undefined elements
+ #####: 1546: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1547: sBytesPush(r, NET_SERIAL_TYPES[UNDEFINED]);
+call 0 never executed
+ #####: 1548: ctx->nibble = highNbl;
+ #####: 1549: ctx->nblOffset = (*r)->count -1;
+ -: 1550: }
+ -: 1551: else {
+ -: 1552: // high nibble
+ #####: 1553: ctx->nibble = lowNbl;
+ #####: 1554: data = (char *)&((*r)->data) + ctx->nblOffset;
+ #####: 1555: *data |= NET_SERIAL_TYPES[UNDEFINED] << 4;
+ -: 1556: }
+ -: 1557: }
+ -: 1558: else {
+ #####: 1559: switch(e->type) {
+branch 0 never executed
+branch 1 never executed
+branch 2 never executed
+branch 3 never executed
+branch 4 never executed
+branch 5 never executed
+branch 6 never executed
+branch 7 never executed
+branch 8 never executed
+ -: 1560: case UNDEFINED:
+ -: 1561: case CONTAINER:
+ #####: 1562: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1563: storeTypeOnly(e);
+call 0 never executed
+ -: 1564: }
+ -: 1565: else {
+ -: 1566: // high nibble
+ #####: 1567: storeTypeInHighNbl(e);
+ -: 1568: }
+ #####: 1569: break;
+ -: 1570: case BOOL:
+ #####: 1571: if (!ctx->boolOffset) {
+branch 0 never executed
+branch 1 never executed
+ -: 1572: // new packed bools
+ #####: 1573: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1574: storeNew4bPackedBool(e);
+branch 0 never executed
+branch 1 never executed
+call 2 never executed
+ -: 1575: }
+ -: 1576: else {
+ -: 1577: // high nibble, next byte is packed bools
+ #####: 1578: storeTypeInHighNbl(e);
+ #####: 1579: storeNew8bPackedBool(e);
+branch 0 never executed
+branch 1 never executed
+call 2 never executed
+ -: 1580: }
+ -: 1581: }
+ -: 1582: else {
+ -: 1583: // there was a bool before this one, fill bits in nibbles
+ #####: 1584: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1585: if (ctx->boolShift == 8) {
+branch 0 never executed
+branch 1 never executed
+ -: 1586: // previous packed bool is full
+ -: 1587: // this byte is the new packed bools
+ #####: 1588: storeNew4bPackedBool(e);
+branch 0 never executed
+branch 1 never executed
+call 2 never executed
+ -: 1589: }
+ -: 1590: else {
+ #####: 1591: storeTypeOnly(e);
+call 0 never executed
+ #####: 1592: storeBool(e);
+branch 0 never executed
+branch 1 never executed
+ -: 1593: }
+ -: 1594: }
+ -: 1595: else {
+ -: 1596: // high nibble
+ #####: 1597: storeTypeInHighNbl(e);
+ #####: 1598: if (ctx->boolShift == 8) {
+branch 0 never executed
+branch 1 never executed
+ -: 1599: // previous packed bool is full
+ -: 1600: // next byte is the new packed bools
+ #####: 1601: storeNew8bPackedBool(e);
+branch 0 never executed
+branch 1 never executed
+call 2 never executed
+ -: 1602: }
+ -: 1603: else {
+ #####: 1604: storeBool(e);
+branch 0 never executed
+branch 1 never executed
+ -: 1605: }
+ -: 1606: }
+ -: 1607: }
+ #####: 1608: break;
+ -: 1609: case DICT:
+ #####: 1610: dictNetSerialLevel2(r, (sDictt *)e, ctx, /*packed=*/false);
+call 0 never executed
+ #####: 1611: break;
+ -: 1612: case DOUBLE:
+ #####: 1613: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1614: storeTypeOnly(e);
+call 0 never executed
+ -: 1615: }
+ -: 1616: else {
+ -: 1617: // high nibble
+ #####: 1618: storeTypeInHighNbl(e);
+ -: 1619: }
+ #####: 1620: sBytesPushBuffer(r, &((sDoublet *)e)->value, sizeof(double));
+call 0 never executed
+ #####: 1621: break;
+ -: 1622: case INT: {
+ -: 1623: // encode int to varint
+ -: 1624: // v is int64_t to convert to varint
+ #####: 1625: i64 v = ((sIntt *)&(e->type))->value;
+ #####: 1626: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ -: 1627: // encode v with arithmetic shifts
+ #####: 1628: uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)e->type], (v << 1) ^ (v >> 63));
+call 0 never executed
+ -: 1629: }
+ -: 1630: else {
+ -: 1631: // high nibble
+ #####: 1632: storeTypeInHighNbl(e);
+ #####: 1633: uintToVarint(r, (v << 1) ^ (v >> 63));
+call 0 never executed
+ -: 1634: }
+ -: 1635: }
+ #####: 1636: break;
+ -: 1637: case STRING:
+ #####: 1638: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1639: storeTypeOnly(e);
+call 0 never executed
+ -: 1640: }
+ -: 1641: else {
+ -: 1642: // high nibble
+ #####: 1643: storeTypeInHighNbl(e);
+ -: 1644: }
+ #####: 1645: sBytesPushBuffer(r, &((sStringt *)e)->data, sizeof(sStringt) + strlen(&(((sStringt *)e)->data)) -1);
+call 0 never executed
+ #####: 1646: break;
+ -: 1647: case ARRAY:
+ #####: 1648: arrayNetSerialLevel2(r, (sArrayt *)e, ctx, /*packed=*/false);
+call 0 never executed
+ #####: 1649: break;
+ -: 1650: case BYTES:
+ #####: 1651: B = (sBytest *)e;
+ #####: 1652: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1653: uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)e->type], B->count);
+call 0 never executed
+ -: 1654: }
+ -: 1655: else {
+ -: 1656: // high nibble
+ #####: 1657: storeTypeInHighNbl(e);
+ #####: 1658: uintToVarint(r, B->count);
+call 0 never executed
+ -: 1659: }
+ #####: 1660: sBytesPushBuffer(r, &(B->data), B->count);
+call 0 never executed
+ #####: 1661: break;
+ -: 1662: }
+ -: 1663: }
+ -: 1664: }
+ #####: 1665: ret;
+ -: 1666:}
+ -: 1667:
+function serialNetSerialLevel2 called 0 returned 0% blocks executed 0%
+ #####: 1668:internal smallBytest* serialNetSerialLevel2(smallJsont *self) {
+ -: 1669:
+ #####: 1670: smallt *o = getsoG(self);
+call 0 never executed
+ -: 1671:
+ #####: 1672: if (o == NULL)
+branch 0 never executed
+branch 1 never executed
+ #####: 1673: ret NULL;
+ -: 1674:
+ #####: 1675: sBytest *B = netSerialLevel2(o);
+call 0 never executed
+ -: 1676:
+ #####: 1677: if (!B) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1678: ret NULL;
+ -: 1679: }
+ -: 1680:
+ #####: 1681: createAllocateSmallBytes(r);
+call 0 never executed
+ #####: 1682: r->B = B;
+ #####: 1683: ret r;
+ -: 1684:}
+ -: 1685:
+ -: 1686:// level 3
+ -: 1687:
+function netSerial called 76 returned 100% blocks executed 88%
+ 76: 1688:internal sBytest* netSerial(smallt *o) {
+ 76: 1689: sBytest *r = NULL;
+ 76: 1690: sBytest *B = NULL;
+ 76: 1691: contextt ctx = {.nibble=lowNbl, .nblOffset=0, .boolShift = 0, .boolOffset=0};
+ -: 1692:
+ 76: 1693: switch(o->type) {
+branch 0 taken 1%
+branch 1 taken 1%
+branch 2 taken 47%
+branch 3 taken 1%
+branch 4 taken 1%
+branch 5 taken 1%
+branch 6 taken 46%
+branch 7 taken 0%
+branch 8 taken 0%
+ -: 1694: case UNDEFINED:
+ -: 1695: case CONTAINER:
+ 1: 1696: sBytesPush(&r, NET_SERIAL_TYPES[(u8)o->type]);
+call 0 returned 100%
+ 1: 1697: break;
+ -: 1698: case BOOL: {
+ 1: 1699: u8 c = NET_SERIAL_TYPES[(u8)o->type];
+ -: 1700: // set bit 4 when true
+ 1: 1701: if (((sBoolt *)&(o->type))->value)
+branch 0 taken 100% (fallthrough)
+branch 1 taken 0%
+ 1: 1702: c |= (1<<4);
+ 1: 1703: sBytesPush(&r, c);
+call 0 returned 100%
+ -: 1704: }
+ 1: 1705: break;
+ -: 1706: case DICT:
+ 36: 1707: dictNetSerial(&r, (sDictt *)&(o->type), &ctx, /*packing=*/NOPACKING);
+call 0 returned 100%
+ 36: 1708: break;
+ -: 1709: case DOUBLE:
+ 1: 1710: sBytesPush(&r, NET_SERIAL_TYPES[(u8)o->type]);
+call 0 returned 100%
+ 1: 1711: sBytesPushBuffer(&r, &((sDoublet *)&(o->type))->value, sizeof(double));
+call 0 returned 100%
+ 1: 1712: break;
+ -: 1713: case INT: {
+ -: 1714: // encode int to varint
+ -: 1715: // v is int64_t to convert to varint
+ 1: 1716: i64 v = ((sIntt *)&(o->type))->value;
+ -: 1717: // encode v with arithmetic shifts
+ 1: 1718: uintToNetTypeVarint(&r, NET_SERIAL_TYPES[(u8)o->type], (v << 1) ^ (v >> 63));
+call 0 returned 100%
+ -: 1719: }
+ 1: 1720: break;
+ -: 1721: case STRING:
+ 1: 1722: sBytesPush(&r, NET_SERIAL_TYPES[(u8)o->type]);
+call 0 returned 100%
+ 1: 1723: sBytesPushBuffer(&r, &((sStringt *)&(o->type))->data, sizeof(sStringt) + strlen(&(((sStringt *)&(o->type))->data)) -1);
+call 0 returned 100%
+ 1: 1724: break;
+ -: 1725: case ARRAY:
+ 35: 1726: arrayNetSerial(&r, (sArrayt *)&(o->type), &ctx, /*packing=*/NOPACKING);
+call 0 returned 100%
+ 35: 1727: break;
+ -: 1728: case BYTES:
+ #####: 1729: B = (sBytest *)&(o->type);
+ #####: 1730: uintToNetTypeVarint(&r, NET_SERIAL_TYPES[(u8)o->type], B->count);
+call 0 never executed
+ #####: 1731: sBytesPushBuffer(&r, &(B->data), B->count);
+call 0 never executed
+ #####: 1732: break;
+ -: 1733: }
+ 76: 1734: ret r;
+ -: 1735:}
+ -: 1736:
+ -: 1737:/**
+ -: 1738: * serialize dictionary
+ -: 1739: *
+ -: 1740: * the serialized dict is pushed to r.
+ -: 1741: * All elements are serialized recursively
+ -: 1742: *
+ -: 1743: * the data in containers is not serialized
+ -: 1744: *
+ -: 1745: * \param
+ -: 1746: * r small bytes object
+ -: 1747: * dict dictionary to serialize
+ -: 1748: */
+function dictNetSerial called 76 returned 100% blocks executed 91%
+ 76: 1749:internal void dictNetSerial(sBytest **r, sDictt *dict, contextt *ctx, packingT packing) {
+ 76: 1750: sBytest *B = NULL;
+ 76: 1751: char *data = NULL;
+ -: 1752:
+ -: 1753: // check if all elements have same type
+ 76: 1754: bool allElementsHaveSameType = true;
+ 76: 1755: bool foundFirstType = false;
+ 76: 1756: char type = 0;
+ 194: 1757: {forEachSDict(dict, e) {
+branch 0 taken 79%
+branch 1 taken 21% (fallthrough)
+ 154: 1758: if (e->key) {
+branch 0 taken 100% (fallthrough)
+branch 1 taken 0%
+ 154: 1759: if (foundFirstType) {
+branch 0 taken 58% (fallthrough)
+branch 1 taken 42%
+ -: 1760: u8 nextType;
+ 89: 1761: switch(e->data->type) {
+branch 0 taken 17%
+branch 1 taken 9%
+branch 2 taken 74%
+ -: 1762: case DICT:
+ 15: 1763: nextType = isDictUniform((sDictt*)e->data);
+call 0 returned 100%
+ 15: 1764: break;
+ -: 1765: case ARRAY:
+ 8: 1766: nextType = isArrayUniform((sArrayt*)e->data);
+call 0 returned 100%
+ 8: 1767: break;
+ -: 1768: default:
+ 66: 1769: nextType = NET_SERIAL_TYPES[(u8)e->data->type];
+ -: 1770: }
+ 89: 1771: if (nextType != type) {
+branch 0 taken 40% (fallthrough)
+branch 1 taken 60%
+ 36: 1772: allElementsHaveSameType = false;
+ 36: 1773: break;
+ -: 1774: }
+ -: 1775: }
+ -: 1776: else {
+ 65: 1777: switch(e->data->type) {
+branch 0 taken 8%
+branch 1 taken 5%
+branch 2 taken 88%
+ -: 1778: case DICT:
+ 5: 1779: type = isDictUniform((sDictt*)e->data);
+call 0 returned 100%
+ 5: 1780: break;
+ -: 1781: case ARRAY:
+ 3: 1782: type = isArrayUniform((sArrayt*)e->data);
+call 0 returned 100%
+ 3: 1783: break;
+ -: 1784: default:
+ 57: 1785: type = NET_SERIAL_TYPES[(u8)e->data->type];
+ -: 1786: }
+ 65: 1787: foundFirstType = true;
+ -: 1788: }
+ -: 1789: }
+ -: 1790: }}
+ -: 1791:
+ 76: 1792: if (allElementsHaveSameType) {
+branch 0 taken 53% (fallthrough)
+branch 1 taken 47%
+ -: 1793: // pack dictionary
+ 40: 1794: if (packing == PACKED) {
+branch 0 taken 45% (fallthrough)
+branch 1 taken 55%
+ -: 1795: // uniform dict can't be packed
+ -: 1796: // because there is only one type of packed arrays
+ 18: 1797: goto normalDict;
+ -: 1798: }
+ 22: 1799: elif (packing == UNIFORM) {
+branch 0 taken 18% (fallthrough)
+branch 1 taken 82%
+ 4: 1800: uintToNetTypeVarint(r, type, dict->count);
+call 0 returned 100%
+ -: 1801: }
+ -: 1802: else {
+ 18: 1803: if (ctx->nibble == lowNbl) {
+branch 0 taken 94% (fallthrough)
+branch 1 taken 6%
+ 17: 1804: sBytesPush(r, (type << 4) + UNIFORM_DICT);
+call 0 returned 100%
+ 17: 1805: uintToVarint(r, dict->count);
+call 0 returned 100%
+ -: 1806: }
+ -: 1807: else {
+ -: 1808: // high nibble
+ 1: 1809: ctx->nibble = lowNbl;
+ 1: 1810: data = (char *)&((*r)->data) + ctx->nblOffset;
+ 1: 1811: *data |= UNIFORM_DICT << 4;
+ 1: 1812: uintToNetTypeVarint(r, type, dict->count);
+call 0 returned 100%
+ -: 1813: }
+ -: 1814: }
+ -: 1815:
+ 22: 1816: switch(type) {
+branch 0 taken 9%
+branch 1 taken 18%
+branch 2 taken 9%
+branch 3 taken 5%
+branch 4 taken 27%
+branch 5 taken 23%
+branch 6 taken 9%
+branch 7 taken 0%
+branch 8 taken 0%
+ -: 1817: case S_UNDEFINED:
+ 8: 1818: {forEachSDict(dict, e) {
+branch 0 taken 75%
+branch 1 taken 25% (fallthrough)
+ 6: 1819: if (e->key) {
+branch 0 taken 100% (fallthrough)
+branch 1 taken 0%
+ 6: 1820: sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+call 0 returned 100%
+ -: 1821: }
+ -: 1822: }}
+ -: 1823:
+ 2: 1824: break;
+ -: 1825: case S_BOOL:
+ 19: 1826: {forEachSDict(dict, e) {
+branch 0 taken 79%
+branch 1 taken 21% (fallthrough)
+ 15: 1827: if (e->key) {
+branch 0 taken 100% (fallthrough)
+branch 1 taken 0%
+ 15: 1828: sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+call 0 returned 100%
+ -: 1829:
+ 15: 1830: if (!ctx->boolOffset) {
+branch 0 taken 20% (fallthrough)
+branch 1 taken 80%
+ -: 1831: // new packed bools
+ 3: 1832: storeNew8bPackedBool(e->data);
+branch 0 taken 100% (fallthrough)
+branch 1 taken 0%
+call 2 returned 100%
+ -: 1833: }
+ -: 1834: else {
+ -: 1835: // there was a bool before this one, fill bits in nibbles
+ 12: 1836: if (ctx->boolShift == 8) {
+branch 0 taken 8% (fallthrough)
+branch 1 taken 92%
+ -: 1837: // previous packed bool is full
+ -: 1838: // next byte is the new packed bools
+ 1: 1839: storeNew8bPackedBool(e->data);
+branch 0 taken 100% (fallthrough)
+branch 1 taken 0%
+call 2 returned 100%
+ -: 1840: }
+ -: 1841: else {
+ 11: 1842: storeBool(e->data);
+branch 0 taken 91% (fallthrough)
+branch 1 taken 9%
+ -: 1843: }
+ -: 1844: }
+ -: 1845: }
+ -: 1846: }}
+ 4: 1847: break;
+ -: 1848: case S_DICT:
+ -: 1849: case UNIFORM_DICT:
+ 6: 1850: {forEachSDict(dict, e) {
+branch 0 taken 67%
+branch 1 taken 33% (fallthrough)
+ 4: 1851: if (e->key) {
+branch 0 taken 100% (fallthrough)
+branch 1 taken 0%
+ 4: 1852: sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+call 0 returned 100%
+ 4: 1853: dictNetSerial(r, (sDictt *)(e->data), ctx, /*packing=*/UNIFORM);
+call 0 returned 100%
+ -: 1854: }
+ -: 1855: }}
+ 2: 1856: break;
+ -: 1857: case S_DOUBLE:
+ 4: 1858: {forEachSDict(dict, e) {
+branch 0 taken 75%
+branch 1 taken 25% (fallthrough)
+ 3: 1859: if (e->key) {
+branch 0 taken 100% (fallthrough)
+branch 1 taken 0%
+ 3: 1860: sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+call 0 returned 100%
+ 3: 1861: sBytesPushBuffer(r, &((sDoublet *)(e->data))->value, sizeof(double));
+call 0 returned 100%
+ -: 1862: }
+ -: 1863: }}
+ 1: 1864: break;
+ -: 1865: case S_INT:
+ 15: 1866: {forEachSDict(dict, e) {
+branch 0 taken 60%
+branch 1 taken 40% (fallthrough)
+ 9: 1867: if (e->key) {
+branch 0 taken 100% (fallthrough)
+branch 1 taken 0%
+ 9: 1868: sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+call 0 returned 100%
+ 9: 1869: i64 v = ((sIntt *)(e->data))->value;
+ 9: 1870: uintToVarint(r, (v << 1) ^ (v >> 63));
+call 0 returned 100%
+ -: 1871: }
+ -: 1872: }}
+ 6: 1873: break;
+ -: 1874: case S_STRING:
+ 16: 1875: {forEachSDict(dict, e) {
+branch 0 taken 69%
+branch 1 taken 31% (fallthrough)
+ 11: 1876: if (e->key) {
+branch 0 taken 100% (fallthrough)
+branch 1 taken 0%
+ 11: 1877: sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+call 0 returned 100%
+ 11: 1878: sBytesPushBuffer(r, &((sStringt *)(e->data))->data, sizeof(sStringt) + strlen(&(((sStringt *)(e->data))->data)) -1);
+call 0 returned 100%
+ -: 1879: }
+ -: 1880: }}
+ 5: 1881: break;
+ -: 1882: case S_ARRAY:
+ -: 1883: case UNIFORM_ARRAY:
+ 4: 1884: {forEachSDict(dict, e) {
+branch 0 taken 50%
+branch 1 taken 50% (fallthrough)
+ 2: 1885: if (e->key) {
+branch 0 taken 100% (fallthrough)
+branch 1 taken 0%
+ 2: 1886: sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+call 0 returned 100%
+ 2: 1887: arrayNetSerial(r, (sArrayt *)(e->data), ctx, /*packing=*/UNIFORM);
+call 0 returned 100%
+ -: 1888: }
+ -: 1889: }}
+ 2: 1890: break;
+ -: 1891: case S_BYTES:
+ #####: 1892: {forEachSDict(dict, e) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1893: if (e->key) {
+branch 0 never executed
+branch 1 never executed
+ #####: 1894: sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+call 0 never executed
+ #####: 1895: B = (sBytest *)(e->data);
+ #####: 1896: uintToVarint(r, B->count);
+call 0 never executed
+ #####: 1897: sBytesPushBuffer(r, &(B->data), B->count);
+call 0 never executed
+ -: 1898: }
+ -: 1899: }}
+ #####: 1900: break;
+ -: 1901: }
+ 22: 1902: ret;
+ -: 1903: }
+ -: 1904:
+ -: 1905: normalDict:
+ 54: 1906: if (packing == PACKED or packing == UNIFORM) {
+branch 0 taken 57% (fallthrough)
+branch 1 taken 43%
+branch 2 taken 13% (fallthrough)
+branch 3 taken 87%
+ 27: 1907: uintToVarint(r, dict->count);
+call 0 returned 100%
+ -: 1908: }
+ -: 1909: else {
+ 27: 1910: if (ctx->nibble == lowNbl) {
+branch 0 taken 93% (fallthrough)
+branch 1 taken 7%
+ 25: 1911: uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)dict->type], dict->count);
+call 0 returned 100%
+ -: 1912: }
+ -: 1913: else {
+ -: 1914: // high nibble
+ -: 1915: #define storeTypeInHighNbl(o)\
+ -: 1916: ctx->nibble = lowNbl;\
+ -: 1917: data = (char *)&((*r)->data) + ctx->nblOffset;\
+ -: 1918: *data |= NET_SERIAL_TYPES[(u8)o->type] << 4
+ 2: 1919: storeTypeInHighNbl(dict);
+ 2: 1920: uintToVarint(r, dict->count);
+call 0 returned 100%
+ -: 1921: }
+ -: 1922: }
+ -: 1923:
+ 54: 1924: bool pack = false;
+ -: 1925: size_t packCount;
+ 210: 1926: enumerateSDict(dict, e, eIdx) {
+branch 0 taken 74%
+branch 1 taken 26% (fallthrough)
+ 156: 1927: if (e->key) {
+branch 0 taken 100% (fallthrough)
+branch 1 taken 0%
+ 156: 1928: if (!pack) {
+branch 0 taken 76% (fallthrough)
+branch 1 taken 24%
+ -: 1929: // scan dict for packing
+ 118: 1930: if ((dict->count - eIdx) > 3) {
+branch 0 taken 35% (fallthrough)
+branch 1 taken 65%
+ -: 1931: // at least 4 elements, less than that is not worth it
+ 41: 1932: if ( e->data->type == DICT
+branch 0 taken 93% (fallthrough)
+branch 1 taken 7%
+ 38: 1933: or e->data->type == DOUBLE
+branch 0 taken 95% (fallthrough)
+branch 1 taken 5%
+ 36: 1934: or e->data->type == INT
+branch 0 taken 94% (fallthrough)
+branch 1 taken 6%
+ 34: 1935: or e->data->type == STRING
+branch 0 taken 94% (fallthrough)
+branch 1 taken 6%
+ 32: 1936: or e->data->type == ARRAY
+branch 0 taken 94% (fallthrough)
+branch 1 taken 6%
+ 30: 1937: or e->data->type == BYTES) {
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ 11: 1938: type = e->data->type;
+ 11: 1939: packCount = 1;
+ 11: 1940: sDictElemt *element = &((dict)->elements) + eIdx;
+ 49: 1941: for (size_t i = eIdx+1; i < (dict)->count ; i++, element = &((dict)->elements) + i) {
+branch 0 taken 100%
+branch 1 taken 0% (fallthrough)
+ 49: 1942: if (element->key) {
+branch 0 taken 100% (fallthrough)
+branch 1 taken 0%
+ 49: 1943: if (element->data->type != type) {
+branch 0 taken 22% (fallthrough)
+branch 1 taken 78%
+ 11: 1944: break;
+ -: 1945: }
+ 38: 1946: packCount++;
+ -: 1947: } // element->key
+ -: 1948: } // for
+ 11: 1949: if (packCount > 3) {
+branch 0 taken 100% (fallthrough)
+branch 1 taken 0%
+ 11: 1950: type = PACKED_NET_SERIAL_TYPES[(u8)type];
+ 11: 1951: pack = true;
+ -: 1952: }
+ -: 1953: } // test current element type
+ -: 1954: } // is dict big enough
+ -: 1955: } // not already packing
+ -: 1956:
+ 156: 1957: sBytesPushBuffer(r, e->key, strlen(e->key) + 1);
+call 0 returned 100%
+ -: 1958:
+ 156: 1959: switch(e->data->type) {
+branch 0 taken 17%
+branch 1 taken 20%
+branch 2 taken 13%
+branch 3 taken 8%
+branch 4 taken 21%
+branch 5 taken 14%
+branch 6 taken 8%
+branch 7 taken 0%
+branch 8 taken 0%
+ -: 1960: case UNDEFINED:
+ -: 1961: case CONTAINER:
+ 26: 1962: if (ctx->nibble == lowNbl) {
+branch 0 taken 92% (fallthrough)
+branch 1 taken 8%
+ -: 1963: #define storeTypeOnly(o)\
+ -: 1964: sBytesPush(r, NET_SERIAL_TYPES[(u8)o->type]);\
+ -: 1965: ctx->nibble = highNbl;\
+ -: 1966: ctx->nblOffset = (*r)->count -1
+ 24: 1967: storeTypeOnly(e->data);
+call 0 returned 100%
+ -: 1968: }
+ -: 1969: else {
+ 2: 1970: storeTypeInHighNbl(e->data);
+ -: 1971: }
+ 26: 1972: break;
+ -: 1973: case BOOL:
+ 31: 1974: if (!ctx->boolOffset) {
+branch 0 taken 16% (fallthrough)
+branch 1 taken 84%
+ -: 1975: // new packed bools
+ 5: 1976: if (ctx->nibble == lowNbl) {
+branch 0 taken 60% (fallthrough)
+branch 1 taken 40%
+ -: 1977: #define storeNew4bPackedBool(o)\
+ -: 1978: u8 c = NET_SERIAL_TYPES[(u8)o->type];\
+ -: 1979: /* set bit 4 when true */\
+ -: 1980: if (((sBoolt *)(o))->value)\
+ -: 1981: c |= (1<<4);\
+ -: 1982: sBytesPush(r, c);\
+ -: 1983: ctx->boolShift = 5;\
+ -: 1984: ctx->boolOffset = (*r)->count -1
+ 3: 1985: storeNew4bPackedBool(e->data);
+branch 0 taken 100% (fallthrough)
+branch 1 taken 0%
+call 2 returned 100%
+ -: 1986: }
+ -: 1987: else {
+ -: 1988: // high nibble, next byte is packed bools
+ 2: 1989: storeTypeInHighNbl(e->data);
+ -: 1990: #define storeNew8bPackedBool(o)\
+ -: 1991: u8 c = 0;\
+ -: 1992: if (((sBoolt *)(o))->value)\
+ -: 1993: c = 1;\
+ -: 1994: sBytesPush(r, c);\
+ -: 1995: ctx->boolShift = 1;\
+ -: 1996: ctx->boolOffset = (*r)->count -1
+ 2: 1997: storeNew8bPackedBool(e->data);
+branch 0 taken 100% (fallthrough)
+branch 1 taken 0%
+call 2 returned 100%
+ -: 1998: }
+ -: 1999: }
+ -: 2000: else {
+ -: 2001: // there was a bool before this one, fill bits in nibbles
+ 26: 2002: if (ctx->nibble == lowNbl) {
+branch 0 taken 58% (fallthrough)
+branch 1 taken 42%
+ 15: 2003: if (ctx->boolShift == 8) {
+branch 0 taken 7% (fallthrough)
+branch 1 taken 93%
+ -: 2004: // previous packed bool is full
+ -: 2005: // this byte is the new packed bools
+ 1: 2006: storeNew4bPackedBool(e->data);
+branch 0 taken 100% (fallthrough)
+branch 1 taken 0%
+call 2 returned 100%
+ -: 2007: }
+ -: 2008: else {
+ 14: 2009: storeTypeOnly(e->data);
+call 0 returned 100%
+ -: 2010: #define storeBool(o)\
+ -: 2011: data = (char *)&((*r)->data) + ctx->boolOffset;\
+ -: 2012: if (((sBoolt *)(o))->value)\
+ -: 2013: *data |= 1 << ctx->boolShift;\
+ -: 2014: ctx->boolShift++
+ 14: 2015: storeBool(e->data);
+branch 0 taken 100% (fallthrough)
+branch 1 taken 0%
+ -: 2016: }
+ -: 2017: }
+ -: 2018: else {
+ -: 2019: // high nibble
+ 11: 2020: storeTypeInHighNbl(e->data);
+ 11: 2021: if (ctx->boolShift == 8) {
+branch 0 taken 18% (fallthrough)
+branch 1 taken 82%
+ -: 2022: // previous packed bool is full
+ -: 2023: // next byte is the new packed bools
+ 2: 2024: storeNew8bPackedBool(e->data);
+branch 0 taken 100% (fallthrough)
+branch 1 taken 0%
+call 2 returned 100%
+ -: 2025: }
+ -: 2026: else {
+ 9: 2027: storeBool(e->data);
+branch 0 taken 100% (fallthrough)
+branch 1 taken 0%
+ -: 2028: }
+ -: 2029: }
+ -: 2030: }
+ 31: 2031: break;
+ -: 2032: case DICT:
+ 20: 2033: if (pack) {
+branch 0 taken 75% (fallthrough)
+branch 1 taken 25%
+ 15: 2034: if (type) {
+branch 0 taken 20% (fallthrough)
+branch 1 taken 80%
+ -: 2035: // this is the first packed element
+ 3: 2036: if (ctx->nibble == lowNbl) {
+branch 0 taken 67% (fallthrough)
+branch 1 taken 33%
+ 2: 2037: uintToNetTypeVarint(r, type, packCount);
+call 0 returned 100%
+ -: 2038: }
+ -: 2039: else {
+ -: 2040: // high nibble
+ -: 2041: // store type in high nibble
+ 1: 2042: ctx->nibble = lowNbl;
+ 1: 2043: data = (char *)&((*r)->data) + ctx->nblOffset;
+ 1: 2044: *data |= type << 4;
+ 1: 2045: uintToVarint(r, packCount);
+call 0 returned 100%
+ -: 2046: }
+ 3: 2047: type = 0;
+ -: 2048: } // if type
+ -: 2049:
+ 15: 2050: dictNetSerial(r, (sDictt *)(e->data), ctx, /*packing=*/PACKED);
+call 0 returned 100%
+ -: 2051: // stop packing when packCount == 0
+ 15: 2052: packCount--;
+ 15: 2053: if (!packCount) pack = false;
+branch 0 taken 20% (fallthrough)
+branch 1 taken 80%
+ -: 2054: } // if pack
+ -: 2055: else
+ 5: 2056: dictNetSerial(r, (sDictt *)(e->data), ctx, /*packing=*/NOPACKING);
+call 0 returned 100%
+ 20: 2057: break;
+ -: 2058: case DOUBLE:
+ 12: 2059: if (pack) {
+branch 0 taken 83% (fallthrough)
+branch 1 taken 17%
+ 10: 2060: if (type) {
+branch 0 taken 20% (fallthrough)
+branch 1 taken 80%
+ -: 2061: // this is the first packed element
+ 2: 2062: if (ctx->nibble == lowNbl) {
+branch 0 taken 50% (fallthrough)
+branch 1 taken 50%
+ 1: 2063: uintToNetTypeVarint(r, type, packCount);
+call 0 returned 100%
+ -: 2064: }
+ -: 2065: else {
+ -: 2066: // high nibble
+ -: 2067: // store type in high nibble
+ 1: 2068: ctx->nibble = lowNbl;
+ 1: 2069: data = (char *)&((*r)->data) + ctx->nblOffset;
+ 1: 2070: *data |= type << 4;
+ 1: 2071: uintToVarint(r, packCount);
+call 0 returned 100%
+ -: 2072: }
+ 2: 2073: type = 0;
+ -: 2074: } // if type
+ -: 2075:
+ 10: 2076: sBytesPushBuffer(r, &((sDoublet *)(e->data))->value, sizeof(double));
+call 0 returned 100%
+ -: 2077: // stop packing when packCount == 0
+ 10: 2078: packCount--;
+ 10: 2079: if (!packCount) pack = false;
+branch 0 taken 20% (fallthrough)
+branch 1 taken 80%
+ -: 2080: } // if pack
+ -: 2081: else {
+ 2: 2082: if (ctx->nibble == lowNbl) {
+branch 0 taken 50% (fallthrough)
+branch 1 taken 50%
+ 1: 2083: storeTypeOnly(e->data);
+call 0 returned 100%
+ -: 2084: }
+ -: 2085: else {
+ -: 2086: // high nibble
+ 1: 2087: storeTypeInHighNbl(e->data);
+ -: 2088: }
+ 2: 2089: sBytesPushBuffer(r, &((sDoublet *)(e->data))->value, sizeof(double));
+call 0 returned 100%
+ -: 2090: }
+ 12: 2091: break;
+ -: 2092: case INT:
+ 32: 2093: if (pack) {
+branch 0 taken 25% (fallthrough)
+branch 1 taken 75%
+ 8: 2094: if (type) {
+branch 0 taken 25% (fallthrough)
+branch 1 taken 75%
+ -: 2095: // this is the first packed element
+ 2: 2096: if (ctx->nibble == lowNbl) {
+branch 0 taken 50% (fallthrough)
+branch 1 taken 50%
+ 1: 2097: uintToNetTypeVarint(r, type, packCount);
+call 0 returned 100%
+ -: 2098: }
+ -: 2099: else {
+ -: 2100: // high nibble
+ -: 2101: // store type in high nibble
+ 1: 2102: ctx->nibble = lowNbl;
+ 1: 2103: data = (char *)&((*r)->data) + ctx->nblOffset;
+ 1: 2104: *data |= type << 4;
+ 1: 2105: uintToVarint(r, packCount);
+call 0 returned 100%
+ -: 2106: }
+ 2: 2107: type = 0;
+ -: 2108: } // if type
+ -: 2109:
+ 8: 2110: i64 v = ((sIntt *)(e->data))->value;
+ 8: 2111: uintToVarint(r, (v << 1) ^ (v >> 63));
+call 0 returned 100%
+ -: 2112: // stop packing when packCount == 0
+ 8: 2113: packCount--;
+ 8: 2114: if (!packCount) pack = false;
+branch 0 taken 25% (fallthrough)
+branch 1 taken 75%
+ -: 2115: } // if pack
+ -: 2116: else {
+ -: 2117: // encode int to varint
+ -: 2118: // v is int64_t to convert to varint
+ 24: 2119: i64 v = ((sIntt *)(e->data))->value;
+ 24: 2120: if (ctx->nibble == lowNbl) {
+branch 0 taken 50% (fallthrough)
+branch 1 taken 50%
+ -: 2121: // encode v with arithmetic shifts
+ 12: 2122: uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)e->data->type], (v << 1) ^ (v >> 63));
+call 0 returned 100%
+ -: 2123: }
+ -: 2124: else {
+ -: 2125: // high nibble
+ 12: 2126: storeTypeInHighNbl(e->data);
+ 12: 2127: uintToVarint(r, (v << 1) ^ (v >> 63));
+call 0 returned 100%
+ -: 2128: }
+ -: 2129: }
+ 32: 2130: break;
+ -: 2131: case STRING:
+ 22: 2132: if (pack) {
+branch 0 taken 36% (fallthrough)
+branch 1 taken 64%
+ 8: 2133: if (type) {
+branch 0 taken 25% (fallthrough)
+branch 1 taken 75%
+ -: 2134: // this is the first packed element
+ 2: 2135: if (ctx->nibble == lowNbl) {
+branch 0 taken 50% (fallthrough)
+branch 1 taken 50%
+ 1: 2136: uintToNetTypeVarint(r, type, packCount);
+call 0 returned 100%
+ -: 2137: }
+ -: 2138: else {
+ -: 2139: // high nibble
+ -: 2140: // store type in high nibble
+ 1: 2141: ctx->nibble = lowNbl;
+ 1: 2142: data = (char *)&((*r)->data) + ctx->nblOffset;
+ 1: 2143: *data |= type << 4;
+ 1: 2144: uintToVarint(r, packCount);
+call 0 returned 100%
+ -: 2145: }
+ 2: 2146: type = 0;
+ -: 2147: } // if type
+ -: 2148:
+ 8: 2149: sBytesPushBuffer(r, &((sStringt *)(e->data))->data, sizeof(sStringt) + strlen(&(((sStringt *)(e->data))->data)) -1);
+call 0 returned 100%
+ -: 2150: // stop packing when packCount == 0
+ 8: 2151: packCount--;
+ 8: 2152: if (!packCount) pack = false;
+branch 0 taken 25% (fallthrough)
+branch 1 taken 75%
+ -: 2153: } // if pack
+ -: 2154: else {
+ 14: 2155: if (ctx->nibble == lowNbl) {
+branch 0 taken 93% (fallthrough)
+branch 1 taken 7%
+ 13: 2156: storeTypeOnly(e->data);
+call 0 returned 100%
+ -: 2157: }
+ -: 2158: else {
+ -: 2159: // high nibble
+ 1: 2160: storeTypeInHighNbl(e->data);
+ -: 2161: }
+ 14: 2162: sBytesPushBuffer(r, &((sStringt *)(e->data))->data, sizeof(sStringt) + strlen(&(((sStringt *)(e->data))->data)) -1);
+call 0 returned 100%
+ -: 2163: }
+ 22: 2164: break;
+ -: 2165: case ARRAY:
+ 13: 2166: if (pack) {
+branch 0 taken 62% (fallthrough)
+branch 1 taken 38%
+ 8: 2167: if (type) {
+branch 0 taken 25% (fallthrough)
+branch 1 taken 75%
+ -: 2168: // this is the first packed element
+ 2: 2169: if (ctx->nibble == lowNbl) {
+branch 0 taken 50% (fallthrough)
+branch 1 taken 50%
+ 1: 2170: uintToNetTypeVarint(r, type, packCount);
+call 0 returned 100%
+ -: 2171: }
+ -: 2172: else {
+ -: 2173: // high nibble
+ -: 2174: // store type in high nibble
+ 1: 2175: ctx->nibble = lowNbl;
+ 1: 2176: data = (char *)&((*r)->data) + ctx->nblOffset;
+ 1: 2177: *data |= type << 4;
+ 1: 2178: uintToVarint(r, packCount);
+call 0 returned 100%
+ -: 2179: }
+ 2: 2180: type = 0;
+ -: 2181: } // if type
+ -: 2182:
+ 8: 2183: arrayNetSerial(r, (sArrayt *)(e->data), ctx, /*packing=*/PACKED);
+call 0 returned 100%
+ -: 2184: // stop packing when packCount == 0
+ 8: 2185: packCount--;
+ 8: 2186: if (!packCount) pack = false;
+branch 0 taken 25% (fallthrough)
+branch 1 taken 75%
+ -: 2187: } // if pack
+ -: 2188: else
+ 5: 2189: arrayNetSerial(r, (sArrayt *)(e->data), ctx, /*packing=*/NOPACKING);
+call 0 returned 100%
+ 13: 2190: break;
+ -: 2191: case BYTES:
+ #####: 2192: if (pack) {
+branch 0 never executed
+branch 1 never executed
+ #####: 2193: if (type) {
+branch 0 never executed
+branch 1 never executed
+ -: 2194: // this is the first packed element
+ #####: 2195: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 2196: uintToNetTypeVarint(r, type, packCount);
+call 0 never executed
+ -: 2197: }
+ -: 2198: else {
+ -: 2199: // high nibble
+ -: 2200: // store type in high nibble
+ #####: 2201: ctx->nibble = lowNbl;
+ #####: 2202: data = (char *)&((*r)->data) + ctx->nblOffset;
+ #####: 2203: *data |= type << 4;
+ #####: 2204: uintToVarint(r, packCount);
+call 0 never executed
+ -: 2205: }
+ #####: 2206: type = 0;
+ -: 2207: } // if type
+ -: 2208:
+ #####: 2209: B = (sBytest *)(e->data);
+ #####: 2210: uintToVarint(r, B->count);
+call 0 never executed
+ #####: 2211: sBytesPushBuffer(r, &(B->data), B->count);
+call 0 never executed
+ -: 2212: // stop packing when packCount == 0
+ #####: 2213: packCount--;
+ #####: 2214: if (!packCount) pack = false;
+branch 0 never executed
+branch 1 never executed
+ -: 2215: } // if pack
+ -: 2216: else {
+ #####: 2217: B = (sBytest *)(e->data);
+ #####: 2218: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 2219: uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)e->data->type], B->count);
+call 0 never executed
+ -: 2220: }
+ -: 2221: else {
+ -: 2222: // high nibble
+ #####: 2223: storeTypeInHighNbl(e->data);
+ #####: 2224: uintToVarint(r, B->count);
+call 0 never executed
+ -: 2225: }
+ #####: 2226: sBytesPushBuffer(r, &(B->data), B->count);
+call 0 never executed
+ -: 2227: }
+ #####: 2228: break;
+ -: 2229: }
+ -: 2230: }
+ -: 2231: }
+ 54: 2232: ret;
+ -: 2233:}
+ -: 2234:
+ -: 2235:/**
+ -: 2236: * serialize array
+ -: 2237: *
+ -: 2238: * the serialized array is pushed to r.
+ -: 2239: * All elements are serialized recursively
+ -: 2240: *
+ -: 2241: * the data in containers is not serialized
+ -: 2242: *
+ -: 2243: * \param
+ -: 2244: * r small bytes object
+ -: 2245: * array to serialize
+ -: 2246: */
+function arrayNetSerial called 71 returned 100% blocks executed 86%
+ 71: 2247:internal void arrayNetSerial(sBytest **r, sArrayt *array, contextt *ctx, packingT packing) {
+ 71: 2248: sBytest *B = NULL;
+ 71: 2249: char *data = NULL;
+ -: 2250:
+ -: 2251: // check if all elements have same type
+ 71: 2252: bool allElementsHaveSameType = true;
+ 71: 2253: bool foundFirstType = false;
+ 71: 2254: char type = 0;
+ -: 2255:
+ 213: 2256: {forEachSArray(array, e) {
+branch 0 taken 82%
+branch 1 taken 18% (fallthrough)
+ 174: 2257: if (!e) {
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ #####: 2258: if (foundFirstType) {
+branch 0 never executed
+branch 1 never executed
+ #####: 2259: if (type != S_UNDEFINED) {
+branch 0 never executed
+branch 1 never executed
+ #####: 2260: allElementsHaveSameType = false;
+ #####: 2261: break;
+ -: 2262: }
+ -: 2263: }
+ -: 2264: else {
+ #####: 2265: type = S_UNDEFINED;
+ #####: 2266: foundFirstType = true;
+ -: 2267: }
+ -: 2268: }
+ -: 2269: else {
+ 174: 2270: if (foundFirstType) {
+branch 0 taken 61% (fallthrough)
+branch 1 taken 39%
+ -: 2271: u8 nextType;
+ 107: 2272: switch(e->type) {
+branch 0 taken 7%
+branch 1 taken 10%
+branch 2 taken 83%
+ -: 2273: case DICT:
+ 7: 2274: nextType = isDictUniform((sDictt*)e);
+call 0 returned 100%
+ 7: 2275: break;
+ -: 2276: case ARRAY:
+ 11: 2277: nextType = isArrayUniform((sArrayt*)e);
+call 0 returned 100%
+ 11: 2278: break;
+ -: 2279: default:
+ 89: 2280: nextType = NET_SERIAL_TYPES[(u8)e->type];
+ -: 2281: }
+ 107: 2282: if (nextType != type) {
+branch 0 taken 30% (fallthrough)
+branch 1 taken 70%
+ 32: 2283: allElementsHaveSameType = false;
+ 32: 2284: break;
+ -: 2285: }
+ -: 2286: }
+ -: 2287: else {
+ 67: 2288: switch(e->type) {
+branch 0 taken 6%
+branch 1 taken 7%
+branch 2 taken 87%
+ -: 2289: case DICT:
+ 4: 2290: type = isDictUniform((sDictt*)e);
+call 0 returned 100%
+ 4: 2291: break;
+ -: 2292: case ARRAY:
+ 5: 2293: type = isArrayUniform((sArrayt*)e);
+call 0 returned 100%
+ 5: 2294: break;
+ -: 2295: default:
+ 58: 2296: type = NET_SERIAL_TYPES[(u8)e->type];
+ -: 2297: }
+ 67: 2298: foundFirstType = true;
+ -: 2299: }
+ -: 2300: }
+ -: 2301: }}
+ -: 2302:
+ 71: 2303: if (allElementsHaveSameType) {
+branch 0 taken 55% (fallthrough)
+branch 1 taken 45%
+ -: 2304: // pack array
+ 39: 2305: if (packing == PACKED) {
+branch 0 taken 41% (fallthrough)
+branch 1 taken 59%
+ -: 2306: // uniform array can't be packed
+ -: 2307: // because there is only one type of packed arrays
+ 16: 2308: goto normalArray;
+ -: 2309: }
+ 23: 2310: elif (packing == UNIFORM) {
+branch 0 taken 9% (fallthrough)
+branch 1 taken 91%
+ 2: 2311: uintToNetTypeVarint(r, type, array->count);
+call 0 returned 100%
+ -: 2312: }
+ -: 2313: else {
+ 21: 2314: if (ctx->nibble == lowNbl) {
+branch 0 taken 76% (fallthrough)
+branch 1 taken 24%
+ 16: 2315: sBytesPush(r, (type << 4) + UNIFORM_ARRAY);
+call 0 returned 100%
+ 16: 2316: uintToVarint(r, array->count);
+call 0 returned 100%
+ -: 2317: }
+ -: 2318: else {
+ -: 2319: // high nibble
+ 5: 2320: ctx->nibble = lowNbl;
+ 5: 2321: data = (char *)&((*r)->data) + ctx->nblOffset;
+ 5: 2322: *data |= UNIFORM_ARRAY << 4;
+ 5: 2323: uintToNetTypeVarint(r, type, array->count);
+call 0 returned 100%
+ -: 2324: }
+ -: 2325: }
+ -: 2326:
+ 23: 2327: switch(type) {
+branch 0 taken 9%
+branch 1 taken 9%
+branch 2 taken 4%
+branch 3 taken 48%
+branch 4 taken 4%
+branch 5 taken 13%
+branch 6 taken 0%
+branch 7 taken 13%
+ -: 2328: case S_BOOL:
+ 16: 2329: {forEachSArray(array, e) {
+branch 0 taken 88%
+branch 1 taken 13% (fallthrough)
+ 14: 2330: if (!ctx->boolOffset) {
+branch 0 taken 14% (fallthrough)
+branch 1 taken 86%
+ -: 2331: // new packed bools
+ 2: 2332: storeNew8bPackedBool(e);
+branch 0 taken 100% (fallthrough)
+branch 1 taken 0%
+call 2 returned 100%
+ -: 2333: }
+ -: 2334: else {
+ -: 2335: // there was a bool before this one, fill bits in nibbles
+ 12: 2336: if (ctx->boolShift == 8) {
+branch 0 taken 8% (fallthrough)
+branch 1 taken 92%
+ -: 2337: // previous packed bool is full
+ -: 2338: // next byte is the new packed bools
+ 1: 2339: storeNew8bPackedBool(e);
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+call 2 returned 100%
+ -: 2340: }
+ -: 2341: else {
+ 11: 2342: storeBool(e);
+branch 0 taken 100% (fallthrough)
+branch 1 taken 0%
+ -: 2343: }
+ -: 2344: }
+ -: 2345: }}
+ 2: 2346: break;
+ -: 2347: case S_DICT:
+ -: 2348: case UNIFORM_DICT:
+ 6: 2349: {forEachSArray(array, e) {
+branch 0 taken 67%
+branch 1 taken 33% (fallthrough)
+ 4: 2350: dictNetSerial(r, (sDictt *)e, ctx, /*packing=*/UNIFORM);
+call 0 returned 100%
+ -: 2351: }}
+ 2: 2352: break;
+ -: 2353: case S_DOUBLE:
+ 4: 2354: {forEachSArray(array, e) {
+branch 0 taken 75%
+branch 1 taken 25% (fallthrough)
+ 3: 2355: sBytesPushBuffer(r, &((sDoublet *)e)->value, sizeof(double));
+call 0 returned 100%
+ -: 2356: }}
+ 1: 2357: break;
+ -: 2358: case S_INT:
+ 49: 2359: {forEachSArray(array, e) {
+branch 0 taken 78%
+branch 1 taken 22% (fallthrough)
+ 38: 2360: i64 v = ((sIntt *)e)->value;
+ 38: 2361: uintToVarint(r, (v << 1) ^ (v >> 63));
+call 0 returned 100%
+ -: 2362: }}
+ 11: 2363: break;
+ -: 2364: case S_STRING:
+ 4: 2365: {forEachSArray(array, e) {
+branch 0 taken 75%
+branch 1 taken 25% (fallthrough)
+ 3: 2366: sBytesPushBuffer(r, &((sStringt *)e)->data, sizeof(sStringt) + strlen(&(((sStringt *)e)->data)) -1);
+call 0 returned 100%
+ -: 2367: }}
+ 1: 2368: break;
+ -: 2369: case S_ARRAY:
+ -: 2370: case UNIFORM_ARRAY:
+ 8: 2371: {forEachSArray(array, e) {
+branch 0 taken 63%
+branch 1 taken 38% (fallthrough)
+ 5: 2372: arrayNetSerial(r, (sArrayt *)e, ctx, /*packing=*/UNIFORM);
+call 0 returned 100%
+ -: 2373: }}
+ 3: 2374: break;
+ -: 2375: case S_BYTES:
+ #####: 2376: {forEachSArray(array, e) {
+branch 0 never executed
+branch 1 never executed
+ #####: 2377: B = (sBytest *)e;
+ #####: 2378: uintToVarint(r, B->count);
+call 0 never executed
+ #####: 2379: sBytesPushBuffer(r, &(B->data), B->count);
+call 0 never executed
+ -: 2380: }}
+ #####: 2381: break;
+ -: 2382: }
+ 23: 2383: ret;
+ -: 2384: }
+ -: 2385:
+ -: 2386: normalArray:
+ 48: 2387: if (packing == PACKED or packing == UNIFORM) {
+branch 0 taken 67% (fallthrough)
+branch 1 taken 33%
+branch 2 taken 16% (fallthrough)
+branch 3 taken 84%
+ 21: 2388: uintToVarint(r, array->count);
+call 0 returned 100%
+ -: 2389: }
+ -: 2390: else {
+ 27: 2391: if (ctx->nibble == lowNbl) {
+branch 0 taken 96% (fallthrough)
+branch 1 taken 4%
+ 26: 2392: uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)array->type], array->count);
+call 0 returned 100%
+ -: 2393: }
+ -: 2394: else {
+ -: 2395: // high nibble
+ 1: 2396: storeTypeInHighNbl(array);
+ 1: 2397: uintToVarint(r, array->count);
+call 0 returned 100%
+ -: 2398: }
+ -: 2399: }
+ -: 2400:
+ 48: 2401: bool pack = false;
+ -: 2402: size_t packCount;
+ 198: 2403: enumerateSArray(array, e, eIdx) {
+branch 0 taken 76%
+branch 1 taken 24% (fallthrough)
+ 150: 2404: if (!e) {
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ -: 2405: // empty slots are represented as undefined elements
+ #####: 2406: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 2407: sBytesPush(r, NET_SERIAL_TYPES[UNDEFINED]);
+call 0 never executed
+ #####: 2408: ctx->nibble = highNbl;
+ #####: 2409: ctx->nblOffset = (*r)->count -1;
+ -: 2410: }
+ -: 2411: else {
+ -: 2412: // high nibble
+ #####: 2413: ctx->nibble = lowNbl;
+ #####: 2414: data = (char *)&((*r)->data) + ctx->nblOffset;
+ #####: 2415: *data |= NET_SERIAL_TYPES[UNDEFINED] << 4;
+ -: 2416: }
+ -: 2417: }
+ -: 2418: else {
+ 150: 2419: if (!pack) {
+branch 0 taken 80% (fallthrough)
+branch 1 taken 20%
+ -: 2420: // scan array for packing
+ 120: 2421: if ((array->count - eIdx) > 3) {
+branch 0 taken 33% (fallthrough)
+branch 1 taken 68%
+ -: 2422: // at least 4 elements, less than that is not worth it
+ 39: 2423: if ( e->type == DICT
+branch 0 taken 92% (fallthrough)
+branch 1 taken 8%
+ 36: 2424: or e->type == DOUBLE
+branch 0 taken 94% (fallthrough)
+branch 1 taken 6%
+ 34: 2425: or e->type == INT
+branch 0 taken 91% (fallthrough)
+branch 1 taken 9%
+ 31: 2426: or e->type == STRING
+branch 0 taken 94% (fallthrough)
+branch 1 taken 6%
+ 29: 2427: or e->type == ARRAY
+branch 0 taken 93% (fallthrough)
+branch 1 taken 7%
+ 27: 2428: or e->type == BYTES) {
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ 12: 2429: type = e->type;
+ 12: 2430: packCount = 1;
+ 12: 2431: smallt *element = ((smallt **) &((array)->data))[eIdx];
+ 45: 2432: for (size_t i = eIdx+1; i < (array)->count ; i++, element = ((smallt **) &((array)->data))[i]) {
+branch 0 taken 100%
+branch 1 taken 0% (fallthrough)
+ 45: 2433: if (!element) {
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ -: 2434: // null element are undefined
+ #####: 2435: break;
+ -: 2436: }
+ -: 2437: else {
+ 45: 2438: if (element->type != type) {
+branch 0 taken 27% (fallthrough)
+branch 1 taken 73%
+ 12: 2439: break;
+ -: 2440: }
+ 33: 2441: packCount++;
+ -: 2442: } // if element
+ -: 2443: } // for
+ 12: 2444: if (packCount > 3) {
+branch 0 taken 83% (fallthrough)
+branch 1 taken 17%
+ 10: 2445: type = PACKED_NET_SERIAL_TYPES[(u8)type];
+ 10: 2446: pack = true;
+ -: 2447: }
+ -: 2448: } // test current element type
+ -: 2449: } // is array big enough
+ -: 2450: } // not already packing
+ -: 2451:
+ 150: 2452: switch(e->type) {
+branch 0 taken 18%
+branch 1 taken 23%
+branch 2 taken 8%
+branch 3 taken 7%
+branch 4 taken 20%
+branch 5 taken 14%
+branch 6 taken 11%
+branch 7 taken 0%
+branch 8 taken 0%
+ -: 2453: case UNDEFINED:
+ -: 2454: case CONTAINER:
+ 27: 2455: if (ctx->nibble == lowNbl) {
+branch 0 taken 93% (fallthrough)
+branch 1 taken 7%
+ 25: 2456: storeTypeOnly(e);
+call 0 returned 100%
+ -: 2457: }
+ -: 2458: else {
+ -: 2459: // high nibble
+ 2: 2460: storeTypeInHighNbl(e);
+ -: 2461: }
+ 27: 2462: break;
+ -: 2463: case BOOL:
+ 34: 2464: if (!ctx->boolOffset) {
+branch 0 taken 18% (fallthrough)
+branch 1 taken 82%
+ -: 2465: // new packed bools
+ 6: 2466: if (ctx->nibble == lowNbl) {
+branch 0 taken 50% (fallthrough)
+branch 1 taken 50%
+ 3: 2467: storeNew4bPackedBool(e);
+branch 0 taken 67% (fallthrough)
+branch 1 taken 33%
+call 2 returned 100%
+ -: 2468: }
+ -: 2469: else {
+ -: 2470: // high nibble, next byte is packed bools
+ 3: 2471: storeTypeInHighNbl(e);
+ 3: 2472: storeNew8bPackedBool(e);
+branch 0 taken 100% (fallthrough)
+branch 1 taken 0%
+call 2 returned 100%
+ -: 2473: }
+ -: 2474: }
+ -: 2475: else {
+ -: 2476: // there was a bool before this one, fill bits in nibbles
+ 28: 2477: if (ctx->nibble == lowNbl) {
+branch 0 taken 61% (fallthrough)
+branch 1 taken 39%
+ 17: 2478: if (ctx->boolShift == 8) {
+branch 0 taken 12% (fallthrough)
+branch 1 taken 88%
+ -: 2479: // previous packed bool is full
+ -: 2480: // this byte is the new packed bools
+ 2: 2481: storeNew4bPackedBool(e);
+branch 0 taken 50% (fallthrough)
+branch 1 taken 50%
+call 2 returned 100%
+ -: 2482: }
+ -: 2483: else {
+ 15: 2484: storeTypeOnly(e);
+call 0 returned 100%
+ 15: 2485: storeBool(e);
+branch 0 taken 53% (fallthrough)
+branch 1 taken 47%
+ -: 2486: }
+ -: 2487: }
+ -: 2488: else {
+ -: 2489: // high nibble
+ 11: 2490: storeTypeInHighNbl(e);
+ 11: 2491: if (ctx->boolShift == 8) {
+branch 0 taken 18% (fallthrough)
+branch 1 taken 82%
+ -: 2492: // previous packed bool is full
+ -: 2493: // next byte is the new packed bools
+ 2: 2494: storeNew8bPackedBool(e);
+branch 0 taken 100% (fallthrough)
+branch 1 taken 0%
+call 2 returned 100%
+ -: 2495: }
+ -: 2496: else {
+ 9: 2497: storeBool(e);
+branch 0 taken 78% (fallthrough)
+branch 1 taken 22%
+ -: 2498: }
+ -: 2499: }
+ -: 2500: }
+ 34: 2501: break;
+ -: 2502: case DICT:
+ 12: 2503: if (pack) {
+branch 0 taken 67% (fallthrough)
+branch 1 taken 33%
+ 8: 2504: if (type) {
+branch 0 taken 25% (fallthrough)
+branch 1 taken 75%
+ -: 2505: // this is the first packed element
+ 2: 2506: if (ctx->nibble == lowNbl) {
+branch 0 taken 50% (fallthrough)
+branch 1 taken 50%
+ 1: 2507: uintToNetTypeVarint(r, type, packCount);
+call 0 returned 100%
+ -: 2508: }
+ -: 2509: else {
+ -: 2510: // high nibble
+ -: 2511: // store type in high nibble
+ 1: 2512: ctx->nibble = lowNbl;
+ 1: 2513: data = (char *)&((*r)->data) + ctx->nblOffset;
+ 1: 2514: *data |= type << 4;
+ 1: 2515: uintToVarint(r, packCount);
+call 0 returned 100%
+ -: 2516: }
+ 2: 2517: type = 0;
+ -: 2518: } // if type
+ -: 2519:
+ 8: 2520: dictNetSerial(r, (sDictt *)e, ctx, /*packing=*/PACKED);
+call 0 returned 100%
+ -: 2521: // stop packing when packCount == 0
+ 8: 2522: packCount--;
+ 8: 2523: if (!packCount) pack = false;
+branch 0 taken 25% (fallthrough)
+branch 1 taken 75%
+ -: 2524: } // if pack
+ -: 2525: else
+ 4: 2526: dictNetSerial(r, (sDictt *)e, ctx, /*packing=*/NOPACKING);
+call 0 returned 100%
+ 12: 2527: break;
+ -: 2528: case DOUBLE:
+ 10: 2529: if (pack) {
+branch 0 taken 80% (fallthrough)
+branch 1 taken 20%
+ 8: 2530: if (type) {
+branch 0 taken 25% (fallthrough)
+branch 1 taken 75%
+ -: 2531: // this is the first packed element
+ 2: 2532: if (ctx->nibble == lowNbl) {
+branch 0 taken 50% (fallthrough)
+branch 1 taken 50%
+ 1: 2533: uintToNetTypeVarint(r, type, packCount);
+call 0 returned 100%
+ -: 2534: }
+ -: 2535: else {
+ -: 2536: // high nibble
+ -: 2537: // store type in high nibble
+ 1: 2538: ctx->nibble = lowNbl;
+ 1: 2539: data = (char *)&((*r)->data) + ctx->nblOffset;
+ 1: 2540: *data |= type << 4;
+ 1: 2541: uintToVarint(r, packCount);
+call 0 returned 100%
+ -: 2542: }
+ 2: 2543: type = 0;
+ -: 2544: } // if type
+ -: 2545:
+ 8: 2546: sBytesPushBuffer(r, &((sDoublet *)e)->value, sizeof(double));
+call 0 returned 100%
+ -: 2547: // stop packing when packCount == 0
+ 8: 2548: packCount--;
+ 8: 2549: if (!packCount) pack = false;
+branch 0 taken 25% (fallthrough)
+branch 1 taken 75%
+ -: 2550: } // if pack
+ -: 2551: else {
+ 2: 2552: if (ctx->nibble == lowNbl) {
+branch 0 taken 50% (fallthrough)
+branch 1 taken 50%
+ 1: 2553: storeTypeOnly(e);
+call 0 returned 100%
+ -: 2554: }
+ -: 2555: else {
+ -: 2556: // high nibble
+ 1: 2557: storeTypeInHighNbl(e);
+ -: 2558: }
+ 2: 2559: sBytesPushBuffer(r, &((sDoublet *)e)->value, sizeof(double));
+call 0 returned 100%
+ -: 2560: }
+ 10: 2561: break;
+ -: 2562: case INT:
+ 30: 2563: if (pack) {
+branch 0 taken 27% (fallthrough)
+branch 1 taken 73%
+ 8: 2564: if (type) {
+branch 0 taken 25% (fallthrough)
+branch 1 taken 75%
+ -: 2565: // this is the first packed element
+ 2: 2566: if (ctx->nibble == lowNbl) {
+branch 0 taken 50% (fallthrough)
+branch 1 taken 50%
+ 1: 2567: uintToNetTypeVarint(r, type, packCount);
+call 0 returned 100%
+ -: 2568: }
+ -: 2569: else {
+ -: 2570: // high nibble
+ -: 2571: // store type in high nibble
+ 1: 2572: ctx->nibble = lowNbl;
+ 1: 2573: data = (char *)&((*r)->data) + ctx->nblOffset;
+ 1: 2574: *data |= type << 4;
+ 1: 2575: uintToVarint(r, packCount);
+call 0 returned 100%
+ -: 2576: }
+ 2: 2577: type = 0;
+ -: 2578: } // if type
+ -: 2579:
+ 8: 2580: i64 v = ((sIntt *)&(e->type))->value;
+ 8: 2581: uintToVarint(r, (v << 1) ^ (v >> 63));
+call 0 returned 100%
+ -: 2582: // stop packing when packCount == 0
+ 8: 2583: packCount--;
+ 8: 2584: if (!packCount) pack = false;
+branch 0 taken 25% (fallthrough)
+branch 1 taken 75%
+ -: 2585: } // if pack
+ -: 2586: else {
+ -: 2587: // encode int to varint
+ -: 2588: // v is int64_t to convert to varint
+ 22: 2589: i64 v = ((sIntt *)&(e->type))->value;
+ 22: 2590: if (ctx->nibble == lowNbl) {
+branch 0 taken 82% (fallthrough)
+branch 1 taken 18%
+ -: 2591: // encode v with arithmetic shifts
+ 18: 2592: uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)e->type], (v << 1) ^ (v >> 63));
+call 0 returned 100%
+ -: 2593: }
+ -: 2594: else {
+ -: 2595: // high nibble
+ 4: 2596: storeTypeInHighNbl(e);
+ 4: 2597: uintToVarint(r, (v << 1) ^ (v >> 63));
+call 0 returned 100%
+ -: 2598: }
+ -: 2599: }
+ 30: 2600: break;
+ -: 2601: case STRING:
+ 21: 2602: if (pack) {
+branch 0 taken 38% (fallthrough)
+branch 1 taken 62%
+ 8: 2603: if (type) {
+branch 0 taken 25% (fallthrough)
+branch 1 taken 75%
+ -: 2604: // this is the first packed element
+ 2: 2605: if (ctx->nibble == lowNbl) {
+branch 0 taken 50% (fallthrough)
+branch 1 taken 50%
+ 1: 2606: uintToNetTypeVarint(r, type, packCount);
+call 0 returned 100%
+ -: 2607: }
+ -: 2608: else {
+ -: 2609: // high nibble
+ -: 2610: // store type in high nibble
+ 1: 2611: ctx->nibble = lowNbl;
+ 1: 2612: data = (char *)&((*r)->data) + ctx->nblOffset;
+ 1: 2613: *data |= type << 4;
+ 1: 2614: uintToVarint(r, packCount);
+call 0 returned 100%
+ -: 2615: }
+ 2: 2616: type = 0;
+ -: 2617: } // if type
+ -: 2618:
+ 8: 2619: sBytesPushBuffer(r, &((sStringt *)e)->data, sizeof(sStringt) + strlen(&(((sStringt *)e)->data)) -1);
+call 0 returned 100%
+ -: 2620: // stop packing when packCount == 0
+ 8: 2621: packCount--;
+ 8: 2622: if (!packCount) pack = false;
+branch 0 taken 25% (fallthrough)
+branch 1 taken 75%
+ -: 2623: } // if pack
+ -: 2624: else {
+ 13: 2625: if (ctx->nibble == lowNbl) {
+branch 0 taken 69% (fallthrough)
+branch 1 taken 31%
+ 9: 2626: storeTypeOnly(e);
+call 0 returned 100%
+ -: 2627: }
+ -: 2628: else {
+ -: 2629: // high nibble
+ 4: 2630: storeTypeInHighNbl(e);
+ -: 2631: }
+ 13: 2632: sBytesPushBuffer(r, &((sStringt *)e)->data, sizeof(sStringt) + strlen(&(((sStringt *)e)->data)) -1);
+call 0 returned 100%
+ -: 2633: }
+ 21: 2634: break;
+ -: 2635: case ARRAY:
+ 16: 2636: if (pack) {
+branch 0 taken 50% (fallthrough)
+branch 1 taken 50%
+ 8: 2637: if (type) {
+branch 0 taken 25% (fallthrough)
+branch 1 taken 75%
+ -: 2638: // this is the first packed element
+ 2: 2639: if (ctx->nibble == lowNbl) {
+branch 0 taken 50% (fallthrough)
+branch 1 taken 50%
+ 1: 2640: uintToNetTypeVarint(r, type, packCount);
+call 0 returned 100%
+ -: 2641: }
+ -: 2642: else {
+ -: 2643: // high nibble
+ -: 2644: // store type in high nibble
+ 1: 2645: ctx->nibble = lowNbl;
+ 1: 2646: data = (char *)&((*r)->data) + ctx->nblOffset;
+ 1: 2647: *data |= type << 4;
+ 1: 2648: uintToVarint(r, packCount);
+call 0 returned 100%
+ -: 2649: }
+ 2: 2650: type = 0;
+ -: 2651: } // if type
+ -: 2652:
+ 8: 2653: arrayNetSerial(r, (sArrayt *)e, ctx, /*packing=*/PACKED);
+call 0 returned 100%
+ -: 2654: // stop packing when packCount == 0
+ 8: 2655: packCount--;
+ 8: 2656: if (!packCount) pack = false;
+branch 0 taken 25% (fallthrough)
+branch 1 taken 75%
+ -: 2657: } // if pack
+ -: 2658: else
+ 8: 2659: arrayNetSerial(r, (sArrayt *)e, ctx, /*packing=*/NOPACKING);
+call 0 returned 100%
+ 16: 2660: break;
+ -: 2661: case BYTES:
+ #####: 2662: if (pack) {
+branch 0 never executed
+branch 1 never executed
+ #####: 2663: if (type) {
+branch 0 never executed
+branch 1 never executed
+ -: 2664: // this is the first packed element
+ #####: 2665: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 2666: uintToNetTypeVarint(r, type, packCount);
+call 0 never executed
+ -: 2667: }
+ -: 2668: else {
+ -: 2669: // high nibble
+ -: 2670: // store type in high nibble
+ #####: 2671: ctx->nibble = lowNbl;
+ #####: 2672: data = (char *)&((*r)->data) + ctx->nblOffset;
+ #####: 2673: *data |= type << 4;
+ #####: 2674: uintToVarint(r, packCount);
+call 0 never executed
+ -: 2675: }
+ #####: 2676: type = 0;
+ -: 2677: } // if type
+ -: 2678:
+ #####: 2679: B = (sBytest *)e;
+ #####: 2680: uintToVarint(r, B->count);
+call 0 never executed
+ #####: 2681: sBytesPushBuffer(r, &(B->data), B->count);
+call 0 never executed
+ -: 2682: // stop packing when packCount == 0
+ #####: 2683: packCount--;
+ #####: 2684: if (!packCount) pack = false;
+branch 0 never executed
+branch 1 never executed
+ -: 2685: } // if pack
+ -: 2686: else {
+ #####: 2687: B = (sBytest *)e;
+ #####: 2688: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 2689: uintToNetTypeVarint(r, NET_SERIAL_TYPES[(u8)e->type], B->count);
+call 0 never executed
+ -: 2690: }
+ -: 2691: else {
+ -: 2692: // high nibble
+ #####: 2693: storeTypeInHighNbl(e);
+ #####: 2694: uintToVarint(r, B->count);
+call 0 never executed
+ -: 2695: }
+ #####: 2696: sBytesPushBuffer(r, &(B->data), B->count);
+call 0 never executed
+ -: 2697: }
+ #####: 2698: break;
+ -: 2699: }
+ -: 2700: }
+ -: 2701: }
+ 48: 2702: ret;
+ -: 2703:}
+ -: 2704:
+function serialNetSerial called 76 returned 100% blocks executed 80%
+ 76: 2705:internal smallBytest* serialNetSerial(smallJsont *self) {
+ -: 2706:
+ 76: 2707: smallt *o = getsoG(self);
+call 0 returned 100%
+ -: 2708:
+ 76: 2709: if (o == NULL)
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ #####: 2710: ret NULL;
+ -: 2711:
+ 76: 2712: sBytest *B = netSerial(o);
+call 0 returned 100%
+ -: 2713:
+ 76: 2714: if (!B) {
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ #####: 2715: ret NULL;
+ -: 2716: }
+ -: 2717:
+ 76: 2718: createAllocateSmallBytes(r);
+call 0 returned 100%
+ 76: 2719: r->B = B;
+ 76: 2720: ret r;
+ -: 2721:}
+ -: 2722:
+ -: 2723:// -------------------------------------
+ -: 2724:// Deserializers
+ -: 2725:
+function netDeserialLevel0 called 0 returned 0% blocks executed 0%
+ #####: 2726:internal smallt* netDeserialLevel0(sBytest *obj) {
+ #####: 2727: smallt *r = NULL;
+ #####: 2728: double *D = NULL;
+ #####: 2729: char *s = NULL;
+ #####: 2730: sBytest *B = NULL;
+ -: 2731: uint32_t count;
+ #####: 2732: char *data = NULL;
+ -: 2733:
+ #####: 2734: switch(obj->data & 0xF) {
+branch 0 never executed
+branch 1 never executed
+branch 2 never executed
+branch 3 never executed
+branch 4 never executed
+branch 5 never executed
+branch 6 never executed
+branch 7 never executed
+branch 8 never executed
+ -: 2735: case S_UNDEFINED:
+ #####: 2736: r = (smallt *) allocSUndefined();
+call 0 never executed
+ #####: 2737: break;
+ -: 2738: case S_BOOL:
+ #####: 2739: r = (smallt *) allocSBool(obj->data & 0x10);
+call 0 never executed
+ #####: 2740: break;
+ -: 2741: case S_DICT:
+ #####: 2742: data = (char *)&(obj->data);
+ #####: 2743: dictNetDeserialLevel0((sDictt **)&r, &data);
+call 0 never executed
+ #####: 2744: break;
+ -: 2745: case S_DOUBLE:
+ #####: 2746: data = &(obj->data)+1;
+ #####: 2747: D = (double *)data;
+ #####: 2748: r = (smallt *) allocSDouble(*D);
+call 0 never executed
+ #####: 2749: break;
+ -: 2750: case S_INT:
+ #####: 2751: data = &(obj->data);
+ #####: 2752: i64 v = netTypeVarintToUint((u8**)&data);
+call 0 never executed
+ #####: 2753: v = (v >> 1) ^ ((v << 63) >> 63);
+ #####: 2754: r = (smallt *) allocSInt(v);
+call 0 never executed
+ #####: 2755: break;
+ -: 2756: case S_STRING:
+ #####: 2757: s = (char *)&(obj->data)+1;
+ #####: 2758: r = (smallt *) allocSStringTiny(s);
+call 0 never executed
+ #####: 2759: break;
+ -: 2760: case S_ARRAY:
+ #####: 2761: data = (char *)&(obj->data);
+ #####: 2762: arrayNetDeserialLevel0((sArrayt **)&r, &data);
+call 0 never executed
+ #####: 2763: break;
+ -: 2764: case S_BYTES:
+ #####: 2765: B = allocSBytes();
+call 0 never executed
+ #####: 2766: data = &(obj->data);
+ #####: 2767: count = netTypeVarintToUint((u8**)&data);
+call 0 never executed
+ #####: 2768: sBytesPushBuffer(&B, data, count);
+call 0 never executed
+ #####: 2769: r = (smallt *)B;
+ #####: 2770: break;
+ -: 2771: }
+ -: 2772:
+ #####: 2773: ret r;
+ -: 2774:}
+ -: 2775:
+ -: 2776:/**
+ -: 2777: * deserialize dictionary from data
+ -: 2778: *
+ -: 2779: * a new dictionary is allocated
+ -: 2780: *
+ -: 2781: * \param
+ -: 2782: * dict dictionary holding the elements
+ -: 2783: * data serialized dictionary
+ -: 2784: */
+function dictNetDeserialLevel0 called 0 returned 0% blocks executed 0%
+ #####: 2785:internal void dictNetDeserialLevel0(sDictt **dict, char **data) {
+ #####: 2786: sUndefinedt *u = NULL;
+ #####: 2787: sBoolt *bo = NULL;
+ #####: 2788: double *D = NULL;
+ #####: 2789: sDoublet *Do = NULL;
+ #####: 2790: sDictt *d = NULL;
+ #####: 2791: sIntt *io = NULL;
+ #####: 2792: char *s = NULL;
+ #####: 2793: sStringt *so = NULL;
+ #####: 2794: sArrayt *a = NULL;
+ #####: 2795: sBytest *B = NULL;
+ -: 2796: uint32_t count;
+ -: 2797: uint32_t dictCount;
+ -: 2798:
+ #####: 2799: dictCount = netTypeVarintToUint((u8**)data);
+call 0 never executed
+ -: 2800:
+ #####: 2801: if (!dictCount) {
+branch 0 never executed
+branch 1 never executed
+ #####: 2802: *dict = allocSDict();
+call 0 never executed
+ #####: 2803: ret;
+ -: 2804: }
+ -: 2805:
+ #####: 2806: loop(dictCount) {
+branch 0 never executed
+branch 1 never executed
+ -: 2807: char type;
+ -: 2808: char *key;
+ #####: 2809: key = *data;
+ #####: 2810: *data += strlen(key)+1;
+ #####: 2811: type = **data;
+ -: 2812:
+ #####: 2813: switch(type & 0xF) {
+branch 0 never executed
+branch 1 never executed
+branch 2 never executed
+branch 3 never executed
+branch 4 never executed
+branch 5 never executed
+branch 6 never executed
+branch 7 never executed
+branch 8 never executed
+ -: 2814: case S_UNDEFINED:
+ #####: 2815: (*data)++;
+ #####: 2816: u = allocSUndefined();
+call 0 never executed
+ #####: 2817: sDictPushTiny(dict, key, (smallt *) u);
+call 0 never executed
+ #####: 2818: break;
+ -: 2819: case S_BOOL:
+ #####: 2820: (*data)++;
+ #####: 2821: bo = allocSBool(type & 0x10);
+call 0 never executed
+ #####: 2822: sDictPushTiny(dict, key, (smallt *) bo);
+call 0 never executed
+ #####: 2823: break;
+ -: 2824: case S_DICT:
+ #####: 2825: d = NULL;
+ #####: 2826: dictNetDeserialLevel0(&d, data);
+call 0 never executed
+ #####: 2827: sDictPushTiny(dict, key, (smallt *) d);
+call 0 never executed
+ #####: 2828: break;
+ -: 2829: case S_DOUBLE:
+ #####: 2830: (*data)++;
+ #####: 2831: D = (double *)(*data);
+ #####: 2832: *data += sizeof(double);
+ #####: 2833: Do = allocSDouble(*D);
+call 0 never executed
+ #####: 2834: sDictPushTiny(dict, key, (smallt *) Do);
+call 0 never executed
+ #####: 2835: break;
+ -: 2836: case S_INT: {
+ #####: 2837: i64 v = netTypeVarintToUint((u8**)data);
+call 0 never executed
+ #####: 2838: v = (v >> 1) ^ ((v << 63) >> 63);
+ #####: 2839: io = allocSInt(v);
+call 0 never executed
+ #####: 2840: sDictPushTiny(dict, key, (smallt *) io);
+call 0 never executed
+ -: 2841: }
+ #####: 2842: break;
+ -: 2843: case S_STRING:
+ #####: 2844: (*data)++;
+ #####: 2845: s = (char *)(*data);
+ #####: 2846: *data += strlen(s)+1;
+ #####: 2847: so = allocSStringTiny(s);
+call 0 never executed
+ #####: 2848: sDictPushTiny(dict, key, (smallt *) so);
+call 0 never executed
+ #####: 2849: break;
+ -: 2850: case S_ARRAY:
+ #####: 2851: a = NULL;
+ #####: 2852: arrayNetDeserialLevel0(&a, data);
+call 0 never executed
+ #####: 2853: sDictPushTiny(dict, key, (smallt *) a);
+call 0 never executed
+ #####: 2854: break;
+ -: 2855: case S_BYTES:
+ #####: 2856: B = allocSBytes();
+call 0 never executed
+ #####: 2857: count = netTypeVarintToUint((u8**)data);
+call 0 never executed
+ #####: 2858: sBytesPushBuffer(&B, data, count);
+call 0 never executed
+ #####: 2859: *data += count;
+ #####: 2860: sDictPushTiny(dict, key, (smallt *) B);
+call 0 never executed
+ #####: 2861: break;
+ -: 2862: }
+ -: 2863: }
+ -: 2864:}
+ -: 2865:
+ -: 2866:/**
+ -: 2867: * deserialize array from data
+ -: 2868: *
+ -: 2869: * a new array is allocated
+ -: 2870: *
+ -: 2871: * \param
+ -: 2872: * array holding the elements
+ -: 2873: * data serialized dictionary
+ -: 2874: */
+function arrayNetDeserialLevel0 called 0 returned 0% blocks executed 0%
+ #####: 2875:internal void arrayNetDeserialLevel0(sArrayt **array, char **data) {
+ #####: 2876: sUndefinedt *u = NULL;
+ #####: 2877: sBoolt *bo = NULL;
+ #####: 2878: double *D = NULL;
+ #####: 2879: sDoublet *Do = NULL;
+ #####: 2880: sDictt *d = NULL;
+ #####: 2881: sIntt *io = NULL;
+ #####: 2882: char *s = NULL;
+ #####: 2883: sStringt *so = NULL;
+ #####: 2884: sArrayt *a = NULL;
+ #####: 2885: sBytest *B = NULL;
+ -: 2886: uint32_t count;
+ -: 2887: uint32_t arrayCount;
+ -: 2888:
+ #####: 2889: arrayCount = netTypeVarintToUint((u8**)data);
+call 0 never executed
+ -: 2890:
+ #####: 2891: if (!arrayCount) {
+branch 0 never executed
+branch 1 never executed
+ #####: 2892: *array = allocSArray();;
+call 0 never executed
+ #####: 2893: ret;
+ -: 2894: }
+ -: 2895:
+ #####: 2896: loop(arrayCount) {
+branch 0 never executed
+branch 1 never executed
+ -: 2897: char type;
+ #####: 2898: type = **data;
+ -: 2899:
+ #####: 2900: switch(type & 0xF) {
+branch 0 never executed
+branch 1 never executed
+branch 2 never executed
+branch 3 never executed
+branch 4 never executed
+branch 5 never executed
+branch 6 never executed
+branch 7 never executed
+branch 8 never executed
+ -: 2901: case S_UNDEFINED:
+ #####: 2902: (*data)++;
+ #####: 2903: u = allocSUndefined();
+call 0 never executed
+ #####: 2904: sArrayPushTiny(array, (smallt *) u);
+call 0 never executed
+ #####: 2905: break;
+ -: 2906: case S_BOOL:
+ #####: 2907: (*data)++;
+ #####: 2908: bo = allocSBool(type & 0x10);
+call 0 never executed
+ #####: 2909: sArrayPushTiny(array, (smallt *) bo);
+call 0 never executed
+ #####: 2910: break;
+ -: 2911: case S_DICT:
+ #####: 2912: d = NULL;
+ #####: 2913: dictNetDeserialLevel0(&d, data);
+call 0 never executed
+ #####: 2914: sArrayPushTiny(array, (smallt *) d);
+call 0 never executed
+ #####: 2915: break;
+ -: 2916: case S_DOUBLE:
+ #####: 2917: (*data)++;
+ #####: 2918: D = (double *)(*data);
+ #####: 2919: *data += sizeof(double);
+ #####: 2920: Do = allocSDouble(*D);
+call 0 never executed
+ #####: 2921: sArrayPushTiny(array, (smallt *) Do);
+call 0 never executed
+ #####: 2922: break;
+ -: 2923: case S_INT: {
+ #####: 2924: i64 v = netTypeVarintToUint((u8**)data);
+call 0 never executed
+ #####: 2925: v = (v >> 1) ^ ((v << 63) >> 63);
+ #####: 2926: io = allocSInt(v);
+call 0 never executed
+ #####: 2927: sArrayPushTiny(array, (smallt *) io);
+call 0 never executed
+ -: 2928: }
+ #####: 2929: break;
+ -: 2930: case S_STRING:
+ #####: 2931: (*data)++;
+ #####: 2932: s = (char *)(*data);
+ #####: 2933: *data += strlen(s)+1;
+ #####: 2934: so = allocSStringTiny(s);
+call 0 never executed
+ #####: 2935: sArrayPushTiny(array, (smallt *) so);
+call 0 never executed
+ #####: 2936: break;
+ -: 2937: case S_ARRAY:
+ #####: 2938: a = NULL;
+ #####: 2939: arrayNetDeserialLevel0(&a, data);
+call 0 never executed
+ #####: 2940: sArrayPushTiny(array, (smallt *) a);
+call 0 never executed
+ #####: 2941: break;
+ -: 2942: case S_BYTES:
+ #####: 2943: B = allocSBytes();
+call 0 never executed
+ #####: 2944: count = netTypeVarintToUint((u8**)data);
+call 0 never executed
+ #####: 2945: sBytesPushBuffer(&B, data, count);
+call 0 never executed
+ #####: 2946: *data += count;
+ #####: 2947: sArrayPushTiny(array, (smallt *) B);
+call 0 never executed
+ #####: 2948: break;
+ -: 2949: }
+ -: 2950: }
+ -: 2951:}
+ -: 2952:
+function deserialNetSerialLevel0 called 0 returned 0% blocks executed 0%
+ #####: 2953:internal smallJsont* deserialNetSerialLevel0(smallJsont *self, smallBytest *data) {
+ -: 2954:
+ #####: 2955: if (!data) {
+branch 0 never executed
+branch 1 never executed
+ #####: 2956: ret self;
+ -: 2957: }
+ -: 2958:
+ #####: 2959: smallt *o = netDeserialLevel0(data->B);
+call 0 never executed
+ -: 2960:
+ #####: 2961: if (!o) {
+branch 0 never executed
+branch 1 never executed
+ #####: 2962: ret self;
+ -: 2963: }
+ -: 2964:
+ #####: 2965: freeG(self);
+call 0 never executed
+ -: 2966:
+ #####: 2967: setsoG(self, o);
+call 0 never executed
+ -: 2968:
+ #####: 2969: ret self;
+ -: 2970:}
+ -: 2971:
+ -: 2972:// level 1
+ -: 2973:
+function netDeserialLevel1 called 0 returned 0% blocks executed 0%
+ #####: 2974:internal smallt* netDeserialLevel1(sBytest *obj) {
+ #####: 2975: smallt *r = NULL;
+ #####: 2976: double *D = NULL;
+ #####: 2977: char *s = NULL;
+ #####: 2978: sBytest *B = NULL;
+ -: 2979: uint32_t count;
+ #####: 2980: char *data = NULL;
+ #####: 2981: contextt ctx = {.nibble=lowNbl, .nblAddr=NULL, .boolShift = 0, .boolAddr=NULL};
+ -: 2982:
+ #####: 2983: switch(obj->data & 0xF) {
+branch 0 never executed
+branch 1 never executed
+branch 2 never executed
+branch 3 never executed
+branch 4 never executed
+branch 5 never executed
+branch 6 never executed
+branch 7 never executed
+branch 8 never executed
+ -: 2984: case S_UNDEFINED:
+ #####: 2985: r = (smallt *) allocSUndefined();
+call 0 never executed
+ #####: 2986: break;
+ -: 2987: case S_BOOL:
+ #####: 2988: r = (smallt *) allocSBool(obj->data & 0x10);
+call 0 never executed
+ #####: 2989: break;
+ -: 2990: case S_DICT:
+ #####: 2991: data = (char *)&(obj->data);
+ -: 2992: //debug - ctx.dbuf = (u8*) data;
+ #####: 2993: dictNetDeserialLevel1((sDictt **)&r, (u8**)&data, &ctx);
+call 0 never executed
+ #####: 2994: break;
+ -: 2995: case S_DOUBLE:
+ #####: 2996: data = &(obj->data)+1;
+ #####: 2997: D = (double *)data;
+ #####: 2998: r = (smallt *) allocSDouble(*D);
+call 0 never executed
+ #####: 2999: break;
+ -: 3000: case S_INT:
+ #####: 3001: data = &(obj->data);
+ #####: 3002: i64 v = netTypeVarintToUint((u8**)&data);
+call 0 never executed
+ #####: 3003: v = (v >> 1) ^ ((v << 63) >> 63);
+ #####: 3004: r = (smallt *) allocSInt(v);
+call 0 never executed
+ #####: 3005: break;
+ -: 3006: case S_STRING:
+ #####: 3007: s = (char *)&(obj->data)+1;
+ #####: 3008: r = (smallt *) allocSStringTiny(s);
+call 0 never executed
+ #####: 3009: break;
+ -: 3010: case S_ARRAY:
+ #####: 3011: data = (char *)&(obj->data);
+ -: 3012: //debug - ctx.dbuf = (u8*) data;
+ #####: 3013: arrayNetDeserialLevel1((sArrayt **)&r, (u8**)&data, &ctx);
+call 0 never executed
+ #####: 3014: break;
+ -: 3015: case S_BYTES:
+ #####: 3016: B = allocSBytes();
+call 0 never executed
+ #####: 3017: data = &(obj->data);
+ #####: 3018: count = netTypeVarintToUint((u8**)&data);
+call 0 never executed
+ #####: 3019: sBytesPushBuffer(&B, data, count);
+call 0 never executed
+ #####: 3020: r = (smallt *)B;
+ #####: 3021: break;
+ -: 3022: }
+ -: 3023:
+ #####: 3024: ret r;
+ -: 3025:}
+ -: 3026:
+ -: 3027:/**
+ -: 3028: * deserialize dictionary from data
+ -: 3029: *
+ -: 3030: * a new dictionary is allocated
+ -: 3031: *
+ -: 3032: * \param
+ -: 3033: * dict dictionary holding the elements
+ -: 3034: * data serialized dictionary
+ -: 3035: */
+function dictNetDeserialLevel1 called 0 returned 0% blocks executed 0%
+ #####: 3036:internal void dictNetDeserialLevel1(sDictt **dict, u8 **data, contextt *ctx) {
+ #####: 3037: sUndefinedt *u = NULL;
+ #####: 3038: sBoolt *bo = NULL;
+ #####: 3039: double *D = NULL;
+ #####: 3040: sDoublet *Do = NULL;
+ #####: 3041: sDictt *d = NULL;
+ #####: 3042: sIntt *io = NULL;
+ #####: 3043: char *s = NULL;
+ #####: 3044: sStringt *so = NULL;
+ #####: 3045: sArrayt *a = NULL;
+ #####: 3046: sBytest *B = NULL;
+ -: 3047: uint32_t count;
+ -: 3048: uint32_t dictCount;
+ -: 3049:
+ #####: 3050: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3051: dictCount = netTypeVarintToUint(data);
+call 0 never executed
+ -: 3052: }
+ -: 3053: else {
+ -: 3054: // high nibble
+ -: 3055: // type = *(ctx->dbuf + ctx->nblOffset) >> 4;
+ -: 3056: #define readTypeInHighNbl\
+ -: 3057: ctx->nibble = lowNbl;\
+ -: 3058: if (ctx->nblAddr == *data)\
+ -: 3059: /* data points to the type, next byte is count */\
+ -: 3060: (*data)++
+ #####: 3061: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ #####: 3062: dictCount = varintToUint(data);
+call 0 never executed
+ -: 3063: }
+ -: 3064:
+ #####: 3065: if (!dictCount) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3066: *dict = allocSDict();
+call 0 never executed
+ #####: 3067: ret;
+ -: 3068: }
+ -: 3069:
+ #####: 3070: loop(dictCount) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3071: char *key = (char*)*data;
+ #####: 3072: *data += strlen(key)+1;
+ -: 3073: char type;
+ #####: 3074: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3075: type = (**data) & 0xF;
+ -: 3076: }
+ -: 3077: else {
+ -: 3078: // high nibble
+ #####: 3079: type = (*ctx->nblAddr) >> 4;
+ -: 3080: }
+ -: 3081:
+ #####: 3082: switch(type) {
+branch 0 never executed
+branch 1 never executed
+branch 2 never executed
+branch 3 never executed
+branch 4 never executed
+branch 5 never executed
+branch 6 never executed
+branch 7 never executed
+branch 8 never executed
+ -: 3083: case S_UNDEFINED:
+ #####: 3084: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ -: 3085: #define readTypeOnly\
+ -: 3086: ctx->nibble = highNbl;\
+ -: 3087: ctx->nblAddr = *data;\
+ -: 3088: (*data)++
+ #####: 3089: readTypeOnly;
+ -: 3090: }
+ -: 3091: else {
+ -: 3092: // high nibble
+ #####: 3093: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ -: 3094: }
+ #####: 3095: u = allocSUndefined();
+call 0 never executed
+ #####: 3096: sDictPushTiny(dict, key, (smallt *) u);
+call 0 never executed
+ #####: 3097: break;
+ -: 3098: case S_BOOL:
+ #####: 3099: if (!ctx->boolAddr) {
+branch 0 never executed
+branch 1 never executed
+ -: 3100: // new packed bools
+ #####: 3101: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ -: 3102: #define read4bPackedBool\
+ -: 3103: ctx->boolShift = 5;\
+ -: 3104: ctx->boolAddr = *data;\
+ -: 3105: (*data)++
+ #####: 3106: read4bPackedBool;
+ #####: 3107: bo = allocSBool((*ctx->boolAddr) & 0x10);
+call 0 never executed
+ -: 3108: }
+ -: 3109: else {
+ -: 3110: // high nibble
+ #####: 3111: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ -: 3112: #define read8bPackedBool\
+ -: 3113: ctx->boolShift = 1;\
+ -: 3114: ctx->boolAddr = *data;\
+ -: 3115: (*data)++
+ #####: 3116: read8bPackedBool;
+ #####: 3117: bo = allocSBool((*ctx->boolAddr) & 0x1);
+call 0 never executed
+ -: 3118: }
+ -: 3119: }
+ -: 3120: else {
+ -: 3121: // there was a bool before this one, read bits in nibbles
+ #####: 3122: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3123: if (ctx->boolShift == 8) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3124: read4bPackedBool;
+ #####: 3125: bo = allocSBool((*ctx->boolAddr) & 0x10);
+call 0 never executed
+ -: 3126: }
+ -: 3127: else {
+ #####: 3128: readTypeOnly;
+ #####: 3129: bo = allocSBool((*ctx->boolAddr) & (0x1 << (ctx->boolShift++)));
+call 0 never executed
+ -: 3130: }
+ -: 3131: }
+ -: 3132: else {
+ -: 3133: // high nibble
+ #####: 3134: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ #####: 3135: if (ctx->boolShift == 8) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3136: read8bPackedBool;
+ #####: 3137: bo = allocSBool((*ctx->boolAddr) & 0x1);
+call 0 never executed
+ -: 3138: }
+ -: 3139: else {
+ -: 3140: // high nibble
+ #####: 3141: bo = allocSBool((*ctx->boolAddr) & (0x1 << (ctx->boolShift++)));
+call 0 never executed
+ -: 3142: }
+ -: 3143: }
+ -: 3144: }
+ #####: 3145: sDictPushTiny(dict, key, (smallt *) bo);
+call 0 never executed
+ #####: 3146: break;
+ -: 3147: case S_DICT:
+ #####: 3148: d = NULL;
+ #####: 3149: dictNetDeserialLevel1(&d, data, ctx);
+call 0 never executed
+ #####: 3150: sDictPushTiny(dict, key, (smallt *) d);
+call 0 never executed
+ #####: 3151: break;
+ -: 3152: case S_DOUBLE:
+ #####: 3153: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3154: readTypeOnly;
+ -: 3155: }
+ -: 3156: else {
+ -: 3157: // high nibble
+ #####: 3158: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ -: 3159: }
+ #####: 3160: D = (double *)(*data);
+ #####: 3161: *data += sizeof(double);
+ #####: 3162: Do = allocSDouble(*D);
+call 0 never executed
+ #####: 3163: sDictPushTiny(dict, key, (smallt *) Do);
+call 0 never executed
+ #####: 3164: break;
+ -: 3165: case S_INT: {
+ -: 3166: i64 v;
+ #####: 3167: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3168: v = netTypeVarintToUint((u8**)data);
+call 0 never executed
+ -: 3169: }
+ -: 3170: else {
+ -: 3171: // high nibble
+ #####: 3172: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ #####: 3173: v = varintToUint(data);
+call 0 never executed
+ -: 3174: }
+ #####: 3175: v = (v >> 1) ^ ((v << 63) >> 63);
+ #####: 3176: io = allocSInt(v);
+call 0 never executed
+ #####: 3177: sDictPushTiny(dict, key, (smallt *) io);
+call 0 never executed
+ -: 3178: }
+ #####: 3179: break;
+ -: 3180: case S_STRING:
+ #####: 3181: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3182: readTypeOnly;
+ -: 3183: }
+ -: 3184: else {
+ -: 3185: // high nibble
+ #####: 3186: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ -: 3187: }
+ #####: 3188: s = (char *)(*data);
+ #####: 3189: *data += strlen(s)+1;
+ #####: 3190: so = allocSStringTiny(s);
+call 0 never executed
+ #####: 3191: sDictPushTiny(dict, key, (smallt *) so);
+call 0 never executed
+ #####: 3192: break;
+ -: 3193: case S_ARRAY:
+ #####: 3194: a = NULL;
+ #####: 3195: arrayNetDeserialLevel1(&a, data, ctx);
+call 0 never executed
+ #####: 3196: sDictPushTiny(dict, key, (smallt *) a);
+call 0 never executed
+ #####: 3197: break;
+ -: 3198: case S_BYTES:
+ #####: 3199: B = allocSBytes();
+call 0 never executed
+ #####: 3200: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3201: count = netTypeVarintToUint((u8**)data);
+call 0 never executed
+ -: 3202: }
+ -: 3203: else {
+ -: 3204: // high nibble
+ #####: 3205: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ #####: 3206: count = varintToUint((u8**)data);
+call 0 never executed
+ -: 3207: }
+ #####: 3208: sBytesPushBuffer(&B, data, count);
+call 0 never executed
+ #####: 3209: *data += count;
+ #####: 3210: sDictPushTiny(dict, key, (smallt *) B);
+call 0 never executed
+ #####: 3211: break;
+ -: 3212: }
+ -: 3213: }
+ -: 3214:}
+ -: 3215:
+ -: 3216:/**
+ -: 3217: * deserialize array from data
+ -: 3218: *
+ -: 3219: * a new array is allocated
+ -: 3220: *
+ -: 3221: * \param
+ -: 3222: * array holding the elements
+ -: 3223: * data serialized dictionary
+ -: 3224: */
+function arrayNetDeserialLevel1 called 0 returned 0% blocks executed 0%
+ #####: 3225:internal void arrayNetDeserialLevel1(sArrayt **array, u8 **data, contextt *ctx) {
+ #####: 3226: sUndefinedt *u = NULL;
+ #####: 3227: sBoolt *bo = NULL;
+ #####: 3228: double *D = NULL;
+ #####: 3229: sDoublet *Do = NULL;
+ #####: 3230: sDictt *d = NULL;
+ #####: 3231: sIntt *io = NULL;
+ #####: 3232: char *s = NULL;
+ #####: 3233: sStringt *so = NULL;
+ #####: 3234: sArrayt *a = NULL;
+ #####: 3235: sBytest *B = NULL;
+ -: 3236: uint32_t count;
+ -: 3237: uint32_t arrayCount;
+ -: 3238:
+ #####: 3239: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3240: arrayCount = netTypeVarintToUint(data);
+call 0 never executed
+ -: 3241: }
+ -: 3242: else {
+ -: 3243: // high nibble
+ #####: 3244: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ #####: 3245: arrayCount = varintToUint(data);
+call 0 never executed
+ -: 3246: }
+ -: 3247:
+ #####: 3248: if (!arrayCount) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3249: *array = allocSArray();;
+call 0 never executed
+ #####: 3250: ret;
+ -: 3251: }
+ -: 3252:
+ #####: 3253: loop(arrayCount) {
+branch 0 never executed
+branch 1 never executed
+ -: 3254: char type;
+ #####: 3255: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3256: type = (**data) & 0xF;
+ -: 3257: }
+ -: 3258: else {
+ -: 3259: // high nibble
+ #####: 3260: type = (*ctx->nblAddr) >> 4;
+ -: 3261: }
+ -: 3262:
+ #####: 3263: switch(type) {
+branch 0 never executed
+branch 1 never executed
+branch 2 never executed
+branch 3 never executed
+branch 4 never executed
+branch 5 never executed
+branch 6 never executed
+branch 7 never executed
+branch 8 never executed
+ -: 3264: case S_UNDEFINED:
+ #####: 3265: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3266: readTypeOnly;
+ -: 3267: }
+ -: 3268: else {
+ -: 3269: // high nibble
+ #####: 3270: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ -: 3271: }
+ #####: 3272: u = allocSUndefined();
+call 0 never executed
+ #####: 3273: sArrayPushTiny(array, (smallt *) u);
+call 0 never executed
+ #####: 3274: break;
+ -: 3275: case S_BOOL:
+ #####: 3276: if (!ctx->boolAddr) {
+branch 0 never executed
+branch 1 never executed
+ -: 3277: // new packed bools
+ #####: 3278: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3279: read4bPackedBool;
+ #####: 3280: bo = allocSBool((*ctx->boolAddr) & 0x10);
+call 0 never executed
+ -: 3281: }
+ -: 3282: else {
+ -: 3283: // high nibble
+ #####: 3284: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ #####: 3285: read8bPackedBool;
+ #####: 3286: bo = allocSBool((*ctx->boolAddr) & 0x1);
+call 0 never executed
+ -: 3287: }
+ -: 3288: }
+ -: 3289: else {
+ -: 3290: // there was a bool before this one, read bits in nibbles
+ #####: 3291: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3292: if (ctx->boolShift == 8) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3293: read4bPackedBool;
+ #####: 3294: bo = allocSBool((*ctx->boolAddr) & 0x10);
+call 0 never executed
+ -: 3295: }
+ -: 3296: else {
+ #####: 3297: readTypeOnly;
+ #####: 3298: bo = allocSBool((*ctx->boolAddr) & (0x1 << (ctx->boolShift++)));
+call 0 never executed
+ -: 3299: }
+ -: 3300: }
+ -: 3301: else {
+ -: 3302: // high nibble
+ #####: 3303: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ #####: 3304: if (ctx->boolShift == 8) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3305: read8bPackedBool;
+ #####: 3306: bo = allocSBool((*ctx->boolAddr) & 0x1);
+call 0 never executed
+ -: 3307: }
+ -: 3308: else {
+ #####: 3309: bo = allocSBool((*ctx->boolAddr) & (0x1 << (ctx->boolShift++)));
+call 0 never executed
+ -: 3310: }
+ -: 3311: }
+ -: 3312: }
+ #####: 3313: sArrayPushTiny(array, (smallt *) bo);
+call 0 never executed
+ #####: 3314: break;
+ -: 3315: case S_DICT:
+ #####: 3316: d = NULL;
+ #####: 3317: dictNetDeserialLevel1(&d, data, ctx);
+call 0 never executed
+ #####: 3318: sArrayPushTiny(array, (smallt *) d);
+call 0 never executed
+ #####: 3319: break;
+ -: 3320: case S_DOUBLE:
+ #####: 3321: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3322: readTypeOnly;
+ -: 3323: }
+ -: 3324: else {
+ -: 3325: // high nibble
+ #####: 3326: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ -: 3327: }
+ #####: 3328: D = (double *)(*data);
+ #####: 3329: *data += sizeof(double);
+ #####: 3330: Do = allocSDouble(*D);
+call 0 never executed
+ #####: 3331: sArrayPushTiny(array, (smallt *) Do);
+call 0 never executed
+ #####: 3332: break;
+ -: 3333: case S_INT: {
+ -: 3334: i64 v;
+ #####: 3335: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3336: v = netTypeVarintToUint((u8**)data);
+call 0 never executed
+ -: 3337: }
+ -: 3338: else {
+ -: 3339: // high nibble
+ #####: 3340: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ #####: 3341: v = varintToUint(data);
+call 0 never executed
+ -: 3342: }
+ #####: 3343: v = (v >> 1) ^ ((v << 63) >> 63);
+ #####: 3344: io = allocSInt(v);
+call 0 never executed
+ #####: 3345: sArrayPushTiny(array, (smallt *) io);
+call 0 never executed
+ -: 3346: }
+ #####: 3347: break;
+ -: 3348: case S_STRING:
+ #####: 3349: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3350: readTypeOnly;
+ -: 3351: }
+ -: 3352: else {
+ -: 3353: // high nibble
+ #####: 3354: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ -: 3355: }
+ #####: 3356: s = (char *)(*data);
+ #####: 3357: *data += strlen(s)+1;
+ #####: 3358: so = allocSStringTiny(s);
+call 0 never executed
+ #####: 3359: sArrayPushTiny(array, (smallt *) so);
+call 0 never executed
+ #####: 3360: break;
+ -: 3361: case S_ARRAY:
+ #####: 3362: a = NULL;
+ #####: 3363: arrayNetDeserialLevel1(&a, data, ctx);
+call 0 never executed
+ #####: 3364: sArrayPushTiny(array, (smallt *) a);
+call 0 never executed
+ #####: 3365: break;
+ -: 3366: case S_BYTES:
+ #####: 3367: B = allocSBytes();
+call 0 never executed
+ #####: 3368: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3369: count = netTypeVarintToUint((u8**)data);
+call 0 never executed
+ -: 3370: }
+ -: 3371: else {
+ -: 3372: // high nibble
+ #####: 3373: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ #####: 3374: count = varintToUint((u8**)data);
+call 0 never executed
+ -: 3375: }
+ #####: 3376: sBytesPushBuffer(&B, data, count);
+call 0 never executed
+ #####: 3377: *data += count;
+ #####: 3378: sArrayPushTiny(array, (smallt *) B);
+call 0 never executed
+ #####: 3379: break;
+ -: 3380: }
+ -: 3381: }
+ -: 3382:}
+ -: 3383:
+function deserialNetSerialLevel1 called 0 returned 0% blocks executed 0%
+ #####: 3384:internal smallJsont* deserialNetSerialLevel1(smallJsont *self, smallBytest *data) {
+ -: 3385:
+ #####: 3386: if (!data) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3387: ret self;
+ -: 3388: }
+ -: 3389:
+ #####: 3390: smallt *o = netDeserialLevel1(data->B);
+call 0 never executed
+ -: 3391:
+ #####: 3392: if (!o) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3393: ret self;
+ -: 3394: }
+ -: 3395:
+ #####: 3396: freeG(self);
+call 0 never executed
+ -: 3397:
+ #####: 3398: setsoG(self, o);
+call 0 never executed
+ -: 3399:
+ #####: 3400: ret self;
+ -: 3401:}
+ -: 3402:
+ -: 3403:// level 2
+ -: 3404:
+function netDeserialLevel2 called 0 returned 0% blocks executed 0%
+ #####: 3405:internal smallt* netDeserialLevel2(sBytest *obj) {
+ #####: 3406: smallt *r = NULL;
+ #####: 3407: double *D = NULL;
+ #####: 3408: char *s = NULL;
+ #####: 3409: sBytest *B = NULL;
+ -: 3410: uint32_t count;
+ #####: 3411: char *data = NULL;
+ #####: 3412: contextt ctx = {.nibble=lowNbl, .nblAddr=NULL, .boolShift = 0, .boolAddr=NULL};
+ -: 3413:
+ #####: 3414: switch(obj->data & 0xF) {
+branch 0 never executed
+branch 1 never executed
+branch 2 never executed
+branch 3 never executed
+branch 4 never executed
+branch 5 never executed
+branch 6 never executed
+branch 7 never executed
+branch 8 never executed
+branch 9 never executed
+branch 10 never executed
+ -: 3415: case S_UNDEFINED:
+ #####: 3416: r = (smallt *) allocSUndefined();
+call 0 never executed
+ #####: 3417: break;
+ -: 3418: case S_BOOL:
+ #####: 3419: r = (smallt *) allocSBool(obj->data & 0x10);
+call 0 never executed
+ #####: 3420: break;
+ -: 3421: case S_DICT:
+ #####: 3422: data = (char *)&(obj->data);
+ -: 3423: //debug - ctx.dbuf = (u8*) data;
+ #####: 3424: dictNetDeserialLevel2((sDictt **)&r, (u8**)&data, &ctx, /*packed=*/false);
+call 0 never executed
+ #####: 3425: break;
+ -: 3426: case S_DOUBLE:
+ #####: 3427: data = &(obj->data)+1;
+ #####: 3428: D = (double *)data;
+ #####: 3429: r = (smallt *) allocSDouble(*D);
+call 0 never executed
+ #####: 3430: break;
+ -: 3431: case S_INT:
+ #####: 3432: data = &(obj->data);
+ #####: 3433: i64 v = netTypeVarintToUint((u8**)&data);
+call 0 never executed
+ #####: 3434: v = (v >> 1) ^ ((v << 63) >> 63);
+ #####: 3435: r = (smallt *) allocSInt(v);
+call 0 never executed
+ #####: 3436: break;
+ -: 3437: case S_STRING:
+ #####: 3438: s = (char *)&(obj->data)+1;
+ #####: 3439: r = (smallt *) allocSStringTiny(s);
+call 0 never executed
+ #####: 3440: break;
+ -: 3441: case S_ARRAY:
+ #####: 3442: data = (char *)&(obj->data);
+ -: 3443: //debug - ctx.dbuf = (u8*) data;
+ #####: 3444: arrayNetDeserialLevel2((sArrayt **)&r, (u8**)&data, &ctx, /*packed=*/false);
+call 0 never executed
+ #####: 3445: break;
+ -: 3446: case S_BYTES:
+ #####: 3447: B = allocSBytes();
+call 0 never executed
+ #####: 3448: data = &(obj->data);
+ #####: 3449: count = netTypeVarintToUint((u8**)&data);
+call 0 never executed
+ #####: 3450: sBytesPushBuffer(&B, data, count);
+call 0 never executed
+ #####: 3451: r = (smallt *)B;
+ #####: 3452: break;
+ -: 3453: case UNIFORM_DICT:
+ #####: 3454: data = (char *)&(obj->data);
+ -: 3455: //debug - ctx.dbuf = (u8*) data;
+ #####: 3456: uniformDictNetDeserialLevel2((sDictt **)&r, (u8**)&data, &ctx, /*packed=*/false);
+call 0 never executed
+ #####: 3457: break;
+ -: 3458: case UNIFORM_ARRAY:
+ #####: 3459: data = (char *)&(obj->data);
+ -: 3460: //debug - ctx.dbuf = (u8*) data;
+ #####: 3461: uniformArrayNetDeserialLevel2((sArrayt **)&r, (u8**)&data, &ctx, /*packed=*/false);
+call 0 never executed
+ #####: 3462: break;
+ -: 3463: }
+ -: 3464:
+ #####: 3465: ret r;
+ -: 3466:}
+ -: 3467:
+ -: 3468:/**
+ -: 3469: * deserialize dictionary from data
+ -: 3470: *
+ -: 3471: * a new dictionary is allocated
+ -: 3472: *
+ -: 3473: * \param
+ -: 3474: * dict dictionary holding the elements
+ -: 3475: * data serialized dictionary
+ -: 3476: */
+function dictNetDeserialLevel2 called 0 returned 0% blocks executed 0%
+ #####: 3477:internal void dictNetDeserialLevel2(sDictt **dict, u8 **data, contextt *ctx, bool packed) {
+ #####: 3478: sUndefinedt *u = NULL;
+ #####: 3479: sBoolt *bo = NULL;
+ #####: 3480: double *D = NULL;
+ #####: 3481: sDoublet *Do = NULL;
+ #####: 3482: sDictt *d = NULL;
+ #####: 3483: sIntt *io = NULL;
+ #####: 3484: char *s = NULL;
+ #####: 3485: sStringt *so = NULL;
+ #####: 3486: sArrayt *a = NULL;
+ #####: 3487: sBytest *B = NULL;
+ -: 3488: uint32_t count;
+ -: 3489: uint32_t dictCount;
+ -: 3490:
+ #####: 3491: if (packed) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3492: dictCount = varintToUint(data);
+call 0 never executed
+ -: 3493: }
+ -: 3494: else {
+ #####: 3495: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3496: dictCount = netTypeVarintToUint(data);
+call 0 never executed
+ -: 3497: }
+ -: 3498: else {
+ -: 3499: // high nibble
+ -: 3500: // type = *(ctx->dbuf + ctx->nblOffset) >> 4;
+ -: 3501: #define readTypeInHighNbl\
+ -: 3502: ctx->nibble = lowNbl;\
+ -: 3503: if (ctx->nblAddr == *data)\
+ -: 3504: /* data points to the type, next byte is count */\
+ -: 3505: (*data)++
+ #####: 3506: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ #####: 3507: dictCount = varintToUint(data);
+call 0 never executed
+ -: 3508: }
+ -: 3509: }
+ -: 3510:
+ #####: 3511: if (!dictCount) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3512: *dict = allocSDict();
+call 0 never executed
+ #####: 3513: ret;
+ -: 3514: }
+ -: 3515:
+ #####: 3516: loop(dictCount) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3517: char *key = (char*)*data;
+ #####: 3518: *data += strlen(key)+1;
+ -: 3519: char type;
+ #####: 3520: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3521: type = (**data) & 0xF;
+ -: 3522: }
+ -: 3523: else {
+ -: 3524: // high nibble
+ #####: 3525: type = (*ctx->nblAddr) >> 4;
+ -: 3526: }
+ -: 3527:
+ #####: 3528: switch(type) {
+branch 0 never executed
+branch 1 never executed
+branch 2 never executed
+branch 3 never executed
+branch 4 never executed
+branch 5 never executed
+branch 6 never executed
+branch 7 never executed
+branch 8 never executed
+branch 9 never executed
+branch 10 never executed
+ -: 3529: case S_UNDEFINED:
+ #####: 3530: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ -: 3531: #define readTypeOnly\
+ -: 3532: ctx->nibble = highNbl;\
+ -: 3533: ctx->nblAddr = *data;\
+ -: 3534: (*data)++
+ #####: 3535: readTypeOnly;
+ -: 3536: }
+ -: 3537: else {
+ -: 3538: // high nibble
+ #####: 3539: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ -: 3540: }
+ #####: 3541: u = allocSUndefined();
+call 0 never executed
+ #####: 3542: sDictPushTiny(dict, key, (smallt *) u);
+call 0 never executed
+ #####: 3543: break;
+ -: 3544: case S_BOOL:
+ #####: 3545: if (!ctx->boolAddr) {
+branch 0 never executed
+branch 1 never executed
+ -: 3546: // new packed bools
+ #####: 3547: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ -: 3548: #define read4bPackedBool\
+ -: 3549: ctx->boolShift = 5;\
+ -: 3550: ctx->boolAddr = *data;\
+ -: 3551: (*data)++
+ #####: 3552: read4bPackedBool;
+ #####: 3553: bo = allocSBool((*ctx->boolAddr) & 0x10);
+call 0 never executed
+ -: 3554: }
+ -: 3555: else {
+ -: 3556: // high nibble
+ #####: 3557: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ -: 3558: #define read8bPackedBool\
+ -: 3559: ctx->boolShift = 1;\
+ -: 3560: ctx->boolAddr = *data;\
+ -: 3561: (*data)++
+ #####: 3562: read8bPackedBool;
+ #####: 3563: bo = allocSBool((*ctx->boolAddr) & 0x1);
+call 0 never executed
+ -: 3564: }
+ -: 3565: }
+ -: 3566: else {
+ -: 3567: // there was a bool before this one, read bits in nibbles
+ #####: 3568: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3569: if (ctx->boolShift == 8) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3570: read4bPackedBool;
+ #####: 3571: bo = allocSBool((*ctx->boolAddr) & 0x10);
+call 0 never executed
+ -: 3572: }
+ -: 3573: else {
+ #####: 3574: readTypeOnly;
+ #####: 3575: bo = allocSBool((*ctx->boolAddr) & (0x1 << (ctx->boolShift++)));
+call 0 never executed
+ -: 3576: }
+ -: 3577: }
+ -: 3578: else {
+ -: 3579: // high nibble
+ #####: 3580: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ #####: 3581: if (ctx->boolShift == 8) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3582: read8bPackedBool;
+ #####: 3583: bo = allocSBool((*ctx->boolAddr) & 0x1);
+call 0 never executed
+ -: 3584: }
+ -: 3585: else {
+ -: 3586: // high nibble
+ #####: 3587: bo = allocSBool((*ctx->boolAddr) & (0x1 << (ctx->boolShift++)));
+call 0 never executed
+ -: 3588: }
+ -: 3589: }
+ -: 3590: }
+ #####: 3591: sDictPushTiny(dict, key, (smallt *) bo);
+call 0 never executed
+ #####: 3592: break;
+ -: 3593: case S_DICT:
+ #####: 3594: d = NULL;
+ #####: 3595: dictNetDeserialLevel2(&d, data, ctx, /*packed=*/false);
+call 0 never executed
+ #####: 3596: sDictPushTiny(dict, key, (smallt *) d);
+call 0 never executed
+ #####: 3597: break;
+ -: 3598: case S_DOUBLE:
+ #####: 3599: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3600: readTypeOnly;
+ -: 3601: }
+ -: 3602: else {
+ -: 3603: // high nibble
+ #####: 3604: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ -: 3605: }
+ #####: 3606: D = (double *)(*data);
+ #####: 3607: *data += sizeof(double);
+ #####: 3608: Do = allocSDouble(*D);
+call 0 never executed
+ #####: 3609: sDictPushTiny(dict, key, (smallt *) Do);
+call 0 never executed
+ #####: 3610: break;
+ -: 3611: case S_INT: {
+ -: 3612: i64 v;
+ #####: 3613: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3614: v = netTypeVarintToUint((u8**)data);
+call 0 never executed
+ -: 3615: }
+ -: 3616: else {
+ -: 3617: // high nibble
+ #####: 3618: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ #####: 3619: v = varintToUint(data);
+call 0 never executed
+ -: 3620: }
+ #####: 3621: v = (v >> 1) ^ ((v << 63) >> 63);
+ #####: 3622: io = allocSInt(v);
+call 0 never executed
+ #####: 3623: sDictPushTiny(dict, key, (smallt *) io);
+call 0 never executed
+ -: 3624: }
+ #####: 3625: break;
+ -: 3626: case S_STRING:
+ #####: 3627: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3628: readTypeOnly;
+ -: 3629: }
+ -: 3630: else {
+ -: 3631: // high nibble
+ #####: 3632: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ -: 3633: }
+ #####: 3634: s = (char *)(*data);
+ #####: 3635: *data += strlen(s)+1;
+ #####: 3636: so = allocSStringTiny(s);
+call 0 never executed
+ #####: 3637: sDictPushTiny(dict, key, (smallt *) so);
+call 0 never executed
+ #####: 3638: break;
+ -: 3639: case S_ARRAY:
+ #####: 3640: a = NULL;
+ #####: 3641: arrayNetDeserialLevel2(&a, data, ctx, /*packed=*/false);
+call 0 never executed
+ #####: 3642: sDictPushTiny(dict, key, (smallt *) a);
+call 0 never executed
+ #####: 3643: break;
+ -: 3644: case S_BYTES:
+ #####: 3645: B = allocSBytes();
+call 0 never executed
+ #####: 3646: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3647: count = netTypeVarintToUint((u8**)data);
+call 0 never executed
+ -: 3648: }
+ -: 3649: else {
+ -: 3650: // high nibble
+ #####: 3651: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ #####: 3652: count = varintToUint((u8**)data);
+call 0 never executed
+ -: 3653: }
+ #####: 3654: sBytesPushBuffer(&B, data, count);
+call 0 never executed
+ #####: 3655: *data += count;
+ #####: 3656: sDictPushTiny(dict, key, (smallt *) B);
+call 0 never executed
+ #####: 3657: break;
+ -: 3658: case UNIFORM_DICT:
+ #####: 3659: d = NULL;
+ #####: 3660: uniformDictNetDeserialLevel2(&d, data, ctx, /*packed=*/false);
+call 0 never executed
+ #####: 3661: sDictPushTiny(dict, key, (smallt *) d);
+call 0 never executed
+ #####: 3662: break;
+ -: 3663: case UNIFORM_ARRAY:
+ #####: 3664: a = NULL;
+ #####: 3665: uniformArrayNetDeserialLevel2(&a, data, ctx, /*packed=*/false);
+call 0 never executed
+ #####: 3666: sDictPushTiny(dict, key, (smallt *) a);
+call 0 never executed
+ #####: 3667: break;
+ -: 3668: }
+ -: 3669: }
+ -: 3670:}
+ -: 3671:
+ -: 3672:/**
+ -: 3673: * deserialize dictionary from data
+ -: 3674: *
+ -: 3675: * a new dictionary is allocated
+ -: 3676: *
+ -: 3677: * \param
+ -: 3678: * dict dictionary holding the elements
+ -: 3679: * data serialized dictionary
+ -: 3680: */
+function uniformDictNetDeserialLevel2 called 0 returned 0% blocks executed 0%
+ #####: 3681:internal void uniformDictNetDeserialLevel2(sDictt **dict, u8 **data, contextt *ctx, bool packed) {
+ #####: 3682: sUndefinedt *u = NULL;
+ #####: 3683: sBoolt *bo = NULL;
+ #####: 3684: double *D = NULL;
+ #####: 3685: sDoublet *Do = NULL;
+ #####: 3686: sDictt *d = NULL;
+ #####: 3687: sIntt *io = NULL;
+ #####: 3688: char *s = NULL;
+ #####: 3689: sStringt *so = NULL;
+ #####: 3690: sArrayt *a = NULL;
+ #####: 3691: sBytest *B = NULL;
+ -: 3692: uint32_t count;
+ -: 3693: uint32_t dictCount;
+ -: 3694: u8 type;
+ -: 3695:
+ #####: 3696: if (packed) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3697: type = (**data) & 0xF;
+ #####: 3698: dictCount = netTypeVarintToUint(data);
+call 0 never executed
+ -: 3699: }
+ -: 3700: else {
+ #####: 3701: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3702: type = (**data) >> 4;
+ #####: 3703: (*data)++;
+ #####: 3704: dictCount = varintToUint(data);
+call 0 never executed
+ -: 3705: }
+ -: 3706: else {
+ #####: 3707: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ #####: 3708: type = (**data) & 0xF;
+ #####: 3709: dictCount = netTypeVarintToUint(data);
+call 0 never executed
+ -: 3710: }
+ -: 3711: }
+ -: 3712:
+ #####: 3713: if (!dictCount) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3714: *dict = allocSDict();
+call 0 never executed
+ #####: 3715: ret;
+ -: 3716: }
+ -: 3717:
+ -: 3718:
+ #####: 3719: switch(type) {
+branch 0 never executed
+branch 1 never executed
+branch 2 never executed
+branch 3 never executed
+branch 4 never executed
+branch 5 never executed
+branch 6 never executed
+branch 7 never executed
+branch 8 never executed
+branch 9 never executed
+branch 10 never executed
+ -: 3720: case S_UNDEFINED:
+ #####: 3721: loop(dictCount) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3722: char *key = (char*)*data;
+ #####: 3723: *data += strlen(key)+1;
+ #####: 3724: u = allocSUndefined();
+call 0 never executed
+ #####: 3725: sDictPushTiny(dict, key, (smallt *) u);
+call 0 never executed
+ -: 3726: }
+ #####: 3727: break;
+ -: 3728: case S_BOOL:
+ #####: 3729: loop(dictCount) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3730: char *key = (char*)*data;
+ #####: 3731: *data += strlen(key)+1;
+ #####: 3732: if (!ctx->boolAddr) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3733: read8bPackedBool;
+ #####: 3734: ctx->boolShift = 0;
+ -: 3735: }
+ #####: 3736: if (ctx->boolShift == 8) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3737: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ #####: 3738: read8bPackedBool;
+ #####: 3739: bo = allocSBool((*ctx->boolAddr) & 0x1);
+call 0 never executed
+ -: 3740: }
+ -: 3741: else {
+ -: 3742: // high nibble
+ #####: 3743: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ #####: 3744: bo = allocSBool((*ctx->boolAddr) & (0x1 << (ctx->boolShift++)));
+call 0 never executed
+ -: 3745: }
+ #####: 3746: sDictPushTiny(dict, key, (smallt *) bo);
+call 0 never executed
+ -: 3747: }
+ #####: 3748: break;
+ -: 3749: case S_DICT:
+ #####: 3750: loop(dictCount) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3751: char *key = (char*)*data;
+ #####: 3752: *data += strlen(key)+1;
+ #####: 3753: d = NULL;
+ #####: 3754: dictNetDeserialLevel2(&d, data, ctx, /*packed=*/true);
+call 0 never executed
+ #####: 3755: sDictPushTiny(dict, key, (smallt *) d);
+call 0 never executed
+ -: 3756: }
+ #####: 3757: break;
+ -: 3758: case S_DOUBLE:
+ #####: 3759: loop(dictCount) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3760: char *key = (char*)*data;
+ #####: 3761: *data += strlen(key)+1;
+ #####: 3762: D = (double *)(*data);
+ #####: 3763: *data += sizeof(double);
+ #####: 3764: Do = allocSDouble(*D);
+call 0 never executed
+ #####: 3765: sDictPushTiny(dict, key, (smallt *) Do);
+call 0 never executed
+ -: 3766: }
+ #####: 3767: break;
+ -: 3768: case S_INT:
+ #####: 3769: loop(dictCount) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3770: char *key = (char*)*data;
+ #####: 3771: *data += strlen(key)+1;
+ #####: 3772: i64 v = varintToUint(data);
+call 0 never executed
+ #####: 3773: v = (v >> 1) ^ ((v << 63) >> 63);
+ #####: 3774: io = allocSInt(v);
+call 0 never executed
+ #####: 3775: sDictPushTiny(dict, key, (smallt *) io);
+call 0 never executed
+ -: 3776: }
+ #####: 3777: break;
+ -: 3778: case S_STRING:
+ #####: 3779: loop(dictCount) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3780: char *key = (char*)*data;
+ #####: 3781: *data += strlen(key)+1;
+ #####: 3782: s = (char *)(*data);
+ #####: 3783: *data += strlen(s)+1;
+ #####: 3784: so = allocSStringTiny(s);
+call 0 never executed
+ #####: 3785: sDictPushTiny(dict, key, (smallt *) so);
+call 0 never executed
+ -: 3786: }
+ #####: 3787: break;
+ -: 3788: case S_ARRAY:
+ #####: 3789: loop(dictCount) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3790: char *key = (char*)*data;
+ #####: 3791: *data += strlen(key)+1;
+ #####: 3792: a = NULL;
+ #####: 3793: arrayNetDeserialLevel2(&a, data, ctx, /*packed=*/true);
+call 0 never executed
+ #####: 3794: sDictPushTiny(dict, key, (smallt *) a);
+call 0 never executed
+ -: 3795: }
+ #####: 3796: break;
+ -: 3797: case S_BYTES:
+ #####: 3798: loop(dictCount) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3799: char *key = (char*)*data;
+ #####: 3800: *data += strlen(key)+1;
+ #####: 3801: B = allocSBytes();
+call 0 never executed
+ #####: 3802: count = varintToUint((u8**)data);
+call 0 never executed
+ #####: 3803: sBytesPushBuffer(&B, data, count);
+call 0 never executed
+ #####: 3804: *data += count;
+ #####: 3805: sDictPushTiny(dict, key, (smallt *) B);
+call 0 never executed
+ -: 3806: }
+ #####: 3807: break;
+ -: 3808: case UNIFORM_DICT:
+ #####: 3809: loop(dictCount) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3810: char *key = (char*)*data;
+ #####: 3811: *data += strlen(key)+1;
+ #####: 3812: d = NULL;
+ #####: 3813: uniformDictNetDeserialLevel2(&d, data, ctx, /*packed=*/true);
+call 0 never executed
+ #####: 3814: sDictPushTiny(dict, key, (smallt *) d);
+call 0 never executed
+ -: 3815: }
+ #####: 3816: break;
+ -: 3817: case UNIFORM_ARRAY:
+ #####: 3818: loop(dictCount) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3819: char *key = (char*)*data;
+ #####: 3820: *data += strlen(key)+1;
+ #####: 3821: a = NULL;
+ #####: 3822: uniformArrayNetDeserialLevel2(&a, data, ctx, /*packed=*/true);
+call 0 never executed
+ #####: 3823: sDictPushTiny(dict, key, (smallt *) a);
+call 0 never executed
+ -: 3824: }
+ #####: 3825: break;
+ -: 3826: }
+ -: 3827:}
+ -: 3828:
+ -: 3829:/**
+ -: 3830: * deserialize array from data
+ -: 3831: *
+ -: 3832: * a new array is allocated
+ -: 3833: *
+ -: 3834: * \param
+ -: 3835: * array holding the elements
+ -: 3836: * data serialized dictionary
+ -: 3837: */
+function arrayNetDeserialLevel2 called 0 returned 0% blocks executed 0%
+ #####: 3838:internal void arrayNetDeserialLevel2(sArrayt **array, u8 **data, contextt *ctx, bool packed) {
+ #####: 3839: sUndefinedt *u = NULL;
+ #####: 3840: sBoolt *bo = NULL;
+ #####: 3841: double *D = NULL;
+ #####: 3842: sDoublet *Do = NULL;
+ #####: 3843: sDictt *d = NULL;
+ #####: 3844: sIntt *io = NULL;
+ #####: 3845: char *s = NULL;
+ #####: 3846: sStringt *so = NULL;
+ #####: 3847: sArrayt *a = NULL;
+ #####: 3848: sBytest *B = NULL;
+ -: 3849: uint32_t count;
+ -: 3850: uint32_t arrayCount;
+ -: 3851:
+ #####: 3852: if (packed) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3853: arrayCount = varintToUint(data);
+call 0 never executed
+ -: 3854: }
+ -: 3855: else {
+ #####: 3856: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3857: arrayCount = netTypeVarintToUint(data);
+call 0 never executed
+ -: 3858: }
+ -: 3859: else {
+ -: 3860: // high nibble
+ #####: 3861: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ #####: 3862: arrayCount = varintToUint(data);
+call 0 never executed
+ -: 3863: }
+ -: 3864: }
+ -: 3865:
+ #####: 3866: if (!arrayCount) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3867: *array = allocSArray();;
+call 0 never executed
+ #####: 3868: ret;
+ -: 3869: }
+ -: 3870:
+ #####: 3871: loop(arrayCount) {
+branch 0 never executed
+branch 1 never executed
+ -: 3872: char type;
+ #####: 3873: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3874: type = (**data) & 0xF;
+ -: 3875: }
+ -: 3876: else {
+ -: 3877: // high nibble
+ #####: 3878: type = (*ctx->nblAddr) >> 4;
+ -: 3879: }
+ -: 3880:
+ #####: 3881: switch(type) {
+branch 0 never executed
+branch 1 never executed
+branch 2 never executed
+branch 3 never executed
+branch 4 never executed
+branch 5 never executed
+branch 6 never executed
+branch 7 never executed
+branch 8 never executed
+branch 9 never executed
+branch 10 never executed
+ -: 3882: case S_UNDEFINED:
+ #####: 3883: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3884: readTypeOnly;
+ -: 3885: }
+ -: 3886: else {
+ -: 3887: // high nibble
+ #####: 3888: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ -: 3889: }
+ #####: 3890: u = allocSUndefined();
+call 0 never executed
+ #####: 3891: sArrayPushTiny(array, (smallt *) u);
+call 0 never executed
+ #####: 3892: break;
+ -: 3893: case S_BOOL:
+ #####: 3894: if (!ctx->boolAddr) {
+branch 0 never executed
+branch 1 never executed
+ -: 3895: // new packed bools
+ #####: 3896: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3897: read4bPackedBool;
+ #####: 3898: bo = allocSBool((*ctx->boolAddr) & 0x10);
+call 0 never executed
+ -: 3899: }
+ -: 3900: else {
+ -: 3901: // high nibble
+ #####: 3902: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ #####: 3903: read8bPackedBool;
+ #####: 3904: bo = allocSBool((*ctx->boolAddr) & 0x1);
+call 0 never executed
+ -: 3905: }
+ -: 3906: }
+ -: 3907: else {
+ -: 3908: // there was a bool before this one, read bits in nibbles
+ #####: 3909: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3910: if (ctx->boolShift == 8) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3911: read4bPackedBool;
+ #####: 3912: bo = allocSBool((*ctx->boolAddr) & 0x10);
+call 0 never executed
+ -: 3913: }
+ -: 3914: else {
+ #####: 3915: readTypeOnly;
+ #####: 3916: bo = allocSBool((*ctx->boolAddr) & (0x1 << (ctx->boolShift++)));
+call 0 never executed
+ -: 3917: }
+ -: 3918: }
+ -: 3919: else {
+ -: 3920: // high nibble
+ #####: 3921: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ #####: 3922: if (ctx->boolShift == 8) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3923: read8bPackedBool;
+ #####: 3924: bo = allocSBool((*ctx->boolAddr) & 0x1);
+call 0 never executed
+ -: 3925: }
+ -: 3926: else {
+ #####: 3927: bo = allocSBool((*ctx->boolAddr) & (0x1 << (ctx->boolShift++)));
+call 0 never executed
+ -: 3928: }
+ -: 3929: }
+ -: 3930: }
+ #####: 3931: sArrayPushTiny(array, (smallt *) bo);
+call 0 never executed
+ #####: 3932: break;
+ -: 3933: case S_DICT:
+ #####: 3934: d = NULL;
+ #####: 3935: dictNetDeserialLevel2(&d, data, ctx, /*packed=*/false);
+call 0 never executed
+ #####: 3936: sArrayPushTiny(array, (smallt *) d);
+call 0 never executed
+ #####: 3937: break;
+ -: 3938: case S_DOUBLE:
+ #####: 3939: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3940: readTypeOnly;
+ -: 3941: }
+ -: 3942: else {
+ -: 3943: // high nibble
+ #####: 3944: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ -: 3945: }
+ #####: 3946: D = (double *)(*data);
+ #####: 3947: *data += sizeof(double);
+ #####: 3948: Do = allocSDouble(*D);
+call 0 never executed
+ #####: 3949: sArrayPushTiny(array, (smallt *) Do);
+call 0 never executed
+ #####: 3950: break;
+ -: 3951: case S_INT: {
+ -: 3952: i64 v;
+ #####: 3953: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3954: v = netTypeVarintToUint((u8**)data);
+call 0 never executed
+ -: 3955: }
+ -: 3956: else {
+ -: 3957: // high nibble
+ #####: 3958: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ #####: 3959: v = varintToUint(data);
+call 0 never executed
+ -: 3960: }
+ #####: 3961: v = (v >> 1) ^ ((v << 63) >> 63);
+ #####: 3962: io = allocSInt(v);
+call 0 never executed
+ #####: 3963: sArrayPushTiny(array, (smallt *) io);
+call 0 never executed
+ -: 3964: }
+ #####: 3965: break;
+ -: 3966: case S_STRING:
+ #####: 3967: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3968: readTypeOnly;
+ -: 3969: }
+ -: 3970: else {
+ -: 3971: // high nibble
+ #####: 3972: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ -: 3973: }
+ #####: 3974: s = (char *)(*data);
+ #####: 3975: *data += strlen(s)+1;
+ #####: 3976: so = allocSStringTiny(s);
+call 0 never executed
+ #####: 3977: sArrayPushTiny(array, (smallt *) so);
+call 0 never executed
+ #####: 3978: break;
+ -: 3979: case S_ARRAY:
+ #####: 3980: a = NULL;
+ #####: 3981: arrayNetDeserialLevel2(&a, data, ctx, /*packed=*/false);
+call 0 never executed
+ #####: 3982: sArrayPushTiny(array, (smallt *) a);
+call 0 never executed
+ #####: 3983: break;
+ -: 3984: case S_BYTES:
+ #####: 3985: B = allocSBytes();
+call 0 never executed
+ #####: 3986: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 3987: count = netTypeVarintToUint((u8**)data);
+call 0 never executed
+ -: 3988: }
+ -: 3989: else {
+ -: 3990: // high nibble
+ #####: 3991: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ #####: 3992: count = varintToUint((u8**)data);
+call 0 never executed
+ -: 3993: }
+ #####: 3994: sBytesPushBuffer(&B, data, count);
+call 0 never executed
+ #####: 3995: *data += count;
+ #####: 3996: sArrayPushTiny(array, (smallt *) B);
+call 0 never executed
+ #####: 3997: break;
+ -: 3998: case UNIFORM_DICT:
+ #####: 3999: d = NULL;
+ #####: 4000: uniformDictNetDeserialLevel2(&d, data, ctx, /*packed=*/false);
+call 0 never executed
+ #####: 4001: sArrayPushTiny(array, (smallt *) d);
+call 0 never executed
+ #####: 4002: break;
+ -: 4003: case UNIFORM_ARRAY:
+ #####: 4004: a = NULL;
+ #####: 4005: uniformArrayNetDeserialLevel2(&a, data, ctx, /*packed=*/false);
+call 0 never executed
+ #####: 4006: sArrayPushTiny(array, (smallt *) a);
+call 0 never executed
+ #####: 4007: break;
+ -: 4008: }
+ -: 4009: }
+ -: 4010:}
+ -: 4011:
+function uniformArrayNetDeserialLevel2 called 0 returned 0% blocks executed 0%
+ #####: 4012:internal void uniformArrayNetDeserialLevel2(sArrayt **array, u8 **data, contextt *ctx, bool packed) {
+ #####: 4013: sUndefinedt *u = NULL;
+ #####: 4014: sBoolt *bo = NULL;
+ #####: 4015: double *D = NULL;
+ #####: 4016: sDoublet *Do = NULL;
+ #####: 4017: sDictt *d = NULL;
+ #####: 4018: sIntt *io = NULL;
+ #####: 4019: char *s = NULL;
+ #####: 4020: sStringt *so = NULL;
+ #####: 4021: sArrayt *a = NULL;
+ #####: 4022: sBytest *B = NULL;
+ -: 4023: uint32_t count;
+ -: 4024: uint32_t arrayCount;
+ -: 4025: u8 type;
+ -: 4026:
+ #####: 4027: if (packed) {
+branch 0 never executed
+branch 1 never executed
+ #####: 4028: type = (**data) & 0xF;
+ #####: 4029: arrayCount = netTypeVarintToUint(data);
+call 0 never executed
+ -: 4030: }
+ -: 4031: else {
+ #####: 4032: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 4033: type = (**data) >> 4;
+ #####: 4034: (*data)++;
+ #####: 4035: arrayCount = varintToUint(data);
+call 0 never executed
+ -: 4036: }
+ -: 4037: else {
+ #####: 4038: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ #####: 4039: type = (**data) & 0xF;
+ #####: 4040: arrayCount = netTypeVarintToUint(data);
+call 0 never executed
+ -: 4041: }
+ -: 4042: }
+ -: 4043:
+ #####: 4044: if (!arrayCount) {
+branch 0 never executed
+branch 1 never executed
+ #####: 4045: *array = allocSArray();;
+call 0 never executed
+ #####: 4046: ret;
+ -: 4047: }
+ -: 4048:
+ #####: 4049: switch(type) {
+branch 0 never executed
+branch 1 never executed
+branch 2 never executed
+branch 3 never executed
+branch 4 never executed
+branch 5 never executed
+branch 6 never executed
+branch 7 never executed
+branch 8 never executed
+branch 9 never executed
+branch 10 never executed
+ -: 4050: case S_UNDEFINED:
+ #####: 4051: loop(arrayCount) {
+branch 0 never executed
+branch 1 never executed
+ #####: 4052: u = allocSUndefined();
+call 0 never executed
+ #####: 4053: sArrayPushTiny(array, (smallt *) u);
+call 0 never executed
+ -: 4054: }
+ #####: 4055: break;
+ -: 4056: case S_BOOL:
+ #####: 4057: loop(arrayCount) {
+branch 0 never executed
+branch 1 never executed
+ #####: 4058: if (!ctx->boolAddr) {
+branch 0 never executed
+branch 1 never executed
+ #####: 4059: read8bPackedBool;
+ #####: 4060: ctx->boolShift = 0;
+ -: 4061: }
+ #####: 4062: if (ctx->boolShift == 8) {
+branch 0 never executed
+branch 1 never executed
+ #####: 4063: read8bPackedBool;
+ #####: 4064: bo = allocSBool((*ctx->boolAddr) & 0x1);
+call 0 never executed
+ -: 4065: }
+ -: 4066: else {
+ #####: 4067: bo = allocSBool((*ctx->boolAddr) & (0x1 << (ctx->boolShift++)));
+call 0 never executed
+ -: 4068: }
+ #####: 4069: sArrayPushTiny(array, (smallt *) bo);
+call 0 never executed
+ -: 4070: }
+ #####: 4071: break;
+ -: 4072: case S_DICT:
+ #####: 4073: loop(arrayCount) {
+branch 0 never executed
+branch 1 never executed
+ #####: 4074: d = NULL;
+ #####: 4075: dictNetDeserialLevel2(&d, data, ctx, /*packed=*/true);
+call 0 never executed
+ #####: 4076: sArrayPushTiny(array, (smallt *) d);
+call 0 never executed
+ -: 4077: }
+ #####: 4078: break;
+ -: 4079: case S_DOUBLE:
+ #####: 4080: loop(arrayCount) {
+branch 0 never executed
+branch 1 never executed
+ #####: 4081: D = (double *)(*data);
+ #####: 4082: *data += sizeof(double);
+ #####: 4083: Do = allocSDouble(*D);
+call 0 never executed
+ #####: 4084: sArrayPushTiny(array, (smallt *) Do);
+call 0 never executed
+ -: 4085: }
+ #####: 4086: break;
+ -: 4087: case S_INT:
+ #####: 4088: loop(arrayCount) {
+branch 0 never executed
+branch 1 never executed
+ #####: 4089: i64 v = varintToUint(data);
+call 0 never executed
+ #####: 4090: v = (v >> 1) ^ ((v << 63) >> 63);
+ #####: 4091: io = allocSInt(v);
+call 0 never executed
+ #####: 4092: sArrayPushTiny(array, (smallt *) io);
+call 0 never executed
+ -: 4093: }
+ #####: 4094: break;
+ -: 4095: case S_STRING:
+ #####: 4096: loop(arrayCount) {
+branch 0 never executed
+branch 1 never executed
+ #####: 4097: s = (char *)(*data);
+ #####: 4098: *data += strlen(s)+1;
+ #####: 4099: so = allocSStringTiny(s);
+call 0 never executed
+ #####: 4100: sArrayPushTiny(array, (smallt *) so);
+call 0 never executed
+ -: 4101: }
+ #####: 4102: break;
+ -: 4103: case S_ARRAY:
+ #####: 4104: loop(arrayCount) {
+branch 0 never executed
+branch 1 never executed
+ #####: 4105: a = NULL;
+ #####: 4106: arrayNetDeserialLevel2(&a, data, ctx, /*packed=*/true);
+call 0 never executed
+ #####: 4107: sArrayPushTiny(array, (smallt *) a);
+call 0 never executed
+ -: 4108: }
+ #####: 4109: break;
+ -: 4110: case S_BYTES:
+ #####: 4111: loop(arrayCount) {
+branch 0 never executed
+branch 1 never executed
+ #####: 4112: B = allocSBytes();
+call 0 never executed
+ #####: 4113: count = varintToUint((u8**)data);
+call 0 never executed
+ #####: 4114: sBytesPushBuffer(&B, data, count);
+call 0 never executed
+ #####: 4115: *data += count;
+ #####: 4116: sArrayPushTiny(array, (smallt *) B);
+call 0 never executed
+ -: 4117: }
+ #####: 4118: break;
+ -: 4119: case UNIFORM_DICT:
+ #####: 4120: loop(arrayCount) {
+branch 0 never executed
+branch 1 never executed
+ #####: 4121: d = NULL;
+ #####: 4122: uniformDictNetDeserialLevel2(&d, data, ctx, /*packed=*/true);
+call 0 never executed
+ #####: 4123: sArrayPushTiny(array, (smallt *) d);
+call 0 never executed
+ -: 4124: }
+ #####: 4125: break;
+ -: 4126: case UNIFORM_ARRAY:
+ #####: 4127: loop(arrayCount) {
+branch 0 never executed
+branch 1 never executed
+ #####: 4128: a = NULL;
+ #####: 4129: uniformArrayNetDeserialLevel2(&a, data, ctx, /*packed=*/true);
+call 0 never executed
+ #####: 4130: sArrayPushTiny(array, (smallt *) a);
+call 0 never executed
+ -: 4131: }
+ #####: 4132: break;
+ -: 4133: }
+ -: 4134:}
+ -: 4135:
+function deserialNetSerialLevel2 called 0 returned 0% blocks executed 0%
+ #####: 4136:internal smallJsont* deserialNetSerialLevel2(smallJsont *self, smallBytest *data) {
+ -: 4137:
+ #####: 4138: if (!data) {
+branch 0 never executed
+branch 1 never executed
+ #####: 4139: ret self;
+ -: 4140: }
+ -: 4141:
+ #####: 4142: smallt *o = netDeserialLevel2(data->B);
+call 0 never executed
+ -: 4143:
+ #####: 4144: if (!o) {
+branch 0 never executed
+branch 1 never executed
+ #####: 4145: ret self;
+ -: 4146: }
+ -: 4147:
+ #####: 4148: freeG(self);
+call 0 never executed
+ -: 4149:
+ #####: 4150: setsoG(self, o);
+call 0 never executed
+ -: 4151:
+ #####: 4152: ret self;
+ -: 4153:}
+ -: 4154:
+ -: 4155:// level 3
+ -: 4156:
+function netDeserial called 76 returned 100% blocks executed 85%
+ 76: 4157:internal smallt* netDeserial(sBytest *obj) {
+ 76: 4158: smallt *r = NULL;
+ 76: 4159: double *D = NULL;
+ 76: 4160: char *s = NULL;
+ 76: 4161: sBytest *B = NULL;
+ -: 4162: uint32_t count;
+ 76: 4163: char *data = NULL;
+ 76: 4164: contextt ctx = {.nibble=lowNbl, .nblAddr=NULL, .boolShift = 0, .boolAddr=NULL};
+ -: 4165:
+ 76: 4166: switch(obj->data & 0xF) {
+branch 0 taken 1%
+branch 1 taken 1%
+branch 2 taken 32%
+branch 3 taken 1%
+branch 4 taken 1%
+branch 5 taken 1%
+branch 6 taken 32%
+branch 7 taken 0%
+branch 8 taken 16%
+branch 9 taken 14%
+branch 10 taken 0%
+ -: 4167: case S_UNDEFINED:
+ 1: 4168: r = (smallt *) allocSUndefined();
+call 0 returned 100%
+ 1: 4169: break;
+ -: 4170: case S_BOOL:
+ 1: 4171: r = (smallt *) allocSBool(obj->data & 0x10);
+call 0 returned 100%
+ 1: 4172: break;
+ -: 4173: case S_DICT:
+ 24: 4174: data = (char *)&(obj->data);
+ -: 4175: //debug - ctx.dbuf = (u8*) data;
+ 24: 4176: dictNetDeserial((sDictt **)&r, (u8**)&data, &ctx, /*packed=*/false);
+call 0 returned 100%
+ 24: 4177: break;
+ -: 4178: case S_DOUBLE:
+ 1: 4179: data = &(obj->data)+1;
+ 1: 4180: D = (double *)data;
+ 1: 4181: r = (smallt *) allocSDouble(*D);
+call 0 returned 100%
+ 1: 4182: break;
+ -: 4183: case S_INT:
+ 1: 4184: data = &(obj->data);
+ 1: 4185: i64 v = netTypeVarintToUint((u8**)&data);
+call 0 returned 100%
+ 1: 4186: v = (v >> 1) ^ ((v << 63) >> 63);
+ 1: 4187: r = (smallt *) allocSInt(v);
+call 0 returned 100%
+ 1: 4188: break;
+ -: 4189: case S_STRING:
+ 1: 4190: s = (char *)&(obj->data)+1;
+ 1: 4191: r = (smallt *) allocSStringTiny(s);
+call 0 returned 100%
+ 1: 4192: break;
+ -: 4193: case S_ARRAY:
+ 24: 4194: data = (char *)&(obj->data);
+ -: 4195: //debug - ctx.dbuf = (u8*) data;
+ 24: 4196: arrayNetDeserial((sArrayt **)&r, (u8**)&data, &ctx, /*packed=*/false);
+call 0 returned 100%
+ 24: 4197: break;
+ -: 4198: case S_BYTES:
+ #####: 4199: B = allocSBytes();
+call 0 never executed
+ #####: 4200: data = &(obj->data);
+ #####: 4201: count = netTypeVarintToUint((u8**)&data);
+call 0 never executed
+ #####: 4202: sBytesPushBuffer(&B, data, count);
+call 0 never executed
+ #####: 4203: r = (smallt *)B;
+ #####: 4204: break;
+ -: 4205: case UNIFORM_DICT:
+ 12: 4206: data = (char *)&(obj->data);
+ -: 4207: //debug - ctx.dbuf = (u8*) data;
+ 12: 4208: uniformDictNetDeserial((sDictt **)&r, (u8**)&data, &ctx, /*packed=*/false);
+call 0 returned 100%
+ 12: 4209: break;
+ -: 4210: case UNIFORM_ARRAY:
+ 11: 4211: data = (char *)&(obj->data);
+ -: 4212: //debug - ctx.dbuf = (u8*) data;
+ 11: 4213: uniformArrayNetDeserial((sArrayt **)&r, (u8**)&data, &ctx, /*packed=*/false);
+call 0 returned 100%
+ 11: 4214: break;
+ -: 4215: }
+ -: 4216:
+ 76: 4217: ret r;
+ -: 4218:}
+ -: 4219:
+ -: 4220:/**
+ -: 4221: * deserialize dictionary from data
+ -: 4222: *
+ -: 4223: * a new dictionary is allocated
+ -: 4224: *
+ -: 4225: * \param
+ -: 4226: * dict dictionary holding the elements
+ -: 4227: * data serialized dictionary
+ -: 4228: */
+function dictNetDeserial called 54 returned 100% blocks executed 78%
+ 54: 4229:internal void dictNetDeserial(sDictt **dict, u8 **data, contextt *ctx, bool packed) {
+ 54: 4230: sUndefinedt *u = NULL;
+ 54: 4231: sBoolt *bo = NULL;
+ 54: 4232: double *D = NULL;
+ 54: 4233: sDoublet *Do = NULL;
+ 54: 4234: sDictt *d = NULL;
+ 54: 4235: sIntt *io = NULL;
+ 54: 4236: char *s = NULL;
+ 54: 4237: sStringt *so = NULL;
+ 54: 4238: sArrayt *a = NULL;
+ 54: 4239: sBytest *B = NULL;
+ -: 4240: uint32_t count;
+ -: 4241: uint32_t dictCount;
+ -: 4242:
+ 54: 4243: if (packed) {
+branch 0 taken 50% (fallthrough)
+branch 1 taken 50%
+ 27: 4244: dictCount = varintToUint(data);
+call 0 returned 100%
+ -: 4245: }
+ -: 4246: else {
+ 27: 4247: if (ctx->nibble == lowNbl) {
+branch 0 taken 93% (fallthrough)
+branch 1 taken 7%
+ 25: 4248: dictCount = netTypeVarintToUint(data);
+call 0 returned 100%
+ -: 4249: }
+ -: 4250: else {
+ -: 4251: // high nibble
+ -: 4252: // type = *(ctx->dbuf + ctx->nblOffset) >> 4;
+ -: 4253: #define readTypeInHighNbl\
+ -: 4254: ctx->nibble = lowNbl;\
+ -: 4255: if (ctx->nblAddr == *data)\
+ -: 4256: /* data points to the type, next byte is count */\
+ -: 4257: (*data)++
+ 2: 4258: readTypeInHighNbl;
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ 2: 4259: dictCount = varintToUint(data);
+call 0 returned 100%
+ -: 4260: }
+ -: 4261: }
+ -: 4262:
+ 54: 4263: if (!dictCount) {
+branch 0 taken 19% (fallthrough)
+branch 1 taken 81%
+ 10: 4264: *dict = allocSDict();
+call 0 returned 100%
+ 10: 4265: ret;
+ -: 4266: }
+ -: 4267:
+ 44: 4268: bool inPack = false;
+ -: 4269: u8 packedType;
+ -: 4270: size_t packCount;
+ 200: 4271: loop(dictCount) {
+branch 0 taken 78%
+branch 1 taken 22% (fallthrough)
+ 156: 4272: char *key = (char*)*data;
+ 156: 4273: *data += strlen(key)+1;
+ -: 4274: char type;
+ 156: 4275: if (inPack) {
+branch 0 taken 24% (fallthrough)
+branch 1 taken 76%
+ 38: 4276: type = packedType;
+ -: 4277: }
+ -: 4278: else {
+ 118: 4279: if (ctx->nibble == lowNbl) {
+branch 0 taken 67% (fallthrough)
+branch 1 taken 33%
+ 79: 4280: type = (**data) & 0xF;
+ -: 4281: }
+ -: 4282: else {
+ -: 4283: // high nibble
+ 39: 4284: type = (*ctx->nblAddr) >> 4;
+ -: 4285: }
+ -: 4286: }
+ -: 4287:
+ 156: 4288: switch(type) {
+branch 0 taken 17%
+branch 1 taken 20%
+branch 2 taken 1%
+branch 3 taken 1%
+branch 4 taken 15%
+branch 5 taken 9%
+branch 6 taken 1%
+branch 7 taken 0%
+branch 8 taken 10%
+branch 9 taken 6%
+branch 10 taken 5%
+branch 11 taken 5%
+branch 12 taken 5%
+branch 13 taken 0%
+branch 14 taken 3%
+branch 15 taken 3%
+branch 16 taken 0%
+ -: 4289: case S_UNDEFINED:
+ 26: 4290: if (ctx->nibble == lowNbl) {
+branch 0 taken 92% (fallthrough)
+branch 1 taken 8%
+ -: 4291: #define readTypeOnly\
+ -: 4292: ctx->nibble = highNbl;\
+ -: 4293: ctx->nblAddr = *data;\
+ -: 4294: (*data)++
+ 24: 4295: readTypeOnly;
+ -: 4296: }
+ -: 4297: else {
+ -: 4298: // high nibble
+ 2: 4299: readTypeInHighNbl;
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ -: 4300: }
+ 26: 4301: u = allocSUndefined();
+call 0 returned 100%
+ 26: 4302: sDictPushTiny(dict, key, (smallt *) u);
+call 0 returned 100%
+ 26: 4303: break;
+ -: 4304: case S_BOOL:
+ 31: 4305: if (!ctx->boolAddr) {
+branch 0 taken 16% (fallthrough)
+branch 1 taken 84%
+ -: 4306: // new packed bools
+ 5: 4307: if (ctx->nibble == lowNbl) {
+branch 0 taken 60% (fallthrough)
+branch 1 taken 40%
+ -: 4308: #define read4bPackedBool\
+ -: 4309: ctx->boolShift = 5;\
+ -: 4310: ctx->boolAddr = *data;\
+ -: 4311: (*data)++
+ 3: 4312: read4bPackedBool;
+ 3: 4313: bo = allocSBool((*ctx->boolAddr) & 0x10);
+call 0 returned 100%
+ -: 4314: }
+ -: 4315: else {
+ -: 4316: // high nibble
+ 2: 4317: readTypeInHighNbl;
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ -: 4318: #define read8bPackedBool\
+ -: 4319: ctx->boolShift = 1;\
+ -: 4320: ctx->boolAddr = *data;\
+ -: 4321: (*data)++
+ 2: 4322: read8bPackedBool;
+ 2: 4323: bo = allocSBool((*ctx->boolAddr) & 0x1);
+call 0 returned 100%
+ -: 4324: }
+ -: 4325: }
+ -: 4326: else {
+ -: 4327: // there was a bool before this one, read bits in nibbles
+ 26: 4328: if (ctx->nibble == lowNbl) {
+branch 0 taken 58% (fallthrough)
+branch 1 taken 42%
+ 15: 4329: if (ctx->boolShift == 8) {
+branch 0 taken 7% (fallthrough)
+branch 1 taken 93%
+ 1: 4330: read4bPackedBool;
+ 1: 4331: bo = allocSBool((*ctx->boolAddr) & 0x10);
+call 0 returned 100%
+ -: 4332: }
+ -: 4333: else {
+ 14: 4334: readTypeOnly;
+ 14: 4335: bo = allocSBool((*ctx->boolAddr) & (0x1 << (ctx->boolShift++)));
+call 0 returned 100%
+ -: 4336: }
+ -: 4337: }
+ -: 4338: else {
+ -: 4339: // high nibble
+ 11: 4340: readTypeInHighNbl;
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ 11: 4341: if (ctx->boolShift == 8) {
+branch 0 taken 18% (fallthrough)
+branch 1 taken 82%
+ 2: 4342: read8bPackedBool;
+ 2: 4343: bo = allocSBool((*ctx->boolAddr) & 0x1);
+call 0 returned 100%
+ -: 4344: }
+ -: 4345: else {
+ -: 4346: // high nibble
+ 9: 4347: readTypeInHighNbl;
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ 9: 4348: bo = allocSBool((*ctx->boolAddr) & (0x1 << (ctx->boolShift++)));
+call 0 returned 100%
+ -: 4349: }
+ -: 4350: }
+ -: 4351: }
+ 31: 4352: sDictPushTiny(dict, key, (smallt *) bo);
+call 0 returned 100%
+ 31: 4353: break;
+ -: 4354: case S_DICT:
+ 1: 4355: d = NULL;
+ 1: 4356: dictNetDeserial(&d, data, ctx, /*packed=*/false);
+call 0 returned 100%
+ 1: 4357: sDictPushTiny(dict, key, (smallt *) d);
+call 0 returned 100%
+ 1: 4358: break;
+ -: 4359: case S_DOUBLE:
+ 2: 4360: if (ctx->nibble == lowNbl) {
+branch 0 taken 50% (fallthrough)
+branch 1 taken 50%
+ 1: 4361: readTypeOnly;
+ -: 4362: }
+ -: 4363: else {
+ -: 4364: // high nibble
+ 1: 4365: readTypeInHighNbl;
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ -: 4366: }
+ 2: 4367: D = (double *)(*data);
+ 2: 4368: *data += sizeof(double);
+ 2: 4369: Do = allocSDouble(*D);
+call 0 returned 100%
+ 2: 4370: sDictPushTiny(dict, key, (smallt *) Do);
+call 0 returned 100%
+ 2: 4371: break;
+ -: 4372: case S_INT: {
+ -: 4373: i64 v;
+ 24: 4374: if (ctx->nibble == lowNbl) {
+branch 0 taken 50% (fallthrough)
+branch 1 taken 50%
+ 12: 4375: v = netTypeVarintToUint((u8**)data);
+call 0 returned 100%
+ -: 4376: }
+ -: 4377: else {
+ -: 4378: // high nibble
+ 12: 4379: readTypeInHighNbl;
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ 12: 4380: v = varintToUint(data);
+call 0 returned 100%
+ -: 4381: }
+ 24: 4382: v = (v >> 1) ^ ((v << 63) >> 63);
+ 24: 4383: io = allocSInt(v);
+call 0 returned 100%
+ 24: 4384: sDictPushTiny(dict, key, (smallt *) io);
+call 0 returned 100%
+ -: 4385: }
+ 24: 4386: break;
+ -: 4387: case S_STRING:
+ 14: 4388: if (ctx->nibble == lowNbl) {
+branch 0 taken 93% (fallthrough)
+branch 1 taken 7%
+ 13: 4389: readTypeOnly;
+ -: 4390: }
+ -: 4391: else {
+ -: 4392: // high nibble
+ 1: 4393: readTypeInHighNbl;
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ -: 4394: }
+ 14: 4395: s = (char *)(*data);
+ 14: 4396: *data += strlen(s)+1;
+ 14: 4397: so = allocSStringTiny(s);
+call 0 returned 100%
+ 14: 4398: sDictPushTiny(dict, key, (smallt *) so);
+call 0 returned 100%
+ 14: 4399: break;
+ -: 4400: case S_ARRAY:
+ 1: 4401: a = NULL;
+ 1: 4402: arrayNetDeserial(&a, data, ctx, /*packed=*/false);
+call 0 returned 100%
+ 1: 4403: sDictPushTiny(dict, key, (smallt *) a);
+call 0 returned 100%
+ 1: 4404: break;
+ -: 4405: case S_BYTES:
+ #####: 4406: B = allocSBytes();
+call 0 never executed
+ #####: 4407: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 4408: count = netTypeVarintToUint((u8**)data);
+call 0 never executed
+ -: 4409: }
+ -: 4410: else {
+ -: 4411: // high nibble
+ #####: 4412: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ #####: 4413: count = varintToUint((u8**)data);
+call 0 never executed
+ -: 4414: }
+ #####: 4415: sBytesPushBuffer(&B, data, count);
+call 0 never executed
+ #####: 4416: *data += count;
+ #####: 4417: sDictPushTiny(dict, key, (smallt *) B);
+call 0 never executed
+ #####: 4418: break;
+ -: 4419: case PK_DICT:
+ 15: 4420: if (!inPack) {
+branch 0 taken 20% (fallthrough)
+branch 1 taken 80%
+ 3: 4421: inPack = true;
+ 3: 4422: if (ctx->nibble == lowNbl) {
+branch 0 taken 67% (fallthrough)
+branch 1 taken 33%
+ 2: 4423: packCount = netTypeVarintToUint((u8**)data);
+call 0 returned 100%
+ -: 4424: }
+ -: 4425: else {
+ -: 4426: // high nibble
+ 1: 4427: readTypeInHighNbl;
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ 1: 4428: packCount = varintToUint((u8**)data);
+call 0 returned 100%
+ -: 4429: }
+ 3: 4430: packedType = PK_DICT;
+ -: 4431: }
+ -: 4432:
+ 15: 4433: d = NULL;
+ 15: 4434: dictNetDeserial(&d, data, ctx, /*packed=*/true);
+call 0 returned 100%
+ 15: 4435: sDictPushTiny(dict, key, (smallt *) d);
+call 0 returned 100%
+ -: 4436: // stop unpacking when packCount == 0
+ 15: 4437: packCount--;
+ 15: 4438: if (!packCount) inPack = false;
+branch 0 taken 20% (fallthrough)
+branch 1 taken 80%
+ 15: 4439: break;
+ -: 4440: case PK_DOUBLE:
+ 10: 4441: if (!inPack) {
+branch 0 taken 20% (fallthrough)
+branch 1 taken 80%
+ 2: 4442: inPack = true;
+ 2: 4443: if (ctx->nibble == lowNbl) {
+branch 0 taken 50% (fallthrough)
+branch 1 taken 50%
+ 1: 4444: packCount = netTypeVarintToUint((u8**)data);
+call 0 returned 100%
+ -: 4445: }
+ -: 4446: else {
+ -: 4447: // high nibble
+ 1: 4448: readTypeInHighNbl;
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ 1: 4449: packCount = varintToUint((u8**)data);
+call 0 returned 100%
+ -: 4450: }
+ 2: 4451: packedType = PK_DOUBLE;
+ -: 4452: }
+ -: 4453:
+ 10: 4454: D = (double *)(*data);
+ 10: 4455: *data += sizeof(double);
+ 10: 4456: Do = allocSDouble(*D);
+call 0 returned 100%
+ 10: 4457: sDictPushTiny(dict, key, (smallt *) Do);
+call 0 returned 100%
+ -: 4458: // stop unpacking when packCount == 0
+ 10: 4459: packCount--;
+ 10: 4460: if (!packCount) inPack = false;
+branch 0 taken 20% (fallthrough)
+branch 1 taken 80%
+ 10: 4461: break;
+ -: 4462: case PK_INT:
+ 8: 4463: if (!inPack) {
+branch 0 taken 25% (fallthrough)
+branch 1 taken 75%
+ 2: 4464: inPack = true;
+ 2: 4465: if (ctx->nibble == lowNbl) {
+branch 0 taken 50% (fallthrough)
+branch 1 taken 50%
+ 1: 4466: packCount = netTypeVarintToUint((u8**)data);
+call 0 returned 100%
+ -: 4467: }
+ -: 4468: else {
+ -: 4469: // high nibble
+ 1: 4470: readTypeInHighNbl;
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ 1: 4471: packCount = varintToUint((u8**)data);
+call 0 returned 100%
+ -: 4472: }
+ 2: 4473: packedType = PK_INT;
+ -: 4474: }
+ -: 4475:
+ 8: 4476: i64 v = varintToUint(data);
+call 0 returned 100%
+ 8: 4477: v = (v >> 1) ^ ((v << 63) >> 63);
+ 8: 4478: io = allocSInt(v);
+call 0 returned 100%
+ 8: 4479: sDictPushTiny(dict, key, (smallt *) io);
+call 0 returned 100%
+ -: 4480: // stop unpacking when packCount == 0
+ 8: 4481: packCount--;
+ 8: 4482: if (!packCount) inPack = false;
+branch 0 taken 25% (fallthrough)
+branch 1 taken 75%
+ 8: 4483: break;
+ -: 4484: case PK_STRING:
+ 8: 4485: if (!inPack) {
+branch 0 taken 25% (fallthrough)
+branch 1 taken 75%
+ 2: 4486: inPack = true;
+ 2: 4487: if (ctx->nibble == lowNbl) {
+branch 0 taken 50% (fallthrough)
+branch 1 taken 50%
+ 1: 4488: packCount = netTypeVarintToUint((u8**)data);
+call 0 returned 100%
+ -: 4489: }
+ -: 4490: else {
+ -: 4491: // high nibble
+ 1: 4492: readTypeInHighNbl;
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ 1: 4493: packCount = varintToUint((u8**)data);
+call 0 returned 100%
+ -: 4494: }
+ 2: 4495: packedType = PK_STRING;
+ -: 4496: }
+ -: 4497:
+ 8: 4498: s = (char *)(*data);
+ 8: 4499: *data += strlen(s)+1;
+ 8: 4500: so = allocSStringTiny(s);
+call 0 returned 100%
+ 8: 4501: sDictPushTiny(dict, key, (smallt *) so);
+call 0 returned 100%
+ -: 4502: // stop unpacking when packCount == 0
+ 8: 4503: packCount--;
+ 8: 4504: if (!packCount) inPack = false;
+branch 0 taken 25% (fallthrough)
+branch 1 taken 75%
+ 8: 4505: break;
+ -: 4506: case PK_ARRAY:
+ 8: 4507: if (!inPack) {
+branch 0 taken 25% (fallthrough)
+branch 1 taken 75%
+ 2: 4508: inPack = true;
+ 2: 4509: if (ctx->nibble == lowNbl) {
+branch 0 taken 50% (fallthrough)
+branch 1 taken 50%
+ 1: 4510: packCount = netTypeVarintToUint((u8**)data);
+call 0 returned 100%
+ -: 4511: }
+ -: 4512: else {
+ -: 4513: // high nibble
+ 1: 4514: readTypeInHighNbl;
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ 1: 4515: packCount = varintToUint((u8**)data);
+call 0 returned 100%
+ -: 4516: }
+ 2: 4517: packedType = PK_ARRAY;
+ -: 4518: }
+ -: 4519:
+ 8: 4520: a = NULL;
+ 8: 4521: arrayNetDeserial(&a, data, ctx, /*packed=*/true);
+call 0 returned 100%
+ 8: 4522: sDictPushTiny(dict, key, (smallt *) a);
+call 0 returned 100%
+ -: 4523: // stop unpacking when packCount == 0
+ 8: 4524: packCount--;
+ 8: 4525: if (!packCount) inPack = false;
+branch 0 taken 25% (fallthrough)
+branch 1 taken 75%
+ 8: 4526: break;
+ -: 4527: case PK_BYTES:
+ #####: 4528: if (!inPack) {
+branch 0 never executed
+branch 1 never executed
+ #####: 4529: inPack = true;
+ #####: 4530: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 4531: packCount = netTypeVarintToUint((u8**)data);
+call 0 never executed
+ -: 4532: }
+ -: 4533: else {
+ -: 4534: // high nibble
+ #####: 4535: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ #####: 4536: packCount = varintToUint((u8**)data);
+call 0 never executed
+ -: 4537: }
+ #####: 4538: packedType = PK_BYTES;
+ -: 4539: }
+ -: 4540:
+ #####: 4541: B = allocSBytes();
+call 0 never executed
+ #####: 4542: count = varintToUint((u8**)data);
+call 0 never executed
+ #####: 4543: sBytesPushBuffer(&B, data, count);
+call 0 never executed
+ #####: 4544: *data += count;
+ #####: 4545: sDictPushTiny(dict, key, (smallt *) B);
+call 0 never executed
+ -: 4546: // stop unpacking when packCount == 0
+ #####: 4547: packCount--;
+ #####: 4548: if (!packCount) inPack = false;
+branch 0 never executed
+branch 1 never executed
+ #####: 4549: break;
+ -: 4550: case UNIFORM_DICT:
+ 4: 4551: d = NULL;
+ 4: 4552: uniformDictNetDeserial(&d, data, ctx, /*packed=*/false);
+call 0 returned 100%
+ 4: 4553: sDictPushTiny(dict, key, (smallt *) d);
+call 0 returned 100%
+ 4: 4554: break;
+ -: 4555: case UNIFORM_ARRAY:
+ 4: 4556: a = NULL;
+ 4: 4557: uniformArrayNetDeserial(&a, data, ctx, /*packed=*/false);
+call 0 returned 100%
+ 4: 4558: sDictPushTiny(dict, key, (smallt *) a);
+call 0 returned 100%
+ 4: 4559: break;
+ -: 4560: }
+ -: 4561: }
+ -: 4562:}
+ -: 4563:
+ -: 4564:/**
+ -: 4565: * deserialize dictionary from data
+ -: 4566: *
+ -: 4567: * a new dictionary is allocated
+ -: 4568: *
+ -: 4569: * \param
+ -: 4570: * dict dictionary holding the elements
+ -: 4571: * data serialized dictionary
+ -: 4572: */
+function uniformDictNetDeserial called 22 returned 100% blocks executed 87%
+ 22: 4573:internal void uniformDictNetDeserial(sDictt **dict, u8 **data, contextt *ctx, bool packed) {
+ 22: 4574: sUndefinedt *u = NULL;
+ 22: 4575: sBoolt *bo = NULL;
+ 22: 4576: double *D = NULL;
+ 22: 4577: sDoublet *Do = NULL;
+ 22: 4578: sDictt *d = NULL;
+ 22: 4579: sIntt *io = NULL;
+ 22: 4580: char *s = NULL;
+ 22: 4581: sStringt *so = NULL;
+ 22: 4582: sArrayt *a = NULL;
+ 22: 4583: sBytest *B = NULL;
+ -: 4584: uint32_t count;
+ -: 4585: uint32_t dictCount;
+ -: 4586: u8 type;
+ -: 4587:
+ 22: 4588: if (packed) {
+branch 0 taken 18% (fallthrough)
+branch 1 taken 82%
+ 4: 4589: type = (**data) & 0xF;
+ 4: 4590: dictCount = netTypeVarintToUint(data);
+call 0 returned 100%
+ -: 4591: }
+ -: 4592: else {
+ 18: 4593: if (ctx->nibble == lowNbl) {
+branch 0 taken 94% (fallthrough)
+branch 1 taken 6%
+ 17: 4594: type = (**data) >> 4;
+ 17: 4595: (*data)++;
+ 17: 4596: dictCount = varintToUint(data);
+call 0 returned 100%
+ -: 4597: }
+ -: 4598: else {
+ 1: 4599: readTypeInHighNbl;
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ 1: 4600: type = (**data) & 0xF;
+ 1: 4601: dictCount = netTypeVarintToUint(data);
+call 0 returned 100%
+ -: 4602: }
+ -: 4603: }
+ -: 4604:
+ 22: 4605: if (!dictCount) {
+branch 0 taken 5% (fallthrough)
+branch 1 taken 95%
+ 1: 4606: *dict = allocSDict();
+call 0 returned 100%
+ 1: 4607: ret;
+ -: 4608: }
+ -: 4609:
+ -: 4610:
+ 21: 4611: switch(type) {
+branch 0 taken 5%
+branch 1 taken 19%
+branch 2 taken 5%
+branch 3 taken 5%
+branch 4 taken 29%
+branch 5 taken 24%
+branch 6 taken 5%
+branch 7 taken 0%
+branch 8 taken 5%
+branch 9 taken 5%
+branch 10 taken 0%
+ -: 4612: case S_UNDEFINED:
+ 7: 4613: loop(dictCount) {
+branch 0 taken 86%
+branch 1 taken 14% (fallthrough)
+ 6: 4614: char *key = (char*)*data;
+ 6: 4615: *data += strlen(key)+1;
+ 6: 4616: u = allocSUndefined();
+call 0 returned 100%
+ 6: 4617: sDictPushTiny(dict, key, (smallt *) u);
+call 0 returned 100%
+ -: 4618: }
+ 1: 4619: break;
+ -: 4620: case S_BOOL:
+ 19: 4621: loop(dictCount) {
+branch 0 taken 79%
+branch 1 taken 21% (fallthrough)
+ 15: 4622: char *key = (char*)*data;
+ 15: 4623: *data += strlen(key)+1;
+ 15: 4624: if (!ctx->boolAddr) {
+branch 0 taken 20% (fallthrough)
+branch 1 taken 80%
+ 3: 4625: read8bPackedBool;
+ 3: 4626: ctx->boolShift = 0;
+ -: 4627: }
+ 15: 4628: if (ctx->boolShift == 8) {
+branch 0 taken 7% (fallthrough)
+branch 1 taken 93%
+ 1: 4629: readTypeInHighNbl;
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ 1: 4630: read8bPackedBool;
+ 1: 4631: bo = allocSBool((*ctx->boolAddr) & 0x1);
+call 0 returned 100%
+ -: 4632: }
+ -: 4633: else {
+ -: 4634: // high nibble
+ 14: 4635: readTypeInHighNbl;
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ 14: 4636: bo = allocSBool((*ctx->boolAddr) & (0x1 << (ctx->boolShift++)));
+call 0 returned 100%
+ -: 4637: }
+ 15: 4638: sDictPushTiny(dict, key, (smallt *) bo);
+call 0 returned 100%
+ -: 4639: }
+ 4: 4640: break;
+ -: 4641: case S_DICT:
+ 3: 4642: loop(dictCount) {
+branch 0 taken 67%
+branch 1 taken 33% (fallthrough)
+ 2: 4643: char *key = (char*)*data;
+ 2: 4644: *data += strlen(key)+1;
+ 2: 4645: d = NULL;
+ 2: 4646: dictNetDeserial(&d, data, ctx, /*packed=*/true);
+call 0 returned 100%
+ 2: 4647: sDictPushTiny(dict, key, (smallt *) d);
+call 0 returned 100%
+ -: 4648: }
+ 1: 4649: break;
+ -: 4650: case S_DOUBLE:
+ 4: 4651: loop(dictCount) {
+branch 0 taken 75%
+branch 1 taken 25% (fallthrough)
+ 3: 4652: char *key = (char*)*data;
+ 3: 4653: *data += strlen(key)+1;
+ 3: 4654: D = (double *)(*data);
+ 3: 4655: *data += sizeof(double);
+ 3: 4656: Do = allocSDouble(*D);
+call 0 returned 100%
+ 3: 4657: sDictPushTiny(dict, key, (smallt *) Do);
+call 0 returned 100%
+ -: 4658: }
+ 1: 4659: break;
+ -: 4660: case S_INT:
+ 15: 4661: loop(dictCount) {
+branch 0 taken 60%
+branch 1 taken 40% (fallthrough)
+ 9: 4662: char *key = (char*)*data;
+ 9: 4663: *data += strlen(key)+1;
+ 9: 4664: i64 v = varintToUint(data);
+call 0 returned 100%
+ 9: 4665: v = (v >> 1) ^ ((v << 63) >> 63);
+ 9: 4666: io = allocSInt(v);
+call 0 returned 100%
+ 9: 4667: sDictPushTiny(dict, key, (smallt *) io);
+call 0 returned 100%
+ -: 4668: }
+ 6: 4669: break;
+ -: 4670: case S_STRING:
+ 16: 4671: loop(dictCount) {
+branch 0 taken 69%
+branch 1 taken 31% (fallthrough)
+ 11: 4672: char *key = (char*)*data;
+ 11: 4673: *data += strlen(key)+1;
+ 11: 4674: s = (char *)(*data);
+ 11: 4675: *data += strlen(s)+1;
+ 11: 4676: so = allocSStringTiny(s);
+call 0 returned 100%
+ 11: 4677: sDictPushTiny(dict, key, (smallt *) so);
+call 0 returned 100%
+ -: 4678: }
+ 5: 4679: break;
+ -: 4680: case S_ARRAY:
+ 2: 4681: loop(dictCount) {
+branch 0 taken 50%
+branch 1 taken 50% (fallthrough)
+ 1: 4682: char *key = (char*)*data;
+ 1: 4683: *data += strlen(key)+1;
+ 1: 4684: a = NULL;
+ 1: 4685: arrayNetDeserial(&a, data, ctx, /*packed=*/true);
+call 0 returned 100%
+ 1: 4686: sDictPushTiny(dict, key, (smallt *) a);
+call 0 returned 100%
+ -: 4687: }
+ 1: 4688: break;
+ -: 4689: case S_BYTES:
+ #####: 4690: loop(dictCount) {
+branch 0 never executed
+branch 1 never executed
+ #####: 4691: char *key = (char*)*data;
+ #####: 4692: *data += strlen(key)+1;
+ #####: 4693: B = allocSBytes();
+call 0 never executed
+ #####: 4694: count = varintToUint((u8**)data);
+call 0 never executed
+ #####: 4695: sBytesPushBuffer(&B, data, count);
+call 0 never executed
+ #####: 4696: *data += count;
+ #####: 4697: sDictPushTiny(dict, key, (smallt *) B);
+call 0 never executed
+ -: 4698: }
+ #####: 4699: break;
+ -: 4700: case UNIFORM_DICT:
+ 3: 4701: loop(dictCount) {
+branch 0 taken 67%
+branch 1 taken 33% (fallthrough)
+ 2: 4702: char *key = (char*)*data;
+ 2: 4703: *data += strlen(key)+1;
+ 2: 4704: d = NULL;
+ 2: 4705: uniformDictNetDeserial(&d, data, ctx, /*packed=*/true);
+call 0 returned 100%
+ 2: 4706: sDictPushTiny(dict, key, (smallt *) d);
+call 0 returned 100%
+ -: 4707: }
+ 1: 4708: break;
+ -: 4709: case UNIFORM_ARRAY:
+ 2: 4710: loop(dictCount) {
+branch 0 taken 50%
+branch 1 taken 50% (fallthrough)
+ 1: 4711: char *key = (char*)*data;
+ 1: 4712: *data += strlen(key)+1;
+ 1: 4713: a = NULL;
+ 1: 4714: uniformArrayNetDeserial(&a, data, ctx, /*packed=*/true);
+call 0 returned 100%
+ 1: 4715: sDictPushTiny(dict, key, (smallt *) a);
+call 0 returned 100%
+ -: 4716: }
+ 1: 4717: break;
+ -: 4718: }
+ -: 4719:}
+ -: 4720:
+ -: 4721:/**
+ -: 4722: * deserialize array from data
+ -: 4723: *
+ -: 4724: * a new array is allocated
+ -: 4725: *
+ -: 4726: * \param
+ -: 4727: * array holding the elements
+ -: 4728: * data serialized dictionary
+ -: 4729: */
+function arrayNetDeserial called 48 returned 100% blocks executed 78%
+ 48: 4730:internal void arrayNetDeserial(sArrayt **array, u8 **data, contextt *ctx, bool packed) {
+ 48: 4731: sUndefinedt *u = NULL;
+ 48: 4732: sBoolt *bo = NULL;
+ 48: 4733: double *D = NULL;
+ 48: 4734: sDoublet *Do = NULL;
+ 48: 4735: sDictt *d = NULL;
+ 48: 4736: sIntt *io = NULL;
+ 48: 4737: char *s = NULL;
+ 48: 4738: sStringt *so = NULL;
+ 48: 4739: sArrayt *a = NULL;
+ 48: 4740: sBytest *B = NULL;
+ -: 4741: uint32_t count;
+ -: 4742: uint32_t arrayCount;
+ -: 4743:
+ 48: 4744: if (packed) {
+branch 0 taken 44% (fallthrough)
+branch 1 taken 56%
+ 21: 4745: arrayCount = varintToUint(data);
+call 0 returned 100%
+ -: 4746: }
+ -: 4747: else {
+ 27: 4748: if (ctx->nibble == lowNbl) {
+branch 0 taken 96% (fallthrough)
+branch 1 taken 4%
+ 26: 4749: arrayCount = netTypeVarintToUint(data);
+call 0 returned 100%
+ -: 4750: }
+ -: 4751: else {
+ -: 4752: // high nibble
+ 1: 4753: readTypeInHighNbl;
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ 1: 4754: arrayCount = varintToUint(data);
+call 0 returned 100%
+ -: 4755: }
+ -: 4756: }
+ -: 4757:
+ 48: 4758: if (!arrayCount) {
+branch 0 taken 4% (fallthrough)
+branch 1 taken 96%
+ 2: 4759: *array = allocSArray();;
+call 0 returned 100%
+ 2: 4760: ret;
+ -: 4761: }
+ -: 4762:
+ 46: 4763: bool inPack = false;
+ -: 4764: u8 packedType;
+ -: 4765: size_t packCount;
+ 196: 4766: loop(arrayCount) {
+branch 0 taken 77%
+branch 1 taken 23% (fallthrough)
+ -: 4767: char type;
+ 150: 4768: if (inPack) {
+branch 0 taken 20% (fallthrough)
+branch 1 taken 80%
+ 30: 4769: type = packedType;
+ -: 4770: }
+ -: 4771: else {
+ 120: 4772: if (ctx->nibble == lowNbl) {
+branch 0 taken 72% (fallthrough)
+branch 1 taken 28%
+ 86: 4773: type = (**data) & 0xF;
+ -: 4774: }
+ -: 4775: else {
+ -: 4776: // high nibble
+ 34: 4777: type = (*ctx->nblAddr) >> 4;
+ -: 4778: }
+ -: 4779: }
+ -: 4780:
+ 150: 4781: switch(type) {
+branch 0 taken 18%
+branch 1 taken 23%
+branch 2 taken 1%
+branch 3 taken 1%
+branch 4 taken 15%
+branch 5 taken 9%
+branch 6 taken 1%
+branch 7 taken 0%
+branch 8 taken 5%
+branch 9 taken 5%
+branch 10 taken 5%
+branch 11 taken 5%
+branch 12 taken 5%
+branch 13 taken 0%
+branch 14 taken 1%
+branch 15 taken 4%
+branch 16 taken 0%
+ -: 4782: case S_UNDEFINED:
+ 27: 4783: if (ctx->nibble == lowNbl) {
+branch 0 taken 93% (fallthrough)
+branch 1 taken 7%
+ 25: 4784: readTypeOnly;
+ -: 4785: }
+ -: 4786: else {
+ -: 4787: // high nibble
+ 2: 4788: readTypeInHighNbl;
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ -: 4789: }
+ 27: 4790: u = allocSUndefined();
+call 0 returned 100%
+ 27: 4791: sArrayPushTiny(array, (smallt *) u);
+call 0 returned 100%
+ 27: 4792: break;
+ -: 4793: case S_BOOL:
+ 34: 4794: if (!ctx->boolAddr) {
+branch 0 taken 18% (fallthrough)
+branch 1 taken 82%
+ -: 4795: // new packed bools
+ 6: 4796: if (ctx->nibble == lowNbl) {
+branch 0 taken 50% (fallthrough)
+branch 1 taken 50%
+ 3: 4797: read4bPackedBool;
+ 3: 4798: bo = allocSBool((*ctx->boolAddr) & 0x10);
+call 0 returned 100%
+ -: 4799: }
+ -: 4800: else {
+ -: 4801: // high nibble
+ 3: 4802: readTypeInHighNbl;
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ 3: 4803: read8bPackedBool;
+ 3: 4804: bo = allocSBool((*ctx->boolAddr) & 0x1);
+call 0 returned 100%
+ -: 4805: }
+ -: 4806: }
+ -: 4807: else {
+ -: 4808: // there was a bool before this one, read bits in nibbles
+ 28: 4809: if (ctx->nibble == lowNbl) {
+branch 0 taken 61% (fallthrough)
+branch 1 taken 39%
+ 17: 4810: if (ctx->boolShift == 8) {
+branch 0 taken 12% (fallthrough)
+branch 1 taken 88%
+ 2: 4811: read4bPackedBool;
+ 2: 4812: bo = allocSBool((*ctx->boolAddr) & 0x10);
+call 0 returned 100%
+ -: 4813: }
+ -: 4814: else {
+ 15: 4815: readTypeOnly;
+ 15: 4816: bo = allocSBool((*ctx->boolAddr) & (0x1 << (ctx->boolShift++)));
+call 0 returned 100%
+ -: 4817: }
+ -: 4818: }
+ -: 4819: else {
+ -: 4820: // high nibble
+ 11: 4821: readTypeInHighNbl;
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ 11: 4822: if (ctx->boolShift == 8) {
+branch 0 taken 18% (fallthrough)
+branch 1 taken 82%
+ 2: 4823: read8bPackedBool;
+ 2: 4824: bo = allocSBool((*ctx->boolAddr) & 0x1);
+call 0 returned 100%
+ -: 4825: }
+ -: 4826: else {
+ 9: 4827: bo = allocSBool((*ctx->boolAddr) & (0x1 << (ctx->boolShift++)));
+call 0 returned 100%
+ -: 4828: }
+ -: 4829: }
+ -: 4830: }
+ 34: 4831: sArrayPushTiny(array, (smallt *) bo);
+call 0 returned 100%
+ 34: 4832: break;
+ -: 4833: case S_DICT:
+ 2: 4834: d = NULL;
+ 2: 4835: dictNetDeserial(&d, data, ctx, /*packed=*/false);
+call 0 returned 100%
+ 2: 4836: sArrayPushTiny(array, (smallt *) d);
+call 0 returned 100%
+ 2: 4837: break;
+ -: 4838: case S_DOUBLE:
+ 2: 4839: if (ctx->nibble == lowNbl) {
+branch 0 taken 50% (fallthrough)
+branch 1 taken 50%
+ 1: 4840: readTypeOnly;
+ -: 4841: }
+ -: 4842: else {
+ -: 4843: // high nibble
+ 1: 4844: readTypeInHighNbl;
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ -: 4845: }
+ 2: 4846: D = (double *)(*data);
+ 2: 4847: *data += sizeof(double);
+ 2: 4848: Do = allocSDouble(*D);
+call 0 returned 100%
+ 2: 4849: sArrayPushTiny(array, (smallt *) Do);
+call 0 returned 100%
+ 2: 4850: break;
+ -: 4851: case S_INT: {
+ -: 4852: i64 v;
+ 22: 4853: if (ctx->nibble == lowNbl) {
+branch 0 taken 82% (fallthrough)
+branch 1 taken 18%
+ 18: 4854: v = netTypeVarintToUint((u8**)data);
+call 0 returned 100%
+ -: 4855: }
+ -: 4856: else {
+ -: 4857: // high nibble
+ 4: 4858: readTypeInHighNbl;
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ 4: 4859: v = varintToUint(data);
+call 0 returned 100%
+ -: 4860: }
+ 22: 4861: v = (v >> 1) ^ ((v << 63) >> 63);
+ 22: 4862: io = allocSInt(v);
+call 0 returned 100%
+ 22: 4863: sArrayPushTiny(array, (smallt *) io);
+call 0 returned 100%
+ -: 4864: }
+ 22: 4865: break;
+ -: 4866: case S_STRING:
+ 13: 4867: if (ctx->nibble == lowNbl) {
+branch 0 taken 69% (fallthrough)
+branch 1 taken 31%
+ 9: 4868: readTypeOnly;
+ -: 4869: }
+ -: 4870: else {
+ -: 4871: // high nibble
+ 4: 4872: readTypeInHighNbl;
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ -: 4873: }
+ 13: 4874: s = (char *)(*data);
+ 13: 4875: *data += strlen(s)+1;
+ 13: 4876: so = allocSStringTiny(s);
+call 0 returned 100%
+ 13: 4877: sArrayPushTiny(array, (smallt *) so);
+call 0 returned 100%
+ 13: 4878: break;
+ -: 4879: case S_ARRAY:
+ 2: 4880: a = NULL;
+ 2: 4881: arrayNetDeserial(&a, data, ctx, /*packed=*/false);
+call 0 returned 100%
+ 2: 4882: sArrayPushTiny(array, (smallt *) a);
+call 0 returned 100%
+ 2: 4883: break;
+ -: 4884: case S_BYTES:
+ #####: 4885: B = allocSBytes();
+call 0 never executed
+ #####: 4886: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 4887: count = netTypeVarintToUint((u8**)data);
+call 0 never executed
+ -: 4888: }
+ -: 4889: else {
+ -: 4890: // high nibble
+ #####: 4891: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ #####: 4892: count = varintToUint((u8**)data);
+call 0 never executed
+ -: 4893: }
+ #####: 4894: sBytesPushBuffer(&B, data, count);
+call 0 never executed
+ #####: 4895: *data += count;
+ #####: 4896: sArrayPushTiny(array, (smallt *) B);
+call 0 never executed
+ #####: 4897: break;
+ -: 4898: case PK_DICT:
+ 8: 4899: if (!inPack) {
+branch 0 taken 25% (fallthrough)
+branch 1 taken 75%
+ 2: 4900: inPack = true;
+ 2: 4901: if (ctx->nibble == lowNbl) {
+branch 0 taken 50% (fallthrough)
+branch 1 taken 50%
+ 1: 4902: packCount = netTypeVarintToUint((u8**)data);
+call 0 returned 100%
+ -: 4903: }
+ -: 4904: else {
+ -: 4905: // high nibble
+ 1: 4906: readTypeInHighNbl;
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ 1: 4907: packCount = varintToUint((u8**)data);
+call 0 returned 100%
+ -: 4908: }
+ 2: 4909: packedType = PK_DICT;
+ -: 4910: }
+ -: 4911:
+ 8: 4912: d = NULL;
+ 8: 4913: dictNetDeserial(&d, data, ctx, /*packed=*/true);
+call 0 returned 100%
+ 8: 4914: sArrayPushTiny(array, (smallt *) d);
+call 0 returned 100%
+ -: 4915: // stop unpacking when packCount == 0
+ 8: 4916: packCount--;
+ 8: 4917: if (!packCount) inPack = false;
+branch 0 taken 25% (fallthrough)
+branch 1 taken 75%
+ 8: 4918: break;
+ -: 4919: case PK_DOUBLE:
+ 8: 4920: if (!inPack) {
+branch 0 taken 25% (fallthrough)
+branch 1 taken 75%
+ 2: 4921: inPack = true;
+ 2: 4922: if (ctx->nibble == lowNbl) {
+branch 0 taken 50% (fallthrough)
+branch 1 taken 50%
+ 1: 4923: packCount = netTypeVarintToUint((u8**)data);
+call 0 returned 100%
+ -: 4924: }
+ -: 4925: else {
+ -: 4926: // high nibble
+ 1: 4927: readTypeInHighNbl;
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ 1: 4928: packCount = varintToUint((u8**)data);
+call 0 returned 100%
+ -: 4929: }
+ 2: 4930: packedType = PK_DOUBLE;
+ -: 4931: }
+ -: 4932:
+ 8: 4933: D = (double *)(*data);
+ 8: 4934: *data += sizeof(double);
+ 8: 4935: Do = allocSDouble(*D);
+call 0 returned 100%
+ 8: 4936: sArrayPushTiny(array, (smallt *) Do);
+call 0 returned 100%
+ -: 4937: // stop unpacking when packCount == 0
+ 8: 4938: packCount--;
+ 8: 4939: if (!packCount) inPack = false;
+branch 0 taken 25% (fallthrough)
+branch 1 taken 75%
+ 8: 4940: break;
+ -: 4941: case PK_INT:
+ 8: 4942: if (!inPack) {
+branch 0 taken 25% (fallthrough)
+branch 1 taken 75%
+ 2: 4943: inPack = true;
+ 2: 4944: if (ctx->nibble == lowNbl) {
+branch 0 taken 50% (fallthrough)
+branch 1 taken 50%
+ 1: 4945: packCount = netTypeVarintToUint((u8**)data);
+call 0 returned 100%
+ -: 4946: }
+ -: 4947: else {
+ -: 4948: // high nibble
+ 1: 4949: readTypeInHighNbl;
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ 1: 4950: packCount = varintToUint((u8**)data);
+call 0 returned 100%
+ -: 4951: }
+ 2: 4952: packedType = PK_INT;
+ -: 4953: }
+ -: 4954:
+ 8: 4955: i64 v = varintToUint(data);
+call 0 returned 100%
+ 8: 4956: v = (v >> 1) ^ ((v << 63) >> 63);
+ 8: 4957: io = allocSInt(v);
+call 0 returned 100%
+ 8: 4958: sArrayPushTiny(array, (smallt *) io);
+call 0 returned 100%
+ -: 4959: // stop unpacking when packCount == 0
+ 8: 4960: packCount--;
+ 8: 4961: if (!packCount) inPack = false;
+branch 0 taken 25% (fallthrough)
+branch 1 taken 75%
+ 8: 4962: break;
+ -: 4963: case PK_STRING:
+ 8: 4964: if (!inPack) {
+branch 0 taken 25% (fallthrough)
+branch 1 taken 75%
+ 2: 4965: inPack = true;
+ 2: 4966: if (ctx->nibble == lowNbl) {
+branch 0 taken 50% (fallthrough)
+branch 1 taken 50%
+ 1: 4967: packCount = netTypeVarintToUint((u8**)data);
+call 0 returned 100%
+ -: 4968: }
+ -: 4969: else {
+ -: 4970: // high nibble
+ 1: 4971: readTypeInHighNbl;
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ 1: 4972: packCount = varintToUint((u8**)data);
+call 0 returned 100%
+ -: 4973: }
+ 2: 4974: packedType = PK_STRING;
+ -: 4975: }
+ -: 4976:
+ 8: 4977: s = (char *)(*data);
+ 8: 4978: *data += strlen(s)+1;
+ 8: 4979: so = allocSStringTiny(s);
+call 0 returned 100%
+ 8: 4980: sArrayPushTiny(array, (smallt *) so);
+call 0 returned 100%
+ -: 4981: // stop unpacking when packCount == 0
+ 8: 4982: packCount--;
+ 8: 4983: if (!packCount) inPack = false;
+branch 0 taken 25% (fallthrough)
+branch 1 taken 75%
+ 8: 4984: break;
+ -: 4985: case PK_ARRAY:
+ 8: 4986: if (!inPack) {
+branch 0 taken 25% (fallthrough)
+branch 1 taken 75%
+ 2: 4987: inPack = true;
+ 2: 4988: if (ctx->nibble == lowNbl) {
+branch 0 taken 50% (fallthrough)
+branch 1 taken 50%
+ 1: 4989: packCount = netTypeVarintToUint((u8**)data);
+call 0 returned 100%
+ -: 4990: }
+ -: 4991: else {
+ -: 4992: // high nibble
+ 1: 4993: readTypeInHighNbl;
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ 1: 4994: packCount = varintToUint((u8**)data);
+call 0 returned 100%
+ -: 4995: }
+ 2: 4996: packedType = PK_ARRAY;
+ -: 4997: }
+ -: 4998:
+ 8: 4999: a = NULL;
+ 8: 5000: arrayNetDeserial(&a, data, ctx, /*packed=*/true);
+call 0 returned 100%
+ 8: 5001: sArrayPushTiny(array, (smallt *) a);
+call 0 returned 100%
+ -: 5002: // stop unpacking when packCount == 0
+ 8: 5003: packCount--;
+ 8: 5004: if (!packCount) inPack = false;
+branch 0 taken 25% (fallthrough)
+branch 1 taken 75%
+ 8: 5005: break;
+ -: 5006: case PK_BYTES:
+ #####: 5007: if (!inPack) {
+branch 0 never executed
+branch 1 never executed
+ #####: 5008: inPack = true;
+ #####: 5009: if (ctx->nibble == lowNbl) {
+branch 0 never executed
+branch 1 never executed
+ #####: 5010: packCount = netTypeVarintToUint((u8**)data);
+call 0 never executed
+ -: 5011: }
+ -: 5012: else {
+ -: 5013: // high nibble
+ #####: 5014: readTypeInHighNbl;
+branch 0 never executed
+branch 1 never executed
+ #####: 5015: packCount = varintToUint((u8**)data);
+call 0 never executed
+ -: 5016: }
+ #####: 5017: packedType = PK_BYTES;
+ -: 5018: }
+ -: 5019:
+ #####: 5020: B = allocSBytes();
+call 0 never executed
+ #####: 5021: count = varintToUint((u8**)data);
+call 0 never executed
+ #####: 5022: sBytesPushBuffer(&B, data, count);
+call 0 never executed
+ #####: 5023: *data += count;
+ #####: 5024: sArrayPushTiny(array, (smallt *) B);
+call 0 never executed
+ -: 5025: // stop unpacking when packCount == 0
+ #####: 5026: packCount--;
+ #####: 5027: if (!packCount) inPack = false;
+branch 0 never executed
+branch 1 never executed
+ #####: 5028: break;
+ -: 5029: case UNIFORM_DICT:
+ 2: 5030: d = NULL;
+ 2: 5031: uniformDictNetDeserial(&d, data, ctx, /*packed=*/false);
+call 0 returned 100%
+ 2: 5032: sArrayPushTiny(array, (smallt *) d);
+call 0 returned 100%
+ 2: 5033: break;
+ -: 5034: case UNIFORM_ARRAY:
+ 6: 5035: a = NULL;
+ 6: 5036: uniformArrayNetDeserial(&a, data, ctx, /*packed=*/false);
+call 0 returned 100%
+ 6: 5037: sArrayPushTiny(array, (smallt *) a);
+call 0 returned 100%
+ 6: 5038: break;
+ -: 5039: }
+ -: 5040: }
+ -: 5041:}
+ -: 5042:
+function uniformArrayNetDeserial called 23 returned 100% blocks executed 89%
+ 23: 5043:internal void uniformArrayNetDeserial(sArrayt **array, u8 **data, contextt *ctx, bool packed) {
+ 23: 5044: sUndefinedt *u = NULL;
+ 23: 5045: sBoolt *bo = NULL;
+ 23: 5046: double *D = NULL;
+ 23: 5047: sDoublet *Do = NULL;
+ 23: 5048: sDictt *d = NULL;
+ 23: 5049: sIntt *io = NULL;
+ 23: 5050: char *s = NULL;
+ 23: 5051: sStringt *so = NULL;
+ 23: 5052: sArrayt *a = NULL;
+ 23: 5053: sBytest *B = NULL;
+ -: 5054: uint32_t count;
+ -: 5055: uint32_t arrayCount;
+ -: 5056: u8 type;
+ -: 5057:
+ 23: 5058: if (packed) {
+branch 0 taken 9% (fallthrough)
+branch 1 taken 91%
+ 2: 5059: type = (**data) & 0xF;
+ 2: 5060: arrayCount = netTypeVarintToUint(data);
+call 0 returned 100%
+ -: 5061: }
+ -: 5062: else {
+ 21: 5063: if (ctx->nibble == lowNbl) {
+branch 0 taken 76% (fallthrough)
+branch 1 taken 24%
+ 16: 5064: type = (**data) >> 4;
+ 16: 5065: (*data)++;
+ 16: 5066: arrayCount = varintToUint(data);
+call 0 returned 100%
+ -: 5067: }
+ -: 5068: else {
+ 5: 5069: readTypeInHighNbl;
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ 5: 5070: type = (**data) & 0xF;
+ 5: 5071: arrayCount = netTypeVarintToUint(data);
+call 0 returned 100%
+ -: 5072: }
+ -: 5073: }
+ -: 5074:
+ 23: 5075: if (!arrayCount) {
+branch 0 taken 9% (fallthrough)
+branch 1 taken 91%
+ 2: 5076: *array = allocSArray();;
+call 0 returned 100%
+ 2: 5077: ret;
+ -: 5078: }
+ -: 5079:
+ 21: 5080: switch(type) {
+branch 0 taken 5%
+branch 1 taken 10%
+branch 2 taken 5%
+branch 3 taken 5%
+branch 4 taken 52%
+branch 5 taken 5%
+branch 6 taken 10%
+branch 7 taken 0%
+branch 8 taken 5%
+branch 9 taken 5%
+branch 10 taken 0%
+ -: 5081: case S_UNDEFINED:
+ 7: 5082: loop(arrayCount) {
+branch 0 taken 86%
+branch 1 taken 14% (fallthrough)
+ 6: 5083: u = allocSUndefined();
+call 0 returned 100%
+ 6: 5084: sArrayPushTiny(array, (smallt *) u);
+call 0 returned 100%
+ -: 5085: }
+ 1: 5086: break;
+ -: 5087: case S_BOOL:
+ 16: 5088: loop(arrayCount) {
+branch 0 taken 88%
+branch 1 taken 13% (fallthrough)
+ 14: 5089: if (!ctx->boolAddr) {
+branch 0 taken 14% (fallthrough)
+branch 1 taken 86%
+ 2: 5090: read8bPackedBool;
+ 2: 5091: ctx->boolShift = 0;
+ -: 5092: }
+ 14: 5093: if (ctx->boolShift == 8) {
+branch 0 taken 7% (fallthrough)
+branch 1 taken 93%
+ 1: 5094: read8bPackedBool;
+ 1: 5095: bo = allocSBool((*ctx->boolAddr) & 0x1);
+call 0 returned 100%
+ -: 5096: }
+ -: 5097: else {
+ 13: 5098: bo = allocSBool((*ctx->boolAddr) & (0x1 << (ctx->boolShift++)));
+call 0 returned 100%
+ -: 5099: }
+ 14: 5100: sArrayPushTiny(array, (smallt *) bo);
+call 0 returned 100%
+ -: 5101: }
+ 2: 5102: break;
+ -: 5103: case S_DICT:
+ 3: 5104: loop(arrayCount) {
+branch 0 taken 67%
+branch 1 taken 33% (fallthrough)
+ 2: 5105: d = NULL;
+ 2: 5106: dictNetDeserial(&d, data, ctx, /*packed=*/true);
+call 0 returned 100%
+ 2: 5107: sArrayPushTiny(array, (smallt *) d);
+call 0 returned 100%
+ -: 5108: }
+ 1: 5109: break;
+ -: 5110: case S_DOUBLE:
+ 4: 5111: loop(arrayCount) {
+branch 0 taken 75%
+branch 1 taken 25% (fallthrough)
+ 3: 5112: D = (double *)(*data);
+ 3: 5113: *data += sizeof(double);
+ 3: 5114: Do = allocSDouble(*D);
+call 0 returned 100%
+ 3: 5115: sArrayPushTiny(array, (smallt *) Do);
+call 0 returned 100%
+ -: 5116: }
+ 1: 5117: break;
+ -: 5118: case S_INT:
+ 49: 5119: loop(arrayCount) {
+branch 0 taken 78%
+branch 1 taken 22% (fallthrough)
+ 38: 5120: i64 v = varintToUint(data);
+call 0 returned 100%
+ 38: 5121: v = (v >> 1) ^ ((v << 63) >> 63);
+ 38: 5122: io = allocSInt(v);
+call 0 returned 100%
+ 38: 5123: sArrayPushTiny(array, (smallt *) io);
+call 0 returned 100%
+ -: 5124: }
+ 11: 5125: break;
+ -: 5126: case S_STRING:
+ 4: 5127: loop(arrayCount) {
+branch 0 taken 75%
+branch 1 taken 25% (fallthrough)
+ 3: 5128: s = (char *)(*data);
+ 3: 5129: *data += strlen(s)+1;
+ 3: 5130: so = allocSStringTiny(s);
+call 0 returned 100%
+ 3: 5131: sArrayPushTiny(array, (smallt *) so);
+call 0 returned 100%
+ -: 5132: }
+ 1: 5133: break;
+ -: 5134: case S_ARRAY:
+ 6: 5135: loop(arrayCount) {
+branch 0 taken 67%
+branch 1 taken 33% (fallthrough)
+ 4: 5136: a = NULL;
+ 4: 5137: arrayNetDeserial(&a, data, ctx, /*packed=*/true);
+call 0 returned 100%
+ 4: 5138: sArrayPushTiny(array, (smallt *) a);
+call 0 returned 100%
+ -: 5139: }
+ 2: 5140: break;
+ -: 5141: case S_BYTES:
+ #####: 5142: loop(arrayCount) {
+branch 0 never executed
+branch 1 never executed
+ #####: 5143: B = allocSBytes();
+call 0 never executed
+ #####: 5144: count = varintToUint((u8**)data);
+call 0 never executed
+ #####: 5145: sBytesPushBuffer(&B, data, count);
+call 0 never executed
+ #####: 5146: *data += count;
+ #####: 5147: sArrayPushTiny(array, (smallt *) B);
+call 0 never executed
+ -: 5148: }
+ #####: 5149: break;
+ -: 5150: case UNIFORM_DICT:
+ 3: 5151: loop(arrayCount) {
+branch 0 taken 67%
+branch 1 taken 33% (fallthrough)
+ 2: 5152: d = NULL;
+ 2: 5153: uniformDictNetDeserial(&d, data, ctx, /*packed=*/true);
+call 0 returned 100%
+ 2: 5154: sArrayPushTiny(array, (smallt *) d);
+call 0 returned 100%
+ -: 5155: }
+ 1: 5156: break;
+ -: 5157: case UNIFORM_ARRAY:
+ 2: 5158: loop(arrayCount) {
+branch 0 taken 50%
+branch 1 taken 50% (fallthrough)
+ 1: 5159: a = NULL;
+ 1: 5160: uniformArrayNetDeserial(&a, data, ctx, /*packed=*/true);
+call 0 returned 100%
+ 1: 5161: sArrayPushTiny(array, (smallt *) a);
+call 0 returned 100%
+ -: 5162: }
+ 1: 5163: break;
+ -: 5164: }
+ -: 5165:}
+ -: 5166:
+function deserialNetSerial called 76 returned 100% blocks executed 78%
+ 76: 5167:internal smallJsont* deserialNetSerial(smallJsont *self, smallBytest *data) {
+ -: 5168:
+ 76: 5169: if (!data) {
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ #####: 5170: ret self;
+ -: 5171: }
+ -: 5172:
+ 76: 5173: smallt *o = netDeserial(data->B);
+call 0 returned 100%
+ -: 5174:
+ 76: 5175: if (!o) {
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
+ #####: 5176: ret self;
+ -: 5177: }
+ -: 5178:
+ 76: 5179: freeG(self);
+call 0 returned 100%
+ -: 5180:
+ 76: 5181: setsoG(self, o);
+call 0 returned 100%
+ -: 5182:
+ 76: 5183: ret self;
+ -: 5184:}
+ -: 5185:
+ -: 5186:// vim: set expandtab ts=2 sw=2:
diff --git a/netSerial.h b/netSerial.h
@@ -0,0 +1,106 @@
+#pragma once
+
+/** \file
+ * TODO
+ * create a not trusted version of deserializer that check the data and stop when there is an error
+ *
+ * the netSerial class inherits from the smallJson class
+ * the generics for smallJson can be used with netSerial objects
+ *
+ * serializer level 3 (default) interface:
+ * createNetSerial
+ * initiateNetSerial
+ * initiateAllocateNetSerial
+ * finalizeNetSerial
+ * allocNetSerial
+ * serialG
+ * deserialG
+ *
+ * serializer level 3 (default) description:
+ *
+ * data
+ * 4 bits type
+ * 0 undefined
+ * 1 bool
+ * 2 dict
+ * 3 double
+ * 4 varint
+ * 5 string
+ * 6 array
+ * 7 bytes = faststring
+ * 8 packed dict
+ * 9 packed double
+ * 10 A packed varint
+ * 11 B packed string
+ * 12 C packed array
+ * 13 D packed bytes = faststring
+ * 14 E dict - all elements have same type
+ * 15 F array - all elements have same type
+ *
+ * undefined takes 4 bits (type 0)
+ * bool takes 5 bites and is packed in groups of 4 or 8
+ * dict is normal or uniform
+ * double takes 8.5 bytes
+ * varint: b7=0 last bytes, b7=1 next byte belongs to this varint
+ * string takes 4 bits + string size including nul terminator
+ * array is normal or uniform
+ * bytes takes 4 bits + data for count + sBytes size
+ *
+ * normal array/dict are array/dict having any type of data, each element has a 4 bit type
+ * when 4 or more element have the identical types among dict,double,int,string,array and bytes, they are packed, the element types are not recorded
+ * array/dict are always normal array/dict when packed
+ *
+ * uniform array/dict are array/dict having only one type of data, type is not recorded for the elements
+ * undefined elements dont take space in uniform array/dict
+ * bools are stored in single bits in uniform array/dict
+ *
+ *
+ * > undefined if in b0..3 then next type is b4..7, if in b4..7 then no information about next byte
+ * > bool if in b0..3 then b4 is value, b5..7 is the value for next 3 bools, if in b4..7 then next byte is bool value for next 8 bools
+ * > dict if in b0..3 then b4..7 is varint of length (0 to 7), if in b4..7 then next byte is length varint, if b0..2 are 1 then all elements have the same type and next byte is type for all elements
+ * > double if in b0..3 next 8 bytes is double and b4..7 is type for next element
+ * > varint (n << 1) ^ (n >>(arithmetic shift) 63) sign bit at bit 0, if in b0..3 then b4..7 is varint start, if in b4..7 then next byte is first varint byte
+ * > string next bytes are NUL terminated string
+ * > array if in b0..3 then b4..7 is varint of length (0 to 7), if in b4..7 then next byte is length varint, if b0..2 are 1 then all elements have the same type and next byte is type for all elements
+ * > bytes if in b0..3 then b4..7 is varint of length (0 to 7) and next bytes are string, if in b4..7 then next byte is length varint
+ * > packed double if in b0..3 then b4..7 is varint of element count (0 to 7) and next groups of 8 bytes are doubles
+ * > packed varint if in b0..3 then b4..7 is varint of element count (0 to 7) and next bytes are varints
+ * > uniform dict if in b0..3 then b4..7 is element type, next byte is element count
+ * > unfiform array if in b0..3 then b4..7 is element type, next byte is element count
+ */
+
+
+/* netSerial */
+
+#define createNetSerialLevel0(obj) ;smallJsont obj; initiateNetSerialLevel0(&obj)
+#define createNetSerialLevel1(obj) ;smallJsont obj; initiateNetSerialLevel1(&obj)
+#define createNetSerialLevel2(obj) ;smallJsont obj; initiateNetSerialLevel2(&obj)
+#define createNetSerial(obj) ;smallJsont obj; initiateNetSerial(&obj)
+#define createAllocateNetSerialLevel0(obj) ;smallJsont *obj; initiateAllocateNetSerialLevel0(&obj)
+#define createAllocateNetSerialLevel1(obj) ;smallJsont *obj; initiateAllocateNetSerialLevel1(&obj)
+#define createAllocateNetSerialLevel2(obj) ;smallJsont *obj; initiateAllocateNetSerialLevel2(&obj)
+#define createAllocateNetSerial(obj) ;smallJsont *obj; initiateAllocateNetSerial(&obj)
+
+void initiateNetSerialLevel0(smallJsont *self);
+void initiateNetSerialLevel1(smallJsont *self);
+void initiateNetSerialLevel2(smallJsont *self);
+void initiateNetSerial(smallJsont *self);
+void initiateAllocateNetSerialLevel0(smallJsont **self);
+void initiateAllocateNetSerialLevel1(smallJsont **self);
+void initiateAllocateNetSerialLevel2(smallJsont **self);
+void initiateAllocateNetSerial(smallJsont **self);
+void finalizeNetSerial(void);
+
+/* initialize class methods, call registerMethodsNetSerial from classes inheriting this class */
+void registerMethodsNetSerialLevel0(smallJsonFunctionst *f);
+void registerMethodsNetSerialLevel1(smallJsonFunctionst *f);
+void registerMethodsNetSerialLevel2(smallJsonFunctionst *f);
+void registerMethodsNetSerial(smallJsonFunctionst *f);
+
+smallJsont* allocNetSerialLevel0(void);
+smallJsont* allocNetSerialLevel1(void);
+smallJsont* allocNetSerialLevel2(void);
+smallJsont* allocNetSerial(void);
+
+/* end class netSerial*/
+// vim: set expandtab ts=2 sw=2:
diff --git a/netSerialInternal.h b/netSerialInternal.h
@@ -0,0 +1,61 @@
+#pragma once
+
+static smallJsonFunctionst *netSerialF = NULL;
+
+/** 4 bits - 16 types in the serialized bitstream */
+enum {S_UNDEFINED, S_BOOL, S_DICT, S_DOUBLE, S_INT, S_STRING, S_ARRAY, S_BYTES, PK_DICT, PK_DOUBLE, PK_INT, PK_STRING, PK_ARRAY, PK_BYTES, UNIFORM_DICT, UNIFORM_ARRAY};
+
+typ enum {NOPACKING, PACKED, UNIFORM} packingT;
+
+/**
+ * libsheepy object types to netSerial types
+ */
+static const u8 NET_SERIAL_TYPES[] = {
+ 0, // "not a sheepy object",
+ 0, // "undefined",
+ 1, // "bool",
+ 0, // "container",
+ 2, // "dict",
+ 0, // "element",
+ 3, // "double",
+ 4, // "int",
+ 5, // "string",
+ 7, // "faststring",
+ 6, // "array",
+ 7 // "bytes"
+};
+
+/**
+ * object types to packed netSerial type
+ */
+static const u8 PACKED_NET_SERIAL_TYPES[] = {
+ 0, // "not a sheepy object",
+ 0, // "undefined",
+ 0, // "bool",
+ 0, // "container",
+ 8, // "dict",
+ 0, // "element",
+ 9, // "double",
+ 10, // "int",
+ 11, // "string",
+ 13, // "faststring",
+ 12, // "array",
+ 13 // "bytes"
+};
+
+/** where is next nibble in current bytes: high or low */
+enum {lowNbl, highNbl};
+
+/** de/serializer context to keep track of which nibble to use and where are the bits for the bools */
+typ struct {
+ // store next type in low or high nibble
+ u8 nibble;
+ size_t nblOffset;
+ u8 boolShift;
+ size_t boolOffset;
+ // debug - u8 *dbuf; // deserial buffer start
+ u8 *nblAddr;
+ u8 *boolAddr;
+} contextt;
+
+// vim: set expandtab ts=2 sw=2:
diff --git a/package.yml b/package.yml
@@ -0,0 +1,28 @@
+---
+ name: netSerial
+ version: 0.0.1
+ description: "network serializer with binary format more compact than the default serializer in smallJson"
+ bin: ./netSerial.c
+ #cflags: -DA -ggdb -std=gnu11 -fPIC -pipe
+ #lflags: -lpcre
+ repository:
+ type: git
+ url: git+https://github.com/RemyNoulin/netSerial.git
+ keywords:
+ - serialization
+ author: Remy
+ license: MIT
+ bugs:
+ url: https://github.com/RemyNoulin/netSerial/issues
+ homepage: https://github.com/RemyNoulin/netSerial#readme
+ # Test configuration:
+ testBin: ./testNetSerial.c
+ testCflags: -ggdb -std=gnu11 -fPIC -pipe -fprofile-arcs -ftest-coverage -Wall -Wextra
+ testLflags: -lcheck_pic -lrt -lm -lsubunit -fprofile-arcs -ftest-coverage -rdynamic
+ # Memcheck configuration:
+ memcheckBin: ./memcheckNetSerial.c
+ memcheckCmd: valgrind --leak-check=full --show-leak-kinds=all
+ memcheckCflags: -ggdb -std=gnu11 -fPIC -pipe
+ memcheckLflags: -rdynamic
+ #documentationCmd: # command for generating the documentation with spm doc
+ private: false # true for private package
diff --git a/runMemtest.c b/runMemtest.c
@@ -0,0 +1,108 @@
+#! /usr/bin/env sheepy
+/* or direct path to sheepy: #! /usr/local/bin/sheepy */
+
+//
+// in unit test file, add line:
+// //START MEM TEST ANCHOR
+//
+//
+
+#include "libsheepyObject.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+int argc; char **argv;
+
+enum {START, TEST, TESTEND, SEARCH};
+
+int main(int ARGC, char** ARGV) {
+ char **list = NULL;
+ char **tests = NULL;
+ char **functions = NULL;
+ char **result = NULL;
+
+ argc = ARGC; argv = ARGV;;//
+
+ initLibsheepy(argv[0]);
+
+ if (argc < 3) {
+ printf("Give a parameter: unit test c file and template file");
+ printf("\n");
+ XFAILURE;
+ }
+
+ // get function list from argv[1]
+ list = readText(argv[1]);
+
+ int status = START;;
+ forEachCharP(list, e) {
+ if (status != START) {
+ if (findS(*e, "#include")) {
+ listPushS(&tests, *e);
+ continue;
+ }
+ if (findS(*e, "START_TEST(")) {
+ char **l = split(*e, "(");
+ char **l2 = split(l[1], ")");;
+ iAppendS(&l2[0], "();");
+ listPushS(&functions, l2[0]);
+ listFreeManyS(l,l2);
+ iReplaceManyS(e, "START_TEST(", "void ", ")", "(void) {");
+ status = TEST;
+ }
+ if (findS(*e, "END_TEST")) {
+ iReplaceS(e, "END_TEST", "}",0);
+ status = TESTEND;
+ }
+ if (status == SEARCH) {
+ char *s = sliceS(*e, 0, 5);;
+ if (strEq(s, "Suite")) {
+ break;
+ }
+ free(s);
+ listPushS(&tests, *e);
+ continue;
+ }
+ if ((status == TEST) || (status == TESTEND)) {
+ listPushS(&tests, *e);
+ if (status == TESTEND) {
+ status = SEARCH;
+ }
+ }
+ }
+ else if (findS(*e, "START MEM TEST ANCHOR")) {
+ status = SEARCH;
+ }
+ }
+
+ listFreeS(list);
+
+ //listPrintS(tests);
+ //listPrintS(functions);
+
+ // read template
+ char **template = readText(argv[2]);
+
+ // process template
+ forEachCharP(template, e) {
+ if (findS(*e, "__tests")) {
+ listAppendS(&result, tests);
+ }
+ else if (findS(*e, "__calls")) {
+ listAppendS(&result, functions);
+ }
+ else {
+ listPushS(&result, *e);
+ }
+ }
+
+ // save result
+ putsG("./memcheckNetSerial.c");
+ writeText("./memcheckNetSerial.c", result);
+
+ listFreeManyS(tests, functions, result, template);
+
+ XSUCCESS;
+}
+// vim: set expandtab ts=2 sw=2:+
\ No newline at end of file
diff --git a/test.c b/test.c
@@ -0,0 +1,95 @@
+#! /usr/bin/env sheepy
+/* or direct path to sheepy: #! /usr/local/bin/sheepy */
+
+/* Libsheepy documentation: http://spartatek.se/libsheepy/ */
+#include "libsheepyObject.h"
+#include "netSerial.h"
+
+int argc; char **argv;
+
+/* enable/disable logging */
+/* #undef pLog */
+/* #define pLog(...) */
+
+#define lv logVarG
+
+int main(int ARGC, char** ARGV) {
+
+ argc = ARGC; argv = ARGV;
+
+ initLibsheepy(ARGV[0]);
+ setLogMode(LOG_FUNC);
+
+ createNetSerial(n);
+ createNetSerial(ds);
+ createSmallJson(j);
+ char *s;
+
+ puts(helpO(&n));
+
+ // empty > null
+ var r = serialG(&n);
+ lv(r);
+
+ void show(void) {
+ logI("------------------------");
+ s = toStringG(&n);
+ lv(strlen(s));
+ free(s);
+ lv(&n);
+ stopwatchStart;
+ r = serialG(&n);
+ stopwatchLog;
+ logI("len %u", lenG(r));
+ logSI(BLD"netSerial"RST" %s",toHexSepS(getValG(r), lenG(r), " "));
+ deserialG(&ds, r);
+ lv(&ds)
+ terminateG(r);freeG(&ds);
+ setsoG(&j, getsoG(&n));
+ stopwatchStart;
+ r = serialG(&j);
+ stopwatchLog;
+ logI("smallJson len %u", lenG(r));
+ logSI(BLD"smallJson"RST" %s",toHexSepS(getValG(r), lenG(r), " "));
+ terminateG(r);freeG(&n);
+ }
+
+ // bool
+ setTopG(&n, TRUE);
+ show();
+
+ // dict
+ parseG(&n, "{\"sdf\":true, \"0\":null, \"1\":null, \"2\":true, \"3\":true}");
+ show();
+
+ // array
+ pushG(&n, "qwe");
+ show();
+
+ /* // bytes */
+ /* createSmallBytes(B); */
+ /* freeG(&B); */
+
+ // simple message
+ setTopG(&n, 150);
+ show();
+
+ setTopG(&n, "testing");
+ show();
+
+ parseG(&n, "[150]");
+ show();
+
+ parseG(&n, "[3,270,-86942]");
+ show();
+
+ parseG(&n, "[null,null,null]");
+ show();
+
+ parseG(&n, "{\"a\":[3,270,-86942]}");
+ show();
+
+ parseG(&n, "[{\"dict\":\"hello \\\"wef\\\" qewe\",\"array\":[1,1],\"float\":3.434000e+01,\"asd\":true},\"asd \\\"qwe\\\"qwe\",234]");
+ show();
+}
+// vim: set expandtab ts=2 sw=2:
diff --git a/testNetSerial.c b/testNetSerial.c
@@ -0,0 +1,1565 @@
+#! /usr/bin/env sheepy
+/* or direct path to sheepy: #! /usr/local/bin/sheepy */
+
+/** \file
+ * Each test must be independent and self contained
+ */
+
+#include <check.h>
+
+//START MEM TEST ANCHOR
+
+#include "libsheepyObject.h"
+#include "netSerial.h"
+
+int argc; char **argv;
+
+/* enable/disable logging */
+/* #undef pLog */
+/* #define pLog(...) */
+
+
+START_TEST(topT)
+
+ // STEPS
+ // init
+ // init allocate
+ // terminate
+ // allocate
+ // string
+ // duplicate
+
+ createNetSerial(n);
+ createNetSerial(ds);
+ char *s;
+ smallBytest *B;
+ createSmallDict(d);
+ createSmallArray(a);
+
+ // undefined
+ undefinedt *oU = allocUndefined();
+ setTopNFreeG(&n, (baset *)oU);
+ B = serialG(&n);
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "null");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // bool
+ setTopG(&n, TRUE);
+ B = serialG(&n);
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[17]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "true");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // double
+ setTopG(&n, 1.2);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s", toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[3,51,51,51,51,51,51,-13,63]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "1.200000e+00");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // int
+ setTopG(&n, 120);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[-12,30]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "120");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // string
+ setTopG(&n, "string");
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[5,115,116,114,105,110,103,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "string");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // dict
+ setG(&d, "k", 4);
+ setTopG(&n, &d);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[78,1,107,0,8]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"k\":4}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // array
+ pushG(&a, "k");
+ pushG(&a, 4);
+ setTopG(&n, &a);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[38,69,107,0,8]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[\"k\",4]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+END_TEST
+
+
+
+START_TEST(uniformDictT)
+
+ // STEPS
+ // init
+ // init allocate
+ // terminate
+ // allocate
+ // string
+ // duplicate
+
+ createNetSerial(n);
+ createNetSerial(ds);
+ char *s;
+ smallBytest *B;
+ createSmallDict(d);
+ createSmallDict(dd);
+ createSmallArray(a);
+
+ // undefined
+ undefinedt *oU = allocUndefined();
+ setG(&d, "0", oU);
+ setG(&d, "1", oU);
+ setG(&d, "2", oU);
+ setG(&d, "3", oU);
+ setG(&d, "4", oU);
+ setNFreeG(&d, "5", oU);
+ setTopG(&n, &d);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[14,6,48,0,49,0,50,0,51,0,52,0,53,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":null,\"1\":null,\"2\":null,\"3\":null,\"4\":null,\"5\":null}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // empty dict
+ initiateG(&d);
+ setTopG(&n, &d);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[14,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // bool
+ initiateG(&d);
+ setG(&d, "0", TRUE);
+ setG(&d, "1", TRUE);
+ setG(&d, "2", TRUE);
+ setG(&d, "3", TRUE);
+ setTopG(&n, &d);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[30,4,48,0,15,49,0,50,0,51,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":true,\"1\":true,\"2\":true,\"3\":true}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // 9 bools
+ initiateG(&d);
+ setG(&d, "0", TRUE);
+ setG(&d, "1", TRUE);
+ setG(&d, "2", TRUE);
+ setG(&d, "3", TRUE);
+ setG(&d, "4", TRUE);
+ setG(&d, "5", TRUE);
+ setG(&d, "6", TRUE);
+ setG(&d, "7", TRUE);
+ setG(&d, "8", TRUE);
+ setTopG(&n, &d);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[30,9,48,0,-1,49,0,50,0,51,0,52,0,53,0,54,0,55,0,56,0,1]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":true,\"1\":true,\"2\":true,\"3\":true,\"4\":true,\"5\":true,\"6\":true,\"7\":true,\"8\":true}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+
+ // double
+ initiateG(&d);
+ setG(&d, "0", 1.1);
+ setG(&d, "1", 2.2);
+ setG(&d, "2", 3.3);
+ setTopG(&n, &d);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[62,3,48,0,-10,-10,-10,-10,-10,-10,-15,63,49,0,-10,-10,-10,-10,-10,-10,1,64,50,0,102,102,102,102,102,102,10,64]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":1.100000e+00,\"1\":2.200000e+00,\"2\":3.300000e+00}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // int
+ initiateG(&d);
+ setG(&d, "0", 1);
+ setG(&d, "1", 2);
+ setTopG(&n, &d);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[78,2,48,0,2,49,0,4]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":1,\"1\":2}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // string
+ initiateG(&d);
+ setG(&d, "0", "a");
+ setG(&d, "1", "A");
+ setG(&d, "2", "z");
+ setTopG(&n, &d);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[94,3,48,0,97,0,49,0,65,0,50,0,122,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":\"a\",\"1\":\"A\",\"2\":\"z\"}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // dict
+ initiateG(&d);
+ setG(&dd, "9", "z");
+ setG(&dd, "1", 1);
+ setG(&d, "0", &dd);
+ initiateG(&dd);
+ setG(&dd, "Z", "-");
+ setG(&dd, "A", 234);
+ setG(&d, "1", &dd);
+ setTopG(&n, &d);
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[46,2,48,0,2,57,0,69,122,0,49,0,2,49,0,2,90,0,69,45,0,65,0,-44,3]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":{\"9\":\"z\",\"1\":1},\"1\":{\"Z\":\"-\",\"A\":234}}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // uniform dict
+ initiateG(&dd);
+ initiateG(&d);
+ setG(&dd, "9", 1);
+ setG(&dd, "1", 2);
+ setG(&d, "0", &dd);
+ initiateG(&dd);
+ setG(&dd, "Z", "-");
+ setG(&dd, "A", "+");
+ setG(&d, "1", &dd);
+ setTopG(&n, &d);
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[-18,2,48,0,36,57,0,2,49,0,4,49,0,37,90,0,45,0,65,0,43,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":{\"9\":1,\"1\":2},\"1\":{\"Z\":\"-\",\"A\":\"+\"}}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // array
+ initiateG(&d);
+ pushG(&a, "k");
+ pushG(&a, 4);
+ setG(&d, "0", &a);
+ setTopG(&n, &d);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[110,1,48,0,2,69,107,0,8]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":[\"k\",4]}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // uniform array
+ initiateG(&d);
+ initiateG(&a);
+ pushG(&a, 1);
+ pushG(&a, 2);
+ pushG(&a, 3);
+ pushG(&a, 4);
+ setG(&d, "0", &a);
+ setTopG(&n, &d);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[-2,1,48,0,68,2,4,6,8]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":[1,2,3,4]}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+END_TEST
+
+
+// uniformArray
+START_TEST(uniformArrayT)
+
+ // STEPS
+ // init
+ // init allocate
+ // terminate
+ // allocate
+ // string
+ // duplicate
+
+ createNetSerial(n);
+ createNetSerial(ds);
+ char *s;
+ smallBytest *B;
+ createSmallArray(A);
+ createSmallDict(dd);
+ createSmallArray(a);
+
+ // undefined
+ undefinedt *oU = allocUndefined();
+ pushG(&A, oU);
+ pushG(&A, oU);
+ pushG(&A, oU);
+ pushG(&A, oU);
+ pushG(&A, oU);
+ pushNFreeG(&A, oU);
+ setTopG(&n, &A);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[15,6]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[null,null,null,null,null,null]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // empty dict
+ initiateG(&A);
+ setTopG(&n, &A);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[15,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // bool
+ initiateG(&A);
+ pushG(&A, TRUE);
+ pushG(&A, TRUE);
+ pushG(&A, TRUE);
+ pushG(&A, TRUE);
+ setTopG(&n, &A);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[31,4,15]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[true,true,true,true]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // double
+ initiateG(&A);
+ pushG(&A, 1.1);
+ pushG(&A, 2.2);
+ pushG(&A, 3.3);
+ setTopG(&n, &A);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[63,3,-10,-10,-10,-10,-10,-10,-15,63,-10,-10,-10,-10,-10,-10,1,64,102,102,102,102,102,102,10,64]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[1.100000e+00,2.200000e+00,3.300000e+00]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // int
+ initiateG(&A);
+ pushG(&A, 1);
+ pushG(&A, 2);
+ setTopG(&n, &A);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[79,2,2,4]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[1,2]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // string
+ initiateG(&A);
+ pushG(&A, "a");
+ pushG(&A, "A");
+ pushG(&A, "z");
+ setTopG(&n, &A);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[95,3,97,0,65,0,122,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[\"a\",\"A\",\"z\"]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // dict
+ initiateG(&A);
+ setG(&dd, "9", "z");
+ setG(&dd, "1", 1);
+ pushG(&A, &dd);
+ initiateG(&dd);
+ setG(&dd, "Z", "-");
+ setG(&dd, "A", 234);
+ pushG(&A, &dd);
+ setTopG(&n, &A);
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[47,2,2,57,0,69,122,0,49,0,2,2,90,0,69,45,0,65,0,-44,3]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[{\"9\":\"z\",\"1\":1},{\"Z\":\"-\",\"A\":234}]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // uniform dict
+ initiateG(&dd);
+ initiateG(&A);
+ setG(&dd, "9", 1);
+ setG(&dd, "1", 2);
+ pushG(&A, &dd);
+ initiateG(&dd);
+ setG(&dd, "Z", "-");
+ setG(&dd, "A", "+");
+ pushG(&A, &dd);
+ setTopG(&n, &A);
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[-17,2,36,57,0,2,49,0,4,37,90,0,45,0,65,0,43,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[{\"9\":1,\"1\":2},{\"Z\":\"-\",\"A\":\"+\"}]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // array
+ initiateG(&A);
+ pushG(&a, "k");
+ pushG(&a, 4);
+ pushG(&A, &a);
+ setTopG(&n, &A);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[111,1,2,69,107,0,8]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[[\"k\",4]]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ initiateG(&A);
+ initiateG(&a);
+ pushG(&a, 1);
+ pushG(&a, 2);
+ pushG(&a, 3);
+ pushG(&a, 4);
+ pushG(&A, &a);
+ setTopG(&n, &A);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[-1,1,68,2,4,6,8]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[[1,2,3,4]]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // many bools in uniform array
+ parseG(&n, "[true,true,true,true,true,true,true,true,false,true]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[31,10,-1,2]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[true,true,true,true,true,true,true,true,false,true]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+END_TEST
+
+
+// dict with values, dict, array, uniforms, packed test high/low nibbles
+START_TEST(dictT)
+
+ // STEPS
+ // init
+ // init allocate
+ // terminate
+ // allocate
+ // string
+ // duplicate
+
+ createNetSerial(n);
+ createNetSerial(ds);
+ char *s;
+ smallBytest *B;
+ createSmallDict(d);
+ createSmallDict(dd);
+ createSmallArray(a);
+
+ // null and uniform dict
+ initiateG(&d);
+ setG(&d, "0", NULL);
+ initiateG(&dd);
+ setG(&dd, "Z", "-");
+ setG(&dd, "A", "+");
+ setG(&d, "1", &dd);
+ setTopG(&n, &d);
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[34,48,0,-32,49,0,37,90,0,45,0,65,0,43,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":null,\"1\":{\"Z\":\"-\",\"A\":\"+\"}}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // null and dict
+ initiateG(&d);
+ setG(&d, "0", NULL);
+ initiateG(&dd);
+ setG(&dd, "Z", "-");
+ setG(&dd, "A", 1);
+ setG(&d, "1", &dd);
+ setTopG(&n, &d);
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[34,48,0,32,49,0,2,90,0,69,45,0,65,0,2]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":null,\"1\":{\"Z\":\"-\",\"A\":1}}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // bool and uniform dict
+ initiateG(&d);
+ setG(&d, "0", TRUE);
+ initiateG(&dd);
+ setG(&dd, "Z", "-");
+ setG(&dd, "A", "+");
+ setG(&d, "1", &dd);
+ setTopG(&n, &d);
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[34,48,0,17,49,0,94,2,90,0,45,0,65,0,43,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":true,\"1\":{\"Z\":\"-\",\"A\":\"+\"}}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // null element and uniform array
+ initiateG(&d);
+ setG(&d, "1", NULL);
+ initiateG(&a);
+ pushG(&a, 1);
+ pushG(&a, 2);
+ pushG(&a, 3);
+ pushG(&a, 4);
+ setG(&d, "0", &a);
+ setTopG(&n, &d);
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[34,49,0,-16,48,0,68,2,4,6,8]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"1\":null,\"0\":[1,2,3,4]}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // uniform array high nibble
+ initiateG(&d);
+ setG(&d, "1", TRUE);
+ initiateG(&a);
+ pushG(&a, 1);
+ pushG(&a, 2);
+ pushG(&a, 3);
+ pushG(&a, 4);
+ setG(&d, "0", &a);
+ setTopG(&n, &d);
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[34,49,0,17,48,0,79,4,2,4,6,8]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"1\":true,\"0\":[1,2,3,4]}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // uniform array in high nibble
+ initiateG(&d);
+ setG(&d, "1", "1");
+ initiateG(&a);
+ pushG(&a, 1);
+ pushG(&a, 2);
+ pushG(&a, 3);
+ pushG(&a, 4);
+ setG(&d, "0", &a);
+ setTopG(&n, &d);
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[34,49,0,-11,49,0,48,0,68,2,4,6,8]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"1\":\"1\",\"0\":[1,2,3,4]}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // low and high nibble undefined
+ parseG(&n, "{"_"0"_":null,"_"1"_":null, "_"2"_":1}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[50,48,0,0,49,0,50,0,36]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":null,\"1\":null,\"2\":1}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // low and high nibble bool
+ parseG(&n, "{"_"z"_":null,"_"0"_":true,"_"1"_":true, "_"2"_":true, "_"3"_":true"_"4"_":true"_"5"_":true, "_"6"_":true, "_"7"_":true, "_"8"_":true, "_"9"_":true, "_"a"_":true, "_"b"_":true, "_"c"_":true, "_"d"_":true}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[-14,1,122,0,16,48,0,-1,49,0,17,50,0,51,0,17,52,0,53,0,17,54,0,55,0,17,56,0,63,57,0,17,97,0,98,0,17,99,0,100,0,1]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"z\":null,\"0\":true,\"1\":true,\"2\":true,\"3\":true,\"4\":true,\"5\":true,\"6\":true,\"7\":true,\"8\":true,\"9\":true,\"a\":true,\"b\":true,\"c\":true,\"d\":true}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // low and high nibble bool - deserialDict ctx->nibble == lowNbl and ctx->boolShift == 8
+ parseG(&n, "{"_"z"_":null,"_"0"_":true,"_"1"_":true, "_"2"_":true, "_"3"_":true, "_"4"_":true, "_"5"_":true, "_"6"_":true, "_"7"_":true, \"Z\": null, "_"8"_":true, "_"9"_":true, "_"a"_":true, "_"b"_":true, "_"c"_":true, "_"d"_":true}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[-12,2,122,0,16,48,0,-1,49,0,17,50,0,51,0,17,52,0,53,0,17,54,0,55,0,1,90,0,56,0,-15,57,0,17,97,0,98,0,17,99,0,3,100,0,1]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"z\":null,\"0\":true,\"1\":true,\"2\":true,\"3\":true,\"4\":true,\"5\":true,\"6\":true,\"7\":true,\"Z\":null,\"8\":true,\"9\":true,\"a\":true,\"b\":true,\"c\":true,\"d\":true}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // dict in dict
+ parseG(&n, "{"_"0"_":{\"0\":true}, "_"2"_":{\"0\":false},\"z\":null}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[50,48,0,30,1,48,0,1,50,0,30,1,48,0,122,0,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":{\"0\":true},\"2\":{\"0\":false},\"z\":null}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+
+ // low and high nibble double
+ parseG(&n, "{"_"0"_":0.0, "_"2"_":2.0,\"z\":null}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[50,48,0,51,0,0,0,0,0,0,0,0,50,0,0,0,0,0,0,0,0,64,122,0,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":0.000000e+00,\"2\":2.000000e+00,\"z\":null}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // high nibble string
+ parseG(&n, "{"_"0"_":null, "_"2"_":\"2.0\",\"z\":null}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[50,48,0,80,50,0,50,46,48,0,122,0,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":null,\"2\":\"2.0\",\"z\":null}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // array in dict
+ parseG(&n, "{"_"0"_":null, "_"2"_":[1,2],\"z\":[true,3]}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[50,48,0,-16,50,0,36,2,4,122,0,38,17,100]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":null,\"2\":[1,2],\"z\":[true,3]}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+
+
+ // packed dicts
+ parseG(&n, "{"_"0"_":{},"_"1"_":{}, "_"2"_":{}, "_"3"_":{}, "_"4"_":{}, "_"5"_": 1}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[98,48,0,88,0,49,0,0,50,0,0,51,0,0,52,0,0,53,0,36]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":{},\"1\":{},\"2\":{},\"3\":{},\"4\":{},\"5\":1}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ parseG(&n, "{"_"0"_":{"_"0"_":null,"_"1"_":1},"_"1"_":{"_"0"_":"_"0"_","_"1"_":1}, "_"2"_":{"_"0"_":"_"0"_","_"1"_":1}, "_"3"_":{"_"0"_":"_"0"_","_"1"_":1}, "_"4"_":{"_"0"_":"_"0"_","_"1"_":1}, "_"5"_": 1}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[98,48,0,88,2,48,0,64,49,0,2,49,0,2,48,0,69,48,0,49,0,2,50,0,2,48,0,69,48,0,49,0,2,51,0,2,48,0,69,48,0,49,0,2,52,0,2,48,0,69,48,0,49,0,2,53,0,36]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":{\"0\":null,\"1\":1},\"1\":{\"0\":\"0\",\"1\":1},\"2\":{\"0\":\"0\",\"1\":1},\"3\":{\"0\":\"0\",\"1\":1},\"4\":{\"0\":\"0\",\"1\":1},\"5\":1}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // high nibble packed dicts
+ parseG(&n, "{\"a\": null,"_"0"_":{},"_"1"_":{}, "_"2"_":{}, "_"3"_":{}, "_"4"_":{}, "_"5"_": 1}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[114,97,0,-12,48,0,5,0,49,0,0,50,0,0,51,0,0,52,0,0,53,0,36]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"a\":null,\"0\":{},\"1\":{},\"2\":{},\"3\":{},\"4\":{},\"5\":1}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+
+ // packed doubles
+ parseG(&n, "{"_"0"_":0.0,"_"1"_":1.0, "_"2"_":2.0, "_"3"_":3.0, "_"4"_":4.0, "_"5"_": null}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[98,48,0,89,0,0,0,0,0,0,0,0,49,0,0,0,0,0,0,0,-16,63,50,0,0,0,0,0,0,0,0,64,51,0,0,0,0,0,0,0,8,64,52,0,0,0,0,0,0,0,16,64,53,0,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":0.000000e+00,\"1\":1.000000e+00,\"2\":2.000000e+00,\"3\":3.000000e+00,\"4\":4.000000e+00,\"5\":null}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // high nibble packed doubles
+ parseG(&n, "{\"a\": null, "_"0"_":0.0,"_"1"_":1.0, "_"2"_":2.0, "_"3"_":3.0, "_"4"_":4.0, "_"5"_": null}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[114,97,0,-11,48,0,5,0,0,0,0,0,0,0,0,49,0,0,0,0,0,0,0,-16,63,50,0,0,0,0,0,0,0,0,64,51,0,0,0,0,0,0,0,8,64,52,0,0,0,0,0,0,0,16,64,53,0,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"a\":null,\"0\":0.000000e+00,\"1\":1.000000e+00,\"2\":2.000000e+00,\"3\":3.000000e+00,\"4\":4.000000e+00,\"5\":null}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+
+ // packed ints
+ parseG(&n, "{\"1\":1,\"2\":2,\"3\":3,\"4\":4,\"Z\":\"l\"}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[82,49,0,74,2,50,0,4,51,0,6,52,0,8,90,0,5,108,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"1\":1,\"2\":2,\"3\":3,\"4\":4,\"Z\":\"l\"}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // high nibble packed ints
+ parseG(&n, "{\"0\":null,\"1\":1,\"2\":2,\"3\":3,\"4\":4,\"Z\":\"l\"}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[98,48,0,-96,49,0,4,2,50,0,4,51,0,6,52,0,8,90,0,5,108,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":null,\"1\":1,\"2\":2,\"3\":3,\"4\":4,\"Z\":\"l\"}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+
+ // packed strings
+ parseG(&n, "{\"1\":\"1\",\"2\":\"2\",\"3\":\"3\",\"4\":\"4\",\"Z\":null}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[82,49,0,75,49,0,50,0,50,0,51,0,51,0,52,0,52,0,90,0,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"1\":\"1\",\"2\":\"2\",\"3\":\"3\",\"4\":\"4\",\"Z\":null}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // high nibble packed strings
+ parseG(&n, "{\"0\":null,\"1\":\"1\",\"2\":\"2\",\"3\":\"3\",\"4\":\"4\",\"Z\":null}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[98,48,0,-80,49,0,4,49,0,50,0,50,0,51,0,51,0,52,0,52,0,90,0,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":null,\"1\":\"1\",\"2\":\"2\",\"3\":\"3\",\"4\":\"4\",\"Z\":null}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // packed arrays
+ parseG(&n, "{\"1\":[],\"2\":[1],\"3\":[\"3r\"],\"4\":[true],\"Z\":null}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[82,49,0,76,0,50,0,1,36,51,0,1,21,51,114,0,52,0,1,1,90,0,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"1\":[],\"2\":[1],\"3\":[\"3r\"],\"4\":[true],\"Z\":null}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // high nibble packed arrays
+ parseG(&n, "{\"0\":null,\"1\":[],\"2\":[1],\"3\":[\"3r\"],\"4\":[true],\"Z\":null}");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[98,48,0,-64,49,0,4,0,50,0,1,36,51,0,1,21,51,114,0,52,0,1,1,90,0,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "{\"0\":null,\"1\":[],\"2\":[1],\"3\":[\"3r\"],\"4\":[true],\"Z\":null}");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+END_TEST
+
+
+// array with values, dict, array, uniforms, packed test high/low nibbles
+START_TEST(arrayT)
+
+ // STEPS
+ // init
+ // init allocate
+ // terminate
+ // allocate
+ // string
+ // duplicate
+
+ createNetSerial(n);
+ createNetSerial(ds);
+ char *s;
+ smallBytest *B;
+ createSmallArray(A);
+ createSmallArray(a);
+
+ // null and uniform array
+ initiateG(&A);
+ pushG(&A, NULL);
+ initiateG(&a);
+ pushG(&a, 1);
+ pushG(&a, 2);
+ pushG(&a, 3);
+ pushG(&a, 4);
+ pushG(&A, &a);
+ setTopG(&n, &A);
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[38,-16,68,2,4,6,8]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ //ck_assert_str_eq(s, "[null,null]");
+ ck_assert_str_eq(s, "[null,[1,2,3,4]]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // uniform array in high low
+ initiateG(&A);
+ pushG(&A, FALSE);
+ initiateG(&a);
+ pushG(&a, 1);
+ pushG(&a, 2);
+ pushG(&a, 3);
+ pushG(&a, 4);
+ pushG(&A, &a);
+ setTopG(&n, &A);
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[38,1,79,4,2,4,6,8]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ //ck_assert_str_eq(s, "[null,null]");
+ ck_assert_str_eq(s, "[false,[1,2,3,4]]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // uniform array in high nibble
+ initiateG(&A);
+ pushG(&A, "1");
+ initiateG(&a);
+ pushG(&a, 1);
+ pushG(&a, 2);
+ pushG(&a, 3);
+ pushG(&a, 4);
+ pushG(&A, &a);
+ setTopG(&n, &A);
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[38,-11,49,0,68,2,4,6,8]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[\"1\",[1,2,3,4]]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // high nibble array
+ parseG(&n, "[null, [1,null]]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[38,96,2,36,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[null,[1,null]]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // low and high undefined
+ parseG(&n, "[null,null,1]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[54,0,36]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[null,null,1]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // low and high nibble bool
+ parseG(&n, "[null,true,false,false,true,true,false,true,false,true,true,true,true,true]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[-26,1,16,89,17,17,17,17,31,17,17]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[null,true,false,false,true,true,false,true,false,true,true,true,true,true]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // low and high nibble bool - ctx->boolOffset != 0 ctx->nibble == lowNbl ctx->boolShift == 8
+ parseG(&n, "[true,false,false,true,null,true,false,true,false,true,true,true,true,true]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[-26,1,-11,17,1,81,17,17,31,17,17]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[true,false,false,true,null,true,false,true,false,true,true,true,true,true]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+
+ // dict in array
+ parseG(&n, "[{\"0\":null,\"1\":1},{\"2\":2},{\"3\":3},null]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[70,34,48,0,64,49,0,2,78,1,50,0,4,78,1,51,0,6,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[{\"0\":null,\"1\":1},{\"2\":2},{\"3\":3},null]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // double in array
+ parseG(&n, "[1.0,2.0,null]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[54,51,0,0,0,0,0,0,-16,63,0,0,0,0,0,0,0,64,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[1.000000e+00,2.000000e+00,null]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // int in array
+ parseG(&n, "[1,2,null]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[54,36,68,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[1,2,null]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // string in array
+ parseG(&n, "[\"1\",\"2\",null]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[54,85,49,0,50,0,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[\"1\",\"2\",null]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // array in array
+ parseG(&n, "[[],[1,2],null]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[54,15,0,79,2,2,4,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[[],[1,2],null]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+
+ // packed dicts
+ parseG(&n, "[{\"1\":1},{\"2\":2},{\"3\":3},{\"4\":4},null]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[86,72,1,49,0,36,1,50,0,68,1,51,0,100,1,52,0,-12,1,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[{\"1\":1},{\"2\":2},{\"3\":3},{\"4\":4},null]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // high nibble packed dicts
+ parseG(&n, "[null,{\"1\":1},{\"2\":2},{\"3\":3},{\"4\":4},null]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[102,-12,4,1,49,0,36,1,50,0,68,1,51,0,100,1,52,0,-12,1,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[null,{\"1\":1},{\"2\":2},{\"3\":3},{\"4\":4},null]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // packed doubles
+ parseG(&n, "[1.0,2.0,3.0,4.0,null]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[86,73,0,0,0,0,0,0,-16,63,0,0,0,0,0,0,0,64,0,0,0,0,0,0,8,64,0,0,0,0,0,0,16,64,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[1.000000e+00,2.000000e+00,3.000000e+00,4.000000e+00,null]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // high nibble packed doubles
+ parseG(&n, "[null,1.0,2.0,3.0,4.0,null]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[102,-11,4,0,0,0,0,0,0,-16,63,0,0,0,0,0,0,0,64,0,0,0,0,0,0,8,64,0,0,0,0,0,0,16,64,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[null,1.000000e+00,2.000000e+00,3.000000e+00,4.000000e+00,null]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // packed ints
+ parseG(&n, "[1,2,3,4,null]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[86,74,2,4,6,8,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[1,2,3,4,null]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // high nibble packed ints
+ parseG(&n, "[null,1,2,3,4,null]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[102,-96,4,2,4,6,8,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[null,1,2,3,4,null]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // packed strings
+ parseG(&n, "[\"1\",\"2\",\"3\",\"4\",null]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[86,75,49,0,50,0,51,0,52,0,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[\"1\",\"2\",\"3\",\"4\",null]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // high nibble packed strings
+ parseG(&n, "[null,\"1\",\"2\",\"3\",\"4\",null]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[102,-80,4,49,0,50,0,51,0,52,0,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[null,\"1\",\"2\",\"3\",\"4\",null]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // packed arrays
+ parseG(&n, "[[1],[2],[3],[4],null]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[86,76,1,36,1,68,1,100,1,-12,1,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[[1],[2],[3],[4],null]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+ // high nibble packed arrays
+ parseG(&n, "[null,[1],[2],[3],[4],null]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[102,-64,4,1,36,1,68,1,100,1,-12,1,0]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[null,[1],[2],[3],[4],null]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+END_TEST
+
+
+START_TEST(variousT)
+
+ createNetSerial(n);
+ createNetSerial(ds);
+ char *s;
+ smallBytest *B;
+
+
+ // array dict int bool string
+ parseG(&n, "[0, \"asd\", {\"rpc\":\"ds\", \"id\":1, \"p\":true}, [true, \"user\", [[false,\"name\",1], [true, \"name2\", 12340], [false, \"zxc\", 234]]]]");
+ logVarG(&n);
+ B = serialG(&n);
+ logI("len %u", lenG(B));
+ logSI("%s",toHexSepS(getValG(B), lenG(B), " "));
+ s = sToString((smallt *) B->B);
+ ck_assert_str_eq(s, "[70,4,37,97,115,100,0,3,114,112,99,0,69,100,115,0,105,100,0,2,112,0,-79,54,81,117,115,101,114,0,111,3,3,81,110,97,109,101,0,36,3,81,110,97,109,101,50,0,-12,-11,24,3,1,69,122,120,99,0,-44,3]");
+ free(s);
+ deserialG(&ds, B);
+ s = toStringG(&ds);
+ ck_assert_str_eq(s, "[0,\"asd\",{\"rpc\":\"ds\",\"id\":1,\"p\":true},[true,\"user\",[[false,\"name\",1],[true,\"name2\",12340],[false,\"zxc\",234]]]]");
+ free(s);
+ terminateG(B);
+ freeManyG(&n, &ds);
+
+
+END_TEST
+
+Suite * netSerialSuite(void) {
+ Suite *s;
+ TCase *tc_core;
+
+ s = suite_create("netSerial");
+
+ /* Core test case */
+ tc_core = tcase_create("Core");
+
+
+ tcase_add_test(tc_core, topT);
+ tcase_add_test(tc_core, uniformDictT);
+ tcase_add_test(tc_core, uniformArrayT);
+ tcase_add_test(tc_core, dictT);
+ tcase_add_test(tc_core, arrayT);
+ tcase_add_test(tc_core, variousT);
+
+ //TODO register tests
+
+ suite_add_tcase(s, tc_core);
+
+ ret s;
+}
+
+int main(int ARGC, char** ARGV) {
+
+ argc = ARGC; argv = ARGV;
+
+ //dont initialize libsheepy, it conflicts with libcheck - initLibsheepy(ARGV[0]);
+ setLogMode(LOG_FUNC);
+
+ int number_failed;
+ Suite *s;
+ SRunner *sr;
+
+ s = netSerialSuite();
+ sr = srunner_create(s);
+
+ srunner_run_all(sr, CK_NORMAL);
+ number_failed = srunner_ntests_failed(sr);
+ srunner_free(sr);
+
+ exit((number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE);
+}
+// vim: set expandtab ts=2 sw=2:
diff --git a/testNetSerial.sh b/testNetSerial.sh
@@ -0,0 +1,5 @@
+spm test
+cd ~/.sheepy/build/home/remy/git/sw/sheepyPackagesGitHub/netSerial/
+gcov -b netSerial.c
+cd -
+cp ~/.sheepy/build/home/remy/git/sw/sheepyPackagesGitHub/netSerial/netSerial.c.gcov .
diff --git a/testNetSerialMem.sh b/testNetSerialMem.sh
@@ -0,0 +1,2 @@
+./runMemtest.c ./testNetSerial.c memTest.c.template
+spm memcheck+
\ No newline at end of file