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)
46inline 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)),
79 _offset(baseBuilder.len()),
94 _buf(sizeof(
BSONObj::Holder) + tracker.getSize()),
95 _offset(sizeof(
BSONObj::Holder)),
101 _b.skip(
sizeof(
int));
112 if (!_doneCalled && _b.buf() && _buf.getSize() == 0) {
127 _b.appendBuf((
void*)e.rawdata(), e.
size());
135 _b.appendNum((
char)e.
type());
136 _b.appendStr(fieldName);
143 checkFieldName(fieldName);
144 _b.appendNum((
char)
Object);
145 _b.appendStr(fieldName);
152 checkFieldName(fieldName);
158 verify(size > 4 && size < 100000000);
160 _b.appendNum((
char)
Object);
161 _b.appendStr(fieldName);
162 _b.appendBuf((
void*)objdata, size);
178 checkFieldName(fieldName);
179 _b.appendNum((
char)
Object);
180 _b.appendStr(fieldName);
188 checkFieldName(fieldName);
189 _b.appendNum((
char)
Array);
190 _b.appendStr(fieldName);
195 return appendArray(fieldName, arr);
201 checkFieldName(fieldName);
202 _b.appendNum((
char)
Array);
203 _b.appendStr(fieldName);
209 checkFieldName(fieldName);
210 _b.appendNum((
char)
Bool);
211 _b.appendStr(fieldName);
212 _b.appendNum((
char)(val ? 1 : 0));
218 checkFieldName(fieldName);
219 _b.appendNum((
char)
Bool);
220 _b.appendStr(fieldName);
221 _b.appendNum((
char)(val ? 1 : 0));
227 checkFieldName(fieldName);
229 _b.appendStr(fieldName);
236 return append(fieldName, (
int)n);
241 checkFieldName(fieldName);
243 _b.appendStr(fieldName);
251 static const long long maxInt = (std::numeric_limits<int>::max)() / 2;
252 static const long long minInt = -maxInt;
253 if (minInt < n && n < maxInt) {
254 append(fieldName,
static_cast<int>(n));
256 append(fieldName, n);
266 return append(fieldName, n);
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));
291 }
else if (minDouble < llNumber && llNumber < maxDouble) {
292 append(fieldName,
static_cast<double>(llNumber));
294 append(fieldName, llNumber);
302 checkFieldName(fieldName);
304 _b.appendStr(fieldName);
320 bool generateIfBlank =
false) {
321 checkFieldName(fieldName);
322 _b.appendNum((
char)
jstOID);
323 _b.appendStr(fieldName);
325 _b.appendBuf(oid->view().view(), OID::kOIDSize);
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);
385 checkFieldName(fieldName);
386 uassert(0,
"regex cannot contain null bytes", regex.find(
'\0') == std::string::npos);
387 _b.appendNum((
char)
RegEx);
388 _b.appendStr(fieldName);
390 _b.appendStr(options);
395 return appendRegex(fieldName, regex.pattern, regex.flags);
398 BSONObjBuilder& appendCode(
const StringData& fieldName,
const StringData& code) {
399 checkFieldName(fieldName);
400 _b.appendNum((
char)Code);
401 _b.appendStr(fieldName);
402 _b.appendNum((
int)code.size() + 1);
407 BSONObjBuilder& append(
const StringData& fieldName,
const BSONCode& code) {
408 return appendCode(fieldName, code.code);
414 checkFieldName(fieldName);
415 _b.appendNum((
char)
String);
416 _b.appendStr(fieldName);
417 _b.appendNum((
int)sz);
418 _b.appendBuf(str, sz);
423 return append(fieldName, str, (
int)strlen(str) + 1);
427 return append(fieldName, str.c_str(), (
int)str.size() + 1);
431 checkFieldName(fieldName);
432 _b.appendNum((
char)
String);
433 _b.appendStr(fieldName);
434 _b.appendNum((
int)str.size() + 1);
435 _b.appendStr(str,
true);
440 checkFieldName(fieldName);
441 _b.appendNum((
char)Symbol);
442 _b.appendStr(fieldName);
443 _b.appendNum((
int)symbol.size() + 1);
444 _b.appendStr(symbol);
448 BSONObjBuilder& append(
const StringData& fieldName,
const BSONSymbol& symbol) {
449 return appendSymbol(fieldName, symbol.symbol);
454 msgasserted(16234,
"Invalid call to appendNull in BSONObj Builder.");
459 checkFieldName(fieldName);
461 _b.appendStr(fieldName);
467 checkFieldName(fieldName);
468 _b.appendNum((
char)MinKey);
469 _b.appendStr(fieldName);
473 BSONObjBuilder& appendMaxKey(
const StringData& fieldName) {
474 checkFieldName(fieldName);
475 _b.appendNum((
char)MaxKey);
476 _b.appendStr(fieldName);
483 checkFieldName(fieldName);
485 _b.appendStr(fieldName);
487 char buf[2 *
sizeof(uint32_t)];
489 cur.writeLEAndAdvance<>(ts.increment());
490 cur.writeLEAndAdvance<>(ts.seconds());
492 _b.appendBuf(buf,
sizeof(buf));
497 return appendTimestamp(fieldName, ts);
504 BSONObjBuilder& appendDBRef(
const StringData& fieldName,
const StringData& ns,
const OID& oid) {
505 checkFieldName(fieldName);
506 _b.appendNum((
char)DBRef);
507 _b.appendStr(fieldName);
508 _b.appendNum((
int)ns.size() + 1);
510 _b.appendBuf(oid.view().view(), OID::kOIDSize);
514 BSONObjBuilder& append(
const StringData& fieldName,
const BSONDBRef& dbref) {
515 return appendDBRef(fieldName, dbref.ns, dbref.oid);
529 checkFieldName(fieldName);
531 _b.appendStr(fieldName);
533 _b.appendNum((
char)type);
534 _b.appendBuf(data, len);
539 return appendBinData(fieldName, bd.length, bd.type, bd.data);
549 checkFieldName(fieldName);
551 _b.appendStr(fieldName);
552 _b.appendNum(len + 4);
553 _b.appendNum((
char)0x2);
555 _b.appendBuf(data, len);
565 checkFieldName(fieldName);
567 _b.appendStr(fieldName);
568 _b.appendNum((
int)(4 + 4 + code.size() + 1 + scope.
objsize()));
569 _b.appendNum((
int)code.size() + 1);
576 return appendCodeWScope(fieldName, cws.code, cws.scope);
579 void appendUndefined(
const StringData& fieldName) {
580 _b.appendNum((
char)Undefined);
581 _b.appendStr(fieldName);
585 void appendWhere(
const StringData& code,
const BSONObj& scope) {
586 appendCodeWScope(
"$where", code, scope);
593 void appendMaxForType(
const StringData& fieldName,
int type);
610 template <
class K,
class T>
619 massert(10335,
"builder does not own memory", owned());
621 char* buf = _b.buf();
623 return BSONObj::takeOwnership(buf);
646 _b.setlen(_b.len() - 1);
667 void appendKeys(
const BSONObj& keyPattern,
const BSONObj& values);
669 static std::string MONGO_CLIENT_FUNC numStr(
int i) {
670 if (i >= 0 && i < 100 && numStrsReady)
689 massert(10336,
"No subobject started", _s.subobjStarted());
693 template <
typename T>
694 BSONObjBuilderValueStream& operator<<(
const BSONField<T>& f) {
695 _s.endField(f.name());
699 template <
typename T>
700 BSONObjBuilder& operator<<(
const BSONFieldValue<T>& v) {
701 append(v.name(), v.value());
705 BSONObjBuilder& operator<<(
const BSONElement& e) {
735 return _b.buf() + _offset;
743 _b.claimReservedBytes(1);
744 _b.appendNum((
char)EOO);
746 char* data = _b.buf() + _offset;
747 int size = _b.len() - _offset;
748 DataView(data).writeLE(size);
757 BSONObjBuilderValueStream _s;
758 BSONSizeTracker* _tracker;
761 static const std::string numStrs[100];
762 static bool numStrsReady;
771 template <
typename T>
778 _b.appendAs(e, num());
786 template <
typename T>
788 _b << num().c_str() << x;
793 _b.appendNull(num());
796 void appendUndefined() {
797 _b.appendUndefined(num());
820 BSONArrayBuilder& append(
const std::list<T>& vals);
823 BSONArrayBuilder& append(
const std::set<T>& vals);
826 BufBuilder& subobjStart() {
827 return _b.subobjStart(num());
829 BufBuilder& subarrayStart() {
830 return _b.subarrayStart(num());
833 BSONArrayBuilder& appendRegex(
const StringData& regex,
const StringData& options =
"") {
834 uassert(0,
"regex cannot contain null bytes", regex.find(
'\0') == std::string::npos);
835 _b.appendRegex(num(), regex, options);
839 BSONArrayBuilder& appendBinData(
int len, BinDataType type,
const void* data) {
840 _b.appendBinData(num(), len, type, data);
844 BSONArrayBuilder& appendCode(
const StringData& code) {
845 _b.appendCode(num(), code);
849 BSONArrayBuilder& appendCodeWScope(
const StringData& code,
const BSONObj& scope) {
850 _b.appendCodeWScope(num(), code, scope);
854 BSONArrayBuilder& appendTimeT(time_t dt) {
855 _b.appendTimeT(num(), dt);
859 BSONArrayBuilder& appendDate(Date_t dt) {
860 _b.appendDate(num(), dt);
864 BSONArrayBuilder& appendBool(
bool val) {
865 _b.appendBool(num(), val);
869 bool isArray()
const {
876 int arrSize()
const {
886 return _b.numStr(_i++);
894 const std::vector<T>& vals) {
896 for (
unsigned int i = 0; i < vals.size(); ++i)
897 arrBuilder.
append(numStr(i), vals[i]);
908 for (
typename L::const_iterator i = vals.begin(); i != vals.end(); i++)
909 arrBuilder.
append(BSONObjBuilder::numStr(n++), *i);
916 const std::list<T>& vals) {
917 return _appendIt<std::list<T> >(*
this, fieldName, vals);
922 const std::set<T>& vals) {
923 return _appendIt<std::set<T> >(*
this, fieldName, vals);
926template <
class K,
class T>
928 const std::map<K, T>& vals) {
930 for (
typename std::map<K, T>::const_iterator i = vals.begin(); i != vals.end(); ++i) {
931 bob.
append(i->first, i->second);
940 for (
typename L::const_iterator i = vals.begin(); i != vals.end(); i++)
946inline BSONArrayBuilder& BSONArrayBuilder::append(
const std::list<T>& vals) {
947 return _appendArrayIt<std::list<T> >(*
this, vals);
951inline BSONArrayBuilder& BSONArrayBuilder::append(
const std::set<T>& vals) {
952 return _appendArrayIt<std::set<T> >(*
this, vals);
956inline BSONFieldValue<BSONObj> BSONField<T>::query(
const char* q,
const T& t)
const {
959 return BSONFieldValue<BSONObj>(_name, b.obj());
963inline BSONObj OR(
const BSONObj& a,
const BSONObj& b) {
964 return BSON(
"$or" << BSON_ARRAY(a << b));
966inline BSONObj OR(
const BSONObj& a,
const BSONObj& b,
const BSONObj& c) {
967 return BSON(
"$or" << BSON_ARRAY(a << b << c));
969inline BSONObj OR(
const BSONObj& a,
const BSONObj& b,
const BSONObj& c,
const BSONObj& d) {
970 return BSON(
"$or" << BSON_ARRAY(a << b << c << d));
973 const BSONObj& a,
const BSONObj& b,
const BSONObj& c,
const BSONObj& d,
const BSONObj& e) {
974 return BSON(
"$or" << BSON_ARRAY(a << b << c << d << e));
976inline BSONObj OR(
const BSONObj& a,
982 return BSON(
"$or" << BSON_ARRAY(a << b << c << d << e << f));
Definition bsonobjbuilder.h:765
BSONArray arr()
destructive - ownership moves to returned BSONArray
Definition bsonobjbuilder.h:804
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:216
const char * value() const
raw data of the element's value (so be careful).
Definition bsonelement.h:212
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:172
BSONType type() const
Returns the type of the element.
Definition bsonelement.h:154
Definition bsonmisc.h:208
Utility for creating a BSONObj.
Definition bsonobjbuilder.h:53
BSONObjBuilder(BufBuilder &baseBuilder)
Definition bsonobjbuilder.h:76
void abandon()
Make it look as if "done" has been called, so that our destructor is a no-op.
Definition bsonobjbuilder.h:659
BSONObjBuilder & append(const StringData &fieldName, const std::string &str)
Append a string element.
Definition bsonobjbuilder.h:426
bool owned() const
Definition bsonobjbuilder.h:716
BSONObjBuilder & append(const StringData &fieldName, BSONObj subObj)
add a subobject as a member
Definition bsonobjbuilder.h:142
BSONObjBuilder & append(const BSONElement &e)
append element to the object we are building
Definition bsonobjbuilder.h:124
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:226
BSONObjBuilder & append(const StringData &fieldName, double n)
Append a double element.
Definition bsonobjbuilder.h:301
BSONObjBuilder & append(const StringData &fieldName, long long n)
Append a NumberLong.
Definition bsonobjbuilder.h:240
BSONObj asTempObj()
Peek at what is in the builder, but leave the builder ready for more appends.
Definition bsonobjbuilder.h:644
BSONObjBuilder & appendOID(const StringData &fieldName, OID *oid=0, bool generateIfBlank=false)
Append a BSON Object ID (OID type).
Definition bsonobjbuilder.h:318
void appendNull()
Implements builder interface but no-op in ObjBuilder.
Definition bsonobjbuilder.h:453
BSONObjBuilder & append(const StringData &fieldName, unsigned n)
Append a 32 bit unsigned element - cast to a signed int.
Definition bsonobjbuilder.h:235
BSONObjBuilder & appendObject(const StringData &fieldName, const char *objdata, int size=0)
add a subobject as a member
Definition bsonobjbuilder.h:151
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:217
BSONObjBuilder & appendCodeWScope(const StringData &fieldName, const StringData &code, const BSONObj &scope)
Append to the BSON object a field of type CodeWScope.
Definition bsonobjbuilder.h:562
BSONObjBuilder & append(const StringData &fieldName, const char *str, int sz)
Append a string element.
Definition bsonobjbuilder.h:413
BSONObjBuilder & append(const StringData &fieldName, const char *str)
Append a string element.
Definition bsonobjbuilder.h:422
BSONObjBuilder & appendNull(const StringData &fieldName)
Append a Null element to the object.
Definition bsonobjbuilder.h:458
BSONObjBuilder & appendTimestamp(const StringData &fieldName, const Timestamp_t &ts=Timestamp_t())
Append a Timestamp element to the object.
Definition bsonobjbuilder.h:481
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:200
BSONObjBuilder & append(const StringData &fieldName, const StringData &str)
Append a string element.
Definition bsonobjbuilder.h:430
BSONObjBuilderValueStream & operator<<(const StringData &name)
Stream oriented way to add field names and values.
Definition bsonobjbuilder.h:678
BSONObjBuilder & appendAs(const BSONElement &e, const StringData &fieldName)
append an element but with a new name
Definition bsonobjbuilder.h:132
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:548
BSONObjBuilder & appendBinData(const StringData &fieldName, int len, BinDataType type, const void *data)
Append a binary data element.
Definition bsonobjbuilder.h:525
BSONObjBuilder & appendBool(const StringData &fieldName, int val)
Append a boolean element.
Definition bsonobjbuilder.h:208
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:618
BSONObj done()
Fetch the object we have built.
Definition bsonobjbuilder.h:631
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:177
BSONObjBuilder & appendArray(const StringData &fieldName, const BSONObj &subObj)
add a subobject as a member with type Array.
Definition bsonobjbuilder.h:187
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:684
BSONObjBuilder(int initsize=512)
Definition bsonobjbuilder.h:56
BSONObjBuilder & appendIntOrLL(const StringData &fieldName, long long n)
appends a number.
Definition bsonobjbuilder.h:249
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:308
const char * objdata() const
Definition bsonobj.h:303
used in conjuction with BSONObjBuilder, allows for proper buffer size to prevent crazy memory usage
Definition bsonmisc.h:259
Definition data_view.h:30
Definition data_cursor.h:101
Definition bsonmisc.h:120
Object ID type.
Definition oid.h:60
void clear()
initialize to 'null'
Definition oid.h:86
void init()
sets the contents to a new oid / randomized value
Definition shared_buffer.h:67
A StringData object wraps a 'const string&' or a 'const char*' without copying its contents.
Definition string_data.h:43
Definition timestamp.h:23
int len() const
Definition builder.h:222
Utility functions for parsing numbers from strings.
Definition compare_numbers.h:32
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:169
Definition bsonmisc.h:155
Definition bsonmisc.h:162
Definition time_support.h:39
Definition bsonmisc.h:122