/*
 *-------------------------------------------------------------------------
 *
 * mongoc_server_description_new_copy --
 *
 *       A copy of a server description that you must destroy, or NULL.
 *
 *-------------------------------------------------------------------------
 */
mongoc_server_description_t *
mongoc_server_description_new_copy (const mongoc_server_description_t *description)
{
   mongoc_server_description_t *copy;

   if (!description) {
      return NULL;
   }

   copy = (mongoc_server_description_t *)bson_malloc0(sizeof (*copy));

   copy->id = description->id;
   memcpy (&copy->host, &description->host, sizeof (copy->host));
   copy->round_trip_time = -1;

   copy->connection_address = copy->host.host_and_port;

   /* wait for handle_ismaster to fill these in properly */
   copy->has_is_master = false;
   bson_init_static (&copy->hosts, kMongocEmptyBson, sizeof (kMongocEmptyBson));
   bson_init_static (&copy->passives, kMongocEmptyBson, sizeof (kMongocEmptyBson));
   bson_init_static (&copy->arbiters, kMongocEmptyBson, sizeof (kMongocEmptyBson));
   bson_init_static (&copy->tags, kMongocEmptyBson, sizeof (kMongocEmptyBson));

   bson_init (&copy->last_is_master);

   if (description->has_is_master) {
      mongoc_server_description_handle_ismaster (copy, &description->last_is_master,
                                                 description->round_trip_time, NULL);
   }
   /* Preserve the error */
   memcpy (&copy->error, &description->error, sizeof copy->error);
   return copy;
}
/**
 * _mongoc_gridfs_file_new_from_bson:
 *
 * creates a gridfs file from a bson object
 *
 * This is only really useful for instantiating a gridfs file from a server
 * side object
 */
