Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
    }
}
Esempio n. 3
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;
}
Esempio n. 4
0
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};
}
Esempio n. 5
0
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)
  );
}
Esempio n. 6
0
File: bson.c Progetto: CDC/mongolite
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;

}
Esempio n. 7
0
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);
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
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));
}
Esempio n. 11
0
/*!
 * \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;
}
Esempio n. 12
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;
}
Esempio n. 13
0
/**
 * _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));
}
Esempio n. 14
0
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;
}