bool
_mongoc_cursor_cursorid_next (mongoc_cursor_t *cursor, const bson_t **bson)
{
   mongoc_cursor_cursorid_t *cid;
   bool refreshed = false;

   ENTRY;

   *bson = NULL;

   cid = (mongoc_cursor_cursorid_t *) cursor->iface_data;
   BSON_ASSERT (cid);

   if (!cursor->sent) {
      if (!_mongoc_cursor_cursorid_prime (cursor)) {
         GOTO (done);
      }
   }

again:

   /* Two paths:
    * - Mongo 3.2+, sent "getMore" cmd, we're reading reply's "nextBatch" array
    * - Mongo 2.6 to 3, after "aggregate" or similar command we sent OP_GETMORE,
    *   we're reading the raw reply
    */
   if (cid->in_batch) {
      _mongoc_cursor_cursorid_read_from_batch (cursor, bson);

      if (*bson) {
         GOTO (done);
      }

      cid->in_batch = false;
   } else if (cid->in_reader) {
      _mongoc_read_from_buffer (cursor, bson);

      if (*bson) {
         GOTO (done);
      }

      cid->in_reader = false;
   }

   if (!refreshed && mongoc_cursor_get_id (cursor)) {
      if (!_mongoc_cursor_cursorid_get_more (cursor)) {
         GOTO (done);
      }

      refreshed = true;
      GOTO (again);
   }

done:
   if (!*bson && mongoc_cursor_get_id (cursor) == 0) {
      cursor->done = 1;
   }

   RETURN (*bson != NULL);
}
bool
_mongoc_cursor_array_prime (mongoc_cursor_t *cursor)
{
   const bson_t *bson;
   mongoc_cursor_array_t *arr;
   bson_iter_t iter;

   ENTRY;

   arr = (mongoc_cursor_array_t *)cursor->iface_data;

   BSON_ASSERT (arr);

   if (_mongoc_cursor_run_command (cursor, &cursor->query) &&
       _mongoc_read_from_buffer (cursor, &bson) &&
       bson_iter_init_find (&iter, bson, arr->field_name) &&
       BSON_ITER_HOLDS_ARRAY (&iter) &&
       bson_iter_recurse (&iter, &arr->iter)) {
      arr->has_array = true;
   }

   return arr->has_array;
}