summaryrefslogtreecommitdiff
path: root/src/mongo/bson/bsonobjbuilder.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/bson/bsonobjbuilder.h')
-rw-r--r--src/mongo/bson/bsonobjbuilder.h1591
1 files changed, 816 insertions, 775 deletions
diff --git a/src/mongo/bson/bsonobjbuilder.h b/src/mongo/bson/bsonobjbuilder.h
index 4ca65d75693..76ed3f60ec8 100644
--- a/src/mongo/bson/bsonobjbuilder.h
+++ b/src/mongo/bson/bsonobjbuilder.h
@@ -50,918 +50,959 @@ namespace mongo {
#if defined(_WIN32)
// warning: 'this' : used in base member initializer list
-#pragma warning( disable : 4355 )
+#pragma warning(disable : 4355)
#endif
- /** Utility for creating a BSONObj.
- See also the BSON() and BSON_ARRAY() macros.
- */
- class BSONObjBuilder {
- MONGO_DISALLOW_COPYING(BSONObjBuilder);
- public:
- /** @param initsize this is just a hint as to the final size of the object */
- BSONObjBuilder(int initsize=512)
- : _b(_buf)
- , _buf(sizeof(BSONObj::Holder) + initsize)
- , _offset(sizeof(BSONObj::Holder))
- , _s(this)
- , _tracker(0)
- , _doneCalled(false) {
- // Skip over space for a holder object at the beginning of the buffer, followed by
- // space for the object length. The length is filled in by _done.
- _b.skip(sizeof(BSONObj::Holder));
- _b.skip(sizeof(int));
-
- // Reserve space for the EOO byte. This means _done() can't fail.
- _b.reserveBytes(1);
- }
+/** Utility for creating a BSONObj.
+ See also the BSON() and BSON_ARRAY() macros.
+*/
+class BSONObjBuilder {
+ MONGO_DISALLOW_COPYING(BSONObjBuilder);
+
+public:
+ /** @param initsize this is just a hint as to the final size of the object */
+ BSONObjBuilder(int initsize = 512)
+ : _b(_buf),
+ _buf(sizeof(BSONObj::Holder) + initsize),
+ _offset(sizeof(BSONObj::Holder)),
+ _s(this),
+ _tracker(0),
+ _doneCalled(false) {
+ // Skip over space for a holder object at the beginning of the buffer, followed by
+ // space for the object length. The length is filled in by _done.
+ _b.skip(sizeof(BSONObj::Holder));
+ _b.skip(sizeof(int));
+
+ // Reserve space for the EOO byte. This means _done() can't fail.
+ _b.reserveBytes(1);
+ }
- /** @param baseBuilder construct a BSONObjBuilder using an existing BufBuilder
- * This is for more efficient adding of subobjects/arrays. See docs for subobjStart for example.
- */
- BSONObjBuilder(BufBuilder &baseBuilder)
- : _b(baseBuilder)
- , _buf(0)
- , _offset(baseBuilder.len())
- , _s(this)
- , _tracker(0)
- , _doneCalled(false) {
- // Skip over space for the object length, which is filled in by _done. We don't need a
- // holder since we are a sub-builder, and some parent builder has already made the
- // reservation.
- _b.skip(sizeof(int));
-
- // Reserve space for the EOO byte. This means _done() can't fail.
- _b.reserveBytes(1);
- }
+ /** @param baseBuilder construct a BSONObjBuilder using an existing BufBuilder
+ * This is for more efficient adding of subobjects/arrays. See docs for subobjStart for example.
+ */
+ BSONObjBuilder(BufBuilder& baseBuilder)
+ : _b(baseBuilder),
+ _buf(0),
+ _offset(baseBuilder.len()),
+ _s(this),
+ _tracker(0),
+ _doneCalled(false) {
+ // Skip over space for the object length, which is filled in by _done. We don't need a
+ // holder since we are a sub-builder, and some parent builder has already made the
+ // reservation.
+ _b.skip(sizeof(int));
+
+ // Reserve space for the EOO byte. This means _done() can't fail.
+ _b.reserveBytes(1);
+ }
- BSONObjBuilder( const BSONSizeTracker & tracker )
- : _b(_buf)
- , _buf(sizeof(BSONObj::Holder) + tracker.getSize())
- , _offset(sizeof(BSONObj::Holder))
- , _s(this)
- , _tracker(const_cast<BSONSizeTracker*>(&tracker))
- , _doneCalled(false) {
- // See the comments in the first constructor for details.
- _b.skip(sizeof(BSONObj::Holder));
- _b.skip(sizeof(int));
-
- // Reserve space for the EOO byte. This means _done() can't fail.
- _b.reserveBytes(1);
- }
+ BSONObjBuilder(const BSONSizeTracker& tracker)
+ : _b(_buf),
+ _buf(sizeof(BSONObj::Holder) + tracker.getSize()),
+ _offset(sizeof(BSONObj::Holder)),
+ _s(this),
+ _tracker(const_cast<BSONSizeTracker*>(&tracker)),
+ _doneCalled(false) {
+ // See the comments in the first constructor for details.
+ _b.skip(sizeof(BSONObj::Holder));
+ _b.skip(sizeof(int));
+
+ // Reserve space for the EOO byte. This means _done() can't fail.
+ _b.reserveBytes(1);
+ }
- ~BSONObjBuilder() {
- // If 'done' has not already been called, and we have a reference to an owning
- // BufBuilder but do not own it ourselves, then we must call _done to write in the
- // length. Otherwise, we own this memory and its lifetime ends with us, therefore
- // we can elide the write.
- if ( !_doneCalled && _b.buf() && _buf.getSize() == 0 ) {
- _done();
- }
+ ~BSONObjBuilder() {
+ // If 'done' has not already been called, and we have a reference to an owning
+ // BufBuilder but do not own it ourselves, then we must call _done to write in the
+ // length. Otherwise, we own this memory and its lifetime ends with us, therefore
+ // we can elide the write.
+ if (!_doneCalled && _b.buf() && _buf.getSize() == 0) {
+ _done();
}
+ }
- /** add all the fields from the object specified to this object */
- BSONObjBuilder& appendElements(BSONObj x);
-
- /** add all the fields from the object specified to this object if they don't exist already */
- BSONObjBuilder& appendElementsUnique( BSONObj x );
-
- /** append element to the object we are building */
- BSONObjBuilder& append( const BSONElement& e) {
- verify( !e.eoo() ); // do not append eoo, that would corrupt us. the builder auto appends when done() is called.
- _b.appendBuf((void*) e.rawdata(), e.size());
- return *this;
- }
+ /** add all the fields from the object specified to this object */
+ BSONObjBuilder& appendElements(BSONObj x);
- /** append an element but with a new name */
- BSONObjBuilder& appendAs(const BSONElement& e, StringData fieldName) {
- verify( !e.eoo() ); // do not append eoo, that would corrupt us. the builder auto appends when done() is called.
- _b.appendNum((char) e.type());
- _b.appendStr(fieldName);
- _b.appendBuf((void *) e.value(), e.valuesize());
- return *this;
- }
+ /** add all the fields from the object specified to this object if they don't exist already */
+ BSONObjBuilder& appendElementsUnique(BSONObj x);
- /** add a subobject as a member */
- BSONObjBuilder& append(StringData fieldName, BSONObj subObj) {
- _b.appendNum((char) Object);
- _b.appendStr(fieldName);
- _b.appendBuf((void *) subObj.objdata(), subObj.objsize());
- return *this;
- }
+ /** append element to the object we are building */
+ BSONObjBuilder& append(const BSONElement& e) {
+ verify(
+ !e.eoo()); // do not append eoo, that would corrupt us. the builder auto appends when done() is called.
+ _b.appendBuf((void*)e.rawdata(), e.size());
+ return *this;
+ }
- /** add a subobject as a member */
- BSONObjBuilder& appendObject(StringData fieldName, const char * objdata , int size = 0 ) {
- verify( objdata );
- if ( size == 0 ) {
- size = ConstDataView(objdata).read<LittleEndian<int>>();
- }
+ /** append an element but with a new name */
+ BSONObjBuilder& appendAs(const BSONElement& e, StringData fieldName) {
+ verify(
+ !e.eoo()); // do not append eoo, that would corrupt us. the builder auto appends when done() is called.
+ _b.appendNum((char)e.type());
+ _b.appendStr(fieldName);
+ _b.appendBuf((void*)e.value(), e.valuesize());
+ return *this;
+ }
- verify( size > 4 && size < 100000000 );
+ /** add a subobject as a member */
+ BSONObjBuilder& append(StringData fieldName, BSONObj subObj) {
+ _b.appendNum((char)Object);
+ _b.appendStr(fieldName);
+ _b.appendBuf((void*)subObj.objdata(), subObj.objsize());
+ return *this;
+ }
- _b.appendNum((char) Object);
- _b.appendStr(fieldName);
- _b.appendBuf((void*)objdata, size );
- return *this;
+ /** add a subobject as a member */
+ BSONObjBuilder& appendObject(StringData fieldName, const char* objdata, int size = 0) {
+ verify(objdata);
+ if (size == 0) {
+ size = ConstDataView(objdata).read<LittleEndian<int>>();
}
- /** add header for a new subobject and return bufbuilder for writing to
- * the subobject's body
- *
- * example:
- *
- * BSONObjBuilder b;
- * BSONObjBuilder sub (b.subobjStart("fieldName"));
- * // use sub
- * sub.done()
- * // use b and convert to object
- */
- BufBuilder &subobjStart(StringData fieldName) {
- _b.appendNum((char) Object);
- _b.appendStr(fieldName);
- return _b;
- }
+ verify(size > 4 && size < 100000000);
- /** add a subobject as a member with type Array. Thus arr object should have "0", "1", ...
- style fields in it.
- */
- BSONObjBuilder& appendArray(StringData fieldName, const BSONObj &subObj) {
- _b.appendNum((char) Array);
- _b.appendStr(fieldName);
- _b.appendBuf((void *) subObj.objdata(), subObj.objsize());
- return *this;
- }
- BSONObjBuilder& append(StringData fieldName, BSONArray arr) {
- return appendArray(fieldName, arr);
- }
+ _b.appendNum((char)Object);
+ _b.appendStr(fieldName);
+ _b.appendBuf((void*)objdata, size);
+ return *this;
+ }
- /** add header for a new subarray and return bufbuilder for writing to
- the subarray's body */
- BufBuilder &subarrayStart(StringData fieldName) {
- _b.appendNum((char) Array);
- _b.appendStr(fieldName);
- return _b;
- }
+ /** add header for a new subobject and return bufbuilder for writing to
+ * the subobject's body
+ *
+ * example:
+ *
+ * BSONObjBuilder b;
+ * BSONObjBuilder sub (b.subobjStart("fieldName"));
+ * // use sub
+ * sub.done()
+ * // use b and convert to object
+ */
+ BufBuilder& subobjStart(StringData fieldName) {
+ _b.appendNum((char)Object);
+ _b.appendStr(fieldName);
+ return _b;
+ }
- /** Append a boolean element */
- BSONObjBuilder& appendBool(StringData fieldName, int val) {
- _b.appendNum((char) Bool);
- _b.appendStr(fieldName);
- _b.appendNum((char) (val?1:0));
- return *this;
- }
+ /** add a subobject as a member with type Array. Thus arr object should have "0", "1", ...
+ style fields in it.
+ */
+ BSONObjBuilder& appendArray(StringData fieldName, const BSONObj& subObj) {
+ _b.appendNum((char)Array);
+ _b.appendStr(fieldName);
+ _b.appendBuf((void*)subObj.objdata(), subObj.objsize());
+ return *this;
+ }
+ BSONObjBuilder& append(StringData fieldName, BSONArray arr) {
+ return appendArray(fieldName, arr);
+ }
- /** Append a boolean element */
- BSONObjBuilder& append(StringData fieldName, bool val) {
- _b.appendNum((char) Bool);
- _b.appendStr(fieldName);
- _b.appendNum((char) (val?1:0));
- return *this;
- }
+ /** add header for a new subarray and return bufbuilder for writing to
+ the subarray's body */
+ BufBuilder& subarrayStart(StringData fieldName) {
+ _b.appendNum((char)Array);
+ _b.appendStr(fieldName);
+ return _b;
+ }
- /** Append a 32 bit integer element */
- BSONObjBuilder& append(StringData fieldName, int n) {
- _b.appendNum((char) NumberInt);
- _b.appendStr(fieldName);
- _b.appendNum(n);
- return *this;
- }
+ /** Append a boolean element */
+ BSONObjBuilder& appendBool(StringData fieldName, int val) {
+ _b.appendNum((char)Bool);
+ _b.appendStr(fieldName);
+ _b.appendNum((char)(val ? 1 : 0));
+ return *this;
+ }
- /** Append a 32 bit unsigned element - cast to a signed int. */
- BSONObjBuilder& append(StringData fieldName, unsigned n) {
- return append(fieldName, (int) n);
- }
+ /** Append a boolean element */
+ BSONObjBuilder& append(StringData fieldName, bool val) {
+ _b.appendNum((char)Bool);
+ _b.appendStr(fieldName);
+ _b.appendNum((char)(val ? 1 : 0));
+ return *this;
+ }
- /** Append a NumberLong */
- BSONObjBuilder& append(StringData fieldName, long long n) {
- _b.appendNum((char) NumberLong);
- _b.appendStr(fieldName);
- _b.appendNum(n);
- return *this;
- }
+ /** Append a 32 bit integer element */
+ BSONObjBuilder& append(StringData fieldName, int n) {
+ _b.appendNum((char)NumberInt);
+ _b.appendStr(fieldName);
+ _b.appendNum(n);
+ return *this;
+ }
- /** appends a number. if n < max(int)/2 then uses int, otherwise long long */
- BSONObjBuilder& appendIntOrLL( StringData fieldName , long long n ) {
- // extra () to avoid max macro on windows
- static const long long maxInt = (std::numeric_limits<int>::max)() / 2;
- static const long long minInt = -maxInt;
- if ( minInt < n && n < maxInt ) {
- append( fieldName , static_cast<int>( n ) );
- }
- else {
- append( fieldName , n );
- }
- return *this;
- }
+ /** Append a 32 bit unsigned element - cast to a signed int. */
+ BSONObjBuilder& append(StringData fieldName, unsigned n) {
+ return append(fieldName, (int)n);
+ }
- /**
- * appendNumber is a series of method for appending the smallest sensible type
- * mostly for JS
- */
- BSONObjBuilder& appendNumber( StringData fieldName , int n ) {
- return append( fieldName , n );
- }
+ /** Append a NumberLong */
+ BSONObjBuilder& append(StringData fieldName, long long n) {
+ _b.appendNum((char)NumberLong);
+ _b.appendStr(fieldName);
+ _b.appendNum(n);
+ return *this;
+ }
- BSONObjBuilder& appendNumber( StringData fieldName , double d ) {
- return append( fieldName , d );
+ /** appends a number. if n < max(int)/2 then uses int, otherwise long long */
+ BSONObjBuilder& appendIntOrLL(StringData fieldName, long long n) {
+ // extra () to avoid max macro on windows
+ static const long long maxInt = (std::numeric_limits<int>::max)() / 2;
+ static const long long minInt = -maxInt;
+ if (minInt < n && n < maxInt) {
+ append(fieldName, static_cast<int>(n));
+ } else {
+ append(fieldName, n);
}
+ return *this;
+ }
- BSONObjBuilder& appendNumber( StringData fieldName , size_t n ) {
- static const size_t maxInt = ( 1 << 30 );
+ /**
+ * appendNumber is a series of method for appending the smallest sensible type
+ * mostly for JS
+ */
+ BSONObjBuilder& appendNumber(StringData fieldName, int n) {
+ return append(fieldName, n);
+ }
- if ( n < maxInt )
- append( fieldName, static_cast<int>( n ) );
- else
- append( fieldName, static_cast<long long>( n ) );
- return *this;
- }
+ BSONObjBuilder& appendNumber(StringData fieldName, double d) {
+ return append(fieldName, d);
+ }
- BSONObjBuilder& appendNumber( StringData fieldName, long long llNumber ) {
- static const long long maxInt = ( 1LL << 30 );
- static const long long minInt = -maxInt;
- static const long long maxDouble = ( 1LL << 40 );
- static const long long minDouble = -maxDouble;
-
- if ( minInt < llNumber && llNumber < maxInt ) {
- append( fieldName, static_cast<int>( llNumber ) );
- }
- else if ( minDouble < llNumber && llNumber < maxDouble ) {
- append( fieldName, static_cast<double>( llNumber ) );
- }
- else {
- append( fieldName, llNumber );
- }
-
- return *this;
- }
+ BSONObjBuilder& appendNumber(StringData fieldName, size_t n) {
+ static const size_t maxInt = (1 << 30);
- /** Append a double element */
- BSONObjBuilder& append(StringData fieldName, double n) {
- _b.appendNum((char) NumberDouble);
- _b.appendStr(fieldName);
- _b.appendNum(n);
- return *this;
- }
+ if (n < maxInt)
+ append(fieldName, static_cast<int>(n));
+ else
+ append(fieldName, static_cast<long long>(n));
+ return *this;
+ }
- /** tries to append the data as a number
- * @return true if the data was able to be converted to a number
- */
- bool appendAsNumber( StringData fieldName , const std::string& data );
-
- /** Append a BSON Object ID (OID type).
- @deprecated Generally, it is preferred to use the append append(name, oid)
- method for this.
- */
- BSONObjBuilder& appendOID(StringData fieldName, OID *oid = 0 , bool generateIfBlank = false ) {
- _b.appendNum((char) jstOID);
- _b.appendStr(fieldName);
- if ( oid )
- _b.appendBuf( oid->view().view(), OID::kOIDSize );
- else {
- OID tmp;
- if ( generateIfBlank )
- tmp.init();
- else
- tmp.clear();
- _b.appendBuf( tmp.view().view(), OID::kOIDSize );
- }
- return *this;
- }
+ BSONObjBuilder& appendNumber(StringData fieldName, long long llNumber) {
+ static const long long maxInt = (1LL << 30);
+ static const long long minInt = -maxInt;
+ static const long long maxDouble = (1LL << 40);
+ static const long long minDouble = -maxDouble;
- /**
- Append a BSON Object ID.
- @param fieldName Field name, e.g., "_id".
- @returns the builder object
- */
- BSONObjBuilder& append( StringData fieldName, OID oid ) {
- _b.appendNum((char) jstOID);
- _b.appendStr(fieldName);
- _b.appendBuf( oid.view().view(), OID::kOIDSize );
- return *this;
+ if (minInt < llNumber && llNumber < maxInt) {
+ append(fieldName, static_cast<int>(llNumber));
+ } else if (minDouble < llNumber && llNumber < maxDouble) {
+ append(fieldName, static_cast<double>(llNumber));
+ } else {
+ append(fieldName, llNumber);
}
- /**
- Generate and assign an object id for the _id field.
- _id should be the first element in the object for good performance.
- */
- BSONObjBuilder& genOID() {
- return append("_id", OID::gen());
- }
+ return *this;
+ }
- /** Append a time_t date.
- @param dt a C-style 32 bit date value, that is
- the number of seconds since January 1, 1970, 00:00:00 GMT
- */
- BSONObjBuilder& appendTimeT(StringData fieldName, time_t dt) {
- _b.appendNum((char) Date);
- _b.appendStr(fieldName);
- _b.appendNum(static_cast<unsigned long long>(dt) * 1000);
- return *this;
- }
- /** Append a date.
- @param dt a Java-style 64 bit date value, that is
- the number of milliseconds since January 1, 1970, 00:00:00 GMT
- */
- BSONObjBuilder& appendDate(StringData fieldName, Date_t dt);
- BSONObjBuilder& append(StringData fieldName, Date_t dt) {
- return appendDate(fieldName, dt);
- }
+ /** Append a double element */
+ BSONObjBuilder& append(StringData fieldName, double n) {
+ _b.appendNum((char)NumberDouble);
+ _b.appendStr(fieldName);
+ _b.appendNum(n);
+ return *this;
+ }
- /** Append a regular expression value
- @param regex the regular expression pattern
- @param regex options such as "i" or "g"
- */
- BSONObjBuilder& appendRegex(StringData fieldName, StringData regex, StringData options = "") {
- _b.appendNum((char) RegEx);
- _b.appendStr(fieldName);
- _b.appendStr(regex);
- _b.appendStr(options);
- return *this;
- }
+ /** tries to append the data as a number
+ * @return true if the data was able to be converted to a number
+ */
+ bool appendAsNumber(StringData fieldName, const std::string& data);
- BSONObjBuilder& append(StringData fieldName, const BSONRegEx& regex) {
- return appendRegex(fieldName, regex.pattern, regex.flags);
+ /** Append a BSON Object ID (OID type).
+ @deprecated Generally, it is preferred to use the append append(name, oid)
+ method for this.
+ */
+ BSONObjBuilder& appendOID(StringData fieldName, OID* oid = 0, bool generateIfBlank = false) {
+ _b.appendNum((char)jstOID);
+ _b.appendStr(fieldName);
+ if (oid)
+ _b.appendBuf(oid->view().view(), OID::kOIDSize);
+ else {
+ OID tmp;
+ if (generateIfBlank)
+ tmp.init();
+ else
+ tmp.clear();
+ _b.appendBuf(tmp.view().view(), OID::kOIDSize);
}
+ return *this;
+ }
- BSONObjBuilder& appendCode(StringData fieldName, StringData code) {
- _b.appendNum((char) Code);
- _b.appendStr(fieldName);
- _b.appendNum((int) code.size()+1);
- _b.appendStr(code);
- return *this;
- }
+ /**
+ Append a BSON Object ID.
+ @param fieldName Field name, e.g., "_id".
+ @returns the builder object
+ */
+ BSONObjBuilder& append(StringData fieldName, OID oid) {
+ _b.appendNum((char)jstOID);
+ _b.appendStr(fieldName);
+ _b.appendBuf(oid.view().view(), OID::kOIDSize);
+ return *this;
+ }
- BSONObjBuilder& append(StringData fieldName, const BSONCode& code) {
- return appendCode(fieldName, code.code);
- }
+ /**
+ Generate and assign an object id for the _id field.
+ _id should be the first element in the object for good performance.
+ */
+ BSONObjBuilder& genOID() {
+ return append("_id", OID::gen());
+ }
- /** Append a std::string element.
- @param sz size includes terminating null character */
- BSONObjBuilder& append(StringData fieldName, const char *str, int sz) {
- _b.appendNum((char) String);
- _b.appendStr(fieldName);
- _b.appendNum((int)sz);
- _b.appendBuf(str, sz);
- return *this;
- }
- /** Append a std::string element */
- BSONObjBuilder& append(StringData fieldName, const char *str) {
- return append(fieldName, str, (int) strlen(str)+1);
- }
- /** Append a std::string element */
- BSONObjBuilder& append(StringData fieldName, const std::string& str) {
- return append(fieldName, str.c_str(), (int) str.size()+1);
- }
- /** Append a std::string element */
- BSONObjBuilder& append(StringData fieldName, StringData str) {
- _b.appendNum((char) String);
- _b.appendStr(fieldName);
- _b.appendNum((int)str.size()+1);
- _b.appendStr(str, true);
- return *this;
- }
+ /** Append a time_t date.
+ @param dt a C-style 32 bit date value, that is
+ the number of seconds since January 1, 1970, 00:00:00 GMT
+ */
+ BSONObjBuilder& appendTimeT(StringData fieldName, time_t dt) {
+ _b.appendNum((char)Date);
+ _b.appendStr(fieldName);
+ _b.appendNum(static_cast<unsigned long long>(dt) * 1000);
+ return *this;
+ }
+ /** Append a date.
+ @param dt a Java-style 64 bit date value, that is
+ the number of milliseconds since January 1, 1970, 00:00:00 GMT
+ */
+ BSONObjBuilder& appendDate(StringData fieldName, Date_t dt);
+ BSONObjBuilder& append(StringData fieldName, Date_t dt) {
+ return appendDate(fieldName, dt);
+ }
- BSONObjBuilder& appendSymbol(StringData fieldName, StringData symbol) {
- _b.appendNum((char) Symbol);
- _b.appendStr(fieldName);
- _b.appendNum((int) symbol.size()+1);
- _b.appendStr(symbol);
- return *this;
- }
+ /** Append a regular expression value
+ @param regex the regular expression pattern
+ @param regex options such as "i" or "g"
+ */
+ BSONObjBuilder& appendRegex(StringData fieldName, StringData regex, StringData options = "") {
+ _b.appendNum((char)RegEx);
+ _b.appendStr(fieldName);
+ _b.appendStr(regex);
+ _b.appendStr(options);
+ return *this;
+ }
- BSONObjBuilder& append(StringData fieldName, const BSONSymbol& symbol) {
- return appendSymbol(fieldName, symbol.symbol);
- }
+ BSONObjBuilder& append(StringData fieldName, const BSONRegEx& regex) {
+ return appendRegex(fieldName, regex.pattern, regex.flags);
+ }
- /** Implements builder interface but no-op in ObjBuilder */
- void appendNull() {
- msgasserted(16234, "Invalid call to appendNull in BSONObj Builder.");
- }
+ BSONObjBuilder& appendCode(StringData fieldName, StringData code) {
+ _b.appendNum((char)Code);
+ _b.appendStr(fieldName);
+ _b.appendNum((int)code.size() + 1);
+ _b.appendStr(code);
+ return *this;
+ }
- /** Append a Null element to the object */
- BSONObjBuilder& appendNull( StringData fieldName ) {
- _b.appendNum( (char) jstNULL );
- _b.appendStr( fieldName );
- return *this;
- }
+ BSONObjBuilder& append(StringData fieldName, const BSONCode& code) {
+ return appendCode(fieldName, code.code);
+ }
- // Append an element that is less than all other keys.
- BSONObjBuilder& appendMinKey( StringData fieldName ) {
- _b.appendNum( (char) MinKey );
- _b.appendStr( fieldName );
- return *this;
- }
- // Append an element that is greater than all other keys.
- BSONObjBuilder& appendMaxKey( StringData fieldName ) {
- _b.appendNum( (char) MaxKey );
- _b.appendStr( fieldName );
- return *this;
- }
+ /** Append a std::string element.
+ @param sz size includes terminating null character */
+ BSONObjBuilder& append(StringData fieldName, const char* str, int sz) {
+ _b.appendNum((char)String);
+ _b.appendStr(fieldName);
+ _b.appendNum((int)sz);
+ _b.appendBuf(str, sz);
+ return *this;
+ }
+ /** Append a std::string element */
+ BSONObjBuilder& append(StringData fieldName, const char* str) {
+ return append(fieldName, str, (int)strlen(str) + 1);
+ }
+ /** Append a std::string element */
+ BSONObjBuilder& append(StringData fieldName, const std::string& str) {
+ return append(fieldName, str.c_str(), (int)str.size() + 1);
+ }
+ /** Append a std::string element */
+ BSONObjBuilder& append(StringData fieldName, StringData str) {
+ _b.appendNum((char)String);
+ _b.appendStr(fieldName);
+ _b.appendNum((int)str.size() + 1);
+ _b.appendStr(str, true);
+ return *this;
+ }
- // Append a Timestamp field -- will be updated to next server Timestamp
- BSONObjBuilder& appendTimestamp( StringData fieldName );
-
- BSONObjBuilder& appendTimestamp( StringData fieldName , unsigned long long val );
-
- /**
- * To store a Timestamp in BSON, use this function.
- * This captures both the secs and inc fields.
- */
- BSONObjBuilder& append(StringData fieldName, Timestamp timestamp);
-
- /*
- Append an element of the deprecated DBRef type.
- @deprecated
- */
- BSONObjBuilder& appendDBRef( StringData fieldName, StringData ns, const OID &oid ) {
- _b.appendNum( (char) DBRef );
- _b.appendStr( fieldName );
- _b.appendNum( (int) ns.size() + 1 );
- _b.appendStr( ns );
- _b.appendBuf( oid.view().view(), OID::kOIDSize );
- return *this;
- }
+ BSONObjBuilder& appendSymbol(StringData fieldName, StringData symbol) {
+ _b.appendNum((char)Symbol);
+ _b.appendStr(fieldName);
+ _b.appendNum((int)symbol.size() + 1);
+ _b.appendStr(symbol);
+ return *this;
+ }
- BSONObjBuilder& append(StringData fieldName, const BSONDBRef& dbref) {
- return appendDBRef(fieldName, dbref.ns, dbref.oid);
- }
+ BSONObjBuilder& append(StringData fieldName, const BSONSymbol& symbol) {
+ return appendSymbol(fieldName, symbol.symbol);
+ }
- /** Append a binary data element
- @param fieldName name of the field
- @param len length of the binary data in bytes
- @param subtype subtype information for the data. @see enum BinDataType in bsontypes.h.
- Use BinDataGeneral if you don't care about the type.
- @param data the byte array
- */
- BSONObjBuilder& appendBinData( StringData fieldName, int len, BinDataType type, const void *data ) {
- _b.appendNum( (char) BinData );
- _b.appendStr( fieldName );
- _b.appendNum( len );
- _b.appendNum( (char) type );
- _b.appendBuf( data, len );
- return *this;
- }
+ /** Implements builder interface but no-op in ObjBuilder */
+ void appendNull() {
+ msgasserted(16234, "Invalid call to appendNull in BSONObj Builder.");
+ }
- BSONObjBuilder& append(StringData fieldName, const BSONBinData& bd) {
- return appendBinData(fieldName, bd.length, bd.type, bd.data);
- }
+ /** Append a Null element to the object */
+ BSONObjBuilder& appendNull(StringData fieldName) {
+ _b.appendNum((char)jstNULL);
+ _b.appendStr(fieldName);
+ return *this;
+ }
- /**
- Subtype 2 is deprecated.
- Append a BSON bindata bytearray element.
- @param data a byte array
- @param len the length of data
- */
- BSONObjBuilder& appendBinDataArrayDeprecated( const char * fieldName , const void * data , int len ) {
- _b.appendNum( (char) BinData );
- _b.appendStr( fieldName );
- _b.appendNum( len + 4 );
- _b.appendNum( (char)0x2 );
- _b.appendNum( len );
- _b.appendBuf( data, len );
- return *this;
- }
+ // Append an element that is less than all other keys.
+ BSONObjBuilder& appendMinKey(StringData fieldName) {
+ _b.appendNum((char)MinKey);
+ _b.appendStr(fieldName);
+ return *this;
+ }
+ // Append an element that is greater than all other keys.
+ BSONObjBuilder& appendMaxKey(StringData fieldName) {
+ _b.appendNum((char)MaxKey);
+ _b.appendStr(fieldName);
+ return *this;
+ }
- /** Append to the BSON object a field of type CodeWScope. This is a javascript code
- fragment accompanied by some scope that goes with it.
- */
- BSONObjBuilder& appendCodeWScope( StringData fieldName, StringData code, const BSONObj &scope ) {
- _b.appendNum( (char) CodeWScope );
- _b.appendStr( fieldName );
- _b.appendNum( ( int )( 4 + 4 + code.size() + 1 + scope.objsize() ) );
- _b.appendNum( ( int ) code.size() + 1 );
- _b.appendStr( code );
- _b.appendBuf( ( void * )scope.objdata(), scope.objsize() );
- return *this;
- }
+ // Append a Timestamp field -- will be updated to next server Timestamp
+ BSONObjBuilder& appendTimestamp(StringData fieldName);
- BSONObjBuilder& append(StringData fieldName, const BSONCodeWScope& cws) {
- return appendCodeWScope(fieldName, cws.code, cws.scope);
- }
+ BSONObjBuilder& appendTimestamp(StringData fieldName, unsigned long long val);
- void appendUndefined( StringData fieldName ) {
- _b.appendNum( (char) Undefined );
- _b.appendStr( fieldName );
- }
+ /**
+ * To store a Timestamp in BSON, use this function.
+ * This captures both the secs and inc fields.
+ */
+ BSONObjBuilder& append(StringData fieldName, Timestamp timestamp);
- /* helper function -- see Query::where() for primary way to do this. */
- void appendWhere( StringData code, const BSONObj &scope ) {
- appendCodeWScope( "$where" , code , scope );
- }
+ /*
+ Append an element of the deprecated DBRef type.
+ @deprecated
+ */
+ BSONObjBuilder& appendDBRef(StringData fieldName, StringData ns, const OID& oid) {
+ _b.appendNum((char)DBRef);
+ _b.appendStr(fieldName);
+ _b.appendNum((int)ns.size() + 1);
+ _b.appendStr(ns);
+ _b.appendBuf(oid.view().view(), OID::kOIDSize);
+ return *this;
+ }
- /**
- these are the min/max when comparing, not strict min/max elements for a given type
- */
- void appendMinForType( StringData fieldName , int type );
- void appendMaxForType( StringData fieldName , int type );
-
- /** Append an array of values. */
- template < class T >
- BSONObjBuilder& append( StringData fieldName, const std::vector< T >& vals );
-
- template < class T >
- BSONObjBuilder& append( StringData fieldName, const std::list< T >& vals );
-
- /** Append a set of values. */
- template < class T >
- BSONObjBuilder& append( StringData fieldName, const std::set< T >& vals );
-
- /**
- * Append a map of values as a sub-object.
- * Note: the keys of the map should be StringData-compatible (i.e. strings).
- */
- template < class K, class T >
- BSONObjBuilder& append( StringData fieldName, const std::map< K, T >& vals );
-
- /**
- * destructive
- * The returned BSONObj will free the buffer when it is finished.
- * @return owned BSONObj
- */
- BSONObj obj() {
- massert( 10335 , "builder does not own memory", owned() );
- doneFast();
- char* buf = _b.buf();
- decouple();
- return BSONObj::takeOwnership(buf);
- }
+ BSONObjBuilder& append(StringData fieldName, const BSONDBRef& dbref) {
+ return appendDBRef(fieldName, dbref.ns, dbref.oid);
+ }
- /** Fetch the object we have built.
- BSONObjBuilder still frees the object when the builder goes out of
- scope -- very important to keep in mind. Use obj() if you
- would like the BSONObj to last longer than the builder.
- */
- BSONObj done() {
- return BSONObj(_done());
- }
+ /** Append a binary data element
+ @param fieldName name of the field
+ @param len length of the binary data in bytes
+ @param subtype subtype information for the data. @see enum BinDataType in bsontypes.h.
+ Use BinDataGeneral if you don't care about the type.
+ @param data the byte array
+ */
+ BSONObjBuilder& appendBinData(StringData fieldName,
+ int len,
+ BinDataType type,
+ const void* data) {
+ _b.appendNum((char)BinData);
+ _b.appendStr(fieldName);
+ _b.appendNum(len);
+ _b.appendNum((char)type);
+ _b.appendBuf(data, len);
+ return *this;
+ }
- // Like 'done' above, but does not construct a BSONObj to return to the caller.
- void doneFast() {
- (void)_done();
- }
+ BSONObjBuilder& append(StringData fieldName, const BSONBinData& bd) {
+ return appendBinData(fieldName, bd.length, bd.type, bd.data);
+ }
- /** Peek at what is in the builder, but leave the builder ready for more appends.
- The returned object is only valid until the next modification or destruction of the builder.
- Intended use case: append a field if not already there.
- */
- BSONObj asTempObj() {
- BSONObj temp(_done());
- _b.setlen(_b.len()-1); //next append should overwrite the EOO
- _b.reserveBytes(1); // Rereserve room for the real EOO
- _doneCalled = false;
- return temp;
- }
+ /**
+ Subtype 2 is deprecated.
+ Append a BSON bindata bytearray element.
+ @param data a byte array
+ @param len the length of data
+ */
+ BSONObjBuilder& appendBinDataArrayDeprecated(const char* fieldName, const void* data, int len) {
+ _b.appendNum((char)BinData);
+ _b.appendStr(fieldName);
+ _b.appendNum(len + 4);
+ _b.appendNum((char)0x2);
+ _b.appendNum(len);
+ _b.appendBuf(data, len);
+ return *this;
+ }
- /** Make it look as if "done" has been called, so that our destructor is a no-op. Do
- * this if you know that you don't care about the contents of the builder you are
- * destroying.
- *
- * Note that it is invalid to call any method other than the destructor after invoking
- * this method.
- */
- void abandon() {
- _doneCalled = true;
- }
+ /** Append to the BSON object a field of type CodeWScope. This is a javascript code
+ fragment accompanied by some scope that goes with it.
+ */
+ BSONObjBuilder& appendCodeWScope(StringData fieldName, StringData code, const BSONObj& scope) {
+ _b.appendNum((char)CodeWScope);
+ _b.appendStr(fieldName);
+ _b.appendNum((int)(4 + 4 + code.size() + 1 + scope.objsize()));
+ _b.appendNum((int)code.size() + 1);
+ _b.appendStr(code);
+ _b.appendBuf((void*)scope.objdata(), scope.objsize());
+ return *this;
+ }
- void decouple() {
- _b.decouple(); // post done() call version. be sure jsobj frees...
- }
+ BSONObjBuilder& append(StringData fieldName, const BSONCodeWScope& cws) {
+ return appendCodeWScope(fieldName, cws.code, cws.scope);
+ }
- void appendKeys( const BSONObj& keyPattern , const BSONObj& values );
+ void appendUndefined(StringData fieldName) {
+ _b.appendNum((char)Undefined);
+ _b.appendStr(fieldName);
+ }
- static std::string numStr( int i ) {
- if (i>=0 && i<100 && numStrsReady)
- return numStrs[i];
- StringBuilder o;
- o << i;
- return o.str();
- }
+ /* helper function -- see Query::where() for primary way to do this. */
+ void appendWhere(StringData code, const BSONObj& scope) {
+ appendCodeWScope("$where", code, scope);
+ }
- /** Stream oriented way to add field names and values. */
- BSONObjBuilderValueStream &operator<<( StringData name ) {
- _s.endField( name );
- return _s;
- }
+ /**
+ these are the min/max when comparing, not strict min/max elements for a given type
+ */
+ void appendMinForType(StringData fieldName, int type);
+ void appendMaxForType(StringData fieldName, int type);
+
+ /** Append an array of values. */
+ template <class T>
+ BSONObjBuilder& append(StringData fieldName, const std::vector<T>& vals);
+
+ template <class T>
+ BSONObjBuilder& append(StringData fieldName, const std::list<T>& vals);
+
+ /** Append a set of values. */
+ template <class T>
+ BSONObjBuilder& append(StringData fieldName, const std::set<T>& vals);
+
+ /**
+ * Append a map of values as a sub-object.
+ * Note: the keys of the map should be StringData-compatible (i.e. strings).
+ */
+ template <class K, class T>
+ BSONObjBuilder& append(StringData fieldName, const std::map<K, T>& vals);
+
+ /**
+ * destructive
+ * The returned BSONObj will free the buffer when it is finished.
+ * @return owned BSONObj
+ */
+ BSONObj obj() {
+ massert(10335, "builder does not own memory", owned());
+ doneFast();
+ char* buf = _b.buf();
+ decouple();
+ return BSONObj::takeOwnership(buf);
+ }
- /** Stream oriented way to add field names and values. */
- BSONObjBuilder& operator<<( GENOIDLabeler ) { return genOID(); }
+ /** Fetch the object we have built.
+ BSONObjBuilder still frees the object when the builder goes out of
+ scope -- very important to keep in mind. Use obj() if you
+ would like the BSONObj to last longer than the builder.
+ */
+ BSONObj done() {
+ return BSONObj(_done());
+ }
- Labeler operator<<( const Labeler::Label &l ) {
- massert( 10336 , "No subobject started", _s.subobjStarted() );
- return _s << l;
- }
+ // Like 'done' above, but does not construct a BSONObj to return to the caller.
+ void doneFast() {
+ (void)_done();
+ }
- template<typename T>
- BSONObjBuilderValueStream& operator<<( const BSONField<T>& f ) {
- _s.endField( f.name() );
- return _s;
- }
+ /** Peek at what is in the builder, but leave the builder ready for more appends.
+ The returned object is only valid until the next modification or destruction of the builder.
+ Intended use case: append a field if not already there.
+ */
+ BSONObj asTempObj() {
+ BSONObj temp(_done());
+ _b.setlen(_b.len() - 1); // next append should overwrite the EOO
+ _b.reserveBytes(1); // Rereserve room for the real EOO
+ _doneCalled = false;
+ return temp;
+ }
- template<typename T>
- BSONObjBuilder& operator<<( const BSONFieldValue<T>& v ) {
- append( v.name(), v.value() );
- return *this;
- }
+ /** Make it look as if "done" has been called, so that our destructor is a no-op. Do
+ * this if you know that you don't care about the contents of the builder you are
+ * destroying.
+ *
+ * Note that it is invalid to call any method other than the destructor after invoking
+ * this method.
+ */
+ void abandon() {
+ _doneCalled = true;
+ }
- BSONObjBuilder& operator<<( const BSONElement& e ){
- append( e );
- return *this;
- }
+ void decouple() {
+ _b.decouple(); // post done() call version. be sure jsobj frees...
+ }
- bool isArray() const {
- return false;
- }
+ void appendKeys(const BSONObj& keyPattern, const BSONObj& values);
- /** @return true if we are using our own bufbuilder, and not an alternate that was given to us in our constructor */
- bool owned() const { return &_b == &_buf; }
+ static std::string numStr(int i) {
+ if (i >= 0 && i < 100 && numStrsReady)
+ return numStrs[i];
+ StringBuilder o;
+ o << i;
+ return o.str();
+ }
- BSONObjIterator iterator() const ;
+ /** Stream oriented way to add field names and values. */
+ BSONObjBuilderValueStream& operator<<(StringData name) {
+ _s.endField(name);
+ return _s;
+ }
- bool hasField( StringData name ) const ;
+ /** Stream oriented way to add field names and values. */
+ BSONObjBuilder& operator<<(GENOIDLabeler) {
+ return genOID();
+ }
- int len() const { return _b.len(); }
+ Labeler operator<<(const Labeler::Label& l) {
+ massert(10336, "No subobject started", _s.subobjStarted());
+ return _s << l;
+ }
- BufBuilder& bb() { return _b; }
+ template <typename T>
+ BSONObjBuilderValueStream& operator<<(const BSONField<T>& f) {
+ _s.endField(f.name());
+ return _s;
+ }
- private:
- char* _done() {
- if ( _doneCalled )
- return _b.buf() + _offset;
+ template <typename T>
+ BSONObjBuilder& operator<<(const BSONFieldValue<T>& v) {
+ append(v.name(), v.value());
+ return *this;
+ }
- _doneCalled = true;
+ BSONObjBuilder& operator<<(const BSONElement& e) {
+ append(e);
+ return *this;
+ }
- // TODO remove this or find some way to prevent it from failing. Since this is intended
- // for use with BSON() literal queries, it is less likely to result in oversized BSON.
- _s.endField();
+ bool isArray() const {
+ return false;
+ }
- _b.claimReservedBytes(1); // Prevents adding EOO from failing.
- _b.appendNum((char) EOO);
+ /** @return true if we are using our own bufbuilder, and not an alternate that was given to us in our constructor */
+ bool owned() const {
+ return &_b == &_buf;
+ }
- char *data = _b.buf() + _offset;
- int size = _b.len() - _offset;
- DataView(data).write(tagLittleEndian(size));
- if ( _tracker )
- _tracker->got( size );
- return data;
- }
+ BSONObjIterator iterator() const;
- BufBuilder &_b;
- BufBuilder _buf;
- int _offset;
- BSONObjBuilderValueStream _s;
- BSONSizeTracker * _tracker;
- bool _doneCalled;
-
- static const std::string numStrs[100]; // cache of 0 to 99 inclusive
- static bool numStrsReady; // for static init safety
- };
-
- class BSONArrayBuilder {
- MONGO_DISALLOW_COPYING(BSONArrayBuilder);
- public:
- BSONArrayBuilder() : _i(0), _b() {}
- BSONArrayBuilder( BufBuilder &_b ) : _i(0), _b(_b) {}
- BSONArrayBuilder( int initialSize ) : _i(0), _b(initialSize) {}
-
- template <typename T>
- BSONArrayBuilder& append(const T& x) {
- _b.append(num(), x);
- return *this;
- }
+ bool hasField(StringData name) const;
- BSONArrayBuilder& append(const BSONElement& e) {
- _b.appendAs(e, num());
- return *this;
- }
+ int len() const {
+ return _b.len();
+ }
- BSONArrayBuilder& operator<<(const BSONElement& e) {
- return append(e);
- }
+ BufBuilder& bb() {
+ return _b;
+ }
- template <typename T>
- BSONArrayBuilder& operator<<(const T& x) {
- _b << num().c_str() << x;
- return *this;
- }
+private:
+ char* _done() {
+ if (_doneCalled)
+ return _b.buf() + _offset;
- void appendNull() {
- _b.appendNull(num());
- }
+ _doneCalled = true;
- void appendUndefined() {
- _b.appendUndefined(num());
- }
+ // TODO remove this or find some way to prevent it from failing. Since this is intended
+ // for use with BSON() literal queries, it is less likely to result in oversized BSON.
+ _s.endField();
- /**
- * destructive - ownership moves to returned BSONArray
- * @return owned BSONArray
- */
- BSONArray arr() { return BSONArray(_b.obj()); }
- BSONObj obj() { return _b.obj(); }
+ _b.claimReservedBytes(1); // Prevents adding EOO from failing.
+ _b.appendNum((char)EOO);
- BSONObj done() { return _b.done(); }
+ char* data = _b.buf() + _offset;
+ int size = _b.len() - _offset;
+ DataView(data).write(tagLittleEndian(size));
+ if (_tracker)
+ _tracker->got(size);
+ return data;
+ }
- void doneFast() { _b.doneFast(); }
+ BufBuilder& _b;
+ BufBuilder _buf;
+ int _offset;
+ BSONObjBuilderValueStream _s;
+ BSONSizeTracker* _tracker;
+ bool _doneCalled;
- template < class T >
- BSONArrayBuilder& append( const std::list< T >& vals );
+ static const std::string numStrs[100]; // cache of 0 to 99 inclusive
+ static bool numStrsReady; // for static init safety
+};
- template < class T >
- BSONArrayBuilder& append( const std::set< T >& vals );
+class BSONArrayBuilder {
+ MONGO_DISALLOW_COPYING(BSONArrayBuilder);
- // These two just use next position
- BufBuilder &subobjStart() { return _b.subobjStart( num() ); }
- BufBuilder &subarrayStart() { return _b.subarrayStart( num() ); }
+public:
+ BSONArrayBuilder() : _i(0), _b() {}
+ BSONArrayBuilder(BufBuilder& _b) : _i(0), _b(_b) {}
+ BSONArrayBuilder(int initialSize) : _i(0), _b(initialSize) {}
- BSONArrayBuilder& appendRegex(StringData regex, StringData options = "") {
- _b.appendRegex(num(), regex, options);
- return *this;
- }
+ template <typename T>
+ BSONArrayBuilder& append(const T& x) {
+ _b.append(num(), x);
+ return *this;
+ }
- BSONArrayBuilder& appendBinData(int len, BinDataType type, const void* data) {
- _b.appendBinData(num(), len, type, data);
- return *this;
- }
+ BSONArrayBuilder& append(const BSONElement& e) {
+ _b.appendAs(e, num());
+ return *this;
+ }
- BSONArrayBuilder& appendCode(StringData code) {
- _b.appendCode(num(), code);
- return *this;
- }
+ BSONArrayBuilder& operator<<(const BSONElement& e) {
+ return append(e);
+ }
- BSONArrayBuilder& appendCodeWScope(StringData code, const BSONObj& scope) {
- _b.appendCodeWScope(num(), code, scope);
- return *this;
- }
+ template <typename T>
+ BSONArrayBuilder& operator<<(const T& x) {
+ _b << num().c_str() << x;
+ return *this;
+ }
- BSONArrayBuilder& appendTimeT(time_t dt) {
- _b.appendTimeT(num(), dt);
- return *this;
- }
+ void appendNull() {
+ _b.appendNull(num());
+ }
- BSONArrayBuilder& appendDate(Date_t dt) {
- _b.appendDate(num(), dt);
- return *this;
- }
+ void appendUndefined() {
+ _b.appendUndefined(num());
+ }
- BSONArrayBuilder& appendBool(bool val) {
- _b.appendBool(num(), val);
- return *this;
- }
+ /**
+ * destructive - ownership moves to returned BSONArray
+ * @return owned BSONArray
+ */
+ BSONArray arr() {
+ return BSONArray(_b.obj());
+ }
+ BSONObj obj() {
+ return _b.obj();
+ }
- BSONArrayBuilder& appendTimestamp(unsigned long long ts) {
- _b.appendTimestamp(num(), ts);
- return *this;
- }
+ BSONObj done() {
+ return _b.done();
+ }
- bool isArray() const {
- return true;
- }
+ void doneFast() {
+ _b.doneFast();
+ }
- int len() const { return _b.len(); }
- int arrSize() const { return _i; }
+ template <class T>
+ BSONArrayBuilder& append(const std::list<T>& vals);
- BufBuilder& bb() { return _b.bb(); }
+ template <class T>
+ BSONArrayBuilder& append(const std::set<T>& vals);
- private:
+ // These two just use next position
+ BufBuilder& subobjStart() {
+ return _b.subobjStart(num());
+ }
+ BufBuilder& subarrayStart() {
+ return _b.subarrayStart(num());
+ }
- std::string num() { return _b.numStr(_i++); }
- int _i;
- BSONObjBuilder _b;
- };
+ BSONArrayBuilder& appendRegex(StringData regex, StringData options = "") {
+ _b.appendRegex(num(), regex, options);
+ return *this;
+ }
- template < class T >
- inline BSONObjBuilder& BSONObjBuilder::append( StringData fieldName, const std::vector< T >& vals ) {
- BSONObjBuilder arrBuilder;
- for ( unsigned int i = 0; i < vals.size(); ++i )
- arrBuilder.append( numStr( i ), vals[ i ] );
- appendArray( fieldName, arrBuilder.done() );
+ BSONArrayBuilder& appendBinData(int len, BinDataType type, const void* data) {
+ _b.appendBinData(num(), len, type, data);
return *this;
}
- template < class L >
- inline BSONObjBuilder& _appendIt( BSONObjBuilder& _this, StringData fieldName, const L& vals ) {
- BSONObjBuilder arrBuilder;
- int n = 0;
- for( typename L::const_iterator i = vals.begin(); i != vals.end(); i++ )
- arrBuilder.append( BSONObjBuilder::numStr(n++), *i );
- _this.appendArray( fieldName, arrBuilder.done() );
- return _this;
+ BSONArrayBuilder& appendCode(StringData code) {
+ _b.appendCode(num(), code);
+ return *this;
}
- template < class T >
- inline BSONObjBuilder& BSONObjBuilder::append( StringData fieldName, const std::list< T >& vals ) {
- return _appendIt< std::list< T > >( *this, fieldName, vals );
+ BSONArrayBuilder& appendCodeWScope(StringData code, const BSONObj& scope) {
+ _b.appendCodeWScope(num(), code, scope);
+ return *this;
}
- template < class T >
- inline BSONObjBuilder& BSONObjBuilder::append( StringData fieldName, const std::set< T >& vals ) {
- return _appendIt< std::set< T > >( *this, fieldName, vals );
+ BSONArrayBuilder& appendTimeT(time_t dt) {
+ _b.appendTimeT(num(), dt);
+ return *this;
}
- template < class K, class T >
- inline BSONObjBuilder& BSONObjBuilder::append( StringData fieldName, const std::map< K, T >& vals ) {
- BSONObjBuilder bob;
- for( typename std::map<K,T>::const_iterator i = vals.begin(); i != vals.end(); ++i ){
- bob.append(i->first, i->second);
- }
- append(fieldName, bob.obj());
+ BSONArrayBuilder& appendDate(Date_t dt) {
+ _b.appendDate(num(), dt);
return *this;
}
+ BSONArrayBuilder& appendBool(bool val) {
+ _b.appendBool(num(), val);
+ return *this;
+ }
- template < class L >
- inline BSONArrayBuilder& _appendArrayIt( BSONArrayBuilder& _this, const L& vals ) {
- for( typename L::const_iterator i = vals.begin(); i != vals.end(); i++ )
- _this.append( *i );
- return _this;
+ BSONArrayBuilder& appendTimestamp(unsigned long long ts) {
+ _b.appendTimestamp(num(), ts);
+ return *this;
}
- template < class T >
- inline BSONArrayBuilder& BSONArrayBuilder::append( const std::list< T >& vals ) {
- return _appendArrayIt< std::list< T > >( *this, vals );
+ bool isArray() const {
+ return true;
}
- template < class T >
- inline BSONArrayBuilder& BSONArrayBuilder::append( const std::set< T >& vals ) {
- return _appendArrayIt< std::set< T > >( *this, vals );
+ int len() const {
+ return _b.len();
}
-
- template <typename T>
- inline BSONFieldValue<BSONObj> BSONField<T>::query(const char * q, const T& t) const {
- BSONObjBuilder b;
- b.append( q , t );
- return BSONFieldValue<BSONObj>( _name , b.obj() );
+ int arrSize() const {
+ return _i;
}
-
- // $or helper: OR(BSON("x" << GT << 7), BSON("y" << LT 6));
- inline BSONObj OR(const BSONObj& a, const BSONObj& b)
- { return BSON( "$or" << BSON_ARRAY(a << b) ); }
- inline BSONObj OR(const BSONObj& a, const BSONObj& b, const BSONObj& c)
- { return BSON( "$or" << BSON_ARRAY(a << b << c) ); }
- inline BSONObj OR(const BSONObj& a, const BSONObj& b, const BSONObj& c, const BSONObj& d)
- { return BSON( "$or" << BSON_ARRAY(a << b << c << d) ); }
- inline BSONObj OR(const BSONObj& a, const BSONObj& b, const BSONObj& c, const BSONObj& d, const BSONObj& e)
- { return BSON( "$or" << BSON_ARRAY(a << b << c << d << e) ); }
- inline BSONObj OR(const BSONObj& a, const BSONObj& b, const BSONObj& c, const BSONObj& d, const BSONObj& e, const BSONObj& f)
- { return BSON( "$or" << BSON_ARRAY(a << b << c << d << e << f) ); }
-
- inline BSONObjBuilder& BSONObjBuilderValueStream::operator<<(const DateNowLabeler& id) {
- _builder->appendDate(_fieldName, jsTime());
- _fieldName = StringData();
- return *_builder;
+ BufBuilder& bb() {
+ return _b.bb();
}
- inline BSONObjBuilder& BSONObjBuilderValueStream::operator<<(const NullLabeler& id) {
- _builder->appendNull(_fieldName);
- _fieldName = StringData();
- return *_builder;
+private:
+ std::string num() {
+ return _b.numStr(_i++);
}
+ int _i;
+ BSONObjBuilder _b;
+};
+
+template <class T>
+inline BSONObjBuilder& BSONObjBuilder::append(StringData fieldName, const std::vector<T>& vals) {
+ BSONObjBuilder arrBuilder;
+ for (unsigned int i = 0; i < vals.size(); ++i)
+ arrBuilder.append(numStr(i), vals[i]);
+ appendArray(fieldName, arrBuilder.done());
+ return *this;
+}
- inline BSONObjBuilder& BSONObjBuilderValueStream::operator<<(const UndefinedLabeler& id) {
- _builder->appendUndefined(_fieldName);
- _fieldName = StringData();
- return *_builder;
- }
+template <class L>
+inline BSONObjBuilder& _appendIt(BSONObjBuilder& _this, StringData fieldName, const L& vals) {
+ BSONObjBuilder arrBuilder;
+ int n = 0;
+ for (typename L::const_iterator i = vals.begin(); i != vals.end(); i++)
+ arrBuilder.append(BSONObjBuilder::numStr(n++), *i);
+ _this.appendArray(fieldName, arrBuilder.done());
+ return _this;
+}
+template <class T>
+inline BSONObjBuilder& BSONObjBuilder::append(StringData fieldName, const std::list<T>& vals) {
+ return _appendIt<std::list<T>>(*this, fieldName, vals);
+}
- inline BSONObjBuilder& BSONObjBuilderValueStream::operator<<(const MinKeyLabeler& id) {
- _builder->appendMinKey(_fieldName);
- _fieldName = StringData();
- return *_builder;
- }
+template <class T>
+inline BSONObjBuilder& BSONObjBuilder::append(StringData fieldName, const std::set<T>& vals) {
+ return _appendIt<std::set<T>>(*this, fieldName, vals);
+}
- inline BSONObjBuilder& BSONObjBuilderValueStream::operator<<(const MaxKeyLabeler& id) {
- _builder->appendMaxKey(_fieldName);
- _fieldName = StringData();
- return *_builder;
+template <class K, class T>
+inline BSONObjBuilder& BSONObjBuilder::append(StringData fieldName, const std::map<K, T>& vals) {
+ BSONObjBuilder bob;
+ for (typename std::map<K, T>::const_iterator i = vals.begin(); i != vals.end(); ++i) {
+ bob.append(i->first, i->second);
}
+ append(fieldName, bob.obj());
+ return *this;
+}
- template<class T> inline
- BSONObjBuilder& BSONObjBuilderValueStream::operator<<( T value ) {
- _builder->append(_fieldName, value);
- _fieldName = StringData();
- return *_builder;
- }
- template<class T>
- BSONObjBuilder& Labeler::operator<<( T value ) {
- s_->subobj()->append( l_.l_, value );
- return *s_->_builder;
- }
+template <class L>
+inline BSONArrayBuilder& _appendArrayIt(BSONArrayBuilder& _this, const L& vals) {
+ for (typename L::const_iterator i = vals.begin(); i != vals.end(); i++)
+ _this.append(*i);
+ return _this;
+}
- inline BSONObjBuilder& BSONObjBuilder::append(StringData fieldName, Timestamp optime) {
- optime.append(_b, fieldName);
- return *this;
- }
+template <class T>
+inline BSONArrayBuilder& BSONArrayBuilder::append(const std::list<T>& vals) {
+ return _appendArrayIt<std::list<T>>(*this, vals);
+}
- inline BSONObjBuilder& BSONObjBuilder::appendTimestamp( StringData fieldName ) {
- return append(fieldName, Timestamp());
- }
+template <class T>
+inline BSONArrayBuilder& BSONArrayBuilder::append(const std::set<T>& vals) {
+ return _appendArrayIt<std::set<T>>(*this, vals);
+}
- inline BSONObjBuilder& BSONObjBuilder::appendTimestamp( StringData fieldName,
- unsigned long long val ) {
- return append(fieldName, Timestamp(val));
- }
+template <typename T>
+inline BSONFieldValue<BSONObj> BSONField<T>::query(const char* q, const T& t) const {
+ BSONObjBuilder b;
+ b.append(q, t);
+ return BSONFieldValue<BSONObj>(_name, b.obj());
+}
+
+
+// $or helper: OR(BSON("x" << GT << 7), BSON("y" << LT 6));
+inline BSONObj OR(const BSONObj& a, const BSONObj& b) {
+ return BSON("$or" << BSON_ARRAY(a << b));
+}
+inline BSONObj OR(const BSONObj& a, const BSONObj& b, const BSONObj& c) {
+ return BSON("$or" << BSON_ARRAY(a << b << c));
+}
+inline BSONObj OR(const BSONObj& a, const BSONObj& b, const BSONObj& c, const BSONObj& d) {
+ return BSON("$or" << BSON_ARRAY(a << b << c << d));
+}
+inline BSONObj OR(
+ const BSONObj& a, const BSONObj& b, const BSONObj& c, const BSONObj& d, const BSONObj& e) {
+ return BSON("$or" << BSON_ARRAY(a << b << c << d << e));
+}
+inline BSONObj OR(const BSONObj& a,
+ const BSONObj& b,
+ const BSONObj& c,
+ const BSONObj& d,
+ const BSONObj& e,
+ const BSONObj& f) {
+ return BSON("$or" << BSON_ARRAY(a << b << c << d << e << f));
+}
+
+inline BSONObjBuilder& BSONObjBuilderValueStream::operator<<(const DateNowLabeler& id) {
+ _builder->appendDate(_fieldName, jsTime());
+ _fieldName = StringData();
+ return *_builder;
+}
+
+inline BSONObjBuilder& BSONObjBuilderValueStream::operator<<(const NullLabeler& id) {
+ _builder->appendNull(_fieldName);
+ _fieldName = StringData();
+ return *_builder;
+}
+inline BSONObjBuilder& BSONObjBuilderValueStream::operator<<(const UndefinedLabeler& id) {
+ _builder->appendUndefined(_fieldName);
+ _fieldName = StringData();
+ return *_builder;
+}
+
+
+inline BSONObjBuilder& BSONObjBuilderValueStream::operator<<(const MinKeyLabeler& id) {
+ _builder->appendMinKey(_fieldName);
+ _fieldName = StringData();
+ return *_builder;
+}
+
+inline BSONObjBuilder& BSONObjBuilderValueStream::operator<<(const MaxKeyLabeler& id) {
+ _builder->appendMaxKey(_fieldName);
+ _fieldName = StringData();
+ return *_builder;
+}
+
+template <class T>
+inline BSONObjBuilder& BSONObjBuilderValueStream::operator<<(T value) {
+ _builder->append(_fieldName, value);
+ _fieldName = StringData();
+ return *_builder;
+}
+
+template <class T>
+BSONObjBuilder& Labeler::operator<<(T value) {
+ s_->subobj()->append(l_.l_, value);
+ return *s_->_builder;
+}
+
+inline BSONObjBuilder& BSONObjBuilder::append(StringData fieldName, Timestamp optime) {
+ optime.append(_b, fieldName);
+ return *this;
+}
+
+inline BSONObjBuilder& BSONObjBuilder::appendTimestamp(StringData fieldName) {
+ return append(fieldName, Timestamp());
+}
+
+inline BSONObjBuilder& BSONObjBuilder::appendTimestamp(StringData fieldName,
+ unsigned long long val) {
+ return append(fieldName, Timestamp(val));
+}
}