Esempio n. 1
0
MongoBson *
mongo_bson_dup (const MongoBson *bson)
{
   MongoBson *ret = NULL;

   if (bson) {
      if (bson->static_data) {
         ret = mongo_bson_new_from_data(bson->static_data, bson->static_len);
      } else {
         ret = mongo_bson_new_from_data(bson->buf->data, bson->buf->len);
      }
   }

   return ret;
}
Esempio n. 2
0
/**
 * mongo_bson_ref:
 * @bson: (in): A #MongoBson.
 *
 * Atomically increments the reference count of @bson by one. If @bson
 * contains a static buffer, then a new structure will be returned.
 *
 * Returns: (transfer full): @bson.
 */
MongoBson *
mongo_bson_ref (MongoBson *bson)
{
   g_return_val_if_fail(bson != NULL, NULL);
   g_return_val_if_fail(bson->ref_count > 0, NULL);

   if (G_UNLIKELY(bson->static_data)) {
      return mongo_bson_new_from_data(bson->static_data, bson->static_len);
   }
   g_atomic_int_inc(&bson->ref_count);
   return bson;
}
Esempio n. 3
0
/**
 * mongo_bson_stream_next:
 * @stream: (in): A #MongoBsonStream.
 *
 * Gets the next #MongoBson document found in the stream.
 *
 * Returns: (transfer full): A #MongoBson if successful; otherwise %NULL.
 */