mongoc_gridfs_file_t *
_mongoc_gridfs_file_new_from_bson (mongoc_gridfs_t *gridfs,
                                   const bson_t    *data)
{
   mongoc_gridfs_file_t *file;
   const char *key;
   bson_iter_t iter;
   const uint8_t *buf;
   uint32_t buf_len;

   ENTRY;

   BSON_ASSERT (gridfs);
   BSON_ASSERT (data);

   file = bson_malloc0 (sizeof *file);

   file->gridfs = gridfs;
   bson_copy_to (data, &file->bson);

   bson_iter_init (&iter, &file->bson);

   while (bson_iter_next (&iter)) {
      key = bson_iter_key (&iter);

      if (0 == strcmp (key, "_id")) {
         bson_oid_copy (bson_iter_oid (&iter), &file->files_id);
      } else if (0 == strcmp (key, "length")) {
         file->length = bson_iter_int64 (&iter);
      } else if (0 == strcmp (key, "chunkSize")) {
         file->chunk_size = bson_iter_int32 (&iter);
      } else if (0 == strcmp (key, "uploadDate")) {
         file->upload_date = bson_iter_date_time (&iter);
      } else if (0 == strcmp (key, "md5")) {
         file->bson_md5 = bson_iter_utf8 (&iter, NULL);
      } else if (0 == strcmp (key, "filename")) {
         file->bson_filename = bson_iter_utf8 (&iter, NULL);
      } else if (0 == strcmp (key, "contentType")) {
         file->bson_content_type = bson_iter_utf8 (&iter, NULL);
      } else if (0 == strcmp (key, "aliases")) {
         bson_iter_array (&iter, &buf_len, &buf);
         bson_init_static (&file->bson_aliases, buf, buf_len);
      } else if (0 == strcmp (key, "metadata")) {
         bson_iter_document (&iter, &buf_len, &buf);
         bson_init_static (&file->bson_metadata, buf, buf_len);
      }
   }

   /* TODO: is there are a minimal object we should be verifying that we
    * actually have here? */

   RETURN (file);
}
bool
_mongoc_convert_document (mongoc_client_t *client,
                          const bson_iter_t *iter,
                          bson_t *doc,
                          bson_error_t *error)
{
   uint32_t len;
   const uint8_t *data;
   bson_t value;

   if (!BSON_ITER_HOLDS_DOCUMENT (iter)) {
      CONVERSION_ERR ("Invalid field \"%s\" in opts, should contain document,"
                      " not %s",
                      bson_iter_key (iter),
                      _mongoc_bson_type_to_str (bson_iter_type (iter)));
   }

   bson_iter_document (iter, &len, &data);
   if (!bson_init_static (&value, data, len)) {
      BSON_ERR ("Corrupt BSON in field \"%s\" in opts", bson_iter_key (iter));
   }

   bson_destroy (doc);
   bson_copy_to (&value, doc);

   return true;
}
Beispiel #4
0
view::const_iterator view::find(stdx::string_view key) const {
    bson_t b;
    if (!bson_init_static(&b, _data, _length)) {
        return cend();
    }

    bson_iter_t iter;

    // Logically, a default constructed string_view represents the
    // empty string just as does string_view(""), but they have,
    // potentially, different represntations, the former having .data
    // returning nullptr though the latter probably does not. But the
    // C functions like strncmp below can't be called with nullptr. If
    // we were called with a string_data such that its .data() member
    // returns nullptr, then, barring undefined behavior, its length
    // is known to be zero, and it is equivalent to the empty string,
    // an instance of which we reset it to.
    if (key.data() == nullptr) {
        key = "";
    }

    if (!bson_iter_init_find_w_len(&iter, &b, key.data(), static_cast<int>(key.size()))) {
        return cend();
    }

    return const_iterator(element(
        _data, static_cast<uint32_t>(_length), bson_iter_offset(&iter), bson_iter_key_len(&iter)));
}
Beispiel #5
0
void core::append(const types::b_array& value) {
    stdx::string_view key = _impl->next_key();
    bson_t bson;
    bson_init_static(&bson, value.value.data(), value.value.length());

    bson_append_array(_impl->back(), key.data(), key.length(), &bson);
}
Beispiel #6
0
static void
test_bson_as_json_stack_overflow (void)
{
   uint8_t *buf;
   bson_t b;
   size_t buflen = 1024 * 1024 * 17;
   char *str;
   int fd;
   ssize_t r;

   buf = bson_malloc0(buflen);

   fd = bson_open(BINARY_DIR"/stackoverflow.bson", O_RDONLY);
   BSON_ASSERT(-1 != fd);

   r = bson_read(fd, buf, buflen);
   BSON_ASSERT(r == 16777220);

   r = bson_init_static(&b, buf, 16777220);
   BSON_ASSERT(r);

   str = bson_as_json(&b, NULL);
   BSON_ASSERT(str);

   r = !!strstr(str, "...");
   BSON_ASSERT(str);

   bson_free(str);
   bson_destroy(&b);
   bson_free(buf);
}
Beispiel #7
0
/* {{{ proto WriteError[] WriteResult::getWriteErrors()
   Returns any write errors that occurred */
