summaryrefslogtreecommitdiff
path: root/src/bson/bson.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/bson/bson.h')
-rw-r--r--src/bson/bson.h1215
1 files changed, 1215 insertions, 0 deletions
diff --git a/src/bson/bson.h b/src/bson/bson.h
new file mode 100644
index 0000000..02395d0
--- /dev/null
+++ b/src/bson/bson.h
@@ -0,0 +1,1215 @@
+/**
+ * @file bson.h
+ * @brief BSON Declarations
+ */
+
+/* Copyright 2009-2012 10gen Inc.
+ * Copyright (C) 2012-2015 Softmotions Ltd <info@softmotions.com>
+ *
+ * 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.
+ */
+
+#ifndef BSON_H_
+#define BSON_H_
+
+#include "basedefs.h"
+#include <stdio.h>
+#include <stdint.h>
+#if ! defined(__cplusplus)
+#include <stdbool.h>
+#endif
+#include <time.h>
+#include "tcutil.h"
+
+#define BSON_IS_NUM_TYPE(atype) (atype == BSON_INT || atype == BSON_LONG || atype == BSON_DOUBLE)
+#define BSON_IS_STRING_TYPE(atype) (atype == BSON_STRING || atype == BSON_SYMBOL)
+
+EJDB_EXTERN_C_START
+
+#define BSON_OK 0
+#define BSON_ERROR -1
+
+//Maximum field path length allocated on stack
+#define BSON_MAX_FPATH_LEN (255)
+
+enum bson_error_t {
+ BSON_SIZE_OVERFLOW = 1 /**< Trying to create a BSON object larger than INT_MAX. */
+};
+
+enum bson_validity_t {
+ BSON_VALID = 0, /**< BSON is valid and UTF-8 compliant. */
+ BSON_NOT_UTF8 = (1 << 1), /**< A key or a string is not valid UTF-8. */
+ BSON_FIELD_HAS_DOT = (1 << 2), /**< Warning: key contains '.' character. */
+ BSON_FIELD_INIT_DOLLAR = (1 << 3), /**< Warning: key starts with '$' character. */
+ BSON_ALREADY_FINISHED = (1 << 4), /**< Trying to modify a finished BSON object. */
+ BSON_ERROR_ANY = (1 << 5) /**< Unspecified error */
+};
+
+enum bson_binary_subtype_t {
+ BSON_BIN_BINARY = 0,
+ BSON_BIN_FUNC = 1,
+ BSON_BIN_BINARY_OLD = 2,
+ BSON_BIN_UUID = 3,
+ BSON_BIN_MD5 = 5,
+ BSON_BIN_USER = 128
+};
+
+enum bson_flags_t {
+ BSON_FLAG_QUERY_MODE = 1,
+ BSON_FLAG_STACK_ALLOCATED = 1 << 1 /**< If it set BSON data is allocated on stack and realloc should deal with this case */
+};
+
+typedef enum {
+ BSON_EOO = 0,
+ BSON_DOUBLE = 1,
+ BSON_STRING = 2,
+ BSON_OBJECT = 3,
+ BSON_ARRAY = 4,
+ BSON_BINDATA = 5,
+ BSON_UNDEFINED = 6,
+ BSON_OID = 7,
+ BSON_BOOL = 8,
+ BSON_DATE = 9,
+ BSON_NULL = 10,
+ BSON_REGEX = 11,
+ BSON_DBREF = 12, /**< Deprecated. */
+ BSON_CODE = 13,
+ BSON_SYMBOL = 14,
+ BSON_CODEWSCOPE = 15,
+ BSON_INT = 16,
+ BSON_TIMESTAMP = 17,
+ BSON_LONG = 18
+} bson_type;
+
+typedef int bson_bool_t;
+
+typedef struct {
+ const char *cur;
+ bson_bool_t first;
+} bson_iterator;
+
+typedef struct {
+ char *data; /**< Pointer to a block of data in this BSON object. */
+ char *cur; /**< Pointer to the current position. */
+ int dataSize; /**< The number of bytes allocated to char *data. */
+ bson_bool_t finished; /**< When finished, the BSON object can no longer be modified. */
+ int stack[32]; /**< A stack used to keep track of nested BSON elements. */
+ int stackPos; /**< Index of current stack position. */
+ int err; /**< Bitfield representing errors or warnings on this buffer */
+ char *errstr; /**< A string representation of the most recent error or warning. */
+ int flags;
+} bson;
+
+#pragma pack(1)
+
+typedef union {
+ char bytes[12];
+ int ints[3];
+} bson_oid_t;
+#pragma pack()
+
+typedef int64_t bson_date_t; /* milliseconds since epoch UTC */
+
+typedef struct {
+ int i; /* increment */
+ int t; /* time in seconds */
+} bson_timestamp_t;
+
+
+EJDB_EXPORT const char* bson_first_errormsg(bson *bson);
+
+
+#define BSON_ITERATOR_FROM_BUFFER(_bs_I, _bs_B) \
+ (_bs_I)->cur = ((char*) (_bs_B)) + 4; \
+ (_bs_I)->first = 1;
+
+#define BSON_ITERATOR_SUBITERATOR(_bs_I, _bs_S) \
+ BSON_ITERATOR_FROM_BUFFER((_bs_S), bson_iterator_value(_bs_I))
+
+#define BSON_ITERATOR_TYPE(_bs_I) \
+ ((bson_type) (_bs_I)->cur[0])
+
+#define BSON_ITERATOR_KEY(_bs_I) \
+ ((_bs_I)->cur + 1)
+
+#define BSON_ITERATOR_INIT(_bs_I, _bs) \
+ (_bs_I)->cur = (_bs)->data + 4; \
+ (_bs_I)->first = 1;
+
+/* ----------------------------
+ READING
+ ------------------------------ */
+
+EJDB_EXPORT bson* bson_create(void);
+EJDB_EXPORT void bson_dispose(bson* b);
+
+/**
+ * Size of a BSON object.
+ *
+ * @param b the BSON object.
+ *
+ * @return the size.
+ */
+EJDB_EXPORT int bson_size(const bson *b);
+EJDB_EXPORT int bson_size2(const void *bsdata);
+EJDB_EXPORT int bson_buffer_size(const bson *b);
+
+/**
+ * Return a pointer to the raw buffer stored by this bson object.
+ *
+ * @param b a BSON object
+ */
+EJDB_EXPORT const char *bson_data(const bson *b);
+EJDB_EXPORT const char* bson_data2(const bson *b, int *bsize);
+
+/**
+ * Print a string representation of a BSON object.
+ *
+ * @param bson the raw data to print.
+ * @param depth the depth to recurse the object.x
+ */
+EJDB_EXPORT void bson_print_raw(const char *bson, int depth);
+
+/**
+ * Advance a bson_iterator to the named field.
+ *
+ * @param it the bson_iterator to use.
+ * @param obj the BSON object to use.
+ * @param name the name of the field to find.
+ *
+ * @return the type of the found object or BSON_EOO if it is not found.
+ */
+EJDB_EXPORT bson_type bson_find(bson_iterator *it, const bson *obj, const char *name);
+
+EJDB_EXPORT bson_type bson_find_from_buffer(bson_iterator *it, const char *buffer, const char *name);
+
+typedef struct { /**< Find field path context */
+ const char* fpath;
+ int fplen;
+ bson_iterator *input;
+ int stopos;
+ bool stopnestedarr;
+ int mpos; /**< Array index of the first matched array field */
+ int dpos; /**< Position of `$` in array projection fieldpath. */
+} FFPCTX;
+
+
+/**
+ * Advance specified iterator 'it' to field value pointing by 'fieldpath'/
+ * Field path string format: 'field1.nestedfield1.nestedfield.2'.
+ * If specified field not found BSON_EOO will be returned.
+ *
+ * @param fieldpath Path specification to the BSON field.
+ * @param it the bson_iterator to use.
+ * @return the type of the found object or BSON_EOO if it is not found.
+ */
+EJDB_EXPORT bson_type bson_find_fieldpath_value(const char *fieldpath, bson_iterator *it);
+EJDB_EXPORT bson_type bson_find_fieldpath_value2(const char *fpath, int fplen, bson_iterator *it);
+EJDB_EXPORT bson_type bson_find_fieldpath_value3(FFPCTX* ffctx);
+
+/**
+ * BSON object visitor
+ * @param it bson iterator to traverse
+ * @param visitor Visitor function
+ * @param op Opaque data for visitor
+ */
+typedef enum {
+ BSON_TRAVERSE_ARRAYS_EXCLUDED = 1,
+ BSON_TRAVERSE_OBJECTS_EXCLUDED = 1 << 1
+} bson_traverse_flags_t;
+
+typedef enum {
+ BSON_VCMD_OK = 0,
+ BSON_VCMD_TERMINATE = 1,
+ BSON_VCMD_SKIP_NESTED = 1 << 1,
+ BSON_VCMD_SKIP_AFTER = 1 << 2
+} bson_visitor_cmd_t;
+typedef bson_visitor_cmd_t(*BSONVISITOR)(const char *ipath, int ipathlen, const char *key, int keylen, const bson_iterator *it, bool after, void *op);
+EJDB_EXPORT void bson_visit_fields(bson_iterator *it, bson_traverse_flags_t flags, BSONVISITOR visitor, void *op);
+
+
+EJDB_EXPORT bson_iterator* bson_iterator_create(void);
+EJDB_EXPORT void bson_iterator_dispose(bson_iterator*);
+/**
+ * Initialize a bson_iterator.
+ *
+ * @param i the bson_iterator to initialize.
+ * @param bson the BSON object to associate with the iterator.
+ */
+EJDB_EXPORT void bson_iterator_init(bson_iterator *i, const bson *b);
+
+/**
+ * Initialize a bson iterator from a const char* buffer. Note
+ * that this is mostly used internally.
+ *
+ * @param i the bson_iterator to initialize.
+ * @param buffer the buffer to point to.
+ */
+EJDB_EXPORT void bson_iterator_from_buffer(bson_iterator *i, const char *buffer);
+
+/* more returns true for eoo. best to loop with bson_iterator_next(&it) */
+/**
+ * Check to see if the bson_iterator has more data.
+ *
+ * @param i the iterator.
+ *
+ * @return returns true if there is more data.
+ */
+EJDB_EXPORT bson_bool_t bson_iterator_more(const bson_iterator *i);
+
+/**
+ * Point the iterator at the next BSON object.
+ *
+ * @param i the bson_iterator.
+ *
+ * @return the type of the next BSON object.
+ */
+EJDB_EXPORT bson_type bson_iterator_next(bson_iterator *i);
+
+/**
+ * Get the type of the BSON object currently pointed to by the iterator.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the type of the current BSON object.
+ */
+EJDB_EXPORT bson_type bson_iterator_type(const bson_iterator *i);
+
+/**
+ * Get the key of the BSON object currently pointed to by the iterator.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the key of the current BSON object.
+ */
+EJDB_EXPORT const char *bson_iterator_key(const bson_iterator *i);
+
+/**
+ * Get the value of the BSON object currently pointed to by the iterator.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the value of the current BSON object.
+ */
+EJDB_EXPORT const char *bson_iterator_value(const bson_iterator *i);
+
+/* these convert to the right type (return 0 if non-numeric) */
+/**
+ * Get the double value of the BSON object currently pointed to by the
+ * iterator.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the value of the current BSON object.
+ */
+EJDB_EXPORT double bson_iterator_double(const bson_iterator *i);
+
+/**
+ * Get the int value of the BSON object currently pointed to by the iterator.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the value of the current BSON object.
+ */
+EJDB_EXPORT int bson_iterator_int(const bson_iterator *i);
+
+/**
+ * Get the long value of the BSON object currently pointed to by the iterator.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the value of the current BSON object.
+ */
+EJDB_EXPORT int64_t bson_iterator_long(const bson_iterator *i);
+
+/* return the bson timestamp as a whole or in parts */
+/**
+ * Get the timestamp value of the BSON object currently pointed to by
+ * the iterator.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the value of the current BSON object.
+ */
+EJDB_EXPORT bson_timestamp_t bson_iterator_timestamp(const bson_iterator *i);
+EJDB_EXPORT int bson_iterator_timestamp_time(const bson_iterator *i);
+EJDB_EXPORT int bson_iterator_timestamp_increment(const bson_iterator *i);
+
+/**
+ * Get the boolean value of the BSON object currently pointed to by
+ * the iterator.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the value of the current BSON object.
+ */
+/* false: boolean false, 0 in any type, or null */
+/* true: anything else (even empty strings and objects) */
+EJDB_EXPORT bson_bool_t bson_iterator_bool(const bson_iterator *i);
+
+/**
+ * Get the double value of the BSON object currently pointed to by the
+ * iterator. Assumes the correct type is used.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the value of the current BSON object.
+ */
+/* these assume you are using the right type */
+EJDB_EXPORT double bson_iterator_double_raw(const bson_iterator *i);
+
+/**
+ * Get the int value of the BSON object currently pointed to by the
+ * iterator. Assumes the correct type is used.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the value of the current BSON object.
+ */
+EJDB_EXPORT int bson_iterator_int_raw(const bson_iterator *i);
+
+/**
+ * Get the long value of the BSON object currently pointed to by the
+ * iterator. Assumes the correct type is used.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the value of the current BSON object.
+ */
+EJDB_EXPORT int64_t bson_iterator_long_raw(const bson_iterator *i);
+
+/**
+ * Get the bson_bool_t value of the BSON object currently pointed to by the
+ * iterator. Assumes the correct type is used.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the value of the current BSON object.
+ */
+EJDB_EXPORT bson_bool_t bson_iterator_bool_raw(const bson_iterator *i);
+
+/**
+ * Get the bson_oid_t value of the BSON object currently pointed to by the
+ * iterator.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the value of the current BSON object.
+ */
+EJDB_EXPORT bson_oid_t *bson_iterator_oid(const bson_iterator *i);
+
+/**
+ * Get the string value of the BSON object currently pointed to by the
+ * iterator.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the value of the current BSON object.
+ */
+/* these can also be used with bson_code and bson_symbol*/
+EJDB_EXPORT const char *bson_iterator_string(const bson_iterator *i);
+
+/**
+ * Get the string length of the BSON object currently pointed to by the
+ * iterator.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the length of the current BSON object.
+ */
+EJDB_EXPORT int bson_iterator_string_len(const bson_iterator *i);
+
+/**
+ * Get the code value of the BSON object currently pointed to by the
+ * iterator. Works with bson_code, bson_codewscope, and BSON_STRING
+ * returns NULL for everything else.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the code value of the current BSON object.
+ */
+/* works with bson_code, bson_codewscope, and BSON_STRING */
+/* returns NULL for everything else */
+EJDB_EXPORT const char *bson_iterator_code(const bson_iterator *i);
+
+/**
+ * Calls bson_empty on scope if not a bson_codewscope
+ *
+ * @param i the bson_iterator.
+ * @param scope the bson scope.
+ */
+/* calls bson_empty on scope if not a bson_codewscope */
+EJDB_EXPORT void bson_iterator_code_scope(const bson_iterator *i, bson *scope);
+
+/**
+ * Get the date value of the BSON object currently pointed to by the
+ * iterator.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the date value of the current BSON object.
+ */
+/* both of these only work with bson_date */
+EJDB_EXPORT bson_date_t bson_iterator_date(const bson_iterator *i);
+
+/**
+ * Get the time value of the BSON object currently pointed to by the
+ * iterator.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the time value of the current BSON object.
+ */
+EJDB_EXPORT time_t bson_iterator_time_t(const bson_iterator *i);
+
+/**
+ * Get the length of the BSON binary object currently pointed to by the
+ * iterator.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the length of the current BSON binary object.
+ */
+EJDB_EXPORT int bson_iterator_bin_len(const bson_iterator *i);
+
+/**
+ * Get the type of the BSON binary object currently pointed to by the
+ * iterator.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the type of the current BSON binary object.
+ */
+EJDB_EXPORT char bson_iterator_bin_type(const bson_iterator *i);
+
+/**
+ * Get the value of the BSON binary object currently pointed to by the
+ * iterator.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the value of the current BSON binary object.
+ */
+EJDB_EXPORT const char *bson_iterator_bin_data(const bson_iterator *i);
+
+/**
+ * Get the value of the BSON regex object currently pointed to by the
+ * iterator.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the value of the current BSON regex object.
+ */
+EJDB_EXPORT const char *bson_iterator_regex(const bson_iterator *i);
+
+/**
+ * Get the options of the BSON regex object currently pointed to by the
+ * iterator.
+ *
+ * @param i the bson_iterator.
+ *
+ * @return the options of the current BSON regex object.
+ */
+EJDB_EXPORT const char *bson_iterator_regex_opts(const bson_iterator *i);
+
+/* these work with BSON_OBJECT and BSON_ARRAY */
+/**
+ * Get the BSON subobject currently pointed to by the
+ * iterator.
+ *
+ * @param i the bson_iterator.
+ * @param sub the BSON subobject destination.
+ */
+EJDB_EXPORT void bson_iterator_subobject(const bson_iterator *i, bson *sub);
+
+/**
+ * Get a bson_iterator that on the BSON subobject.
+ *
+ * @param i the bson_iterator.
+ * @param sub the iterator to point at the BSON subobject.
+ */
+EJDB_EXPORT void bson_iterator_subiterator(const bson_iterator *i, bson_iterator *sub);
+
+/* str must be at least 24 hex chars + null byte */
+/**
+ * Create a bson_oid_t from a string.
+ *
+ * @param oid the bson_oid_t destination.
+ * @param str a null terminated string comprised of at least 24 hex chars.
+ */
+EJDB_EXPORT void bson_oid_from_string(bson_oid_t *oid, const char *str);
+
+/**
+ * Create a string representation of the bson_oid_t.
+ *
+ * @param oid the bson_oid_t source.
+ * @param str the string representation destination.
+ */
+EJDB_EXPORT void bson_oid_to_string(const bson_oid_t *oid, char *str);
+
+/**
+ * Create a bson_oid object.
+ *
+ * @param oid the destination for the newly created bson_oid_t.
+ */
+EJDB_EXPORT void bson_oid_gen(bson_oid_t *oid);
+
+/**
+ * Set a function to be used to generate the second four bytes
+ * of an object id.
+ *
+ * @param func a pointer to a function that returns an int.
+ */
+EJDB_EXPORT void bson_set_oid_fuzz(int ( *func)(void));
+
+/**
+ * Set a function to be used to generate the incrementing part
+ * of an object id (last four bytes). If you need thread-safety
+ * in generating object ids, you should set this function.
+ *
+ * @param func a pointer to a function that returns an int.
+ */
+EJDB_EXPORT void bson_set_oid_inc(int ( *func)(void));
+
+/**
+ * Get the time a bson_oid_t was created.
+ *
+ * @param oid the bson_oid_t.
+ */
+EJDB_EXPORT time_t bson_oid_generated_time(bson_oid_t *oid); /* Gives the time the OID was created */
+
+/* ----------------------------
+ BUILDING
+ ------------------------------ */
+
+
+EJDB_EXPORT void bson_append(bson *b, const void *data, int len);
+
+/**
+ * Initialize a new bson object. If not created
+ * with bson_new, you must initialize each new bson
+ * object using this function.
+ *
+ * @note When finished, you must pass the bson object to
+ * bson_del( ).
+ */
+EJDB_EXPORT void bson_init(bson *b);
+
+
+/**
+ * Intialize a new bson object. In query contruction mode allowing
+ * dot and dollar chars in field names.
+ * @param b
+ */
+EJDB_EXPORT void bson_init_as_query(bson *b);
+
+/**
+ * Initialize a BSON object, and point its data
+ * pointer to the provided char*.
+ *
+ * @param b the BSON object to initialize.
+ * @param data the raw BSON data.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+EJDB_EXPORT int bson_init_data(bson *b, char *data);
+EJDB_EXPORT int bson_init_finished_data(bson *b, const char *data);
+
+/**
+ * Initialize a BSON object, and set its
+ * buffer to the given size.
+ *
+ * @param b the BSON object to initialize.
+ * @param size the initial size of the buffer.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+EJDB_EXPORT void bson_init_size(bson *b, int size);
+
+EJDB_EXPORT void bson_init_on_stack(bson *b, char *bstack, int mincapacity, int maxonstack);
+
+/**
+ * Grow a bson object.
+ *
+ * @param b the bson to grow.
+ * @param bytesNeeded the additional number of bytes needed.
+ *
+ * @return BSON_OK or BSON_ERROR with the bson error object set.
+ * Exits if allocation fails.
+ */
+EJDB_EXPORT int bson_ensure_space(bson *b, const int bytesNeeded);
+
+/**
+ * Finalize a bson object.
+ *
+ * @param b the bson object to finalize.
+ *
+ * @return the standard error code. To deallocate memory,
+ * call bson_del on the bson object.
+ */
+EJDB_EXPORT int bson_finish(bson *b);
+
+/**
+ * Destroy a bson object.
+ * Clears bson object and frees internal memory buffers held by bson
+ * object BUT does not delete bson object itself
+ * @param b the bson object to destroy.
+ */
+EJDB_EXPORT void bson_destroy(bson *b);
+
+/**
+ * The bson_del() performs bson_destroy() then frees bson object itself.
+ * @param b
+ */
+EJDB_EXPORT void bson_del(bson *b);
+
+EJDB_EXPORT void bson_reset(bson *b);
+
+/**
+ * Returns a pointer to a static empty BSON object.
+ *
+ * @param obj the BSON object to initialize.
+ *
+ * @return the empty initialized BSON object.
+ */
+/* returns pointer to static empty bson object */
+EJDB_EXPORT bson *bson_empty(bson *obj);
+
+/**
+ * Make a complete copy of the a BSON object.
+ * The source bson object must be in a finished
+ * state; otherwise, the copy will fail.
+ *
+ * @param out the copy destination BSON object.
+ * @param in the copy source BSON object.
+ */
+EJDB_EXPORT int bson_copy(bson *out, const bson *in); /* puts data in new buffer. NOOP if out==NULL */
+
+/**
+ * Append a previously created bson_oid_t to a bson object.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the bson_oid_t.
+ * @param oid the bson_oid_t to append.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+EJDB_EXPORT int bson_append_oid(bson *b, const char *name, const bson_oid_t *oid);
+
+/**
+ * Append a bson_oid_t to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the bson_oid_t.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+EJDB_EXPORT int bson_append_new_oid(bson *b, const char *name);
+
+/**
+ * Append an int to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the int.
+ * @param i the int to append.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+EJDB_EXPORT int bson_append_int(bson *b, const char *name, const int i);
+
+/**
+ * Append an long to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the long.
+ * @param i the long to append.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+EJDB_EXPORT int bson_append_long(bson *b, const char *name, const int64_t i);
+
+/**
+ * Append an double to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the double.
+ * @param d the double to append.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+EJDB_EXPORT int bson_append_double(bson *b, const char *name, const double d);
+
+/**
+ * Append a string to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the string.
+ * @param str the string to append.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+EJDB_EXPORT int bson_append_string(bson *b, const char *name, const char *str);
+
+/**
+ * Append len bytes of a string to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the string.
+ * @param str the string to append.
+ * @param len the number of bytes from str to append.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+EJDB_EXPORT int bson_append_string_n(bson *b, const char *name, const char *str, int len);
+
+/**
+ * Append a symbol to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the symbol.
+ * @param str the symbol to append.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+EJDB_EXPORT int bson_append_symbol(bson *b, const char *name, const char *str);
+
+/**
+ * Append len bytes of a symbol to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the symbol.
+ * @param str the symbol to append.
+ * @param len the number of bytes from str to append.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+EJDB_EXPORT int bson_append_symbol_n(bson *b, const char *name, const char *str, int len);
+
+/**
+ * Append code to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the code.
+ * @param str the code to append.
+ * @param len the number of bytes from str to append.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+EJDB_EXPORT int bson_append_code(bson *b, const char *name, const char *str);
+
+/**
+ * Append len bytes of code to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the code.
+ * @param str the code to append.
+ * @param len the number of bytes from str to append.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+EJDB_EXPORT int bson_append_code_n(bson *b, const char *name, const char *str, int len);
+
+/**
+ * Append code to a bson with scope.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the code.
+ * @param str the string to append.
+ * @param scope a BSON object containing the scope.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+EJDB_EXPORT int bson_append_code_w_scope(bson *b, const char *name, const char *code, const bson *scope);
+
+/**
+ * Append len bytes of code to a bson with scope.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the code.
+ * @param str the string to append.
+ * @param len the number of bytes from str to append.
+ * @param scope a BSON object containing the scope.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+EJDB_EXPORT int bson_append_code_w_scope_n(bson *b, const char *name, const char *code, int size, const bson *scope);
+
+/**
+ * Append binary data to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the data.
+ * @param type the binary data type.
+ * @param str the binary data.
+ * @param len the length of the data.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+EJDB_EXPORT int bson_append_binary(bson *b, const char *name, char type, const char *str, int len);
+
+/**
+ * Append a bson_bool_t to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the boolean value.
+ * @param v the bson_bool_t to append.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+EJDB_EXPORT int bson_append_bool(bson *b, const char *name, const bson_bool_t v);
+
+/**
+ * Append a null value to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the null value.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+EJDB_EXPORT int bson_append_null(bson *b, const char *name);
+
+/**
+ * Append an undefined value to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the undefined value.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+EJDB_EXPORT int bson_append_undefined(bson *b, const char *name);
+
+/**
+ * Append a regex value to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the regex value.
+ * @param pattern the regex pattern to append.
+ * @param the regex options.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+EJDB_EXPORT int bson_append_regex(bson *b, const char *name, const char *pattern, const char *opts);
+
+/**
+ * Append bson data to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the bson data.
+ * @param bson the bson object to append.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+EJDB_EXPORT int bson_append_bson(bson *b, const char *name, const bson *bson);
+
+/**
+ * Append a BSON element to a bson from the current point of an iterator.
+ *
+ * @param b the bson to append to.
+ * @param name_or_null the key for the BSON element, or NULL.
+ * @param elem the bson_iterator.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+EJDB_EXPORT int bson_append_element(bson *b, const char *name_or_null, const bson_iterator *elem);
+
+/**
+ * Append a bson_timestamp_t value to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the timestampe value.
+ * @param ts the bson_timestamp_t value to append.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+EJDB_EXPORT int bson_append_timestamp(bson *b, const char *name, bson_timestamp_t *ts);
+EJDB_EXPORT int bson_append_timestamp2(bson *b, const char *name, int time, int increment);
+
+/* these both append a bson_date */
+/**
+ * Append a bson_date_t value to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the date value.
+ * @param millis the bson_date_t to append.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+EJDB_EXPORT int bson_append_date(bson *b, const char *name, bson_date_t millis);
+
+/**
+ * Append a time_t value to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the date value.
+ * @param secs the time_t to append.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+EJDB_EXPORT int bson_append_time_t(bson *b, const char *name, time_t secs);
+
+/**
+ * Start appending a new object to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the name of the new object.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+EJDB_EXPORT int bson_append_start_object(bson *b, const char *name);
+EJDB_EXPORT int bson_append_start_object2(bson *b, const char *name, int namelen);
+
+/**
+ * Start appending a new array to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the name of the new array.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+EJDB_EXPORT int bson_append_start_array(bson *b, const char *name);
+EJDB_EXPORT int bson_append_start_array2(bson *b, const char *name, int namelen);
+
+/**
+ * Finish appending a new object or array to a bson.
+ *
+ * @param b the bson to append to.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+EJDB_EXPORT int bson_append_finish_object(bson *b);
+
+/**
+ * Finish appending a new object or array to a bson. This
+ * is simply an alias for bson_append_finish_object.
+ *
+ * @param b the bson to append to.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+EJDB_EXPORT int bson_append_finish_array(bson *b);
+
+EJDB_EXPORT void bson_numstr(char *str, int64_t i);
+EJDB_EXPORT int bson_numstrn(char *str, int maxbuf, int64_t i);
+
+//void bson_incnumstr(char *str);
+
+/* Error handling and standard library function over-riding. */
+/* -------------------------------------------------------- */
+
+/* bson_err_handlers shouldn't return!!! */
+typedef void( *bson_err_handler)(const char *errmsg);
+typedef int (*bson_printf_func)(const char *, ...);
+
+extern void *(*bson_malloc_func)(size_t);
+extern void *(*bson_realloc_func)(void *, size_t);
+extern void ( *bson_free_func)(void *);
+
+extern bson_printf_func bson_errprintf;
+
+void bson_free(void *ptr);
+
+/**
+ * Allocates memory and checks return value, exiting fatally if malloc() fails.
+ *
+ * @param size bytes to allocate.
+ *
+ * @return a pointer to the allocated memory.
+ *
+ * @sa malloc(3)
+ */
+void *bson_malloc(int size);
+
+/**
+ * Changes the size of allocated memory and checks return value,
+ * exiting fatally if realloc() fails.
+ *
+ * @param ptr pointer to the space to reallocate.
+ * @param size bytes to allocate.
+ *
+ * @return a pointer to the allocated memory.
+ *
+ * @sa realloc()
+ */
+void *bson_realloc(void *ptr, int size);
+
+/**
+ * Set a function for error handling.
+ *
+ * @param func a bson_err_handler function.
+ *
+ * @return the old error handling function, or NULL.
+ */
+EJDB_EXPORT bson_err_handler set_bson_err_handler(bson_err_handler func);
+
+/* does nothing if ok != 0 */
+/**
+ * Exit fatally.
+ *
+ * @param ok exits if ok is equal to 0.
+ */
+void bson_fatal(int ok);
+
+/**
+ * Exit fatally with an error message.
+ *
+ * @param ok exits if ok is equal to 0.
+ * @param msg prints to stderr before exiting.
+ */
+void bson_fatal_msg(int ok, const char *msg);
+
+/**
+ * Invoke the error handler, but do not exit.
+ *
+ * @param b the buffer object.
+ */
+void bson_builder_error(bson *b);
+
+/**
+ * Cast an int64_t to double. This is necessary for embedding in
+ * certain environments.
+ *
+ */
+EJDB_EXPORT double bson_int64_to_double(int64_t i64);
+EJDB_EXPORT void bson_swap_endian32(void *outp, const void *inp);
+EJDB_EXPORT void bson_swap_endian64(void *outp, const void *inp);
+
+
+/**
+ * Append current field from iterator into bson object.
+ *
+ * @param from
+ * @param into
+ * @return BSON_OK or BSON_ERROR.
+ */
+EJDB_EXPORT int bson_append_field_from_iterator(const bson_iterator *from, bson *into);
+
+/**
+ * Append current field value from iterator into bson object under specified string key.
+ *
+ * @param key Key name.
+ * @param from Source iterator value
+ * @param into Target bsob object
+ * @return BSON_OK or BSON_ERROR.
+ */
+EJDB_EXPORT int bson_append_field_from_iterator2(const char *key, const bson_iterator *from, bson *into);
+EJDB_EXPORT int bson_append_object_from_iterator(const char *key, bson_iterator *from, bson *into);
+EJDB_EXPORT int bson_append_array_from_iterator(const char *key, bson_iterator *from, bson *into);
+
+
+/**
+ * Merge bson `b2` into `b1` saving result the 'out' object.
+ * `b1` & `b2` bson must be finished BSONS.
+ * Resulting 'out' bson must be allocated and not finished.
+ *
+ * Nested object skipped and usupported.
+ *
+ * @param b1 BSON to to be merged in `out`
+ * @param b2 Second BSON to to be merged in `out`
+ * @param overwrite if `true` all `b1` fields will be overwriten by corresponding `b2` fields
+ * @param out
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+EJDB_EXPORT int bson_merge(const bson *b1, const bson *b2, bson_bool_t overwrite, bson *out);
+EJDB_EXPORT int bson_merge2(const void *b1data, const void *b2data, bson_bool_t overwrite, bson *out);
+
+/**
+ * Merge bsons.
+ * `bsdata2` may contain field path keys (eg: 'foo.bar').
+ * @param bsdata1 BSON data to to be merged in `out`
+ * @param bsdata2 Second BSON data to to be merged in `out`
+ * @param out Resulting `out` bson must be allocated and not finished.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+EJDB_EXPORT int bson_merge3(const void *bsdata1, const void *bsdata2, bson *out);
+
+EJDB_EXPORT int bson_inplace_set_bool(bson_iterator *pos, bson_bool_t val);
+EJDB_EXPORT int bson_inplace_set_long(bson_iterator *pos, int64_t val);
+EJDB_EXPORT int bson_inplace_set_double(bson_iterator *pos, double val);
+
+typedef struct {
+ TCMAP *ifields; //Required Map of fieldpaths. Map values are a simple boolean bufs.
+ bool imode; //Required If true fpaths will be included. Otherwise fpaths will be excluded from bson.
+ const void *bsbuf; //Required BSON buffer to process.
+ bson *bsout; //Required Allocated output not finished bson* object.
+ TCMAP *fkfields; //Optional: Map (fpath => bson key) used to force specific bson keys for selected fpaths.
+} BSONSTRIPCTX;
+
+/**
+ * Include or exclude fpaths in the specified BSON and put resulting data into `bsout`.
+ * On completion it finishes `bsout` object.
+ *
+ * @param ifields Map of fieldpaths. Map values are a simple boolean bufs.
+ * @param imode If true fpaths will be included. Otherwise fpaths will be excluded from bson.
+ * @param bsbuf BSON buffer to process.
+ * @param bsout Allocated output not finished bson* object
+ * @return BSON error code
+ */
+EJDB_EXPORT int bson_strip(TCMAP *ifields, bool imode, const void *bsbuf, bson *bsout);
+EJDB_EXPORT int bson_strip2(BSONSTRIPCTX *sctx);
+
+
+/**
+ * Compares field path primitive values of two BSONs
+ * @param bsdata1 BSON raw data
+ * @param bsdata2 BSON raw data
+ * @param fpath Field path to the field
+ * @param fplen Length of fpath value
+ */
+EJDB_EXPORT int bson_compare(const void *bsdata1, const void *bsdata2, const char* fpath, int fplen);
+EJDB_EXPORT int bson_compare_fpaths(const void *bsdata1, const void *bsdata2, const char *fpath1, int fplen1, const char *fpath2, int fplen2);
+EJDB_EXPORT int bson_compare_it_current(const bson_iterator *it1, const bson_iterator *it2);
+EJDB_EXPORT int bson_compare_string(const char* cv, const void *bsdata, const char *fpath);
+EJDB_EXPORT int bson_compare_long(long cv, const void *bsdata, const char *fpath);
+EJDB_EXPORT int bson_compare_double(double cv, const void *bsdata, const char *fpath);
+EJDB_EXPORT int bson_compare_bool(bson_bool_t cv, const void *bsdata, const char *fpath);
+
+
+/**
+ * Duplicates BSON object.
+ * @param src BSON
+ * @return Finished copy of src
+ */
+EJDB_EXPORT bson* bson_dup(const bson *src);
+
+
+EJDB_EXPORT bson* bson_create_from_iterator(bson_iterator *from);
+EJDB_EXPORT bson* bson_create_from_buffer(const void *buf, int bufsz);
+EJDB_EXPORT bson* bson_create_from_buffer2(bson *bs, const void *buf, int bufsz);
+EJDB_EXPORT void bson_init_with_data(bson *bs, const void *bsdata);
+
+EJDB_EXPORT bool bson_find_unmerged_array_sets(const void *mbuf, const void *inbuf);
+EJDB_EXPORT bool bson_find_merged_array_sets(const void *mbuf, const void *inbuf, bool expandall);
+EJDB_EXPORT int bson_merge_array_sets(const void *mbuf, const void *inbuf, bool pull, bool expandall, bson *bsout);
+
+
+/**
+ * Convert BSON into JSON buffer.
+ * @param src BSON data
+ * @param buf Allocated buffer with resulting JSON data
+ * @param sp JSON data length will be stored into
+ * @return BSON_OK or BSON_ERROR
+ */
+EJDB_EXPORT int bson2json(const char *bsdata, char **buf, int *sp);
+
+/**
+ * Convert JSON into BSON object.
+ * @param jsonstr NULL terminated JSON string
+ * @return Allocated BSON object filled with given JSON data or NULL on error
+ */
+EJDB_EXPORT bson* json2bson(const char *jsonstr);
+
+
+EJDB_EXTERN_C_END
+#endif