MongoBson *
mongo_bson_stream_next (MongoBsonStream *stream)
{
   MongoBson *bson;
   guint32 doc_len_le;
   guint32 doc_len;
   guint8 *buffer;

   g_return_val_if_fail(MONGO_IS_BSON_STREAM(stream), NULL);
   g_return_val_if_fail(stream->priv->stream ||
                        stream->priv->channel,
                        NULL);

   if (!mongo_bson_stream_read(stream,
                               (guint8 *)&doc_len_le,
                               sizeof doc_len_le,
                               sizeof doc_len_le)) {
      return NULL;
   }

   doc_len = GUINT32_FROM_LE(doc_len_le);

   /*
    * Sanity check to make sure it is less than 8mB and
    * greater than 5 bytes (minimum required).
    */
   if (doc_len > (1024 * 1024 * 8) || doc_len <= 5) {
      return NULL;
   }

   buffer = g_malloc(doc_len);
   memcpy(buffer, &doc_len_le, sizeof doc_len_le);

   /*
    * Read the rest of the BSON document into our buffer.
    */
   if (!mongo_bson_stream_read(stream,
                               buffer + sizeof doc_len_le,
                               doc_len,
                               doc_len - sizeof doc_len_le)) {
      return NULL;
   }

   if (!(bson = mongo_bson_new_from_data(buffer, doc_len))) {
      g_free(buffer);
      return NULL;
   }

   return bson;
}
Esempio n. 4
0
static MongoBson *
mongo_bson_iter_get_value_document (MongoBsonIter *iter,
                                    MongoBsonType  type)
{
   const guint8 *buffer;
   gpointer endbuf;
   guint32 array_len;

   g_return_val_if_fail(iter != NULL, NULL);
   g_return_val_if_fail(iter->user_data1 != NULL, NULL);
   g_return_val_if_fail(iter->user_data2 != NULL, NULL);
   g_return_val_if_fail(iter->user_data6 != NULL, NULL);
   g_return_val_if_fail((type == MONGO_BSON_ARRAY) ||
                        (type == MONGO_BSON_DOCUMENT), NULL);

   if (G_LIKELY(ITER_IS_TYPE(iter, type))) {
      endbuf = GSIZE_TO_POINTER(GPOINTER_TO_SIZE(iter->user_data1) +
                                GPOINTER_TO_SIZE(iter->user_data2));
      if ((iter->user_data6 + 5) > endbuf) {
         return NULL;
      }
      memcpy(&array_len, iter->user_data6, sizeof array_len);
      array_len = GINT_FROM_LE(array_len);
      if ((iter->user_data6 + array_len) > endbuf) {
         return NULL;
      }
      buffer = iter->user_data6;
      return mongo_bson_new_from_data(buffer, array_len);
   }

   if (type == MONGO_BSON_ARRAY) {
      g_warning("Current key is not an array.");
   } else if (type == MONGO_BSON_DOCUMENT) {
      g_warning("Current key is not a document.");
   } else {
      g_assert_not_reached();
   }

   return NULL;
}
static gboolean
mongo_message_query_load_from_data (MongoMessage *message,
                                    const guint8 *data,
                                    gsize         data_len)
{
   MongoMessageQueryPrivate *priv;
   MongoMessageQuery *query = (MongoMessageQuery *)message;
   const gchar *name;
   MongoBson *bson;
   guint32 vu32;

   ENTRY;

   g_assert(MONGO_IS_MESSAGE_QUERY(query));
   g_assert(data);
   g_assert(data_len);

   priv = query->priv;

   if (data_len > 4) {
      /* Query flags */
      memcpy(&vu32, data, sizeof vu32);
      priv->flags = GUINT32_FROM_LE(vu32);

      data_len -= 4;
      data += 4;

      /* Walk through collection name */
      for (name = (gchar *)data; data_len && *data; data_len--, data++) { }

      if (data_len) {
         mongo_message_query_set_collection(query, name);
         data_len--;
         data++;

         /* Skipped documents */
         if (data_len > 4) {
            memcpy(&vu32, data, sizeof vu32);
            mongo_message_query_set_skip(query, GUINT32_FROM_LE(vu32));
            data_len -= 4;
            data += 4;

            /* Maximum return documents */
            if (data_len > 4) {
               memcpy(&vu32, data, sizeof vu32);
               mongo_message_query_set_limit(query, GUINT32_FROM_LE(vu32));
               data_len -= 4;
               data += 4;

               /* Query BSON document */
               if (data_len > 4) {
                  memcpy(&vu32, data, sizeof vu32);
                  vu32 = GUINT32_FROM_LE(vu32);
                  if (data_len >= vu32) {
                     bson = mongo_bson_new_from_data(data, vu32);
                     mongo_message_query_take_query(query, bson);
                     data_len -= vu32;
                     data += vu32;

                     /* Fields bson document */
                     if (data_len > 4) {
                        memcpy(&vu32, data, sizeof vu32);
                        vu32 = GUINT32_FROM_LE(vu32);
                        if (data_len >= vu32) {
                           bson = mongo_bson_new_from_data(data, vu32);
                           mongo_message_query_take_fields(query, bson);
                           data_len -= vu32;
                           data += vu32;
                        }
                     }

                     RETURN(data_len == 0);
                  }
               }
            }
         }
      }
   }

   RETURN(FALSE);
}
static gboolean
mongo_message_update_load_from_data (MongoMessage *message,
                                     const guint8 *data,
                                     gsize         length)
{
   MongoMessageUpdate *update = (MongoMessageUpdate *)message;
   const gchar *name;
   MongoBson *bson;
   guint32 v32;

   ENTRY;

   g_assert(MONGO_IS_MESSAGE_UPDATE(update));
   g_assert(data);
   g_assert(length);

   if (length >= 4) {
      /* First 4 bytes are ZERO, reserved for future. */
      length -= 4;
      data += 4;

      if (length >= 1) {
         /* Walk through collection name */
         for (name = (gchar *)data; length && *data; length--, data++) { }

         if (length) {
            mongo_message_update_set_collection(update, name);
            length--;
            data++;

            /* Update flags */
            if (length >= 4) {
               memcpy(&v32, data, sizeof v32);
               mongo_message_update_set_flags(update, GUINT32_FROM_LE(v32));
               length -= 4;
               data += 4;

               /* Query BSON */
               if (length >= 4) {
                  memcpy(&v32, data, sizeof v32);
                  v32 = GUINT32_FROM_LE(v32);
                  if (v32 <= length) {
                     if ((bson = mongo_bson_new_from_data(data, v32))) {
                        mongo_message_update_set_query(update, bson);
                        mongo_bson_unref(bson);
                        length -= v32;
                        data += v32;

                        /* Update BSON */
                        if (length >= 4) {
                           memcpy(&v32, data, sizeof v32);
                           v32 = GUINT32_FROM_LE(v32);
                           if (v32 <= length) {
                              if ((bson = mongo_bson_new_from_data(data, v32))) {
                                 mongo_message_update_set_update(update, bson);
                                 mongo_bson_unref(bson);
                                 length -= v32;
                                 data += v32;
                                 RETURN(length == 0);
                              }
                           }
                        }
                     }
                  }
               }
            }
         }
      }
   }

   RETURN(FALSE);
}