PHP_METHOD(WriteResult, getWriteErrors)
{
	bson_iter_t iter, child;
	php_phongo_writeresult_t *intern;
	SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used)


	intern = Z_WRITERESULT_OBJ_P(getThis());

	if (zend_parse_parameters_none() == FAILURE) {
		return;
	}


	array_init(return_value);

	if (bson_iter_init_find(&iter, intern->reply, "writeErrors") && BSON_ITER_HOLDS_ARRAY(&iter) && bson_iter_recurse(&iter, &child)) {
		while (bson_iter_next(&child)) {
			bson_t cbson;
			uint32_t len;
			const uint8_t *data;
#if PHP_VERSION_ID >= 70000
			zval writeerror;
#else
			zval *writeerror = NULL;
#endif

			if (!BSON_ITER_HOLDS_DOCUMENT(&child)) {
				continue;
			}

			bson_iter_document(&child, &len, &data);

			if (!bson_init_static(&cbson, data, len)) {
				continue;
			}

#if PHP_VERSION_ID >= 70000
			object_init_ex(&writeerror, php_phongo_writeerror_ce);

			if (!phongo_writeerror_init(&writeerror, &cbson TSRMLS_CC)) {
				zval_ptr_dtor(&writeerror);
				continue;
			}

			add_next_index_zval(return_value, &writeerror);
#else
			MAKE_STD_ZVAL(writeerror);
			object_init_ex(writeerror, php_phongo_writeerror_ce);

			if (!phongo_writeerror_init(writeerror, &cbson TSRMLS_CC)) {
				zval_ptr_dtor(&writeerror);
				continue;
			}

			add_next_index_zval(return_value, writeerror);
#endif
		}
	}
}
Beispiel #8
0
view::const_iterator view::find(stdx::string_view key) const {
    bson_t b;
    bson_iter_t iter;

    if (!bson_init_static(&b, _data, _length)) {
        return cend();
    }

    if (!bson_iter_init(&iter, &b)) {
        return cend();
    }

    if (key.empty()) {
        return cend();
    }

    while (bson_iter_next(&iter)) {
        const char* ikey = bson_iter_key(&iter);
        if (0 == strncmp(key.data(), ikey, key.size())) {
            return const_iterator(element(iter.raw, iter.len, iter.off));
        }
    }

    return cend();
}
Beispiel #9
0
static void
test_bson_corrupt_binary (void)
{
   uint8_t *buf;
   bson_t b;
   size_t buflen = 1024;
   char *str;
   int fd;
   ssize_t r;

   buf = bson_malloc0(buflen);

   fd = bson_open(BINARY_DIR"/test57.bson", O_RDONLY);
   BSON_ASSERT(-1 != fd);

   r = bson_read(fd, buf, buflen);
   BSON_ASSERT(r == 26);

   r = bson_init_static(&b, buf, (uint32_t)r);
   BSON_ASSERT(r);

   str = bson_as_json(&b, NULL);
   BSON_ASSERT(!str);

   bson_destroy(&b);
   bson_free(buf);
}
Beispiel #10
0
/**
 * Performs a count query on a MongoDB collection.
 *
 * @param collection The MongoDB collection to query against.
 * @param query A pointer to a BSON buffer representing the query.
 *
 * @return If unsuccessful, returns -1; otherwise, returns the number of
 * documents counted.
 */
