int ej_bson_parse_uuid( struct _bson_cursor *bc, const unsigned char *field_name, ej_uuid_t *p_value) { if (bson_cursor_type(bc) != BSON_TYPE_BINARY) { err("parse_bson_uuid: uuid field type expected for '%s'", field_name); return -1; } bson_binary_subtype bt = 0; const unsigned char *bd = NULL; int bz = 0; if (!bson_cursor_get_binary(bc, &bt, &bd, &bz)) { err("parse_bson_uuid: failed to fetch binary data for '%s'", field_name); return -1; } if (bt != BSON_BINARY_SUBTYPE_UUID || bz != sizeof(ej_uuid_t)) { err("parse_bson_uuid: invalid binary data for in '%s'", field_name); return -1; } if (p_value) { memcpy(p_value, bd, sizeof(ej_uuid_t)); } return 1; }
void test_bson_cursor_get_binary (void) { bson *b; bson_cursor *c; const guint8 *d = (guint8 *)"deadbeef"; bson_binary_subtype t = 0xff; gint32 s = -1; ok (bson_cursor_get_binary (NULL, &t, &d, &s) == FALSE, "bson_cursor_get_binary() with a NULL cursor fails"); b = test_bson_generate_full (); c = bson_cursor_new (b); ok (bson_cursor_get_binary (c, NULL, NULL, NULL) == FALSE, "bson_cursor_get_binary() with NULL destinations fails"); ok (bson_cursor_get_binary (c, NULL, &d, &s) == FALSE, "bson_cursor_get_binary() with a NULL subtype destination fails"); ok (bson_cursor_get_binary (c, &t, NULL, &s) == FALSE, "bson_cursor_get_binary() with a NULL binary destination fails"); ok (bson_cursor_get_binary (c, &t, &d, NULL) == FALSE, "bson_cursor_get_binary() with a NULL size destination fails"); ok (bson_cursor_get_binary (c, &t, &d, &s) == FALSE, "bson_cursor_get_binary() at the initial position fails"); ok (memcmp (d, "deadbeef", sizeof ("deadbeef")) == 0, "binary destination remains unchanged after failed cursor operations"); cmp_ok (t, "==", 0xff, "subtype destination remains unchanged after failed cursor " "operations"); cmp_ok (s, "==", -1, "size destination remains unchanged after failed cursor operations"); bson_cursor_free (c); c = bson_find (b, "binary0"); ok (bson_cursor_get_binary (c, &t, &d, &s), "bson_cursor_get_binary() works"); cmp_ok (s, "==", 7, "bson_cursor_get_binary() returns the correct result"); ok (memcmp (d, "foo\0bar", s) == 0, "bson_cursor_get_binary() returns the correct result"); cmp_ok (t, "==", BSON_BINARY_SUBTYPE_GENERIC, "bson_cursor_get_binary() returns the correct result"); bson_cursor_next (c); ok (bson_cursor_get_binary (c, &t, &d, &s) == FALSE, "bson_cursor_get_binary() should fail when the cursor points to " "non-binary data"); bson_cursor_free (c); bson_free (b); }
void ej_bson_unparse( FILE *out, const struct _bson *b, int is_array) { if (!b) { fprintf(out, "NULL"); return; } if (is_array) { fprintf(out, "[ "); } else { fprintf(out, "{ "); } bson_cursor *cursor = bson_cursor_new(b); int first = 1; while (bson_cursor_next(cursor)) { if (!first) fprintf(out, ", "); if (!is_array) { fprintf(out, "%s : ", bson_cursor_key(cursor)); } bson_type t = bson_cursor_type(cursor); switch (t) { case BSON_TYPE_DOUBLE: break; case BSON_TYPE_STRING: { const char *value = NULL; if (bson_cursor_get_string(cursor, &value)) { fprintf(out, "\"%s\"", value); } } break; case BSON_TYPE_DOCUMENT: { bson *doc = NULL; if (bson_cursor_get_document(cursor, &doc)) { ej_bson_unparse(out, doc, 0); bson_free(doc); } } break; case BSON_TYPE_ARRAY: { bson *doc = NULL; if (bson_cursor_get_array(cursor, &doc)) { ej_bson_unparse(out, doc, 1); bson_free(doc); } } break; case BSON_TYPE_BINARY: { bson_binary_subtype bt = 0; const unsigned char *bd = NULL; int bz = 0; if (bson_cursor_get_binary(cursor, &bt, &bd, &bz) && bt == BSON_BINARY_SUBTYPE_UUID && bz == sizeof(ej_uuid_t)) { ej_uuid_t value; memcpy(&value, bd, sizeof(value)); fprintf(out, "\"%s\"", ej_uuid_unparse(&value, NULL)); } } break; case BSON_TYPE_OID: case BSON_TYPE_BOOLEAN: break; case BSON_TYPE_UTC_DATETIME: { gint64 ts = 0; if (bson_cursor_get_utc_datetime(cursor, &ts)) { time_t tt = (time_t) (ts / 1000); int ms = (int) (ts % 1000); struct tm *ptm = gmtime(&tt); fprintf(out, "\"%d/%02d/%02d %02d:%02d:%02d.%04d\"", ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, ms); } } break; case BSON_TYPE_NULL: break; case BSON_TYPE_INT32: { int value = 0; if (bson_cursor_get_int32(cursor, &value)) { fprintf(out, "%d", value); } } break; case BSON_TYPE_INT64: { gint64 value = 0; if (bson_cursor_get_int64(cursor, &value)) { fprintf(out, "%lld", (long long) value); } } break; default: break; } first = 0; } bson_cursor_free(cursor); cursor = NULL; if (is_array) { fprintf(out, " ]"); } else { fprintf(out, " }"); } }