40 #include <px4_platform_common/posix.h> 49 # define debug(fmt, args...) do { PX4_INFO("BSON: " fmt, ##args); } while(0) 51 # define debug(fmt, args...) do { } while(0) 54 #define CODER_CHECK(_c) do { if (_c->dead) { debug("coder dead"); return -1; }} while(0) 55 #define CODER_KILL(_c, _reason) do { debug("killed: %s", _reason); _c->dead = true; return -1; } while(0) 57 #define BSON_READ read 58 #define BSON_WRITE write 59 #define BSON_FSYNC fsync 66 if (decoder->
fd > -1) {
67 return (
BSON_READ(decoder->
fd, p, s) == s) ? 0 : -1;
70 if (decoder->
buf !=
nullptr) {
73 CODER_KILL(decoder,
"buffer too small for read");
77 CODER_KILL(decoder,
"not enough data for read");
80 memcpy(p, (decoder->
buf + decoder->
bufpos), s);
92 return read_x(decoder, b,
sizeof(*b));
98 return read_x(decoder, i,
sizeof(*i));
104 return read_x(decoder, i,
sizeof(*i));
110 return read_x(decoder, d,
sizeof(*d));
119 decoder->
buf =
nullptr;
120 decoder->
dead =
false;
122 decoder->
priv = priv;
129 CODER_KILL(decoder,
"failed discarding length");
143 if ((buf ==
nullptr) || (callback ==
nullptr)) {
148 decoder->
buf = (uint8_t *)buf;
149 decoder->
dead =
false;
152 decoder->
bufsize = *(uint32_t *)buf;
153 debug(
"auto-detected %u byte object", decoder->
bufsize);
161 decoder->
priv = priv;
171 if ((len > 0) && (len > (
int)decoder->
bufsize)) {
172 CODER_KILL(decoder,
"document length larger than buffer");
197 debug(
"nesting is zero, document is done");
208 CODER_KILL(decoder,
"read error discarding pending bytes");
216 CODER_KILL(decoder,
"read error on type byte");
239 CODER_KILL(decoder,
"read error on node name");
242 if (decoder->
node.
name[nlen] ==
'\0') {
254 CODER_KILL(decoder,
"read error on BSON_BOOL");
257 decoder->
node.
b = (tbyte != 0);
262 CODER_KILL(decoder,
"read error on BSON_INT");
265 decoder->
node.
i = tint;
270 CODER_KILL(decoder,
"read error on BSON_INT");
277 CODER_KILL(decoder,
"read error on BSON_DOUBLE");
284 CODER_KILL(decoder,
"read error on BSON_STRING length");
291 CODER_KILL(decoder,
"read error on BSON_BINDATA size");
295 CODER_KILL(decoder,
"read error on BSON_BINDATA subtype");
322 CODER_KILL(decoder,
"read error on copy_data");
342 if (encoder->
fd > -1 && encoder->
buf ==
nullptr) {
343 return (
BSON_WRITE(encoder->
fd, p, s) == (
int)s) ? 0 : -1;
350 if (encoder->
fd > -1) {
352 debug(
"writing buffer (%d) to disk", encoder->
bufpos);
355 if (ret == (
int)encoder->
bufpos) {
360 CODER_KILL(encoder,
"fixed-size buffer overflow");
371 CODER_KILL(encoder,
"fixed-size buffer overflow");
376 if (newbuf ==
nullptr) {
380 encoder->
buf = newbuf;
385 memcpy(encoder->
buf + encoder->
bufpos, p, s);
387 debug(
"appended %d bytes", s);
395 return write_x(encoder, &b,
sizeof(b));
401 return write_x(encoder, &i,
sizeof(i));
407 return write_x(encoder, &i,
sizeof(i));
413 return write_x(encoder, &d,
sizeof(d));
419 size_t len = strlen(name);
425 return write_x(encoder, name, len + 1);
432 encoder->
buf =
nullptr;
433 encoder->
dead =
false;
436 CODER_KILL(encoder,
"write error on document length");
446 encoder->
buf = (uint8_t *)buf;
449 encoder->
dead =
false;
453 CODER_KILL(encoder,
"write error on document length");
463 encoder->
buf = (uint8_t *)buf;
465 encoder->
dead =
false;
467 if (encoder->
buf ==
nullptr) {
477 CODER_KILL(encoder,
"write error on document length");
489 CODER_KILL(encoder,
"write error on document terminator");
492 if (encoder->
fd > -1 && encoder->
buf !=
nullptr) {
496 if (ret != (
int)encoder->
bufpos) {
500 }
else if (encoder->
buf !=
nullptr) {
503 memcpy(encoder->
buf, &len,
sizeof(len));
507 if (encoder->
fd > -1) {
519 if (encoder->
fd > -1) {
531 if (encoder->
fd > -1) {
545 CODER_KILL(encoder,
"write error on BSON_BOOL");
559 if (value == (int32_t)value) {
560 debug(
"encoding %lld as int32", value);
566 debug(
"encoding %lld as int64", value);
573 CODER_KILL(encoder,
"write error on BSON_INT");
587 CODER_KILL(encoder,
"write error on BSON_DOUBLE");
601 len = strlen(
string) + 1;
606 write_x(encoder,
string, len)) {
607 CODER_KILL(encoder,
"write error on BSON_STRING");
623 write_x(encoder, data, size)) {
624 CODER_KILL(encoder,
"write error on BSON_BINDATA");
int bson_encoder_init_buf_file(bson_encoder_t encoder, int fd, void *buf, unsigned bufsize)
Initialze the encoder for writing to a file.
static int write_int64(bson_encoder_t encoder, int64_t i)
void * bson_encoder_buf_data(bson_encoder_t encoder)
Get a pointer to the encoded object buffer.
static int write_x(bson_encoder_t encoder, const void *p, size_t s)
int bson_decoder_next(bson_decoder_t decoder)
Process the next node from the stream and invoke the callback.
int bson_encoder_append_binary(bson_encoder_t encoder, const char *name, bson_binary_subtype_t subtype, size_t size, const void *data)
Append a binary blob to the encoded stream.
int bson_decoder_init_file(bson_decoder_t decoder, int fd, bson_decoder_callback callback, void *priv)
Initialise the decoder to read from a file.
#define debug(fmt, args...)
static int read_double(bson_decoder_t decoder, double *d)
bson_binary_subtype_t subtype
static int write_int32(bson_encoder_t encoder, int32_t i)
#define BSON_MAXNAME
Maximum node name length.
int bson_decoder_copy_data(bson_decoder_t decoder, void *buf)
Copy node data.
static int write_double(bson_encoder_t encoder, double d)
int bson_encoder_append_string(bson_encoder_t encoder, const char *name, const char *string)
Append a string to the encoded stream.
A simple subset SAX-style BSON parser and generator.
int bson_encoder_append_double(bson_encoder_t encoder, const char *name, double value)
Append a double to the encoded stream.
int(* bson_decoder_callback)(bson_decoder_t decoder, void *priv, bson_node_t node)
Node callback.
static int read_int64(bson_decoder_t decoder, int64_t *i)
#define BSON_BUF_INCREMENT
Buffer growth increment when writing to a buffer.
static int read_int32(bson_decoder_t decoder, int32_t *i)
int bson_decoder_init_buf(bson_decoder_t decoder, void *buf, unsigned bufsize, bson_decoder_callback callback, void *priv)
Initialise the decoder to read from a buffer in memory.
static int write_name(bson_encoder_t encoder, const char *name)
int bson_encoder_append_bool(bson_encoder_t encoder, const char *name, bool value)
Append a boolean to the encoded stream.
size_t bson_decoder_data_pending(bson_decoder_t decoder)
Report copyable data size.
Simple error/warning functions, heavily inspired by the BSD functions of the same names...
int bson_encoder_fini(bson_encoder_t encoder)
Finalise the encoded stream.
#define CODER_KILL(_c, _reason)
int bson_encoder_buf_size(bson_encoder_t encoder)
Fetch the size of the encoded object; only valid for buffer operations.
bson_type_t
subset of the BSON node types we might care about
int bson_encoder_init_buf(bson_encoder_t encoder, void *buf, unsigned bufsize)
Initialze the encoder for writing to a buffer.
int bson_encoder_init_file(bson_encoder_t encoder, int fd)
Initialze the encoder for writing to a file.
bson_decoder_callback callback
static int write_int8(bson_encoder_t encoder, int8_t b)
int bson_encoder_append_int(bson_encoder_t encoder, const char *name, int64_t value)
Append an integer to the encoded stream.
enum bson_binary_subtype bson_binary_subtype_t
static int read_x(bson_decoder_t decoder, void *p, size_t s)
static int read_int8(bson_decoder_t decoder, int8_t *b)