int64_t monary_query_count(mongoc_collection_t* collection,
                           const uint8_t* query)
{
    bson_error_t error;     // A location for BSON errors
    bson_t query_bson;      // The query converted to BSON format
    int64_t total_count;    // The number of documents counted
    uint32_t query_size;    // Length of the query in bytes

    DEBUG("%s", "Starting Monary count");

    // build BSON query data
    memcpy(&query_size, query, sizeof(uint32_t));
    if (!bson_init_static(&query_bson,
                          query,
                          query_size)) {
        DEBUG("%s", "Failed to initialize raw BSON query");
        return -1;
    }
    
    // Make the count query
    total_count = mongoc_collection_count(collection,
                                          MONGOC_QUERY_NONE,
                                          &query_bson,
                                          0,
                                          0,
                                          NULL,
                                          &error);
    bson_destroy(&query_bson);
    if (total_count < 0) {
        DEBUG("error: %d.%d %s", error.domain, error.code, error.message);
    }

    return total_count;
}
static bool
_mongoc_cursor_array_next (mongoc_cursor_t *cursor,
                           const bson_t   **bson)
{
   bool ret = true;
   mongoc_cursor_array_t *arr;

   ENTRY;

   arr = (mongoc_cursor_array_t *)cursor->iface_data;
   *bson = NULL;

   if (!arr->has_array) {
      ret = _mongoc_cursor_array_prime(cursor);
   }

   if (ret) {
      ret = bson_iter_next (&arr->iter);
   }

   if (ret) {
      bson_iter_document (&arr->iter, &arr->document_len, &arr->document);
      bson_init_static (&arr->bson, arr->document, arr->document_len);

      *bson = &arr->bson;
   }

   RETURN (ret);
}
Beispiel #12
0
void core::append(const types::b_codewscope& value) {
    stdx::string_view key = _impl->next_key();

    bson_t bson;
    bson_init_static(&bson, value.scope.data(), value.scope.length());

    bson_append_code_with_scope(_impl->back(), key.data(), key.length(),
                                value.code.to_string().data(), &bson);
}
Beispiel #13
0
static void
test_bson_init_static (void)
{
   static const bson_uint8_t data[5] = { 5 };
   bson_t b;

   bson_init_static(&b, data, sizeof data);
   assert((b.flags & BSON_FLAG_RDONLY));
   bson_destroy(&b);
}
Beispiel #14
0
view::iterator view::begin() const {
    bson_t b;
    bson_iter_t iter;

    bson_init_static(&b, _data, _length);
    bson_iter_init(&iter, &b);
    bson_iter_next(&iter);

    return iterator(element{iter.raw, iter.len, iter.off});
}
Beispiel #15
0
bool
BsonIterSubObject(BSON_ITERATOR *it, BSON *b)
{
	const uint8_t *buffer;
	uint32_t len;

	bson_iter_document(it, &len, &buffer);
	bson_init_static(b, buffer, len);
	return true;
}
/*
 *--------------------------------------------------------------------------
 *
 * mongoc_server_description_init --
 *
 *       Initialize a new server_description_t.
 *
 * Returns:
 *       None.
 *
 * Side effects:
 *       None.
 *
 *--------------------------------------------------------------------------
 */
void
mongoc_server_description_init (mongoc_server_description_t *sd,
                                const char                  *address,
                                uint32_t                     id)
{
   ENTRY;

   BSON_ASSERT (sd);
   BSON_ASSERT (address);

   memset (sd, 0, sizeof *sd);

   sd->id = id;
   sd->type = MONGOC_SERVER_UNKNOWN;
   sd->round_trip_time = -1;

   sd->set_name = NULL;
   sd->current_primary = NULL;

   if (!_mongoc_host_list_from_string(&sd->host, address)) {
      MONGOC_WARNING("Failed to parse uri for %s", address);
      return;
   }

   sd->connection_address = sd->host.host_and_port;

   sd->min_wire_version = MONGOC_DEFAULT_WIRE_VERSION;
   sd->max_wire_version = MONGOC_DEFAULT_WIRE_VERSION;
   sd->max_msg_size = MONGOC_DEFAULT_MAX_MSG_SIZE;
   sd->max_bson_obj_size = MONGOC_DEFAULT_BSON_OBJ_SIZE;
   sd->max_write_batch_size = MONGOC_DEFAULT_WRITE_BATCH_SIZE;

   bson_init_static (&sd->hosts, kMongocEmptyBson, sizeof (kMongocEmptyBson));
   bson_init_static (&sd->passives, kMongocEmptyBson, sizeof (kMongocEmptyBson));
   bson_init_static (&sd->arbiters, kMongocEmptyBson, sizeof (kMongocEmptyBson));
   bson_init_static (&sd->tags, kMongocEmptyBson, sizeof (kMongocEmptyBson));

   bson_init (&sd->last_is_master);

   EXIT;
}
Beispiel #17
0
view::const_iterator view::cbegin() const {
    bson_t b;
    bson_iter_t iter;

    bson_init_static(&b, _data, _length);
    bson_iter_init(&iter, &b);

    if (!bson_iter_next(&iter)) {
        return const_iterator{};
    }

    return const_iterator(element{iter.raw, iter.len, iter.off});
}
Beispiel #18
0
static const bson_t *
_bson_reader_handle_read (bson_reader_handle_t *reader,      /* IN */
                          bool                 *reached_eof) /* IN */
{
   int32_t blen;

   bson_return_val_if_fail (reader, NULL);

   if (reached_eof) {
      *reached_eof = false;
   }

   while (!reader->done) {
      if ((reader->end - reader->offset) < 4) {
         _bson_reader_handle_fill_buffer (reader);
         continue;
      }

      memcpy (&blen, &reader->data[reader->offset], sizeof blen);
      blen = BSON_UINT32_FROM_LE (blen);

      if (blen < 5) {
         return NULL;
      }

      if (blen > (int32_t)(reader->end - reader->offset)) {
         if (blen > (int32_t)reader->len) {
            _bson_reader_handle_grow_buffer (reader);
         }

         _bson_reader_handle_fill_buffer (reader);
         continue;
      }

      if (!bson_init_static (&reader->inline_bson,
                             &reader->data[reader->offset],
                             (uint32_t)blen)) {
         return NULL;
      }

      reader->offset += blen;

      return &reader->inline_bson;
   }

   if (reached_eof) {
      *reached_eof = reader->done && !reader->failed;
   }

   return NULL;
}
Beispiel #19
0
view::iterator view::find(stdx::string_view key) const {
    bson_t b;
    bson_iter_t iter;

    if (!bson_init_static(&b, _data, _length)) {
        return end();
    }

    if (bson_iter_init_find(&iter, &b, key.data())) {
        return iterator(element(iter.raw, iter.len, iter.off));
    } else {
        return end();
    }
}
Beispiel #20
0
/**
 * Performs an aggregation operation on a MongoDB collection.
 *
 * @param collection The MongoDB collection to query against.
 * @param pipeline A pointer to a BSON buffer representing the pipeline.
 * @param coldata The column data to store the results in.
 *
 * @return If successful, a Monary cursor that should be freed with
 * monary_close_query() when no longer in use. If unsuccessful, or if an invalid
 * pipeline was passed in, NULL is returned.
 */
