<commit_before>/*
 * Copyright 2013 MongoDB, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


#include "mongoc-cursor.h"
#include "mongoc-cursor-private.h"
#include "mongoc-client-private.h"
#include "mongoc-counters-private.h"
#include "mongoc-error.h"
#include "mongoc-log.h"
#include "mongoc-trace.h"
#include "mongoc-cursor-cursorid-private.h"
#include "mongoc-read-concern-private.h"
#include "mongoc-util-private.h"


#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "cursor"


#define CURSOR_FAILED(cursor_) ((cursor_)->error.domain != 0)

static const bson_t *
_mongoc_cursor_op_query (mongoc_cursor_t        *cursor,
                         mongoc_server_stream_t *server_stream);

static const bson_t *
_mongoc_cursor_find_command (mongoc_cursor_t *cursor);


static int32_t
_mongoc_n_return (mongoc_cursor_t * cursor)
{
   if (cursor->is_command) {
      /* commands always have n_return of 1 */
      return 1;
   } else if (cursor->limit) {
      int32_t remaining = cursor->limit - cursor->count;
      BSON_ASSERT (remaining > 0);

      if (cursor->batch_size) {
         return BSON_MIN ((int32_t) cursor->batch_size, remaining);
      } else {
         /* batch_size 0 means accept the default */
         return remaining;
      }
   } else {
      return cursor->batch_size;
   }
}

mongoc_cursor_t *
_mongoc_cursor_new (mongoc_client_t           *client,
                    const char                *db_and_collection,
                    mongoc_query_flags_t       qflags,
                    uint32_t                   skip,
                    uint32_t                   limit,
                    uint32_t                   batch_size,
                    bool                       is_command,
                    const bson_t              *query,
                    const bson_t              *fields,
                    const mongoc_read_prefs_t *read_prefs,
                    const mongoc_read_concern_t *read_concern)
{
   mongoc_cursor_t *cursor;
   bson_iter_t iter;
   int flags = qflags;
   const char *dot;

   ENTRY;

   BSON_ASSERT (client);
   BSON_ASSERT (db_and_collection);

   if (!read_concern) {
      read_concern = client->read_concern;
   }
   if (!read_prefs) {
      read_prefs = client->read_prefs;
   }

   cursor = (mongoc_cursor_t *)bson_malloc0 (sizeof *cursor);

   /*
    * Cursors execute their query lazily. This sadly means that we must copy
    * some extra data around between the bson_t structures. This should be
    * small in most cases, so it reduces to a pure memcpy. The benefit to this
    * design is simplified error handling by API consumers.
    */

   cursor->client = client;
   bson_strncpy (cursor->ns, db_and_collection, sizeof cursor->ns);

   cursor->nslen = (uint32_t)strnlen (cursor->ns, sizeof cursor->ns);
   dot = strstr (db_and_collection, ".");

   if (dot) {
      cursor->dblen = (uint32_t)(dot - db_and_collection);
   } else {
      /* a database name with no collection name */
      cursor->dblen = cursor->nslen;
   }

   cursor->flags = (mongoc_query_flags_t)flags;
   cursor->skip = skip;
   cursor->limit = limit;
   cursor->batch_size = batch_size;
   cursor->is_command = is_command;
   cursor->has_fields = !!fields;

#define MARK_FAILED(c) \
   do { \
      bson_init (&(c)->query); \
      bson_init (&(c)->fields); \
      (c)->done = true; \
      (c)->end_of_event = true; \
      (c)->sent = true; \
   } while (0)
<commit_msg>use bson_strnlen when strnlen is not available<commit_after>/*
 * Copyright 2013 MongoDB, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


#include "mongoc-cursor.h"
#include "mongoc-cursor-private.h"
#include "mongoc-client-private.h"
#include "mongoc-counters-private.h"
#include "mongoc-error.h"
#include "mongoc-log.h"
#include "mongoc-trace.h"
#include "mongoc-cursor-cursorid-private.h"
#include "mongoc-read-concern-private.h"
#include "mongoc-util-private.h"


#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "cursor"


#define CURSOR_FAILED(cursor_) ((cursor_)->error.domain != 0)

static const bson_t *
_mongoc_cursor_op_query (mongoc_cursor_t        *cursor,
                         mongoc_server_stream_t *server_stream);

static const bson_t *
_mongoc_cursor_find_command (mongoc_cursor_t *cursor);


static int32_t
_mongoc_n_return (mongoc_cursor_t * cursor)
{
   if (cursor->is_command) {
      /* commands always have n_return of 1 */
      return 1;
   } else if (cursor->limit) {
      int32_t remaining = cursor->limit - cursor->count;
      BSON_ASSERT (remaining > 0);

      if (cursor->batch_size) {
         return BSON_MIN ((int32_t) cursor->batch_size, remaining);
      } else {
         /* batch_size 0 means accept the default */
         return remaining;
      }
   } else {
      return cursor->batch_size;
   }
}

mongoc_cursor_t *
_mongoc_cursor_new (mongoc_client_t           *client,
                    const char                *db_and_collection,
                    mongoc_query_flags_t       qflags,
                    uint32_t                   skip,
                    uint32_t                   limit,
                    uint32_t                   batch_size,
                    bool                       is_command,
                    const bson_t              *query,
                    const bson_t              *fields,
                    const mongoc_read_prefs_t *read_prefs,
                    const mongoc_read_concern_t *read_concern)
{
   mongoc_cursor_t *cursor;
   bson_iter_t iter;
   int flags = qflags;
   const char *dot;

   ENTRY;

   BSON_ASSERT (client);
   BSON_ASSERT (db_and_collection);

   if (!read_concern) {
      read_concern = client->read_concern;
   }
   if (!read_prefs) {
      read_prefs = client->read_prefs;
   }

   cursor = (mongoc_cursor_t *)bson_malloc0 (sizeof *cursor);

   /*
    * Cursors execute their query lazily. This sadly means that we must copy
    * some extra data around between the bson_t structures. This should be
    * small in most cases, so it reduces to a pure memcpy. The benefit to this
    * design is simplified error handling by API consumers.
    */

   cursor->client = client;
   bson_strncpy (cursor->ns, db_and_collection, sizeof cursor->ns);

   cursor->nslen = (uint32_t)bson_strnlen (cursor->ns, sizeof cursor->ns);
   dot = strstr (db_and_collection, ".");

   if (dot) {
      cursor->dblen = (uint32_t)(dot - db_and_collection);
   } else {
      /* a database name with no collection name */
      cursor->dblen = cursor->nslen;
   }

   cursor->flags = (mongoc_query_flags_t)flags;
   cursor->skip = skip;
   cursor->limit = limit;
   cursor->batch_size = batch_size;
   cursor->is_command = is_command;
   cursor->has_fields = !!fields;

#define MARK_FAILED(c) \
   do { \
      bson_init (&(c)->query); \
      bson_init (&(c)->fields); \
      (c)->done = true; \
      (c)->end_of_event = true; \
      (c)->sent = true; \
   } while (0)

{'fraction_non_alphanumeric': 0.10030165912518854, 'fraction_numerical': 0.007792860734037205, 'mean_word_length': 2.407708779443255, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 65, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1177075', 'n_tokens_mistral': 2573, 'n_tokens_neox': 2472, 'n_words': 666}