void test_bson_null (void) { bson *b; b = bson_new (); ok (bson_append_null (b, "null"), "bson_append_null() works"); bson_finish (b); cmp_ok (bson_size (b), "==", 11, "BSON NULL element size check"); ok (memcmp (bson_data (b), "\013\000\000\000\012\156\165\154\154\000\000", bson_size (b)) == 0, "BSON NULL element contents check"); bson_free (b); b = bson_new (); ok (bson_append_null (b, NULL) == FALSE, "bson_append_null() should fail without a key name"); ok (bson_append_null (NULL, "null") == FALSE, "bson_append_null() should fail without a BSON object"); bson_finish (b); cmp_ok (bson_size (b), "==", 5, "BSON object should be empty"); ok (bson_append_null (b, "null") == FALSE, "Appending to a finished element should fail"); bson_free (b); }
static bool append_value(bson_t* bson, const char* key, size_t length, object_t* value) { switch (value->type) { case type_nil: bson_append_null(bson, key, length); break; case type_bool: bson_append_bool(bson, key, length, value->b); break; case type_double: bson_append_double(bson, key, length, value->d); break; case type_str: bson_append_utf8(bson, key, length, value->str, value->l); break; case type_int: append_int(bson, key, length, value->i); break; case type_uint: append_int(bson, key, length, (int64_t)value->u); break; case type_map: { bson_t child; bson_append_document_begin(bson, key, length, &child); append_document(&child, value); bson_append_document_end(bson, &child); } break; case type_array: { bson_t child; bson_append_array_begin(bson, key, length, &child); append_array(&child, value); bson_append_array_end(bson, &child); } break; default: return false; } return true; }
static int _bson_json_read_null (void *_ctx) { BASIC_YAJL_CB_PREAMBLE; BASIC_YAJL_CB_BAIL_IF_NOT_NORMAL ("null"); bson_append_null (STACK_BSON_CHILD, key, (int)len); return 1; }
static void test_bson_as_json (void) { bson_oid_t oid; bson_decimal128_t decimal128; bson_t *b; bson_t *b2; char *str; size_t len; int i; decimal128.high = 0x3040000000000000ULL; decimal128.low = 0x000000000000000B; bson_oid_init_from_string(&oid, "123412341234abcdabcdabcd"); b = bson_new(); assert(bson_append_utf8(b, "utf8", -1, "bar", -1)); assert(bson_append_int32(b, "int32", -1, 1234)); assert(bson_append_int64(b, "int64", -1, 4321)); assert(bson_append_double(b, "double", -1, 123.4)); assert(bson_append_undefined(b, "undefined", -1)); assert(bson_append_null(b, "null", -1)); assert(bson_append_oid(b, "oid", -1, &oid)); assert(bson_append_bool(b, "true", -1, true)); assert(bson_append_bool(b, "false", -1, false)); assert(bson_append_time_t(b, "date", -1, time(NULL))); assert(bson_append_timestamp(b, "timestamp", -1, (uint32_t)time(NULL), 1234)); assert(bson_append_regex(b, "regex", -1, "^abcd", "xi")); assert(bson_append_dbpointer(b, "dbpointer", -1, "mycollection", &oid)); assert(bson_append_minkey(b, "minkey", -1)); assert(bson_append_maxkey(b, "maxkey", -1)); assert(bson_append_symbol(b, "symbol", -1, "var a = {};", -1)); assert(bson_append_decimal128(b, "decimal128", -1, &decimal128)); b2 = bson_new(); assert(bson_append_int32(b2, "0", -1, 60)); assert(bson_append_document(b, "document", -1, b2)); assert(bson_append_array(b, "array", -1, b2)); { const uint8_t binary[] = { 0, 1, 2, 3, 4 }; assert(bson_append_binary(b, "binary", -1, BSON_SUBTYPE_BINARY, binary, sizeof binary)); } for (i = 0; i < 1000; i++) { str = bson_as_json(b, &len); bson_free(str); } bson_destroy(b); bson_destroy(b2); }
static void test_bson_append_null (void) { bson_t *b; bson_t *b2; b = bson_new(); assert(bson_append_null(b, "hello", -1)); b2 = get_bson("test18.bson"); assert_bson_equal(b, b2); bson_destroy(b); bson_destroy(b2); }
bson * test_bson_generate_full (void) { bson *b, *d, *a, *scope; guint8 oid[] = "1234567890ab"; a = bson_new (); bson_append_int32 (a, "0", 32); bson_append_int64 (a, "1", (gint64)-42); bson_finish (a); d = bson_new (); bson_append_string (d, "name", "sub-document", -1); bson_append_int32 (d, "answer", 42); bson_finish (d); scope = bson_new (); bson_append_string (scope, "v", "hello world", -1); bson_finish (scope); b = bson_new (); bson_append_double (b, "double", 3.14); bson_append_string (b, "str", "hello world", -1); bson_append_document (b, "doc", d); bson_append_array (b, "array", a); bson_append_binary (b, "binary0", BSON_BINARY_SUBTYPE_GENERIC, (guint8 *)"foo\0bar", 7); bson_append_oid (b, "_id", oid); bson_append_boolean (b, "TRUE", FALSE); bson_append_utc_datetime (b, "date", 1294860709000); bson_append_timestamp (b, "ts", 1294860709000); bson_append_null (b, "null"); bson_append_regex (b, "foobar", "s/foo.*bar/", "i"); bson_append_javascript (b, "alert", "alert (\"hello world!\");", -1); bson_append_symbol (b, "sex", "Marilyn Monroe", -1); bson_append_javascript_w_scope (b, "print", "alert (v);", -1, scope); bson_append_int32 (b, "int32", 32); bson_append_int64 (b, "int64", (gint64)-42); bson_finish (b); bson_free (d); bson_free (a); bson_free (scope); return b; }
static void test_null (void) { bson_t bcon, expected; bson_init (&bcon); bson_init (&expected); bson_append_null (&expected, "foo", -1); BCON_APPEND (&bcon, "foo", BCON_NULL); bson_eq_bson (&bcon, &expected); bson_destroy (&bcon); bson_destroy (&expected); }
static void jbson_scalar(void *state, char *token, JsonTokenType tokentype) { json_to_bson_state *_state = (json_to_bson_state *) state; double fval; if (_state->fname == NULL) { elog(ERROR, "unsupported json structure"); } switch (tokentype) { case JSON_TOKEN_STRING: bson_append_string(_state->bson, _state->fname, token); break; case JSON_TOKEN_NUMBER: sscanf(token, "%lf", &fval); bson_append_double(_state->bson, _state->fname, fval); break; case JSON_TOKEN_TRUE: bson_append_bool(_state->bson, _state->fname, true); break; case JSON_TOKEN_FALSE: bson_append_bool(_state->bson, _state->fname, false); break; case JSON_TOKEN_NULL: bson_append_null(_state->bson, _state->fname); break; default: elog(ERROR, "unexpected token type: %d", tokentype); break; } _state->fname = NULL; }
static void test_bson_append_general (void) { bson_uint8_t bytes[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01, 0x23, 0x45 }; bson_oid_t oid; bson_t *bson; bson_t *array; bson_t *subdoc; bson = bson_new(); assert(bson_append_int32(bson, "int", -1, 1)); assert_bson_equal_file(bson, "test1.bson"); bson_destroy(bson); bson = bson_new(); assert(bson_append_int64(bson, "int64", -1, 1)); assert_bson_equal_file(bson, "test2.bson"); bson_destroy(bson); bson = bson_new(); assert(bson_append_double(bson, "double", -1, 1.123)); assert_bson_equal_file(bson, "test3.bson"); bson_destroy(bson); bson = bson_new(); assert(bson_append_utf8(bson, "string", -1, "some string", -1)); assert_bson_equal_file(bson, "test5.bson"); bson_destroy(bson); bson = bson_new(); array = bson_new(); assert(bson_append_int32(array, "0", -1, 1)); assert(bson_append_int32(array, "1", -1, 2)); assert(bson_append_int32(array, "2", -1, 3)); assert(bson_append_int32(array, "3", -1, 4)); assert(bson_append_int32(array, "4", -1, 5)); assert(bson_append_int32(array, "5", -1, 6)); assert(bson_append_array(bson, "array[int]", -1, array)); assert_bson_equal_file(bson, "test6.bson"); bson_destroy(array); bson_destroy(bson); bson = bson_new(); array = bson_new(); assert(bson_append_double(array, "0", -1, 1.123)); assert(bson_append_double(array, "1", -1, 2.123)); assert(bson_append_array(bson, "array[double]", -1, array)); assert_bson_equal_file(bson, "test7.bson"); bson_destroy(array); bson_destroy(bson); bson = bson_new(); subdoc = bson_new(); assert(bson_append_int32(subdoc, "int", -1, 1)); assert(bson_append_document(bson, "document", -1, subdoc)); assert_bson_equal_file(bson, "test8.bson"); bson_destroy(subdoc); bson_destroy(bson); bson = bson_new(); assert(bson_append_null(bson, "null", -1)); assert_bson_equal_file(bson, "test9.bson"); bson_destroy(bson); bson = bson_new(); assert(bson_append_regex(bson, "regex", -1, "1234", "i")); assert_bson_equal_file(bson, "test10.bson"); bson_destroy(bson); bson = bson_new(); assert(bson_append_utf8(bson, "hello", -1, "world", -1)); assert_bson_equal_file(bson, "test11.bson"); bson_destroy(bson); bson = bson_new(); array = bson_new(); assert(bson_append_utf8(array, "0", -1, "awesome", -1)); assert(bson_append_double(array, "1", -1, 5.05)); assert(bson_append_int32(array, "2", -1, 1986)); assert(bson_append_array(bson, "BSON", -1, array)); assert_bson_equal_file(bson, "test12.bson"); bson_destroy(bson); bson_destroy(array); bson = bson_new(); memcpy(&oid, bytes, sizeof oid); assert(bson_append_oid(bson, "_id", -1, &oid)); subdoc = bson_new(); assert(bson_append_oid(subdoc, "_id", -1, &oid)); array = bson_new(); assert(bson_append_utf8(array, "0", -1, "1", -1)); assert(bson_append_utf8(array, "1", -1, "2", -1)); assert(bson_append_utf8(array, "2", -1, "3", -1)); assert(bson_append_utf8(array, "3", -1, "4", -1)); assert(bson_append_array(subdoc, "tags", -1, array)); bson_destroy(array); assert(bson_append_utf8(subdoc, "text", -1, "asdfanother", -1)); array = bson_new(); assert(bson_append_utf8(array, "name", -1, "blah", -1)); assert(bson_append_document(subdoc, "source", -1, array)); bson_destroy(array); assert(bson_append_document(bson, "document", -1, subdoc)); bson_destroy(subdoc); array = bson_new(); assert(bson_append_utf8(array, "0", -1, "source", -1)); assert(bson_append_array(bson, "type", -1, array)); bson_destroy(array); array = bson_new(); assert(bson_append_utf8(array, "0", -1, "server_created_at", -1)); assert(bson_append_array(bson, "missing", -1, array)); bson_destroy(array); assert_bson_equal_file(bson, "test17.bson"); bson_destroy(bson); }
void nullToBSON(const char* key, bson_t* bson) { bson_append_null(bson, key, -1); }
void VariantToBsonConverter::convertNull(bson_t *bson, const char *key) { bson_append_null(bson, key, -1); };
/* * Add key-op-value to a bson filter document */ int db_mongodb_bson_filter_add(bson_t *doc, const db_key_t* _k, const db_op_t* _op, const db_val_t* _v, int idx) { bson_t mdoc; db_key_t tkey; const db_val_t *tval; int vtype; str ocmp; tkey = _k[idx]; tval = _v + idx; vtype = VAL_TYPE(tval); /* OP_EQ is handled separately */ if(!strcmp(_op[idx], OP_LT)) { ocmp.s = "$lt"; ocmp.len = 3; } else if(!strcmp(_op[idx], OP_LEQ)) { ocmp.s = "$lte"; ocmp.len = 4; } else if(!strcmp(_op[idx], OP_GT)) { ocmp.s = "$gt"; ocmp.len = 3; } else if(!strcmp(_op[idx], OP_GEQ)) { ocmp.s = "$gte"; ocmp.len = 4; } else if(!strcmp(_op[idx], OP_NEQ) || !strcmp(_op[idx], "!=")) { ocmp.s = "$ne"; ocmp.len = 3; } else { LM_ERR("unsuported match operator: %s\n", _op[idx]); goto error; } if(!bson_append_document_begin(doc, tkey->s, tkey->len, &mdoc)) { LM_ERR("failed to append start to bson doc %.*s %s ... [%d]\n", tkey->len, tkey->s, ocmp.s, idx); goto error; } if(VAL_NULL(tval)) { if(!bson_append_null(&mdoc, ocmp.s, ocmp.len)) { LM_ERR("failed to append null to bson doc %.*s %s null [%d]\n", tkey->len, tkey->s, ocmp.s, idx); goto error; } goto done; } switch(vtype) { case DB1_INT: if(!bson_append_int32(&mdoc, ocmp.s, ocmp.len, VAL_INT(tval))) { LM_ERR("failed to append int to bson doc %.*s %s %d [%d]\n", tkey->len, tkey->s, ocmp.s, VAL_INT(tval), idx); goto error; } break; case DB1_BIGINT: if(!bson_append_int64(&mdoc, ocmp.s, ocmp.len, VAL_BIGINT(tval ))) { LM_ERR("failed to append bigint to bson doc %.*s %s %lld [%d]\n", tkey->len, tkey->s, ocmp.s, VAL_BIGINT(tval), idx); goto error; } return -1; case DB1_DOUBLE: if(!bson_append_double(&mdoc, ocmp.s, ocmp.len, VAL_DOUBLE(tval))) { LM_ERR("failed to append double to bson doc %.*s %s %f [%d]\n", tkey->len, tkey->s, ocmp.s, VAL_DOUBLE(tval), idx); goto error; } break; case DB1_STRING: if(!bson_append_utf8(&mdoc, ocmp.s, ocmp.len, VAL_STRING(tval), strlen(VAL_STRING(tval))) ) { LM_ERR("failed to append string to bson doc %.*s %s %s [%d]\n", tkey->len, tkey->s, ocmp.s, VAL_STRING(tval), idx); goto error; } break; case DB1_STR: if(!bson_append_utf8(&mdoc, ocmp.s, ocmp.len, VAL_STR(tval).s, VAL_STR(tval).len) ) { LM_ERR("failed to append str to bson doc %.*s %s %.*s [%d]\n", tkey->len, tkey->s, ocmp.s, VAL_STR(tval).len, VAL_STR(tval).s, idx); goto error; } break; case DB1_DATETIME: if(!bson_append_time_t(&mdoc, ocmp.s, ocmp.len, VAL_TIME(tval))) { LM_ERR("failed to append time to bson doc %.*s %s %ld [%d]\n", tkey->len, tkey->s, ocmp.s, VAL_TIME(tval), idx); goto error; } break; case DB1_BLOB: if(!bson_append_binary(&mdoc, ocmp.s, ocmp.len, BSON_SUBTYPE_BINARY, (const uint8_t *)VAL_BLOB(tval).s, VAL_BLOB(tval).len) ) { LM_ERR("failed to append blob to bson doc %.*s %s [bin] [%d]\n", tkey->len, tkey->s, ocmp.s, idx); goto error; } break; case DB1_BITMAP: if(!bson_append_int32(&mdoc, ocmp.s, ocmp.len, VAL_INT(tval))) { LM_ERR("failed to append bitmap to bson doc %.*s %s %d [%d]\n", tkey->len, tkey->s, ocmp.s, VAL_INT(tval), idx); goto error; } break; default: LM_ERR("val type [%d] not supported\n", vtype); goto error; } done: if(!bson_append_document_end(doc, &mdoc)) { LM_ERR("failed to append end to bson doc %.*s %s ... [%d]\n", tkey->len, tkey->s, ocmp.s, idx); goto error; } return 0; error: return -1; }
void test_mongo_wire_cmd_update (void) { bson *sel, *upd, *tmp; mongo_packet *p; mongo_packet_header hdr; const guint8 *data; gint32 data_size; bson_cursor *c; gint32 pos; sel = bson_new (); bson_append_null (sel, "_id"); bson_finish (sel); upd = test_bson_generate_full (); ok (mongo_wire_cmd_update (1, NULL, 0, sel, upd) == NULL, "mongo_wire_cmd_update() with a NULL namespace should fail"); ok (mongo_wire_cmd_update (1, "test.ns", 0, NULL, upd) == NULL, "mongo_wire_cmd_update() with a NULL selector should fail"); ok (mongo_wire_cmd_update (1, "test.ns", 0, sel, NULL) == NULL, "mongo_wire_cmd_update() with a NULL update should fail"); tmp = bson_new (); ok (mongo_wire_cmd_update (1, "test.ns", 0, tmp, upd) == NULL, "mongo_wire_cmd_update() fails with an unfinished selector"); ok (mongo_wire_cmd_update (1, "test.ns", 0, sel, tmp) == NULL, "mongo_wire_cmd_update() fails with an unfinished update"); bson_free (tmp); ok ((p = mongo_wire_cmd_update (1, "test.ns", 0, sel, upd)) != NULL, "mongo_wire_cmd_update() works"); bson_free (sel); mongo_wire_packet_get_header (p, &hdr); cmp_ok ((data_size = mongo_wire_packet_get_data (p, &data)), "!=", -1, "Packet data size looks fine"); cmp_ok (hdr.length, "==", sizeof (mongo_packet_header) + data_size, "Packet header length is OK"); cmp_ok (hdr.id, "==", 1, "Packet request ID is ok"); cmp_ok (hdr.resp_to, "==", 0, "Packet reply ID is ok"); /* * Verify the selector object. */ /* pos = zero + collection_name + NULL + flags */ pos = sizeof (gint32) + strlen ("test.ns") + 1 + sizeof (gint32); ok ((sel = bson_new_from_data (data + pos, (gint32)data[pos] - 1)) != NULL, "Packet contains a valid BSON selector document"); bson_finish (sel); ok ((c = bson_find (sel, "_id")) != NULL, "BSON contains an _id"); cmp_ok (bson_cursor_type (c), "==", BSON_TYPE_NULL, "_id has correct type"); bson_cursor_free (c); bson_free (sel); /* * Verify the update object */ pos += (gint32)data[pos]; ok ((tmp = bson_new_from_data (data + pos, bson_stream_doc_size (data, pos) - 1)) != NULL, "Packet contains a valid BSON update document"); bson_finish (tmp); cmp_ok (bson_size (upd), "==", bson_size (tmp), "Packet's update document has the correct size"); ok ((c = bson_find (tmp, "int32")) != NULL, "BSON contains 'int32'"); cmp_ok (bson_cursor_type (c), "==", BSON_TYPE_INT32, "int32 has correct type"); bson_cursor_next (c); cmp_ok (bson_cursor_type (c), "==", BSON_TYPE_INT64, "next element has correct type too"); ok (bson_cursor_next (c) == FALSE, "No more data after the update BSON object"); bson_cursor_free (c); bson_free (tmp); bson_free (upd); mongo_wire_packet_free (p); }
bool BsonAppendNull(BSON *b, const char* key) { return bson_append_null(b, key, strlen(key)); }
/* * Add key-value to a bson document */ int db_mongodb_bson_add(bson_t *doc, const db_key_t _k, const db_val_t *_v, int idx) { int vtype; vtype = VAL_TYPE(_v); if(VAL_NULL(_v)) { if(!bson_append_null(doc, _k->s, _k->len)) { LM_ERR("failed to append int to bson doc %.*s = %d [%d]\n", _k->len, _k->s, VAL_INT(_v), idx); goto error; } goto done; } switch(vtype) { case DB1_INT: if(!bson_append_int32(doc, _k->s, _k->len, VAL_INT(_v))) { LM_ERR("failed to append int to bson doc %.*s = %d [%d]\n", _k->len, _k->s, VAL_INT(_v), idx); goto error; } break; case DB1_BIGINT: if(!bson_append_int64(doc, _k->s, _k->len, VAL_BIGINT(_v ))) { LM_ERR("failed to append bigint to bson doc %.*s = %lld [%d]\n", _k->len, _k->s, VAL_BIGINT(_v), idx); goto error; } return -1; case DB1_DOUBLE: if(!bson_append_double(doc, _k->s, _k->len, VAL_DOUBLE(_v))) { LM_ERR("failed to append double to bson doc %.*s = %f [%d]\n", _k->len, _k->s, VAL_DOUBLE(_v), idx); goto error; } break; case DB1_STRING: if(!bson_append_utf8(doc, _k->s, _k->len, VAL_STRING(_v), strlen(VAL_STRING(_v))) ) { LM_ERR("failed to append string to bson doc %.*s = %s [%d]\n", _k->len, _k->s, VAL_STRING(_v), idx); goto error; } break; case DB1_STR: if(!bson_append_utf8(doc, _k->s, _k->len, VAL_STR(_v).s, VAL_STR(_v).len) ) { LM_ERR("failed to append str to bson doc %.*s = %.*s [%d]\n", _k->len, _k->s, VAL_STR(_v).len, VAL_STR(_v).s, idx); goto error; } break; case DB1_DATETIME: if(!bson_append_time_t(doc, _k->s, _k->len, VAL_TIME(_v))) { LM_ERR("failed to append time to bson doc %.*s = %ld [%d]\n", _k->len, _k->s, VAL_TIME(_v), idx); goto error; } break; case DB1_BLOB: if(!bson_append_binary(doc, _k->s, _k->len, BSON_SUBTYPE_BINARY, (const uint8_t *)VAL_BLOB(_v).s, VAL_BLOB(_v).len) ) { LM_ERR("failed to append blob to bson doc %.*s = [bin] [%d]\n", _k->len, _k->s, idx); goto error; } break; case DB1_BITMAP: if(!bson_append_int32(doc, _k->s, _k->len, VAL_INT(_v))) { LM_ERR("failed to append bitmap to bson doc %.*s = %d [%d]\n", _k->len, _k->s, VAL_INT(_v), idx); goto error; } break; default: LM_ERR("val type [%d] not supported\n", vtype); return -1; } done: return 0; error: return -1; }
int test_bson_generic( void ) { bson_iterator it, it2, it3; bson_oid_t oid; bson_timestamp_t ts; bson_timestamp_t ts_result; bson b[1]; bson copy[1]; bson scope[1]; ts.i = 1; ts.t = 2; bson_init( b ); bson_append_double( b, "d", 3.14 ); bson_append_string( b, "s", "hello" ); bson_append_string_n( b, "s_n", "goodbye cruel world", 7 ); { bson_append_start_object( b, "o" ); bson_append_start_array( b, "a" ); bson_append_binary( b, "0", 8, "w\0rld", 5 ); bson_append_finish_object( b ); bson_append_finish_object( b ); } bson_append_undefined( b, "u" ); bson_oid_from_string( &oid, "010203040506070809101112" ); ASSERT( !memcmp( oid.bytes, "\x001\x002\x003\x004\x005\x006\x007\x008\x009\x010\x011\x012", 12 ) ); bson_append_oid( b, "oid", &oid ); bson_append_bool( b, "b", 1 ); bson_append_date( b, "date", 0x0102030405060708 ); bson_append_null( b, "n" ); bson_append_regex( b, "r", "^asdf", "imx" ); /* no dbref test (deprecated) */ bson_append_code( b, "c", "function(){}" ); bson_append_code_n( b, "c_n", "function(){}garbage", 12 ); bson_append_symbol( b, "symbol", "symbol" ); bson_append_symbol_n( b, "symbol_n", "symbol and garbage", 6 ); { bson_init( scope ); bson_append_int( scope, "i", 123 ); bson_finish( scope ); bson_append_code_w_scope( b, "cws", "function(){return i}", scope ); bson_destroy( scope ); } bson_append_timestamp( b, "timestamp", &ts ); bson_append_long( b, "l", 0x1122334455667788 ); /* Ensure that we can't copy a non-finished object. */ ASSERT( bson_copy( copy, b ) == BSON_ERROR ); bson_finish( b ); ASSERT( b->err == BSON_VALID ); /* Test append after finish. */ ASSERT( bson_append_string( b, "foo", "bar" ) == BSON_ERROR ); ASSERT( b->err & BSON_ALREADY_FINISHED ); ASSERT( bson_copy( copy, b ) == BSON_OK ); ASSERT( 1 == copy->finished ); ASSERT( 0 == copy->err ); bson_destroy( copy ); bson_print( b ); bson_iterator_init( &it, b ); ASSERT( bson_iterator_more( &it ) ); ASSERT( bson_iterator_next( &it ) == BSON_DOUBLE ); ASSERT( bson_iterator_type( &it ) == BSON_DOUBLE ); ASSERT( !strcmp( bson_iterator_key( &it ), "d" ) ); ASSERT( bson_iterator_double( &it ) == 3.14 ); ASSERT( bson_iterator_more( &it ) ); ASSERT( bson_iterator_next( &it ) == BSON_STRING ); ASSERT( bson_iterator_type( &it ) == BSON_STRING ); ASSERT( !strcmp( bson_iterator_key( &it ), "s" ) ); ASSERT( !strcmp( bson_iterator_string( &it ), "hello" ) ); ASSERT( strcmp( bson_iterator_string( &it ), "" ) ); ASSERT( bson_iterator_more( &it ) ); ASSERT( bson_iterator_next( &it ) == BSON_STRING ); ASSERT( bson_iterator_type( &it ) == BSON_STRING ); ASSERT( !strcmp( bson_iterator_key( &it ), "s_n" ) ); ASSERT( !strcmp( bson_iterator_string( &it ), "goodbye" ) ); ASSERT( bson_iterator_more( &it ) ); ASSERT( bson_iterator_next( &it ) == BSON_OBJECT ); ASSERT( bson_iterator_type( &it ) == BSON_OBJECT ); ASSERT( !strcmp( bson_iterator_key( &it ), "o" ) ); bson_iterator_subiterator( &it, &it2 ); ASSERT( bson_iterator_more( &it2 ) ); ASSERT( bson_iterator_next( &it2 ) == BSON_ARRAY ); ASSERT( bson_iterator_type( &it2 ) == BSON_ARRAY ); ASSERT( !strcmp( bson_iterator_key( &it2 ), "a" ) ); bson_iterator_subiterator( &it2, &it3 ); ASSERT( bson_iterator_more( &it3 ) ); ASSERT( bson_iterator_next( &it3 ) == BSON_BINDATA ); ASSERT( bson_iterator_type( &it3 ) == BSON_BINDATA ); ASSERT( !strcmp( bson_iterator_key( &it3 ), "0" ) ); ASSERT( bson_iterator_bin_type( &it3 ) == 8 ); ASSERT( bson_iterator_bin_len( &it3 ) == 5 ); ASSERT( !memcmp( bson_iterator_bin_data( &it3 ), "w\0rld", 5 ) ); ASSERT( bson_iterator_more( &it3 ) ); ASSERT( bson_iterator_next( &it3 ) == BSON_EOO ); ASSERT( bson_iterator_type( &it3 ) == BSON_EOO ); ASSERT( !bson_iterator_more( &it3 ) ); ASSERT( bson_iterator_more( &it2 ) ); ASSERT( bson_iterator_next( &it2 ) == BSON_EOO ); ASSERT( bson_iterator_type( &it2 ) == BSON_EOO ); ASSERT( !bson_iterator_more( &it2 ) ); ASSERT( bson_iterator_more( &it ) ); ASSERT( bson_iterator_next( &it ) == BSON_UNDEFINED ); ASSERT( bson_iterator_type( &it ) == BSON_UNDEFINED ); ASSERT( !strcmp( bson_iterator_key( &it ), "u" ) ); ASSERT( bson_iterator_more( &it ) ); ASSERT( bson_iterator_next( &it ) == BSON_OID ); ASSERT( bson_iterator_type( &it ) == BSON_OID ); ASSERT( !strcmp( bson_iterator_key( &it ), "oid" ) ); ASSERT( !memcmp( bson_iterator_oid( &it )->bytes, "\x001\x002\x003\x004\x005\x006\x007\x008\x009\x010\x011\x012", 12 ) ); ASSERT( bson_iterator_oid( &it )->ints[0] == oid.ints[0] ); ASSERT( bson_iterator_oid( &it )->ints[1] == oid.ints[1] ); ASSERT( bson_iterator_oid( &it )->ints[2] == oid.ints[2] ); ASSERT( bson_iterator_more( &it ) ); ASSERT( bson_iterator_next( &it ) == BSON_BOOL ); ASSERT( bson_iterator_type( &it ) == BSON_BOOL ); ASSERT( !strcmp( bson_iterator_key( &it ), "b" ) ); ASSERT( bson_iterator_bool( &it ) == 1 ); ASSERT( bson_iterator_more( &it ) ); ASSERT( bson_iterator_next( &it ) == BSON_DATE ); ASSERT( bson_iterator_type( &it ) == BSON_DATE ); ASSERT( !strcmp( bson_iterator_key( &it ), "date" ) ); ASSERT( bson_iterator_date( &it ) == 0x0102030405060708 ); ASSERT( bson_iterator_more( &it ) ); ASSERT( bson_iterator_next( &it ) == BSON_NULL ); ASSERT( bson_iterator_type( &it ) == BSON_NULL ); ASSERT( !strcmp( bson_iterator_key( &it ), "n" ) ); ASSERT( bson_iterator_more( &it ) ); ASSERT( bson_iterator_next( &it ) == BSON_REGEX ); ASSERT( bson_iterator_type( &it ) == BSON_REGEX ); ASSERT( !strcmp( bson_iterator_key( &it ), "r" ) ); ASSERT( !strcmp( bson_iterator_regex( &it ), "^asdf" ) ); ASSERT( !strcmp( bson_iterator_regex_opts( &it ), "imx" ) ); ASSERT( bson_iterator_more( &it ) ); ASSERT( bson_iterator_next( &it ) == BSON_CODE ); ASSERT( bson_iterator_type( &it ) == BSON_CODE ); ASSERT( !strcmp( bson_iterator_code(&it), "function(){}") ); ASSERT( !strcmp( bson_iterator_key( &it ), "c" ) ); ASSERT( !strcmp( bson_iterator_string( &it ), "" ) ); ASSERT( bson_iterator_more( &it ) ); ASSERT( bson_iterator_next( &it ) == BSON_CODE ); ASSERT( bson_iterator_type( &it ) == BSON_CODE ); ASSERT( !strcmp( bson_iterator_key( &it ), "c_n" ) ); ASSERT( !strcmp( bson_iterator_string( &it ), "" ) ); ASSERT( !strcmp( bson_iterator_code( &it ), "function(){}" ) ); ASSERT( bson_iterator_more( &it ) ); ASSERT( bson_iterator_next( &it ) == BSON_SYMBOL ); ASSERT( bson_iterator_type( &it ) == BSON_SYMBOL ); ASSERT( !strcmp( bson_iterator_key( &it ), "symbol" ) ); ASSERT( !strcmp( bson_iterator_string( &it ), "symbol" ) ); ASSERT( bson_iterator_more( &it ) ); ASSERT( bson_iterator_next( &it ) == BSON_SYMBOL ); ASSERT( bson_iterator_type( &it ) == BSON_SYMBOL ); ASSERT( !strcmp( bson_iterator_key( &it ), "symbol_n" ) ); ASSERT( !strcmp( bson_iterator_string( &it ), "symbol" ) ); ASSERT( bson_iterator_more( &it ) ); ASSERT( bson_iterator_next( &it ) == BSON_CODEWSCOPE ); ASSERT( bson_iterator_type( &it ) == BSON_CODEWSCOPE ); ASSERT( !strcmp( bson_iterator_key( &it ), "cws" ) ); ASSERT( !strcmp( bson_iterator_code( &it ), "function(){return i}" ) ); { bson scope; bson_iterator_code_scope( &it, &scope ); bson_iterator_init( &it2, &scope ); ASSERT( bson_iterator_more( &it2 ) ); ASSERT( bson_iterator_next( &it2 ) == BSON_INT ); ASSERT( bson_iterator_type( &it2 ) == BSON_INT ); ASSERT( !strcmp( bson_iterator_key( &it2 ), "i" ) ); ASSERT( bson_iterator_int( &it2 ) == 123 ); ASSERT( bson_iterator_more( &it2 ) ); ASSERT( bson_iterator_next( &it2 ) == BSON_EOO ); ASSERT( bson_iterator_type( &it2 ) == BSON_EOO ); ASSERT( !bson_iterator_more( &it2 ) ); } ASSERT( bson_iterator_more( &it ) ); ASSERT( bson_iterator_next( &it ) == BSON_TIMESTAMP ); ASSERT( bson_iterator_type( &it ) == BSON_TIMESTAMP ); ASSERT( !strcmp( bson_iterator_key( &it ), "timestamp" ) ); ts_result = bson_iterator_timestamp( &it ); ASSERT( ts_result.i == 1 ); ASSERT( ts_result.t == 2 ); ASSERT( bson_iterator_more( &it ) ); ASSERT( bson_iterator_next( &it ) == BSON_LONG ); ASSERT( bson_iterator_type( &it ) == BSON_LONG ); ASSERT( !strcmp( bson_iterator_key( &it ), "l" ) ); ASSERT( bson_iterator_long( &it ) == 0x1122334455667788 ); ASSERT( bson_iterator_more( &it ) ); ASSERT( bson_iterator_next( &it ) == BSON_EOO ); ASSERT( bson_iterator_type( &it ) == BSON_EOO ); ASSERT( !bson_iterator_more( &it ) ); bson_destroy( b ); { bson bsrc[1]; bson_init( bsrc ); bson_append_double( bsrc, "d", 3.14 ); bson_finish( bsrc ); ASSERT( bsrc->err == BSON_VALID ); bson_init( b ); bson_append_double( b, "", 3.14 ); /* test empty name (in general) */ bson_iterator_init( &it, bsrc ); ASSERT( bson_iterator_more( &it ) ); ASSERT( bson_iterator_next( &it ) == BSON_DOUBLE ); ASSERT( bson_iterator_type( &it ) == BSON_DOUBLE ); bson_append_element( b, "d", &it ); bson_append_element( b, 0, &it ); /* test null */ bson_append_element( b, "", &it ); /* test empty name */ bson_finish( b ); ASSERT( b->err == BSON_VALID ); /* bson_print( b ); */ bson_iterator_init( &it, b ); ASSERT( bson_iterator_more( &it ) ); ASSERT( bson_iterator_next( &it ) == BSON_DOUBLE ); ASSERT( !strcmp( bson_iterator_key( &it ), "" ) ); ASSERT( bson_iterator_double( &it ) == 3.14 ); ASSERT( bson_iterator_more( &it ) ); ASSERT( bson_iterator_next( &it ) == BSON_DOUBLE ); ASSERT( !strcmp( bson_iterator_key( &it ), "d" ) ); ASSERT( bson_iterator_double( &it ) == 3.14 ); ASSERT( bson_iterator_more( &it ) ); ASSERT( bson_iterator_next( &it ) == BSON_DOUBLE ); ASSERT( !strcmp( bson_iterator_key( &it ), "d" ) ); ASSERT( bson_iterator_double( &it ) == 3.14 ); ASSERT( bson_iterator_more( &it ) ); ASSERT( bson_iterator_next( &it ) == BSON_DOUBLE ); ASSERT( !strcmp( bson_iterator_key( &it ), "" ) ); ASSERT( bson_iterator_double( &it ) == 3.14 ); ASSERT( bson_iterator_more( &it ) ); ASSERT( bson_iterator_next( &it ) == BSON_EOO ); ASSERT( !bson_iterator_more( &it ) ); bson_destroy( bsrc ); bson_destroy( b ); } return 0; }
void encodeValue(bson *bb, const char *name, v8::Local<v8::Value> element, bool doJson) { if (element.IsEmpty() || element->IsUndefined() || element->IsFunction()) ; else if (element->IsNull()) bson_append_null(bb, name); else if (element->IsDate()) bson_append_date(bb, name, (bson_date_t) element->NumberValue()); else if (element->IsBoolean()) bson_append_bool(bb, name, element->IsTrue()); else if (element->IsNumber() || element->IsNumberObject()) { double value = element->NumberValue(); int64_t num = (int64_t) value; if (value == (double) num) { if (num >= -2147483648ll && num <= 2147483647ll) bson_append_int(bb, name, (int) num); else bson_append_long(bb, name, num); } else bson_append_double(bb, name, value); } else if (element->IsArray()) encodeArray(bb, name, element); else if (element->IsRegExp()) { v8::Local<v8::RegExp> re = v8::Local<v8::RegExp>::Cast(element); v8::Local<v8::String> src = re->GetSource(); v8::RegExp::Flags flgs = re->GetFlags(); char flgStr[4]; char *p = flgStr; if (flgs & v8::RegExp::kIgnoreCase) *p++ = 'i'; if (flgs & v8::RegExp::kGlobal) *p++ = 'g'; if (flgs & v8::RegExp::kMultiline) *p++ = 'm'; *p = 0; bson_append_regex(bb, name, *v8::String::Utf8Value(src), flgStr); } else if (element->IsObject()) { { obj_ptr<Int64> num = (Int64 *)Int64_base::getInstance(element); if (num) { if (num->m_num >= -2147483648ll && num->m_num <= 2147483647ll) bson_append_int(bb, name, (int) num->m_num); else bson_append_long(bb, name, num->m_num); return; } } { obj_ptr<Buffer_base> buf = Buffer_base::getInstance(element); if (buf) { std::string strBuf; buf->toString(strBuf); bson_append_binary(bb, name, BSON_BIN_BINARY, strBuf.c_str(), (int) strBuf.length()); return; } } { obj_ptr<MongoID> oid = (MongoID *) MongoID_base::getInstance( element); if (oid) { bson_append_oid(bb, name, &oid->m_id); return; } } encodeObject(bb, name, element, doJson); } else { v8::String::Utf8Value v(element); bson_append_string(bb, name, ToCString(v)); } }
void Namespace::parseJSON(bson* &p, const char* json, jsmntok_t *tokens, int &tokenCursor, bool createNew, int elementCount) { if (_DEBUG) LOGI("parse"); char buf[100]; int autoKey = 0; char firstChar; int count = 0; char keyBuf[255]; char valueBuf[1024]; bool tokenIsKey = false; for (int i(0); i < elementCount; i++) { jsmntok_t token = tokens[tokenCursor]; tokenIsKey = false; // check if the token contains a key (look for ':' within 5 chars after its end for (int k(0); k < 5; k++) { { if (json[token.end + k] == ':') { memcpy(keyBuf, &json[token.start], token.end - token.start); keyBuf[token.end - token.start] = '\0'; tokenIsKey = true; break; } } } if (tokenIsKey) { tokenCursor++; continue; // that token was key, continue with the rest } switch (token.type) { case JSMN_ARRAY: count = token.size; bson_append_start_array(p, keyBuf); tokenCursor++; parseJSON(p, json, tokens, tokenCursor, false, token.size); bson_append_finish_array(p); break; case JSMN_OBJECT: if (createNew) { createNew = false; tokenCursor++; parseJSON(p, json, tokens, tokenCursor, false, token.size); } else { bson_append_start_object(p, keyBuf); tokenCursor++; parseJSON(p, json, tokens, tokenCursor, false, token.size); bson_append_finish_object(p); } break; case JSMN_STRING: memcpy(valueBuf, &json[token.start], token.end - token.start); valueBuf[token.end - token.start] = '\0'; bson_append_string(p, keyBuf, valueBuf); tokenCursor++; break; case JSMN_PRIMITIVE: firstChar = json[token.start]; if (firstChar == 't' || firstChar == 'f') { // todo: wrong boolean parameter memcpy(valueBuf, &json[token.start], token.end - token.start); valueBuf[token.end - token.start] = '\0'; bson_append_bool(p, keyBuf, atoi(valueBuf)); } else if (firstChar == 'n') { bson_append_null(p, keyBuf); } else { memcpy(valueBuf, &json[token.start], token.end - token.start); valueBuf[token.end - token.start] = '\0'; double v = atof(valueBuf); if (fmod(v, 1) == 0) { /* variable is an integer */ bson_append_int(p, keyBuf, (int) v); } else { bson_append_double(p, keyBuf, v); } } tokenCursor++; break; default: break; } } }
int main(int argc, char *argv[]) { bson_buffer bb; bson b; bson_iterator it, it2, it3; bson_oid_t oid; bson_buffer_init(&bb); bson_append_double(&bb, "d", 3.14); bson_append_string(&bb, "s", "hello"); { bson_buffer *obj = bson_append_start_object(&bb, "o"); bson_buffer *arr = bson_append_start_array(obj, "a"); bson_append_binary(arr, "0", 8, "w\0rld", 5); bson_append_finish_object(arr); bson_append_finish_object(obj); } bson_append_undefined(&bb, "u"); bson_oid_from_string(&oid, "010203040506070809101112"); ASSERT(!memcmp(oid.bytes, "\x001\x002\x003\x004\x005\x006\x007\x008\x009\x010\x011\x012", 12)); bson_append_oid(&bb, "oid", &oid); bson_append_bool(&bb, "b", 1); bson_append_date(&bb, "date", 0x0102030405060708ULL); bson_append_null(&bb, "n"); bson_append_regex(&bb, "r", "^asdf", "imx"); /* no dbref test (deprecated) */ bson_append_code(&bb, "c", "function(){}"); bson_append_symbol(&bb, "symbol", "SYMBOL"); { bson_buffer scope_buf; bson scope; bson_buffer_init(&scope_buf); bson_append_int(&scope_buf, "i", 123); bson_from_buffer(&scope, &scope_buf); bson_append_code_w_scope(&bb, "cws", "function(){return i}", &scope); bson_destroy(&scope); } /* no timestamp test (internal) */ bson_append_long(&bb, "l", 0x1122334455667788ULL); bson_from_buffer(&b, &bb); bson_iterator_init(&it, b.data); ASSERT(bson_iterator_more(&it)); ASSERT(bson_iterator_next(&it) == bson_double); ASSERT(bson_iterator_type(&it) == bson_double); ASSERT(!strcmp(bson_iterator_key(&it), "d")); ASSERT(bson_iterator_double(&it) == 3.14); ASSERT(bson_iterator_more(&it)); ASSERT(bson_iterator_next(&it) == bson_string); ASSERT(bson_iterator_type(&it) == bson_string); ASSERT(!strcmp(bson_iterator_key(&it), "s")); ASSERT(!strcmp(bson_iterator_string(&it), "hello")); ASSERT(bson_iterator_more(&it)); ASSERT(bson_iterator_next(&it) == bson_object); ASSERT(bson_iterator_type(&it) == bson_object); ASSERT(!strcmp(bson_iterator_key(&it), "o")); bson_iterator_subiterator(&it, &it2); ASSERT(bson_iterator_more(&it2)); ASSERT(bson_iterator_next(&it2) == bson_array); ASSERT(bson_iterator_type(&it2) == bson_array); ASSERT(!strcmp(bson_iterator_key(&it2), "a")); bson_iterator_subiterator(&it2, &it3); ASSERT(bson_iterator_more(&it3)); ASSERT(bson_iterator_next(&it3) == bson_bindata); ASSERT(bson_iterator_type(&it3) == bson_bindata); ASSERT(!strcmp(bson_iterator_key(&it3), "0")); ASSERT(bson_iterator_bin_type(&it3) == 8); ASSERT(bson_iterator_bin_len(&it3) == 5); ASSERT(!memcmp(bson_iterator_bin_data(&it3), "w\0rld", 5)); ASSERT(bson_iterator_more(&it3)); ASSERT(bson_iterator_next(&it3) == bson_eoo); ASSERT(bson_iterator_type(&it3) == bson_eoo); ASSERT(!bson_iterator_more(&it3)); ASSERT(bson_iterator_more(&it2)); ASSERT(bson_iterator_next(&it2) == bson_eoo); ASSERT(bson_iterator_type(&it2) == bson_eoo); ASSERT(!bson_iterator_more(&it2)); ASSERT(bson_iterator_more(&it)); ASSERT(bson_iterator_next(&it) == bson_undefined); ASSERT(bson_iterator_type(&it) == bson_undefined); ASSERT(!strcmp(bson_iterator_key(&it), "u")); ASSERT(bson_iterator_more(&it)); ASSERT(bson_iterator_next(&it) == bson_oid); ASSERT(bson_iterator_type(&it) == bson_oid); ASSERT(!strcmp(bson_iterator_key(&it), "oid")); ASSERT(!memcmp(bson_iterator_oid(&it)->bytes, "\x001\x002\x003\x004\x005\x006\x007\x008\x009\x010\x011\x012", 12)); ASSERT(bson_iterator_oid(&it)->ints[0] == oid.ints[0]); ASSERT(bson_iterator_oid(&it)->ints[1] == oid.ints[1]); ASSERT(bson_iterator_oid(&it)->ints[2] == oid.ints[2]); ASSERT(bson_iterator_more(&it)); ASSERT(bson_iterator_next(&it) == bson_bool); ASSERT(bson_iterator_type(&it) == bson_bool); ASSERT(!strcmp(bson_iterator_key(&it), "b")); ASSERT(bson_iterator_bool(&it) == 1); ASSERT(bson_iterator_more(&it)); ASSERT(bson_iterator_next(&it) == bson_date); ASSERT(bson_iterator_type(&it) == bson_date); ASSERT(!strcmp(bson_iterator_key(&it), "date")); ASSERT(bson_iterator_date(&it) == 0x0102030405060708ULL); ASSERT(bson_iterator_more(&it)); ASSERT(bson_iterator_next(&it) == bson_null); ASSERT(bson_iterator_type(&it) == bson_null); ASSERT(!strcmp(bson_iterator_key(&it), "n")); ASSERT(bson_iterator_more(&it)); ASSERT(bson_iterator_next(&it) == bson_regex); ASSERT(bson_iterator_type(&it) == bson_regex); ASSERT(!strcmp(bson_iterator_key(&it), "r")); ASSERT(!strcmp(bson_iterator_regex(&it), "^asdf")); ASSERT(!strcmp(bson_iterator_regex_opts(&it), "imx")); ASSERT(bson_iterator_more(&it)); ASSERT(bson_iterator_next(&it) == bson_code); ASSERT(bson_iterator_type(&it) == bson_code); ASSERT(!strcmp(bson_iterator_key(&it), "c")); ASSERT(!strcmp(bson_iterator_string(&it), "function(){}")); ASSERT(!strcmp(bson_iterator_code(&it), "function(){}")); ASSERT(bson_iterator_more(&it)); ASSERT(bson_iterator_next(&it) == bson_symbol); ASSERT(bson_iterator_type(&it) == bson_symbol); ASSERT(!strcmp(bson_iterator_key(&it), "symbol")); ASSERT(!strcmp(bson_iterator_string(&it), "SYMBOL")); ASSERT(bson_iterator_more(&it)); ASSERT(bson_iterator_next(&it) == bson_codewscope); ASSERT(bson_iterator_type(&it) == bson_codewscope); ASSERT(!strcmp(bson_iterator_key(&it), "cws")); ASSERT(!strcmp(bson_iterator_code(&it), "function(){return i}")); { bson scope; bson_iterator_code_scope(&it, &scope); bson_iterator_init(&it2, scope.data); ASSERT(bson_iterator_more(&it2)); ASSERT(bson_iterator_next(&it2) == bson_int); ASSERT(bson_iterator_type(&it2) == bson_int); ASSERT(!strcmp(bson_iterator_key(&it2), "i")); ASSERT(bson_iterator_int(&it2) == 123); ASSERT(bson_iterator_more(&it2)); ASSERT(bson_iterator_next(&it2) == bson_eoo); ASSERT(bson_iterator_type(&it2) == bson_eoo); ASSERT(!bson_iterator_more(&it2)); } ASSERT(bson_iterator_more(&it)); ASSERT(bson_iterator_next(&it) == bson_long); ASSERT(bson_iterator_type(&it) == bson_long); ASSERT(!strcmp(bson_iterator_key(&it), "l")); ASSERT(bson_iterator_long(&it) == 0x1122334455667788ULL); ASSERT(bson_iterator_more(&it)); ASSERT(bson_iterator_next(&it) == bson_eoo); ASSERT(bson_iterator_type(&it) == bson_eoo); ASSERT(!bson_iterator_more(&it)); return 0; }
static void lua_val_to_bson(lua_State *L, const char *key, int vpos, bson *bs, int tref) { int vtype = lua_type(L, vpos); char nbuf[TCNUMBUFSIZ]; if (key == NULL && vtype != LUA_TTABLE) { luaL_error(L, "lua_val_to_bson: Table must be on top of lua stack"); return; } switch (vtype) { case LUA_TTABLE: { if (vpos < 0) { vpos = lua_gettop(L) + vpos + 1; } lua_checkstack(L, 3); int bsontype_found = luaL_getmetafield(L, vpos, "__bsontype"); if (!bsontype_found) { lua_rawgeti(L, LUA_REGISTRYINDEX, tref); //+ reg table lua_pushvalue(L, vpos); //+ val lua_rawget(L, -2); //-val +reg table val if (lua_toboolean(L, -1)) { //already traversed lua_pop(L, 2); break; } lua_pop(L, 1); //-reg table val lua_pushvalue(L, vpos); lua_pushboolean(L, 1); lua_rawset(L, -3); lua_pop(L, 1); //-reg table int len = 0; bool query = false; bool array = true; if (luaL_getmetafield(L, vpos, "__query")) { lua_pop(L, 1); query = true; array = false; } if (array) { for (lua_pushnil(L); lua_next(L, vpos); lua_pop(L, 1)) { ++len; if ((lua_type(L, -2) != LUA_TNUMBER) || (lua_tointeger(L, -2) != len)) { lua_pop(L, 2); array = false; break; } } } if (array) { if (key) bson_append_start_array(bs, key); int i; for (i = 1; i <= len; ++i, lua_pop(L, 1)) { lua_rawgeti(L, vpos, i); bson_numstrn(nbuf, TCNUMBUFSIZ, (int64_t) i); lua_val_to_bson(L, nbuf, -1, bs, tref); } if (key) bson_append_finish_array(bs); } else if (query) { //special query builder case //oarr format: //{ {fname1, v1, v2...}, {fname2, v21, v22,..}, ... } //where: vN: {op, val} OR {val} with '__bval' metafield //Eg: {fname : {$inc : {...}, $dec : {...}}} -> {fname, {$inc, {}}, {$dec, {}}} lua_getfield(L, vpos, "_oarr"); //+oarr if (!lua_istable(L, -1)) { //it is not array lua_pop(L, 1); break; } if (key) bson_append_start_object(bs, key); //iterate over _oarr int ipos = lua_gettop(L); size_t ilen = lua_objlen(L, ipos); lua_checkstack(L, 2); size_t i; for (i = 1; i <= ilen; ++i, lua_pop(L, 1)) { lua_rawgeti(L, ipos, i); //gettop == 3 if (!lua_istable(L, -1)) continue; char *fname = NULL; int jpos = lua_gettop(L); size_t jlen = lua_objlen(L, jpos); lua_checkstack(L, 3); bool wrapped = false; size_t j; for (j = 1; j <= jlen; ++j, lua_pop(L, 1)) { lua_rawgeti(L, jpos, j); if (j == 1) { fname = strdup(lua_tostring(L, -1)); continue; } if (!fname || !lua_istable(L, -1)) { //invalid state lua_pop(L, 1); //pop val break; } int vblkpos = lua_gettop(L); if (j == 2 && luaL_getmetafield(L, -1, "__bval")) { //{val} single value +metafield lua_pop(L, 1); //-metafield lua_rawgeti(L, vblkpos, 1); //+val lua_val_to_bson(L, fname, lua_gettop(L), bs, tref); lua_pop(L, 2); //-val -lua_rawgeti break; //Terminate due single val } else { //{op, val} value if (!wrapped) { bson_append_start_object(bs, fname); wrapped = true; } lua_rawgeti(L, vblkpos, 1); //+op const char *op = lua_tostring(L, -1); if (op) { lua_rawgeti(L, vblkpos, 2); //+val lua_val_to_bson(L, op, lua_gettop(L), bs, tref); lua_pop(L, 1); //-val } lua_pop(L, 1); //-op } } if (wrapped) { bson_append_finish_object(bs); } if (fname) { free(fname); fname = NULL; } } if (key) bson_append_finish_object(bs); lua_pop(L, 1); //-oarr } else { if (key) bson_append_start_object(bs, key); TCLIST *keys = tclistnew(); //we need to sort keys due to unordered nature of lua tables for (lua_pushnil(L); lua_next(L, vpos);) { lua_pop(L, 1); //-val size_t ksize = 0; int ktype = lua_type(L, -1); if (ktype == LUA_TSTRING) { //accept only string keys const char* key = lua_tolstring(L, -1, &ksize); tclistpush(keys, key, ksize); } } tclistsort(keys); int i; for (i = 0; i < TCLISTNUM(keys); ++i) { int vkeysz = TCLISTVALSIZ(keys, i); const char *vkey = TCLISTVALPTR(keys, i); lua_pushlstring(L, vkey, vkeysz); lua_rawget(L, vpos); //+val if (key == NULL && lua_type(L, -1) == LUA_TSTRING && vkeysz == JDBIDKEYNAMEL && !strcmp(JDBIDKEYNAME, vkey)) { //root level OID as string //pack OID as type table lua_push_bsontype_table(L, BSON_OID); //+type table lua_pushvalue(L, -2); //dup oid(val) on stack lua_rawseti(L, -2, 1); //pop oid val if (ejdbisvalidoidstr(lua_tostring(L, -2))) { lua_val_to_bson(L, vkey, lua_gettop(L), bs, tref); } else { luaL_error(L, "OID _id='%s' is not valid", lua_tostring(L, -2)); } lua_pop(L, 1); //-type table } else { lua_val_to_bson(L, vkey, lua_gettop(L), bs, tref); } lua_pop(L, 1); //-val } tclistdel(keys); if (key) bson_append_finish_object(bs); } } else { //metafield __bsontype on top int bson_type = lua_tointeger(L, -1); if (!key && bson_type != BSON_OBJECT && bson_type != BSON_ARRAY) { lua_pop(L, 1); luaL_error(L, "Invalid object structure"); } lua_pop(L, 1); //-metafield __bsontype lua_rawgeti(L, -1, 1); //get first value switch (bson_type) { case BSON_OID: { const char* boid = lua_tostring(L, -1); if (boid && strlen(boid) == 24) { bson_oid_t oid; bson_oid_from_string(&oid, boid); bson_append_oid(bs, key, &oid); } break; } case BSON_DATE: bson_append_date(bs, key, (bson_date_t) lua_tonumber(L, -1)); break; case BSON_REGEX: { const char* regex = lua_tostring(L, -1); lua_rawgeti(L, -2, 2); // re opts const char* options = lua_tostring(L, -1); if (regex && options) { bson_append_regex(bs, key, regex, options); } lua_pop(L, 1); break; } case BSON_BINDATA: { size_t len; const char* cbuf = lua_tolstring(L, -1, &len); bson_append_binary(bs, key, BSON_BIN_BINARY, cbuf, len); break; } case BSON_NULL: bson_append_null(bs, key); break; case BSON_UNDEFINED: bson_append_undefined(bs, key); break; case BSON_OBJECT: if (key) bson_append_start_object(bs, key); lua_val_to_bson(L, NULL, vpos, bs, tref); if (key) bson_append_finish_object(bs); break; case BSON_ARRAY: if (key) bson_append_start_array(bs, key); lua_val_to_bson(L, NULL, vpos, bs, tref); if (key) bson_append_finish_array(bs); break; case BSON_DOUBLE: bson_append_double(bs, key, (double) lua_tonumber(L, -1)); break; case BSON_INT: bson_append_int(bs, key, (int32_t) lua_tonumber(L, -1)); break; case BSON_LONG: bson_append_long(bs, key, (int64_t) lua_tonumber(L, -1)); break; case BSON_BOOL: bson_append_bool(bs, key, lua_toboolean(L, -1)); break; default: break; } lua_pop(L, 1); //-1 first value } break; } case LUA_TNIL: bson_append_null(bs, key); break; case LUA_TNUMBER: { lua_Number numval = lua_tonumber(L, vpos); if (numval == floor(numval)) { int64_t iv = (int64_t) numval; if (-(1LL << 31) <= iv && iv <= (1LL << 31)) { bson_append_int(bs, key, iv); } else { bson_append_long(bs, key, iv); } } else { bson_append_double(bs, key, numval); } break; } case LUA_TBOOLEAN: bson_append_bool(bs, key, lua_toboolean(L, vpos)); break; case LUA_TSTRING: bson_append_string(bs, key, lua_tostring(L, vpos)); break; } }
EXPORT int mongo_bson_buffer_append_null(struct bson_buffer* b, char *name) { return (bson_append_null((bson*) b, name) == BSON_OK); }
static bcon_error_t bson_bcon_key_value(bson *b, const char *key, const char *typespec, const bcon bci) { bcon_error_t ret = BCON_OK; bson_oid_t oid; char ptype = typespec ? typespec[1] : '_'; char utype = typespec ? typespec[2] : '_'; switch (ptype) { case '_': /* kv(b, key, utype, bci) */ switch (utype) { case '_': /* fall through */ case 's': bson_append_string( b, key, bci.s ); break; /* common case */ case 'f': bson_append_double( b, key, bci.f ); break; case 'D': bson_append_start_object( b, key ); ret = bson_append_bcon( b, bci.D ); bson_append_finish_object( b ); break; case 'A': bson_append_start_array( b, key ); ret = bson_append_bcon_array( b, bci.A ); bson_append_finish_array( b ); break; case 'o': if (*bci.o == '\0') bson_oid_gen( &oid ); else bson_oid_from_string( &oid, bci.o ); bson_append_oid( b, key, &oid ); break; case 'b': bson_append_bool( b, key, bci.b ); break; case 't': bson_append_time_t( b, key, bci.t ); break; case 'v': bson_append_null( b, key ); break; /* void */ case 'x': bson_append_symbol( b, key, bci.x ); break; case 'i': bson_append_int( b, key, bci.i ); break; case 'l': bson_append_long( b, key, bci.l ); break; default: printf("\nptype:'%c' utype:'%c'\n", ptype, utype); assert(NOT_REACHED); break; } break; case 'R': /* krv(b, key, utype, bci) */ switch (utype) { case 'f': bson_append_double( b, key, *bci.Rf ); break; case 's': bson_append_string( b, key, bci.Rs ); break; case 'D': bson_append_start_object( b, key ); ret = bson_append_bcon( b, bci.RD ); bson_append_finish_object( b ); break; case 'A': bson_append_start_array( b, key ); ret = bson_append_bcon_array( b, bci.RA ); bson_append_finish_array( b ); break; case 'o': if (*bci.o == '\0') bson_oid_gen( &oid ); else bson_oid_from_string( &oid, bci.o ); bson_append_oid( b, key, &oid ); break; case 'b': bson_append_bool( b, key, *bci.Rb ); break; case 't': bson_append_time_t( b, key, *bci.Rt ); break; case 'x': bson_append_symbol( b, key, bci.Rx ); break; case 'i': bson_append_int( b, key, *bci.Ri ); break; case 'l': bson_append_long( b, key, *bci.Rl ); break; default: printf("\nptype:'%c' utype:'%c'\n", ptype, utype); assert(NOT_REACHED); break; } break; case 'P': /* kpv(b, key, utype, bci) */ if (*bci.Pv != 0) { switch (utype) { case 'f': bson_append_double( b, key, **bci.Pf ); break; case 's': bson_append_string( b, key, *bci.Ps ); break; case 'D': bson_append_start_object( b, key ); ret = bson_append_bcon( b, *bci.PD ); bson_append_finish_object( b ); break; case 'A': bson_append_start_array( b, key ); ret = bson_append_bcon_array( b, *bci.PA ); bson_append_finish_array( b ); break; case 'o': if (**bci.Po == '\0') bson_oid_gen( &oid ); else bson_oid_from_string( &oid, *bci.Po ); bson_append_oid( b, key, &oid ); break; case 'b': bson_append_bool( b, key, **bci.Pb ); break; case 't': bson_append_time_t( b, key, **bci.Pt ); break; case 'x': if (*bci.Px != 0) bson_append_symbol( b, key, *bci.Px ); break; case 'i': bson_append_int( b, key, **bci.Pi ); break; case 'l': bson_append_long( b, key, **bci.Pl ); break; default: printf("\nptype:'%c' utype:'%c'\n", ptype, utype); assert(NOT_REACHED); break; } } break; default: printf("\nptype:'%c' utype:'%c'\n", ptype, utype); assert(NOT_REACHED); break; } return ret; }
void testCheckDuplicates(void) { bson bs, bs2; bson_iterator it; bson_type bt; bson_init(&bs); bson_append_string(&bs, "a", "a"); bson_append_int(&bs, "b", 2); bson_append_null(&bs, "c"); bson_append_start_object(&bs, "d"); bson_append_string(&bs, "a", "a"); bson_append_int(&bs, "e", 0); bson_append_int(&bs, "d", 1); bson_append_finish_object(&bs); bson_finish(&bs); CU_ASSERT_FALSE_FATAL(bs.err); CU_ASSERT_FALSE(bson_check_duplicate_keys(&bs)); bson_destroy(&bs); bson_init(&bs); bson_append_string(&bs, "a", "a"); bson_append_int(&bs, "b", 2); bson_append_null(&bs, "c"); bson_append_start_object(&bs, "d"); bson_append_string(&bs, "a", "a"); bson_append_int(&bs, "e", 0); bson_append_int(&bs, "e", 1); bson_append_finish_object(&bs); bson_finish(&bs); CU_ASSERT_FALSE_FATAL(bs.err); CU_ASSERT_TRUE(bson_check_duplicate_keys(&bs)); bson_init(&bs2); bson_fix_duplicate_keys(&bs, &bs2); bson_finish(&bs2); CU_ASSERT_FALSE(bson_check_duplicate_keys(&bs2)); BSON_ITERATOR_INIT(&it, &bs2); bt = bson_find_fieldpath_value("d.e", &it); CU_ASSERT_TRUE(BSON_IS_NUM_TYPE(bt)); CU_ASSERT_EQUAL(bson_iterator_int(&it), 1); bson_destroy(&bs2); bson_init(&bs); bson_append_string(&bs, "a", "a"); bson_append_int(&bs, "b", 2); bson_append_null(&bs, "c"); bson_append_start_object(&bs, "d"); bson_append_string(&bs, "a", "a"); bson_append_int(&bs, "e", 0); bson_append_int(&bs, "d", 1); bson_append_finish_object(&bs); bson_append_start_array(&bs, "f"); bson_append_start_object(&bs, "0"); bson_append_string(&bs, "a", "a"); bson_append_string(&bs, "b", "b"); bson_append_int(&bs, "c", 1); bson_append_finish_object(&bs); bson_append_start_object(&bs, "1"); bson_append_string(&bs, "a", "a"); bson_append_string(&bs, "b", "b"); bson_append_int(&bs, "c", 1); bson_append_finish_object(&bs); bson_append_finish_array(&bs); bson_finish(&bs); CU_ASSERT_FALSE_FATAL(bs.err); CU_ASSERT_FALSE(bson_check_duplicate_keys(&bs)); bson_init(&bs); bson_append_string(&bs, "a", "a"); bson_append_int(&bs, "b", 2); bson_append_null(&bs, "c"); bson_append_start_object(&bs, "d"); bson_append_string(&bs, "a", "a"); bson_append_int(&bs, "e", 0); bson_append_int(&bs, "d", 1); bson_append_start_object(&bs, "q"); bson_append_int(&bs, "w", 0); bson_append_finish_object(&bs); bson_append_finish_object(&bs); bson_append_start_array(&bs, "f"); bson_append_start_object(&bs, "0"); bson_append_string(&bs, "a", "a"); bson_append_string(&bs, "b", "b"); bson_append_int(&bs, "a", 1); bson_append_finish_object(&bs); bson_append_start_object(&bs, "1"); bson_append_string(&bs, "a", "a"); bson_append_string(&bs, "b", "b"); bson_append_int(&bs, "c", 1); bson_append_finish_object(&bs); bson_append_finish_array(&bs); bson_append_start_object(&bs, "a"); bson_append_finish_object(&bs); bson_append_start_object(&bs, "d"); bson_append_start_object(&bs, "q"); bson_append_int(&bs, "e", 1); bson_append_finish_object(&bs); bson_append_finish_object(&bs); bson_finish(&bs); CU_ASSERT_FALSE_FATAL(bs.err); CU_ASSERT_TRUE(bson_check_duplicate_keys(&bs)); bson_init(&bs2); bson_fix_duplicate_keys(&bs, &bs2); bson_finish(&bs2); CU_ASSERT_FALSE(bson_check_duplicate_keys(&bs2)); BSON_ITERATOR_INIT(&it, &bs2); bt = bson_find_fieldpath_value("f.0.a", &it); CU_ASSERT_TRUE(BSON_IS_NUM_TYPE(bt)); CU_ASSERT_EQUAL(bson_iterator_int(&it), 1); BSON_ITERATOR_INIT(&it, &bs2); bt = bson_find_fieldpath_value("f.1.a", &it); CU_ASSERT_TRUE(BSON_IS_STRING_TYPE(bt)); CU_ASSERT_FALSE(strcmp(bson_iterator_string(&it), "a")); BSON_ITERATOR_INIT(&it, &bs2); bt = bson_find_fieldpath_value("a", &it); CU_ASSERT_EQUAL(bt, BSON_OBJECT); BSON_ITERATOR_INIT(&it, &bs2); bt = bson_find_fieldpath_value("d.q.w", &it); CU_ASSERT_TRUE(BSON_IS_NUM_TYPE(bt)); CU_ASSERT_EQUAL(bson_iterator_int(&it), 0); BSON_ITERATOR_INIT(&it, &bs2); bt = bson_find_fieldpath_value("d.q.e", &it); CU_ASSERT_TRUE(BSON_IS_NUM_TYPE(bt)); CU_ASSERT_EQUAL(bson_iterator_int(&it), 1); }
static PyObject * cbson_dumps (PyObject *self, PyObject *args) { const char *keystr; PyObject *doc; PyObject *key; PyObject *ret; PyObject *value; Py_ssize_t pos = 0; bson_t *b; size_t keylen; if (!PyArg_ParseTuple(args, "O", &doc)) { return NULL; } if (!PyDict_Check(doc)) { PyErr_SetString(PyExc_TypeError, "doc must be a dict."); return NULL; } b = bson_new(); while (PyDict_Next(doc, &pos, &key, &value)) { /* * TODO: Key validation. Make sure no NULL is present. Ensure valid UTF-8. */ if (PyString_Check(key)) { keystr = PyString_AS_STRING(key); keylen = PyString_GET_SIZE(key); } else if (PyUnicode_Check(key)) { /* * TODO: Convert to UTF-8. */ keystr = (const char *)PyUnicode_AS_UNICODE(key); keylen = PyUnicode_GET_SIZE(key); } else { PyErr_SetString(PyExc_TypeError, "key must be a string."); bson_destroy(b); return NULL; } if (value == Py_None) { if (!bson_append_null(b, keystr, keylen)) { goto failure; } } else if (PyString_Check(value)) { /* * TODO: Validate UTF-8. */ if (!bson_append_utf8(b, keystr, keylen, PyString_AS_STRING(value), PyString_GET_SIZE(value))) { goto failure; } } else if (PyUnicode_Check(value)) { /* * TODO: Convert and validate UTF-8. */ if (!bson_append_utf8(b, keystr, keylen, (const char *)PyUnicode_AS_UNICODE(value), PyUnicode_GET_SIZE(value))) { goto failure; } } else if (PyDateTime_Check(value)) { /* * TODO: Convert to msec since epoch. */ } else if (PyBool_Check(value)) { if (!bson_append_bool(b, keystr, keylen, (value == Py_True))) { goto failure; } } else if (PyLong_Check(value)) { if (!bson_append_int64(b, keystr, keylen, PyLong_AsLong(value))) { goto failure; } } else if (PyInt_Check(value)) { if (!bson_append_int32(b, keystr, keylen, PyInt_AsLong(value))) { goto failure; } } else if (PyFloat_Check(value)) { if (!bson_append_double(b, keystr, keylen, PyFloat_AsDouble(value))) { goto failure; } } else if (cbson_oid_check(value)) { if (!bson_append_oid(b, keystr, keylen, &((cbson_oid_t *)value)->oid)) { goto failure; } /* } else if (CHECK FOR REGEX) { */ /* } else if (CHECK FOR BINARY) { */ } else { goto failure; } } ret = PyString_FromStringAndSize((const char *)bson_get_data(b), b->len); bson_destroy(b); return ret; failure: PyErr_SetString(PyExc_TypeError, "Cannot encode type."); bson_destroy(b); return NULL; }
void core::append(const types::b_null&) { stdx::string_view key = _impl->next_key(); bson_append_null(_impl->back(), key.data(), key.length()); }
static void on_stack_change(jsonsl_t parser, jsonsl_action_t action, struct jsonsl_state_st * state, const jsonsl_char_t * at) { /* printf("%c%c", action, state->type); if (state->type == JSONSL_T_SPECIAL) { printf("%c", state->special_flags); } printf("%d", state->pos_begin); if (action == JSONSL_ACTION_POP) { printf("-%d", state->pos_cur); } printf("\n"); */ struct bson_state * bstate = (struct bson_state *) parser->data; if (action == JSONSL_ACTION_PUSH) { if (state->type == JSONSL_T_OBJECT || state->type == JSONSL_T_LIST) { if (bstate->cur_entry > -1) { bstate->cur_entry++; bstate->entry[bstate->cur_entry].key = (bstring) state->data; } else { bstate->cur_entry = 0; bstate->entry[bstate->cur_entry].key = NULL; } bstate->entry[bstate->cur_entry].bson = bson_new(); bstate->entry[bstate->cur_entry].array_index = 0; } } else if (action == JSONSL_ACTION_POP) { if (state->type == JSONSL_T_HKEY) { state->data = read_string(bstate->text + state->pos_begin, state->pos_cur - state->pos_begin); } else if (state->type == JSONSL_T_OBJECT || state->type == JSONSL_T_LIST) { if (bstate->cur_entry > 0) { struct bson_entry * entry = &(bstate->entry[bstate->cur_entry]); struct bson_entry * parent = &(bstate->entry[bstate->cur_entry - 1]); if (state->type == JSONSL_T_OBJECT) { bson_append_document(parent->bson, bdata(entry->key), blength(entry->key), entry->bson); } else { bson_append_array(parent->bson, bdata(entry->key), blength(entry->key), entry->bson); } } bstate->cur_entry--; } else { bstring key = (bstring) state->data; if (key == NULL) { key = bformat("%d", bstate->entry[bstate->cur_entry].array_index); bstate->entry[bstate->cur_entry].array_index++; } if (state->type == JSONSL_T_SPECIAL) { if (state->special_flags & JSONSL_SPECIALf_BOOLEAN) { bson_append_bool(bstate->entry[bstate->cur_entry].bson, bdata(key), blength(key), state->special_flags & JSONSL_SPECIALf_TRUE); } else if (state->special_flags & JSONSL_SPECIALf_NULL) { bson_append_null(bstate->entry[bstate->cur_entry].bson, bdata(key), blength(key)); } else if (state->special_flags & JSONSL_SPECIALf_NUMERIC) { size_t length = state->pos_cur - state->pos_begin; char num[length + 1]; * (num + length) = '\0'; memcpy(num, bstate->text + state->pos_begin, length); if (state->special_flags & JSONSL_SPECIALf_NUMNOINT) { bson_append_double(bstate->entry[bstate->cur_entry].bson, bdata(key), blength(key), atof(num)); } else { bson_append_int64(bstate->entry[bstate->cur_entry].bson, bdata(key), blength(key), atoi(num)); } } } else { bstring value = read_string(bstate->text + state->pos_begin, state->pos_cur - state->pos_begin); bson_append_utf8(bstate->entry[bstate->cur_entry].bson, bdata(key), blength(key), bdata(value), blength(value)); } } } }