monary_cursor* monary_init_aggregate(mongoc_collection_t* collection,
                                     const uint8_t* pipeline,
                                     monary_column_data* coldata)
{
    bson_t pl_bson;
    int32_t pl_size;
    mongoc_cursor_t* mcursor;
    monary_cursor* cursor;

    // Sanity checks
    if (!collection) {
        DEBUG("%s", "Invalid collection");
        return NULL;
    }
    else if (!pipeline) {
        DEBUG("%s", "Invalid pipeline");
        return NULL;
    }

    // Build BSON pipeline
    memcpy(&pl_size, pipeline, sizeof(int32_t));
    pl_size = (int32_t) BSON_UINT32_FROM_LE(pl_size);
    if (!bson_init_static(&pl_bson,
                          pipeline,
                          pl_size)) {
        DEBUG("%s", "Failed to initialize raw BSON pipeline");
        return NULL;
    }

    // Get an aggregation cursor
    mcursor = mongoc_collection_aggregate(collection,
                                          MONGOC_QUERY_NONE,
                                          &pl_bson,
                                          NULL,
                                          NULL);

    // Clean up
    bson_destroy(&pl_bson);

    if (!mcursor) {
        DEBUG("%s", "An error occurred with the aggregation");
        return NULL;
    }

    cursor = (monary_cursor*) malloc(sizeof(monary_cursor));
    cursor->mcursor = mcursor;
    cursor->coldata = coldata;
    return cursor;
}
Beispiel #21
0
void bsonToMongoCodeWithScope(bson_iter_t* iter, Array* output) {
  uint32_t length;
  uint32_t scope_len;
  const uint8_t* scope;
  const char* code = bson_iter_codewscope(iter, &length, &scope_len, &scope);

  bson_t bson;
  bson_init_static(&bson, scope, scope_len);

  Array scopeArray = Array::Create();
  bsonToVariant(&bson, &scopeArray);

  bsonToObject(iter, output,
    &s_MongoCode,
    make_packed_array(String(code, length, CopyString), scopeArray)
  );
}
Beispiel #22
0
void core::concatenate(const bsoncxx::document::view& view) {
    bson_t other;
    bson_init_static(&other, view.data(), view.length());

    if (_impl->is_array()) {
        bson_iter_t iter;
        bson_iter_init(&iter, &other);

        while (bson_iter_next(&iter)) {
            stdx::string_view key = _impl->next_key();

            bson_append_iter(_impl->back(), key.data(), key.length(), &iter);
        }

    } else {
        bson_concat(_impl->back(), &other);
    }
}
Beispiel #23
0
bool
_mongoc_rpc_reply_get_first (mongoc_rpc_reply_t *reply,
                             bson_t             *bson)
{
   int32_t len;

   if (!reply->documents || reply->documents_len < 4) {
      return false;
   }

   memcpy(&len, reply->documents, 4);
   len = BSON_UINT32_FROM_LE(len);
   if (reply->documents_len < len) {
      return false;
   }

   return bson_init_static(bson, reply->documents, len);
}
Beispiel #24
0
static void
append_documents_from_cmd (const mongoc_cmd_t *cmd,
                           mongoc_apm_command_started_t *event)
{
   int32_t doc_len;
   bson_t doc;
   const uint8_t *pos;
   const char *field_name;
   bson_t bson;
   char str[16];
   const char *key;
   uint32_t i;

   if (!cmd->payload || !cmd->payload_size) {
      return;
   }

   if (!event->command_owned) {
      event->command = bson_copy (event->command);
      event->command_owned = true;
   }

   /* make array from outgoing OP_MSG payload type 1 on an "insert",
    * "update", or "delete" command. */
   field_name = _mongoc_get_documents_field_name (cmd->command_name);
   BSON_ASSERT (field_name);
   BSON_ASSERT (BSON_APPEND_ARRAY_BEGIN (event->command, field_name, &bson));

   pos = cmd->payload;
   i = 0;
   while (pos < cmd->payload + cmd->payload_size) {
      memcpy (&doc_len, pos, sizeof (doc_len));
      doc_len = BSON_UINT32_FROM_LE (doc_len);
      BSON_ASSERT (bson_init_static (&doc, pos, (size_t) doc_len));
      bson_uint32_to_string (i, &key, str, sizeof (str));
      BSON_APPEND_DOCUMENT (&bson, key, &doc);

      pos += doc_len;
      i++;
   }

   bson_append_array_end (event->command, &bson);
}
Beispiel #25
0
static const bson_t *
_bson_reader_data_read (bson_reader_data_t *reader,
                        bson_bool_t        *reached_eof)
{
   bson_uint32_t blen;

   bson_return_val_if_fail (reader, NULL);

   if (reached_eof) {
      *reached_eof = FALSE;
   }

   if ((reader->offset + 4) < reader->length) {
      memcpy (&blen, &reader->data[reader->offset], sizeof blen);
      blen = BSON_UINT32_FROM_LE (blen);

      if ((blen + reader->offset) <= reader->length) {
         if (!bson_init_static (&reader->inline_bson,
                                &reader->data[reader->offset],
                                blen)) {
            if (reached_eof) {
               *reached_eof = FALSE;
            }

            return NULL;
         }

         reader->offset += blen;

         if (reached_eof) {
            *reached_eof = (reader->offset == reader->length);
         }

         return &reader->inline_bson;
      }
   }

   if (reached_eof) {
      *reached_eof = (reader->offset == reader->length);
   }

   return NULL;
}
Beispiel #26
0
static const bson_t *
_bson_reader_fd_read (bson_reader_fd_t *reader,
                      bson_bool_t      *reached_eof)
{
   bson_uint32_t blen;

   bson_return_val_if_fail (reader, NULL);

   while (!reader->done) {
      if ((reader->end - reader->offset) < 4) {
         _bson_reader_fd_fill_buffer (reader);
         continue;
      }

      memcpy (&blen, &reader->data[reader->offset], sizeof blen);
      blen = BSON_UINT32_FROM_LE (blen);

      if (blen > (reader->end - reader->offset)) {
         if (blen > reader->len) {
            _bson_reader_fd_grow_buffer (reader);
         }

         _bson_reader_fd_fill_buffer (reader);
         continue;
      }

      if (!bson_init_static (&reader->inline_bson,
                             &reader->data[reader->offset],
                             blen)) {
         return NULL;
      }

      reader->offset += blen;

      return &reader->inline_bson;
   }

   if (reached_eof) {
      *reached_eof = reader->done && !reader->failed;
   }

   return NULL;
}
Beispiel #27
0
void bsonToArray(bson_iter_t* iter, Array* output, bool isDocument) {
  bson_t bson;
  const uint8_t *document = NULL;
  uint32_t document_len = 0;

  if (isDocument) {
    bson_iter_document(iter, &document_len, &document);
  } else {
    bson_iter_array(iter, &document_len, &document);
  }

  bson_init_static(&bson, document, document_len);

  Array child = Array::Create();
  bsonToVariant(&bson, &child);

  output->add(
    String(bson_iter_key(iter)),
    child
  );   
}
bson_bool_t
_mongoc_rpc_reply_get_first (mongoc_rpc_reply_t *reply,
                             bson_t             *bson)
{
   bson_int32_t len;

   bson_return_val_if_fail(reply, FALSE);
   bson_return_val_if_fail(bson, FALSE);

   if (!reply->documents || reply->documents_len < 4) {
      return FALSE;
   }

   memcpy(&len, reply->documents, 4);
   len = BSON_UINT32_FROM_LE(len);
   if (reply->documents_len < len) {
      return FALSE;
   }

   return bson_init_static(bson, reply->documents, len);
}
Beispiel #29
0
static const bson_t *
_bson_reader_data_read (bson_reader_data_t *reader,      /* IN */
                        bool               *reached_eof) /* IN */
{
   int32_t blen;

   bson_return_val_if_fail (reader, NULL);

   if (reached_eof) {
      *reached_eof = false;
   }

   if ((reader->offset + 4) < reader->length) {
      memcpy (&blen, &reader->data[reader->offset], sizeof blen);
      blen = BSON_UINT32_FROM_LE (blen);

      if (blen < 5) {
         return NULL;
      }

      if (blen > (int32_t)(reader->length - reader->offset)) {
         return NULL;
      }

      if (!bson_init_static (&reader->inline_bson,
                             &reader->data[reader->offset], (uint32_t)blen)) {
         return NULL;
      }

      reader->offset += blen;

      return &reader->inline_bson;
   }

   if (reached_eof) {
      *reached_eof = (reader->offset == reader->length);
   }

   return NULL;
}
Beispiel #30
0
static request_t *
_check_op_query (mock_server_t                    *server,
                 test_collection_find_with_opts_t *test_data)
{
   mongoc_query_flags_t flags;
   request_t *request;
   const bson_t *doc;
   bson_iter_t iter;
   uint32_t len;
   const uint8_t *data;
   bson_t query;

   /* Server Selection Spec: all queries to standalone set slaveOk. */
   flags = test_data->expected_flags | MONGOC_QUERY_SLAVE_OK;

   request = mock_server_receives_query (
      server,
      "db.collection",
      flags,
      test_data->expected_skip,
      test_data->expected_n_return,
      test_data->expected_op_query,
      test_data->expected_op_query_projection);

   ASSERT (request);

   /* check that nothing unexpected is in $query */
   if (bson_empty (test_data->filter_bson)) {
      doc = request_get_doc (request, 0);

      if (bson_iter_init_find (&iter, doc, "$query")) {
         ASSERT (BSON_ITER_HOLDS_DOCUMENT (&iter));
         bson_iter_document (&iter, &len, &data);
         bson_init_static (&query, data, (size_t) len);
         ASSERT (bson_empty (&query));
      }
   }

   return request;
}