25#include <boost/static_assert.hpp>
30#include "mongo/base/data_cursor.h"
31#include "mongo/base/parse_number.h"
32#include "mongo/bson/bson_field.h"
33#include "mongo/bson/bsonelement.h"
34#include "mongo/bson/bsonmisc.h"
35#include "mongo/bson/bsonobj.h"
36#include "mongo/bson/timestamp.h"
37#include "mongo/client/export_macros.h"
43#pragma warning( disable : 4355 )
46 inline void checkFieldName(StringData fieldName) {
47 uassert(0,
"field name cannot contain null bytes", fieldName.find(
'\0') == std::string::npos);
58 , _buf(sizeof(
BSONObj::Holder) + initsize)
59 , _offset(sizeof(
BSONObj::Holder))
62 , _doneCalled(false) {
78 , _offset(baseBuilder.len())
81 , _doneCalled(false) {
93 , _buf(sizeof(
BSONObj::Holder) + tracker.getSize())
94 , _offset(sizeof(
BSONObj::Holder))
97 , _doneCalled(false) {
100 _b.skip(
sizeof(
int));
111 if ( !_doneCalled && _b.buf() && _buf.getSize() == 0 ) {
124 checkFieldName(e.fieldNameStringData());
126 _b.appendBuf((
void*) e.rawdata(), e.
size());
132 checkFieldName(fieldName);
134 _b.appendNum((
char) e.
type());
135 _b.appendStr(fieldName);
142 checkFieldName(fieldName);
143 _b.appendNum((
char)
Object);
144 _b.appendStr(fieldName);
151 checkFieldName(fieldName);
154 size = ConstDataView(objdata).readLE<
int>();
157 verify( size > 4 && size < 100000000 );
159 _b.appendNum((
char)
Object);
160 _b.appendStr(fieldName);
161 _b.appendBuf((
void*)objdata, size );
177 checkFieldName(fieldName);
178 _b.appendNum((
char)
Object);
179 _b.appendStr(fieldName);
187 checkFieldName(fieldName);
188 _b.appendNum((
char)
Array);
189 _b.appendStr(fieldName);
194 return appendArray(fieldName, arr);
200 checkFieldName(fieldName);
201 _b.appendNum((
char)
Array);
202 _b.appendStr(fieldName);
208 checkFieldName(fieldName);
209 _b.appendNum((
char)
Bool);
210 _b.appendStr(fieldName);
211 _b.appendNum((
char) (val?1:0));
217 checkFieldName(fieldName);
218 _b.appendNum((
char)
Bool);
219 _b.appendStr(fieldName);
220 _b.appendNum((
char) (val?1:0));
226 checkFieldName(fieldName);
228 _b.appendStr(fieldName);
235 return append(fieldName, (
int) n);
240 checkFieldName(fieldName);
242 _b.appendStr(fieldName);
250 static const long long maxInt = (std::numeric_limits<int>::max)() / 2;
251 static const long long minInt = -maxInt;
252 if ( minInt < n && n < maxInt ) {
253 append( fieldName ,
static_cast<int>( n ) );
256 append( fieldName , n );
266 return append( fieldName , n );
269 BSONObjBuilder& appendNumber(
const StringData& fieldName ,
double d ) {
270 return append( fieldName , d );
273 BSONObjBuilder& appendNumber(
const StringData& fieldName ,
size_t n ) {
274 static const size_t maxInt = ( 1 << 30 );
277 append( fieldName,
static_cast<int>( n ) );
279 append( fieldName,
static_cast<long long>( n ) );
283 BSONObjBuilder& appendNumber(
const StringData& fieldName,
long long llNumber ) {
284 static const long long maxInt = ( 1LL << 30 );
285 static const long long minInt = -maxInt;
286 static const long long maxDouble = ( 1LL << 40 );
287 static const long long minDouble = -maxDouble;
289 if ( minInt < llNumber && llNumber < maxInt ) {
290 append( fieldName,
static_cast<int>( llNumber ) );
292 else if ( minDouble < llNumber && llNumber < maxDouble ) {
293 append( fieldName,
static_cast<double>( llNumber ) );
296 append( fieldName, llNumber );
304 checkFieldName(fieldName);
306 _b.appendStr(fieldName);
321 checkFieldName(fieldName);
322 _b.appendNum((
char)
jstOID);
323 _b.appendStr(fieldName);
325 _b.appendBuf( oid->view().view(), OID::kOIDSize );
328 if ( generateIfBlank )
332 _b.appendBuf( tmp.view().view(), OID::kOIDSize );
343 checkFieldName(fieldName);
344 _b.appendNum((
char)
jstOID);
345 _b.appendStr(fieldName);
346 _b.appendBuf( oid.view().view(), OID::kOIDSize );
355 return append(
"_id", OID::gen());
363 checkFieldName(fieldName);
364 _b.appendNum((
char)
Date);
365 _b.appendStr(fieldName);
366 _b.appendNum(
static_cast<unsigned long long>(dt) * 1000);
375 return appendDate(fieldName, dt);
383 checkFieldName(fieldName);
384 uassert(0,
"regex cannot contain null bytes", regex.find(
'\0') == std::string::npos);
385 _b.appendNum((
char)
RegEx);
386 _b.appendStr(fieldName);
388 _b.appendStr(options);
393 return appendRegex(fieldName, regex.pattern, regex.flags);
396 BSONObjBuilder& appendCode(
const StringData& fieldName,
const StringData& code) {
397 checkFieldName(fieldName);
398 _b.appendNum((
char) Code);
399 _b.appendStr(fieldName);
400 _b.appendNum((
int) code.size()+1);
405 BSONObjBuilder& append(
const StringData& fieldName,
const BSONCode& code) {
406 return appendCode(fieldName, code.code);
412 checkFieldName(fieldName);
413 _b.appendNum((
char)
String);
414 _b.appendStr(fieldName);
415 _b.appendNum((
int)sz);
416 _b.appendBuf(str, sz);
421 return append(fieldName, str, (
int) strlen(str)+1);
425 return append(fieldName, str.c_str(), (
int) str.size()+1);
429 checkFieldName(fieldName);
430 _b.appendNum((
char)
String);
431 _b.appendStr(fieldName);
432 _b.appendNum((
int)str.size()+1);
433 _b.appendStr(str,
true);
437 BSONObjBuilder& appendSymbol(
const StringData& fieldName,
const StringData& symbol) {
438 checkFieldName(fieldName);
439 _b.appendNum((
char) Symbol);
440 _b.appendStr(fieldName);
441 _b.appendNum((
int) symbol.size()+1);
442 _b.appendStr(symbol);
446 BSONObjBuilder& append(
const StringData& fieldName,
const BSONSymbol& symbol) {
447 return appendSymbol(fieldName, symbol.symbol);
452 msgasserted(16234,
"Invalid call to appendNull in BSONObj Builder.");
457 checkFieldName(fieldName);
458 _b.appendNum( (
char)
jstNULL );
459 _b.appendStr( fieldName );
465 checkFieldName(fieldName);
466 _b.appendNum( (
char) MinKey );
467 _b.appendStr( fieldName );
471 BSONObjBuilder& appendMaxKey(
const StringData& fieldName ) {
472 checkFieldName(fieldName);
473 _b.appendNum( (
char) MaxKey );
474 _b.appendStr( fieldName );
480 checkFieldName(fieldName);
482 _b.appendStr( fieldName );
484 char buf[2 *
sizeof(uint32_t)];
486 cur.writeLEAndAdvance<>(ts.increment());
487 cur.writeLEAndAdvance<>(ts.seconds());
489 _b.appendBuf(buf,
sizeof(buf));
494 return appendTimestamp(fieldName, ts);
501 BSONObjBuilder& appendDBRef(
const StringData& fieldName,
const StringData& ns,
const OID &oid ) {
502 checkFieldName(fieldName);
503 _b.appendNum( (
char) DBRef );
504 _b.appendStr( fieldName );
505 _b.appendNum( (
int) ns.size() + 1 );
507 _b.appendBuf( oid.view().view(), OID::kOIDSize );
511 BSONObjBuilder& append(
const StringData& fieldName,
const BSONDBRef& dbref) {
512 return appendDBRef(fieldName, dbref.ns, dbref.oid);
523 checkFieldName(fieldName);
524 _b.appendNum( (
char)
BinData );
525 _b.appendStr( fieldName );
527 _b.appendNum( (
char) type );
528 _b.appendBuf( data, len );
533 return appendBinData(fieldName, bd.length, bd.type, bd.data);
543 checkFieldName(fieldName);
544 _b.appendNum( (
char)
BinData );
545 _b.appendStr( fieldName );
546 _b.appendNum( len + 4 );
547 _b.appendNum( (
char)0x2 );
549 _b.appendBuf( data, len );
557 checkFieldName(fieldName);
559 _b.appendStr( fieldName );
560 _b.appendNum( (
int )( 4 + 4 + code.size() + 1 + scope.
objsize() ) );
561 _b.appendNum( (
int ) code.size() + 1 );
562 _b.appendStr( code );
568 return appendCodeWScope(fieldName, cws.code, cws.scope);
571 void appendUndefined(
const StringData& fieldName ) {
572 _b.appendNum( (
char) Undefined );
573 _b.appendStr( fieldName );
577 void appendWhere(
const StringData& code,
const BSONObj &scope ) {
578 appendCodeWScope(
"$where" , code , scope );
585 void appendMaxForType(
const StringData& fieldName ,
int type );
589 BSONObjBuilder& append(
const StringData& fieldName,
const std::vector< T >& vals );
592 BSONObjBuilder& append(
const StringData& fieldName,
const std::list< T >& vals );
596 BSONObjBuilder& append(
const StringData& fieldName,
const std::set< T >& vals );
602 template <
class K,
class T >
603 BSONObjBuilder& append(
const StringData& fieldName,
const std::map< K, T >& vals );
611 massert( 10335 ,
"builder does not own memory", owned() );
613 char* buf = _b.buf();
615 return BSONObj::takeOwnership(buf);
638 _b.setlen(_b.len()-1);
659 void appendKeys(
const BSONObj& keyPattern ,
const BSONObj& values );
661 static std::string MONGO_CLIENT_FUNC numStr(
int i ) {
662 if (i>=0 && i<100 && numStrsReady)
679 massert( 10336 ,
"No subobject started", _s.subobjStarted() );
684 BSONObjBuilderValueStream& operator<<(
const BSONField<T>& f ) {
685 _s.endField( f.name() );
690 BSONObjBuilder& operator<<(
const BSONFieldValue<T>& v ) {
691 append( v.name(), v.value() );
695 BSONObjBuilder& operator<<(
const BSONElement& e ){
705 bool owned()
const {
return &_b == &_buf; }
709 bool hasField(
const StringData& name )
const ;
711 int len()
const {
return _b.len(); }
713 BufBuilder& bb() {
return _b; }
718 return _b.buf() + _offset;
726 _b.claimReservedBytes(1);
727 _b.appendNum((
char) EOO);
729 char *data = _b.buf() + _offset;
730 int size = _b.len() - _offset;
731 DataView(data).writeLE(size);
733 _tracker->got( size );
740 BSONObjBuilderValueStream _s;
741 BSONSizeTracker * _tracker;
744 static const std::string numStrs[100];
745 static bool numStrsReady;
754 template <
typename T>
761 _b.appendAs(e, num());
769 template <
typename T>
771 _b << num().c_str() << x;
776 _b.appendNull(num());
779 void appendUndefined() {
780 _b.appendUndefined(num());
788 BSONObj obj() {
return _b.obj(); }
790 BSONObj done() {
return _b.done(); }
792 void doneFast() { _b.doneFast(); }
795 BSONArrayBuilder& append(
const std::list< T >& vals );
798 BSONArrayBuilder& append(
const std::set< T >& vals );
801 BufBuilder &subobjStart() {
return _b.subobjStart( num() ); }
802 BufBuilder &subarrayStart() {
return _b.subarrayStart( num() ); }
804 BSONArrayBuilder& appendRegex(
const StringData& regex,
const StringData& options =
"") {
805 uassert(0,
"regex cannot contain null bytes", regex.find(
'\0') == std::string::npos);
806 _b.appendRegex(num(), regex, options);
810 BSONArrayBuilder& appendBinData(
int len, BinDataType type,
const void* data) {
811 _b.appendBinData(num(), len, type, data);
815 BSONArrayBuilder& appendCode(
const StringData& code) {
816 _b.appendCode(num(), code);
820 BSONArrayBuilder& appendCodeWScope(
const StringData& code,
const BSONObj& scope) {
821 _b.appendCodeWScope(num(), code, scope);
825 BSONArrayBuilder& appendTimeT(time_t dt) {
826 _b.appendTimeT(num(), dt);
830 BSONArrayBuilder& appendDate(Date_t dt) {
831 _b.appendDate(num(), dt);
835 BSONArrayBuilder& appendBool(
bool val) {
836 _b.appendBool(num(), val);
840 bool isArray()
const {
844 int len()
const {
return _b.
len(); }
845 int arrSize()
const {
return _i; }
847 BufBuilder& bb() {
return _b.bb(); }
851 std::string num() {
return _b.numStr(_i++); }
859 for (
unsigned int i = 0; i < vals.size(); ++i )
860 arrBuilder.
append( numStr( i ), vals[ i ] );
869 for(
typename L::const_iterator i = vals.begin(); i != vals.end(); i++ )
870 arrBuilder.
append( BSONObjBuilder::numStr(n++), *i );
876 inline BSONObjBuilder&
BSONObjBuilder::append(
const StringData& fieldName,
const std::list< T >& vals ) {
877 return _appendIt< std::list< T > >( *
this, fieldName, vals );
882 return _appendIt< std::set< T > >( *
this, fieldName, vals );
885 template <
class K,
class T >
888 for(
typename std::map<K,T>::const_iterator i = vals.begin(); i != vals.end(); ++i ){
889 bob.
append(i->first, i->second);
898 for(
typename L::const_iterator i = vals.begin(); i != vals.end(); i++ )
904 inline BSONArrayBuilder& BSONArrayBuilder::append(
const std::list< T >& vals ) {
905 return _appendArrayIt< std::list< T > >( *
this, vals );
909 inline BSONArrayBuilder& BSONArrayBuilder::append(
const std::set< T >& vals ) {
910 return _appendArrayIt< std::set< T > >( *
this, vals );
914 inline BSONFieldValue<BSONObj> BSONField<T>::query(
const char * q ,
const T& t )
const {
917 return BSONFieldValue<BSONObj>( _name , b.obj() );
921 inline BSONObj OR(
const BSONObj& a,
const BSONObj& b)
922 {
return BSON(
"$or" << BSON_ARRAY(a << b) ); }
923 inline BSONObj OR(
const BSONObj& a,
const BSONObj& b,
const BSONObj& c)
924 {
return BSON(
"$or" << BSON_ARRAY(a << b << c) ); }
925 inline BSONObj OR(
const BSONObj& a,
const BSONObj& b,
const BSONObj& c,
const BSONObj& d)
926 {
return BSON(
"$or" << BSON_ARRAY(a << b << c << d) ); }
927 inline BSONObj OR(
const BSONObj& a,
const BSONObj& b,
const BSONObj& c,
const BSONObj& d,
const BSONObj& e)
928 {
return BSON(
"$or" << BSON_ARRAY(a << b << c << d << e) ); }
929 inline BSONObj OR(
const BSONObj& a,
const BSONObj& b,
const BSONObj& c,
const BSONObj& d,
const BSONObj& e,
const BSONObj& f)
930 {
return BSON(
"$or" << BSON_ARRAY(a << b << c << d << e << f) ); }
Definition bsonobjbuilder.h:748
BSONArray arr()
destructive - ownership moves to returned BSONArray
Definition bsonobjbuilder.h:787
BSONElement represents an "element" in a BSONObj.
Definition bsonelement.h:55
int valuesize() const
size in bytes of the element's value (when applicable).
Definition bsonelement.h:166
const char * value() const
raw data of the element's value (so be careful).
Definition bsonelement.h:162
int size(int maxLen) const
Size of the element.
bool eoo() const
Indicates if it is the end-of-object element, which is present at the end of every BSON object.
Definition bsonelement.h:125
BSONType type() const
Returns the type of the element.
Definition bsonelement.h:109
Definition bsonmisc.h:197
Utility for creating a BSONObj.
Definition bsonobjbuilder.h:53
BSONObjBuilder(BufBuilder &baseBuilder)
Definition bsonobjbuilder.h:75
void abandon()
Make it look as if "done" has been called, so that our destructor is a no-op.
Definition bsonobjbuilder.h:651
BSONObjBuilder & append(const StringData &fieldName, const std::string &str)
Append a string element.
Definition bsonobjbuilder.h:424
bool owned() const
Definition bsonobjbuilder.h:705
BSONObjBuilder & append(const StringData &fieldName, BSONObj subObj)
add a subobject as a member
Definition bsonobjbuilder.h:141
BSONObjBuilder & append(const BSONElement &e)
append element to the object we are building
Definition bsonobjbuilder.h:123
BSONObjBuilder & appendElements(BSONObj x)
add all the fields from the object specified to this object
BSONObjBuilder & append(const StringData &fieldName, OID oid)
Append a BSON Object ID.
Definition bsonobjbuilder.h:342
BSONObjBuilder & append(const StringData &fieldName, int n)
Append a 32 bit integer element.
Definition bsonobjbuilder.h:225
BSONObjBuilder & append(const StringData &fieldName, double n)
Append a double element.
Definition bsonobjbuilder.h:303
BSONObjBuilder & append(const StringData &fieldName, long long n)
Append a NumberLong.
Definition bsonobjbuilder.h:239
BSONObj asTempObj()
Peek at what is in the builder, but leave the builder ready for more appends.
Definition bsonobjbuilder.h:636
BSONObjBuilder & appendOID(const StringData &fieldName, OID *oid=0, bool generateIfBlank=false)
Append a BSON Object ID (OID type).
Definition bsonobjbuilder.h:320
void appendNull()
Implements builder interface but no-op in ObjBuilder.
Definition bsonobjbuilder.h:451
BSONObjBuilder & append(const StringData &fieldName, unsigned n)
Append a 32 bit unsigned element - cast to a signed int.
Definition bsonobjbuilder.h:234
BSONObjBuilder & appendObject(const StringData &fieldName, const char *objdata, int size=0)
add a subobject as a member
Definition bsonobjbuilder.h:150
BSONObjBuilder & appendNumber(const StringData &fieldName, int n)
appendNumber is a series of method for appending the smallest sensible type mostly for JS
Definition bsonobjbuilder.h:265
BSONObjBuilder & appendDate(const StringData &fieldName, Date_t dt)
Append a date.
BSONObjBuilder & append(const StringData &fieldName, bool val)
Append a boolean element.
Definition bsonobjbuilder.h:216
BSONObjBuilder & appendCodeWScope(const StringData &fieldName, const StringData &code, const BSONObj &scope)
Append to the BSON object a field of type CodeWScope.
Definition bsonobjbuilder.h:556
BSONObjBuilder & append(const StringData &fieldName, const char *str, int sz)
Append a string element.
Definition bsonobjbuilder.h:411
BSONObjBuilder & append(const StringData &fieldName, const char *str)
Append a string element.
Definition bsonobjbuilder.h:420
BSONObjBuilder & appendNull(const StringData &fieldName)
Append a Null element to the object.
Definition bsonobjbuilder.h:456
BSONObjBuilder & appendTimestamp(const StringData &fieldName, const Timestamp_t &ts=Timestamp_t())
Append a Timestamp element to the object.
Definition bsonobjbuilder.h:479
BSONObjBuilder & appendElementsUnique(BSONObj x)
add all the fields from the object specified to this object if they don't exist already
BufBuilder & subarrayStart(const StringData &fieldName)
add header for a new subarray and return bufbuilder for writing to the subarray's body
Definition bsonobjbuilder.h:199
BSONObjBuilder & append(const StringData &fieldName, const StringData &str)
Append a string element.
Definition bsonobjbuilder.h:428
BSONObjBuilderValueStream & operator<<(const StringData &name)
Stream oriented way to add field names and values.
Definition bsonobjbuilder.h:670
BSONObjBuilder & appendAs(const BSONElement &e, const StringData &fieldName)
append an element but with a new name
Definition bsonobjbuilder.h:131
bool appendAsNumber(const StringData &fieldName, const std::string &data)
tries to append the data as a number
BSONObjBuilder & appendBinDataArrayDeprecated(const char *fieldName, const void *data, int len)
Subtype 2 is deprecated.
Definition bsonobjbuilder.h:542
BSONObjBuilder & appendBinData(const StringData &fieldName, int len, BinDataType type, const void *data)
Append a binary data element.
Definition bsonobjbuilder.h:522
BSONObjBuilder & appendBool(const StringData &fieldName, int val)
Append a boolean element.
Definition bsonobjbuilder.h:207
BSONObjBuilder & appendRegex(const StringData &fieldName, const StringData ®ex, const StringData &options="")
Append a regular expression value.
Definition bsonobjbuilder.h:382
BSONObj obj()
destructive The returned BSONObj will free the buffer when it is finished.
Definition bsonobjbuilder.h:610
BSONObj done()
Fetch the object we have built.
Definition bsonobjbuilder.h:623
BSONObjBuilder & appendTimeT(const StringData &fieldName, time_t dt)
Append a time_t date.
Definition bsonobjbuilder.h:362
BufBuilder & subobjStart(const StringData &fieldName)
add header for a new subobject and return bufbuilder for writing to the subobject's body
Definition bsonobjbuilder.h:176
BSONObjBuilder & appendArray(const StringData &fieldName, const BSONObj &subObj)
add a subobject as a member with type Array.
Definition bsonobjbuilder.h:186
BSONObjBuilder & genOID()
Generate and assign an object id for the _id field.
Definition bsonobjbuilder.h:354
void appendMinForType(const StringData &fieldName, int type)
these are the min/max when comparing, not strict min/max elements for a given type
BSONObjBuilder & operator<<(GENOIDLabeler)
Stream oriented way to add field names and values.
Definition bsonobjbuilder.h:676
BSONObjBuilder(int initsize=512)
Definition bsonobjbuilder.h:56
BSONObjBuilder & appendIntOrLL(const StringData &fieldName, long long n)
appends a number.
Definition bsonobjbuilder.h:248
iterator for a BSONObj
Definition bsonobjiterator.h:37
C++ representation of a "BSON" object – that is, an extended JSON-style object in a binary representa...
Definition bsonobj.h:78
int objsize() const
Definition bsonobj.h:304
const char * objdata() const
Definition bsonobj.h:299
used in conjuction with BSONObjBuilder, allows for proper buffer size to prevent crazy memory usage
Definition bsonmisc.h:240
Definition bsonmisc.h:116
Object ID type.
Definition oid.h:60
void clear()
initialize to 'null'
Definition oid.h:92
void init()
sets the contents to a new oid / randomized value
Definition shared_buffer.h:67
Definition timestamp.h:23
int len() const
Definition builder.h:202
the main MongoDB namespace
Definition bulk_operation_builder.h:24
MONGO_CLIENT_API bool isArray(const StringData &str)
Tests whether the JSON string is an Array.
@ CodeWScope
javascript code that can execute on the database server, with SavedContext
Definition bsontypes.h:72
@ String
character string, stored in utf8
Definition bsontypes.h:46
@ BinData
binary data
Definition bsontypes.h:52
@ Array
an embedded array
Definition bsontypes.h:50
@ Bool
boolean type
Definition bsontypes.h:58
@ Timestamp
Updated to a Date with value next OpTime on insert.
Definition bsontypes.h:76
@ RegEx
regular expression, a pattern with options
Definition bsontypes.h:64
@ jstOID
ObjectId.
Definition bsontypes.h:56
@ Object
an embedded object
Definition bsontypes.h:48
@ NumberLong
64 bit integer
Definition bsontypes.h:78
@ jstNULL
null type
Definition bsontypes.h:62
@ NumberInt
32 bit signed integer
Definition bsontypes.h:74
@ NumberDouble
double precision floating point value
Definition bsontypes.h:44
@ Date
date type
Definition bsontypes.h:60
Definition bsonmisc.h:164
Definition bsonmisc.h:150
Definition bsonmisc.h:157
Definition time_support.h:39
Definition bsonmisc.h:118