binn_map() and binn_create(BINN_MAP) create different outputs
mannol opened this issue · 6 comments
This code produces hex output: e10f02000000022001000000032001
uint8_t out[1000];
binn* obj = binn_map();
binn_map_set_int16(obj, 2, 1);
binn_map_set_int16(obj, 3, 1);
memcpy(out, binn_ptr(obj), binn_size(obj)); // << the said output
However, this code produces the following hex output: 306000009dc8e10f02000000022001
uint8_t out[1000];
binn obj[1];
binn_create(obj, BINN_MAP, 1000, out);
binn_map_set_int16(obj, 2, 1);
binn_map_set_int16(obj, 3, 1);
// now the out[] contains the said output
The consequence:
// in the first case
binn_load((void*)out); // << works
binn_load((void*)(out + 6)); // << fails
// in the second case
binn_load((void*)out); // << fails
binn_load((void*)(out + 6)); // << works
From the outputs I see the data is arranged in different order:
1: e10f02000000022001000000032001
2: 306000009dc8e10f02000000022001
Is that normal? If so, how could one know when the data starts without calling binn_load()
twice?
Hi mannol
To get the content of the binn we must always use the binn_ptr
function. In your second example you are not using it.
Note that the binn header in the serialized data output has a variable size depending on the amount of data it has inside, so the binn_ptr
function will return a pointer inside the buffer that don't need to be the start of the buffer.
In your example the binn_ptr
will return a pointer to out + 6
(as you have tried bellow. Good catch!). The initial bytes are not used in this case.
You should not use (out + 6)
too. Always use the start of the buffer, either the one returned by the binn_ptr
function or a copy of the returned buffer in another app.
There are some usage examples here in the repo.
So the second example should be something like:
uint8_t out[1000];
binn obj[1];
binn_create(obj, BINN_MAP, 1000, out);
binn_map_set_int16(obj, 2, 1);
binn_map_set_int16(obj, 3, 1);
do_something(binn_ptr(obj), binn_size(obj));
binn_free(obj);
Ah, now I get it! Thanks.
OK. Notice also that you don't need to use the binn_load
function.
The read functions can read values directly from the serialized buffer.
Example:
...
char *buffer = binn_ptr(map);
short value = binn_map_int16(buffer, 2);
...
Yep, it uses a linear search so the binn code is simpler and smaller.