int bson_encoder_fini(bson_encoder_t encoder) { CODER_CHECK(encoder); if (write_int8(encoder, BSON_EOO)) { CODER_KILL(encoder, "write error on document terminator"); } /* sync file */ if (encoder->fd > -1) { BSON_FSYNC(encoder->fd); } return 0; }
int bson_encoder_append_string(bson_encoder_t encoder, const char *name, const char *string) { size_t len; CODER_CHECK(encoder); len = strlen(string) + 1; /* include trailing nul */ if (write_int8(encoder, BSON_STRING) || write_name(encoder, name) || write_int32(encoder, len) || write_x(encoder, string, len)) { CODER_KILL(encoder, "write error on BSON_STRING"); } return 0; }
int bson_decoder_copy_data(bson_decoder_t decoder, void *buf) { int result; CODER_CHECK(decoder); /* copy data */ result = read_x(decoder, buf, decoder->pending); if (result != 0) { CODER_KILL(decoder, "read error on copy_data"); } /* pending count is discharged */ decoder->pending = 0; return 0; }
int bson_decoder_next(bson_decoder_t decoder) { int8_t tbyte; int32_t tint; unsigned nlen; CODER_CHECK(decoder); /* if the previous node was EOO, pop a nesting level */ if (decoder->node.type == BSON_EOO) { if (decoder->nesting > 0) { decoder->nesting--; } /* if the nesting level is now zero, the top-level document is done */ if (decoder->nesting == 0) { /* like kill but not an error */ debug("nesting is zero, document is done"); decoder->fd = -1; /* return end-of-file to the caller */ return 0; } } /* if there are unread bytes pending in the stream, discard them */ while (decoder->pending > 0) { if (read_int8(decoder, &tbyte)) { CODER_KILL(decoder, "read error discarding pending bytes"); } decoder->pending--; } /* get the type byte */ if (read_int8(decoder, &tbyte)) { CODER_KILL(decoder, "read error on type byte"); } decoder->node.type = tbyte; decoder->pending = 0; debug("got type byte 0x%02x", decoder->node.type); /* EOO is special; it has no name/data following */ if (decoder->node.type == BSON_EOO) { decoder->node.name[0] = '\0'; } else { /* get the node name */ nlen = 0; for (;;) { if (nlen >= BSON_MAXNAME) { CODER_KILL(decoder, "node name overflow"); } if (read_int8(decoder, (int8_t *)&decoder->node.name[nlen])) { CODER_KILL(decoder, "read error on node name"); } if (decoder->node.name[nlen] == '\0') { break; } nlen++; } debug("got name '%s'", decoder->node.name); switch (decoder->node.type) { case BSON_BOOL: if (read_int8(decoder, &tbyte)) { CODER_KILL(decoder, "read error on BSON_BOOL"); } decoder->node.b = (tbyte != 0); break; case BSON_INT32: if (read_int32(decoder, &tint)) { CODER_KILL(decoder, "read error on BSON_INT"); } decoder->node.i = tint; break; case BSON_INT64: if (read_int64(decoder, &decoder->node.i)) { CODER_KILL(decoder, "read error on BSON_INT"); } break; case BSON_DOUBLE: if (read_double(decoder, &decoder->node.d)) { CODER_KILL(decoder, "read error on BSON_DOUBLE"); } break; case BSON_STRING: if (read_int32(decoder, &decoder->pending)) { CODER_KILL(decoder, "read error on BSON_STRING length"); } break; case BSON_BINDATA: if (read_int32(decoder, &decoder->pending)) { CODER_KILL(decoder, "read error on BSON_BINDATA size"); } if (read_int8(decoder, &tbyte)) { CODER_KILL(decoder, "read error on BSON_BINDATA subtype"); } decoder->node.subtype = tbyte; break; /* XXX currently not supporting other types */ default: CODER_KILL(decoder, "unsupported node type"); } } /* call the callback and pass its results back */ return decoder->callback(decoder, decoder->priv, &decoder->node); }