int monary_load_size_value(const bson_iter_t* bsonit, monary_column_item* citem, int idx) { bson_type_t type; const uint8_t* discard; uint32_t size; uint32_t* dest; type = bson_iter_type(bsonit); switch (type) { case BSON_TYPE_UTF8: case BSON_TYPE_CODE: bson_iter_utf8(bsonit, &size); break; case BSON_TYPE_BINARY: bson_iter_binary(bsonit, NULL, &size, &discard); break; case BSON_TYPE_DOCUMENT: bson_iter_document(bsonit, &size, &discard); break; case BSON_TYPE_ARRAY: bson_iter_array(bsonit, &size, &discard); break; default: return 0; } dest = ((uint32_t*) citem->storage) + idx; memcpy(dest, &size, sizeof(uint32_t)); return 1; }
int monary_load_binary_value(const bson_iter_t* bsonit, monary_column_item* citem, int idx) { bson_subtype_t subtype; const uint8_t* binary; int size; uint32_t binary_len; uint8_t* dest; if (BSON_ITER_HOLDS_BINARY(bsonit)) { // Load the binary bson_iter_binary(bsonit, &subtype, &binary_len, &binary); // Size checking size = citem->type_arg; if(binary_len > size) { binary_len = size; } dest = ((uint8_t*) citem->storage) + (idx * size); memcpy(dest, binary, binary_len); return 1; } else { return 0; } }
const char* BsonIterBinData(BSON_ITERATOR *it, uint32_t *len) { const uint8_t *binary = NULL; bson_subtype_t subtype = BSON_SUBTYPE_BINARY; bson_iter_binary (it, &subtype, len, &binary); return (char*)binary; }
types::b_binary element::get_binary() const { CITER; bson_subtype_t type; std::uint32_t len; const std::uint8_t* binary; bson_iter_binary(&iter, &type, &len, &binary); return types::b_binary{static_cast<binary_sub_type>(type), len, binary}; }
void bsonToMongoBinData(bson_iter_t* iter, Array* output) { bson_subtype_t subtype; uint32_t binary_len; const uint8_t* binary; bson_iter_binary(iter, &subtype, &binary_len, &binary); bsonToObject(iter, output, &s_MongoBinData, make_packed_array(String((const char*)binary, binary_len, CopyString), (int) subtype) ); }
SEXP ConvertBinary(bson_iter_t* iter){ bson_subtype_t subtype; uint32_t binary_len; const uint8_t *binary; bson_iter_binary(iter, &subtype, &binary_len, &binary); //create raw vector SEXP out = PROTECT(allocVector(RAWSXP, binary_len)); for (int i = 0; i < binary_len; i++) { RAW(out)[i] = binary[i]; } setAttrib(out, install("subtype"), ScalarInteger(subtype)); UNPROTECT(1); return out; }
static void test_bson_iter_binary_deprecated (void) { bson_subtype_t subtype; uint32_t binary_len; const uint8_t * binary; bson_iter_t iter; bson_t * b; b = get_bson(BINARY_DIR"/binary_deprecated.bson"); assert(b); assert(bson_iter_init(&iter, b)); assert(bson_iter_next(&iter)); bson_iter_binary(&iter, &subtype, &binary_len, &binary); assert(binary_len == 4); assert(memcmp(binary, "1234", 4) == 0); bson_destroy(b); }
int monary_load_length_value(const bson_iter_t* bsonit, monary_column_item* citem, int idx) { bson_type_t type; bson_iter_t child; const char* discard; uint32_t length; uint32_t* dest; type = bson_iter_type(bsonit); switch (type) { case BSON_TYPE_UTF8: case BSON_TYPE_CODE: discard = bson_iter_utf8(bsonit, &length); for (length = 0; *discard; length++) { discard = bson_utf8_next_char(discard); } break; case BSON_TYPE_ARRAY: case BSON_TYPE_DOCUMENT: if (!bson_iter_recurse(bsonit, &child)) { return 0; } for (length = 0; bson_iter_next(&child); length++); break; case BSON_TYPE_BINARY: bson_iter_binary(bsonit, NULL, &length, (const uint8_t**) &discard); break; default: return 0; } dest = ((uint32_t*) citem->storage) + idx; memcpy(dest, &length, sizeof(uint32_t)); return 1; }
static gboolean sim_parser_connect_sensor_id (bson_iter_t *piter, const char *key, SimCommand *cmd) { g_return_val_if_fail (piter != NULL, FALSE); g_return_val_if_fail (cmd != NULL, FALSE); g_return_val_if_fail (key != NULL, FALSE); gboolean result = FALSE; bson_subtype_t subtype; uint32_t uuidlen; const uint8_t *uuidbin; if (BSON_ITER_HOLDS_BINARY (piter)) { bson_iter_binary (piter, &subtype, &uuidlen, &uuidbin); if (subtype == BSON_SUBTYPE_UUID) { cmd->data.connect.sensor_id = sim_uuid_new_from_bin (uuidbin); result = TRUE; } } if (!result) g_message ("Bad BSON connec message (sensor_id)"); return result; }
/** refresh a gridfs file's underlying page * * This unconditionally fetches the current page, even if the current page * covers the same theoretical chunk. */ static bool _mongoc_gridfs_file_refresh_page (mongoc_gridfs_file_t *file) { bson_t *query, *fields, child, child2; const bson_t *chunk; const char *key; bson_iter_t iter; uint32_t n; const uint8_t *data; uint32_t len; ENTRY; BSON_ASSERT (file); n = (uint32_t)(file->pos / file->chunk_size); if (file->page) { _mongoc_gridfs_file_page_destroy (file->page); file->page = NULL; } /* if the file pointer is past the end of the current file (I.e. pointing to * a new chunk) and we're on a chunk boundary, we'll pass the page * constructor a new empty page */ if ((int64_t)file->pos >= file->length && !(file->pos % file->chunk_size)) { data = (uint8_t *)""; len = 0; } else { /* if we have a cursor, but the cursor doesn't have the chunk we're going * to need, destroy it (we'll grab a new one immediately there after) */ if (file->cursor && !(file->cursor_range[0] >= n && file->cursor_range[1] <= n)) { mongoc_cursor_destroy (file->cursor); file->cursor = NULL; } if (!file->cursor) { query = bson_new (); bson_append_document_begin(query, "$query", -1, &child); bson_append_value (&child, "files_id", -1, &file->files_id); bson_append_document_begin (&child, "n", -1, &child2); bson_append_int32 (&child2, "$gte", -1, (int32_t)(file->pos / file->chunk_size)); bson_append_document_end (&child, &child2); bson_append_document_end(query, &child); bson_append_document_begin(query, "$orderby", -1, &child); bson_append_int32 (&child, "n", -1, 1); bson_append_document_end(query, &child); fields = bson_new (); bson_append_int32 (fields, "n", -1, 1); bson_append_int32 (fields, "data", -1, 1); bson_append_int32 (fields, "_id", -1, 0); /* find all chunks greater than or equal to our current file pos */ file->cursor = mongoc_collection_find (file->gridfs->chunks, MONGOC_QUERY_NONE, 0, 0, 0, query, fields, NULL); file->cursor_range[0] = n; file->cursor_range[1] = (uint32_t)(file->length / file->chunk_size); bson_destroy (query); bson_destroy (fields); BSON_ASSERT (file->cursor); } /* we might have had a cursor before, then seeked ahead past a chunk. * iterate until we're on the right chunk */ while (file->cursor_range[0] <= n) { if (!mongoc_cursor_next (file->cursor, &chunk)) { if (file->cursor->failed) { memcpy (&(file->error), &(file->cursor->error), sizeof (bson_error_t)); file->failed = true; } RETURN (0); } file->cursor_range[0]++; } bson_iter_init (&iter, chunk); /* grab out what we need from the chunk */ while (bson_iter_next (&iter)) { key = bson_iter_key (&iter); if (strcmp (key, "n") == 0) { n = bson_iter_int32 (&iter); } else if (strcmp (key, "data") == 0) { bson_iter_binary (&iter, NULL, &len, &data); } else { RETURN (0); } } /* we're on the wrong chunk somehow... probably because our gridfs is * missing chunks. * * TODO: maybe we should make more noise here? */ if (!(n == file->pos / file->chunk_size)) { return 0; } } file->page = _mongoc_gridfs_file_page_new (data, len, file->chunk_size); /* seek in the page towards wherever we're supposed to be */ RETURN (_mongoc_gridfs_file_page_seek (file->page, file->pos % file->chunk_size)); }
/*! * \brief Convert rows from mongodb to db API representation * \param _h database connection * \param _r database result set * \return 0 on success, negative on failure */ static int db_mongodb_convert_bson(const db1_con_t* _h, db1_res_t* _r, int _row, const bson_t *_rdoc) { static str dummy_string = {"", 0}; int col; db_mongodb_result_t *mgres; const char *colname; bson_type_t coltype; bson_iter_t riter; bson_iter_t citer; bson_iter_t *piter; db_val_t* dval; uint32_t i32tmp; bson_subtype_t subtype; bson_t *cdoc; mgres = (db_mongodb_result_t*)RES_PTR(_r); if(mgres->nrcols==0) { LM_ERR("no fields to convert\n"); return -1; } if(mgres->colsdoc==NULL) { cdoc = (bson_t*)_rdoc; } else { cdoc = (bson_t*)mgres->colsdoc; } if (!bson_iter_init (&citer, cdoc)) { LM_ERR("failed to initialize columns iterator\n"); return -3; } if(mgres->colsdoc) { if (!bson_iter_init (&riter, _rdoc)) { LM_ERR("failed to initialize result iterator\n"); return -3; } } if (db_allocate_row(_r, &(RES_ROWS(_r)[_row])) != 0) { LM_ERR("could not allocate row: %d\n", _row); return -2; } col = 0; while (bson_iter_next (&citer)) { if(col >= RES_COL_N(_r)) { LM_ERR("invalid number of columns (%d/%d)\n", col, RES_COL_N(_r)); return -4; } colname = bson_iter_key (&citer); LM_DBG("looking for field[%d] named: %s\n", col, colname); if(mgres->colsdoc) { if(!bson_iter_find(&riter, colname)) { LM_ERR("field [%s] not found in result iterator\n", colname); return -4; } piter = &riter; } else { piter = &citer; } coltype = bson_iter_type(piter); dval = &(ROW_VALUES(&(RES_ROWS(_r)[_row]))[col]); VAL_TYPE(dval) = RES_TYPES(_r)[col]; switch(coltype) { case BSON_TYPE_BOOL: VAL_INT(dval) = (int)bson_iter_bool (piter); break; case BSON_TYPE_INT32: VAL_INT(dval) = bson_iter_int32 (piter); break; case BSON_TYPE_TIMESTAMP: bson_iter_timestamp (piter, (uint32_t*)&VAL_INT(dval), &i32tmp); break; case BSON_TYPE_INT64: VAL_BIGINT(dval) = bson_iter_int64 (piter); break; case BSON_TYPE_DOUBLE: VAL_DOUBLE(dval) = bson_iter_double (piter); break; case BSON_TYPE_DATE_TIME: VAL_TIME(dval) = (time_t)(bson_iter_date_time (piter)/1000); break; case BSON_TYPE_BINARY: bson_iter_binary (piter, &subtype, (uint32_t*)&VAL_BLOB(dval).len, (const uint8_t**)&VAL_BLOB(dval).s); break; case BSON_TYPE_UTF8: VAL_STRING(dval) = (char*)bson_iter_utf8 (piter, &i32tmp); break; case BSON_TYPE_OID: break; case BSON_TYPE_NULL: memset(dval, 0, sizeof(db_val_t)); /* Initialize the string pointers to a dummy empty * string so that we do not crash when the NULL flag * is set but the module does not check it properly */ VAL_STRING(dval) = dummy_string.s; VAL_STR(dval) = dummy_string; VAL_BLOB(dval) = dummy_string; VAL_TYPE(dval) = RES_TYPES(_r)[col]; VAL_NULL(dval) = 1; break; #if 0 case BSON_TYPE_EOD: case BSON_TYPE_DOCUMENT: case BSON_TYPE_ARRAY: case BSON_TYPE_UNDEFINED: case BSON_TYPE_REGEX: case BSON_TYPE_DBPOINTER: case BSON_TYPE_CODE: case BSON_TYPE_SYMBOL: case BSON_TYPE_CODEWSCOPE: case BSON_TYPE_MAXKEY: case BSON_TYPE_MINKEY: #endif default: LM_WARN("unhandled data type column (%.*s) type id (%d), " "use DB1_STRING as default\n", RES_NAMES(_r)[col]->len, RES_NAMES(_r)[col]->s, coltype); RES_TYPES(_r)[col] = DB1_STRING; break; } LM_DBG("RES_NAMES(%p)[%d]=[%.*s] (%d)\n", RES_NAMES(_r)[col], col, RES_NAMES(_r)[col]->len, RES_NAMES(_r)[col]->s, coltype); col++; } return 0; }
struct transaction* transaction_from_bson(bson_t const* doc) { char key[9]; bson_iter_t iter; bson_iter_t subiter; struct transaction* tx = transaction_new(); if(!bson_iter_init_find(&iter, doc, "version") || !BSON_ITER_HOLDS_INT32(&iter)) goto error; transaction_set_version(tx, bson_iter_int32(&iter)); // Read Inputs if(!bson_iter_init_find(&iter, doc, "inputs") || !BSON_ITER_HOLDS_ARRAY(&iter)) goto error; uint32_t inputs_doc_length; uint8_t const* inputs_doc_data; bson_iter_array(&iter, &inputs_doc_length, &inputs_doc_data); bson_t inputs_doc; bson_init_static(&inputs_doc, inputs_doc_data, inputs_doc_length); size_t index = 0; for(;;) { bson_snprintf(key, sizeof(key), "%u", (unsigned int)index); key[sizeof(key) - 1] = '\0'; // If the array key isn't found, then we reached the end of the array if(!bson_iter_init_find(&subiter, &inputs_doc, key)) break; // If it's not a document, then there's an error if(!BSON_ITER_HOLDS_DOCUMENT(&subiter)) goto error; struct transaction_input* input = transaction_input_new(); struct transaction_output_reference* output_reference = transaction_input_output_reference(input); // Load the input document bson_t element_doc; uint32_t element_doc_length; uint8_t const* element_doc_data; bson_iter_document(&subiter, &element_doc_length, &element_doc_data); bson_init_static(&element_doc, element_doc_data, element_doc_length); bson_iter_t elementiter; // Output reference if(!bson_iter_init_find(&elementiter, &element_doc, "output_reference") || !BSON_ITER_HOLDS_DOCUMENT(&elementiter)) goto error; bson_t output_reference_doc; uint32_t output_reference_doc_length; uint8_t const* output_reference_doc_data; bson_iter_document(&elementiter, &output_reference_doc_length, &output_reference_doc_data); bson_init_static(&output_reference_doc, output_reference_doc_data, output_reference_doc_length); bson_iter_t output_reference_iter; uint8_t const* hash; uint32_t hash_size; if(!bson_iter_init_find(&output_reference_iter, &output_reference_doc, "hash") || !BSON_ITER_HOLDS_BINARY(&output_reference_iter)) goto error; bson_iter_binary(&output_reference_iter, BSON_SUBTYPE_BINARY, &hash_size, &hash); assert(hash_size == 32); transaction_output_reference_set_hash(output_reference, (unsigned char const*)hash); if(!bson_iter_init_find(&output_reference_iter, &output_reference_doc, "index") || !BSON_ITER_HOLDS_INT32(&output_reference_iter)) goto error; transaction_output_reference_set_index(output_reference, bson_iter_int32(&output_reference_iter)); // Script if(!bson_iter_init_find(&elementiter, &element_doc, "script") || !BSON_ITER_HOLDS_BINARY(&elementiter)) goto error; uint32_t script_size; uint8_t const* script_data; bson_iter_binary(&elementiter, BSON_SUBTYPE_BINARY, &script_size, &script_data); struct script* script; size_t script_size_result; script_size_result = unserialize_script((unsigned char const*)script_data, script_size, &script, script_size); assert(script_size_result == script_size); transaction_input_set_script(input, script); // Sequence if(!bson_iter_init_find(&elementiter, &element_doc, "sequence") || !BSON_ITER_HOLDS_INT32(&elementiter)) goto error; transaction_input_set_sequence(input, bson_iter_int32(&elementiter)); transaction_add_input(tx, input); index += 1; } // Read Outputs if(!bson_iter_init_find(&iter, doc, "outputs") || !BSON_ITER_HOLDS_ARRAY(&iter)) goto error; uint32_t outputs_doc_length; uint8_t const* outputs_doc_data; bson_iter_array(&iter, &outputs_doc_length, &outputs_doc_data); bson_t outputs_doc; bson_init_static(&outputs_doc, outputs_doc_data, outputs_doc_length); index = 0; for(;;) { bson_snprintf(key, sizeof(key), "%u", (unsigned int)index); key[sizeof(key) - 1] = '\0'; // If the array key isn't found, then we reached the end of the array if(!bson_iter_init_find(&subiter, &outputs_doc, key)) break; // If it's not a document, then there's an error if(!BSON_ITER_HOLDS_DOCUMENT(&subiter)) goto error; struct transaction_output* output = transaction_output_new(); // Load the output document bson_t element_doc; uint32_t element_doc_length; uint8_t const* element_doc_data; bson_iter_document(&subiter, &element_doc_length, &element_doc_data); bson_init_static(&element_doc, element_doc_data, element_doc_length); bson_iter_t elementiter; // Value if(!bson_iter_init_find(&elementiter, &element_doc, "value") || !BSON_ITER_HOLDS_INT64(&elementiter)) goto error; transaction_output_set_value(output, bson_iter_int64(&elementiter)); // Script if(!bson_iter_init_find(&elementiter, &element_doc, "script") || !BSON_ITER_HOLDS_BINARY(&elementiter)) goto error; uint32_t script_size; uint8_t const* script_data; bson_iter_binary(&elementiter, BSON_SUBTYPE_BINARY, &script_size, &script_data); struct script* script; size_t script_size_result; script_size_result = unserialize_script((unsigned char const*)script_data, script_size, &script, script_size); assert(script_size_result == script_size); transaction_output_set_script(output, script); transaction_add_output(tx, output); index += 1; } if(!bson_iter_init_find(&iter, doc, "lock_time") || !BSON_ITER_HOLDS_INT32(&iter)) goto error; transaction_set_lock_time(tx, bson_iter_int32(&iter)); return tx; error: return NULL; }
/** * _mongoc_gridfs_file_refresh_page: * * Refresh a GridFS file's underlying page. This recalculates the current * page number based on the file's stream position, then fetches that page * from the database. * * Note that this fetch is unconditional and the page is queried from the * database even if the current page covers the same theoretical chunk. * * * Side Effects: * * file->page is loaded with the appropriate buffer, fetched from the * database. If the file position is at the end of the file and on a new * chunk boundary, a new page is created. If the position is far past the * end of the file, _mongoc_gridfs_file_extend is responsible for creating * chunks to file the gap. * * file->n is set based on file->pos. file->error is set on error. */ static bool _mongoc_gridfs_file_refresh_page (mongoc_gridfs_file_t *file) { bson_t query; bson_t child; bson_t opts; const bson_t *chunk; const char *key; bson_iter_t iter; int64_t existing_chunks; int64_t required_chunks; const uint8_t *data = NULL; uint32_t len; ENTRY; BSON_ASSERT (file); file->n = (int32_t) (file->pos / file->chunk_size); if (file->page) { _mongoc_gridfs_file_page_destroy (file->page); file->page = NULL; } /* if the file pointer is past the end of the current file (i.e. pointing to * a new chunk), we'll pass the page constructor a new empty page. */ existing_chunks = divide_round_up (file->length, file->chunk_size); required_chunks = divide_round_up (file->pos + 1, file->chunk_size); if (required_chunks > existing_chunks) { data = (uint8_t *) ""; len = 0; } else { /* if we have a cursor, but the cursor doesn't have the chunk we're going * to need, destroy it (we'll grab a new one immediately there after) */ if (file->cursor && !_mongoc_gridfs_file_keep_cursor (file)) { mongoc_cursor_destroy (file->cursor); file->cursor = NULL; } if (!file->cursor) { bson_init (&query); BSON_APPEND_VALUE (&query, "files_id", &file->files_id); BSON_APPEND_DOCUMENT_BEGIN (&query, "n", &child); BSON_APPEND_INT32 (&child, "$gte", file->n); bson_append_document_end (&query, &child); bson_init (&opts); BSON_APPEND_DOCUMENT_BEGIN (&opts, "sort", &child); BSON_APPEND_INT32 (&child, "n", 1); bson_append_document_end (&opts, &child); BSON_APPEND_DOCUMENT_BEGIN (&opts, "projection", &child); BSON_APPEND_INT32 (&child, "n", 1); BSON_APPEND_INT32 (&child, "data", 1); BSON_APPEND_INT32 (&child, "_id", 0); bson_append_document_end (&opts, &child); /* find all chunks greater than or equal to our current file pos */ file->cursor = mongoc_collection_find_with_opts ( file->gridfs->chunks, &query, &opts, NULL); file->cursor_range[0] = file->n; file->cursor_range[1] = (uint32_t) (file->length / file->chunk_size); bson_destroy (&query); bson_destroy (&opts); BSON_ASSERT (file->cursor); } /* we might have had a cursor before, then seeked ahead past a chunk. * iterate until we're on the right chunk */ while (file->cursor_range[0] <= file->n) { if (!mongoc_cursor_next (file->cursor, &chunk)) { /* copy cursor error; if there's none, we're missing a chunk */ if (!mongoc_cursor_error (file->cursor, &file->error)) { missing_chunk (file); } RETURN (0); } file->cursor_range[0]++; } BSON_ASSERT (bson_iter_init (&iter, chunk)); /* grab out what we need from the chunk */ while (bson_iter_next (&iter)) { key = bson_iter_key (&iter); if (strcmp (key, "n") == 0) { if (file->n != bson_iter_int32 (&iter)) { missing_chunk (file); RETURN (0); } } else if (strcmp (key, "data") == 0) { bson_iter_binary (&iter, NULL, &len, &data); } else { /* Unexpected key. This should never happen */ RETURN (0); } } if (file->n != file->pos / file->chunk_size) { return 0; } } if (!data) { bson_set_error (&file->error, MONGOC_ERROR_GRIDFS, MONGOC_ERROR_GRIDFS_CHUNK_MISSING, "corrupt chunk number %" PRId32, file->n); RETURN (0); } file->page = _mongoc_gridfs_file_page_new (data, len, file->chunk_size); /* seek in the page towards wherever we're supposed to be */ RETURN ( _mongoc_gridfs_file_page_seek (file->page, file->pos % file->chunk_size)); }
QVariantMap TBson::fromBson(const TBsonObject *obj) { QVariantMap ret; bson_iter_t it; const bson_t *bson = (const bson_t *)obj; bson_iter_init(&it, bson); while (bson_iter_next(&it)) { bson_type_t t = bson_iter_type(&it); QString key(bson_iter_key(&it)); switch (t) { case BSON_TYPE_EOD: return ret; break; case BSON_TYPE_DOUBLE: ret[key] = bson_iter_double(&it); break; case BSON_TYPE_UTF8: ret[key] = QString::fromUtf8(bson_iter_utf8(&it, nullptr)); break; case BSON_TYPE_ARRAY: { const uint8_t *docbuf = nullptr; uint32_t doclen = 0; bson_t sub[1]; bson_iter_array(&it, &doclen, &docbuf); if (bson_init_static(sub, docbuf, doclen)) { ret[key] = fromBson(sub).values(); } break; } case BSON_TYPE_DOCUMENT: { const uint8_t *docbuf = nullptr; uint32_t doclen = 0; bson_t sub[1]; bson_iter_document(&it, &doclen, &docbuf); if (bson_init_static(sub, docbuf, doclen)) { ret[key] = fromBson(sub); } break; } case BSON_TYPE_BINARY: { const uint8_t *binary = nullptr; bson_subtype_t subtype = BSON_SUBTYPE_BINARY; uint32_t len = 0; bson_iter_binary(&it, &subtype, &len, &binary); if (binary) { ret[key] = QByteArray((char *)binary, len); } break; } case BSON_TYPE_UNDEFINED: ret[key] = QVariant(); break; case BSON_TYPE_OID: { char oidhex[25]; bson_oid_to_string(bson_iter_oid(&it), oidhex); ret[key] = QString(oidhex); break; } case BSON_TYPE_BOOL: ret[key] = (bool)bson_iter_bool(&it); break; case BSON_TYPE_DATE_TIME: { #if QT_VERSION >= 0x040700 QDateTime date; date.setMSecsSinceEpoch(bson_iter_date_time(&it)); #else qint64 val = bson_iter_date_time(&it); qint64 days = val / 86400000; // 24*60*60*1000 int msecs = val % 86400000; QDate dt = QDate(1970, 1, 1).addDays(days); QTime tm = QTime(0, 0, 0).addMSecs(msecs); QDateTime date(dt, tm, Qt::UTC); #endif ret[key] = date; break; } case BSON_TYPE_NULL: ret[key] = QVariant(); break; case BSON_TYPE_REGEX: ret[key] = QRegExp(QLatin1String(bson_iter_regex(&it, nullptr))); break; case BSON_TYPE_CODE: ret[key] = QString(bson_iter_code(&it, nullptr)); break; case BSON_TYPE_SYMBOL: ret[key] = QString(bson_iter_symbol(&it, nullptr)); break; case BSON_TYPE_INT32: ret[key] = bson_iter_int32(&it); break; case BSON_TYPE_INT64: ret[key] = (qint64)bson_iter_int64(&it); break; case BSON_TYPE_CODEWSCOPE: // FALL THROUGH case BSON_TYPE_TIMESTAMP: // FALL THROUGH (internal use) // do nothing break; default: tError("fromBson() unknown type: %d", t); break; } //tSystemDebug("fromBson : t:%d key:%s = %s", t, qPrintable(key), qPrintable(ret[key].toString())); } return ret; }