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)),
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) {
118 BSONObjBuilder& appendElements(BSONObj x);
121 BSONObjBuilder& appendElementsUnique(BSONObj x);
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);
312 bool appendAsNumber(
const StringData& fieldName,
const std::string& data);
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) {
581 _b.appendStr(fieldName);
585 void appendWhere(
const StringData& code,
const BSONObj& scope) {
586 appendCodeWScope(
"$where", code, scope);
592 void appendMinForType(
const StringData& fieldName,
int type);
593 void appendMaxForType(
const StringData& fieldName,
int type);
597 BSONObjBuilder& append(
const StringData& fieldName,
const std::vector<T>& vals);
600 BSONObjBuilder& append(
const StringData& fieldName,
const std::list<T>& vals);
604 BSONObjBuilder& append(
const StringData& fieldName,
const std::set<T>& vals);
610 template <
class K,
class T>
611 BSONObjBuilder& append(
const StringData& fieldName,
const std::map<K, T>& vals);
619 massert(10335,
"builder does not own memory", owned());
621 char* buf = _b.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);
926 template <
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++)
946 inline BSONArrayBuilder& BSONArrayBuilder::append(
const std::list<T>& vals) {
947 return _appendArrayIt<std::list<T> >(*
this, vals);
951 inline BSONArrayBuilder& BSONArrayBuilder::append(
const std::set<T>& vals) {
952 return _appendArrayIt<std::set<T> >(*
this, vals);
955 template <
typename T>
956 inline BSONFieldValue<BSONObj> BSONField<T>::query(
const char* q,
const T& t)
const {
959 return BSONFieldValue<BSONObj>(_name, b.obj());
963 inline BSONObj OR(
const BSONObj& a,
const BSONObj& b) {
964 return BSON(
"$or" << BSON_ARRAY(a << b));
966 inline BSONObj OR(
const BSONObj& a,
const BSONObj& b,
const BSONObj& c) {
967 return BSON(
"$or" << BSON_ARRAY(a << b << c));
969 inline 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));
976 inline BSONObj OR(
const BSONObj& a,
982 return BSON(
"$or" << BSON_ARRAY(a << b << c << d << e << f));
void abandon()
Make it look as if "done" has been called, so that our destructor is a no-op.
Definition: bsonobjbuilder.h:659
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 & append(const StringData &fieldName, long long n)
Append a NumberLong.
Definition: bsonobjbuilder.h:240
Definition: timestamp.h:23
end of object
Definition: bsontypes.h:42
Definition: bsonmisc.h:155
BSONArray arr()
destructive - ownership moves to returned BSONArray
Definition: bsonobjbuilder.h:804
int objsize() const
Definition: bsonobj.h:308
larger than all other types
Definition: bsontypes.h:82
BSONObjBuilder & appendOID(const StringData &fieldName, OID *oid=0, bool generateIfBlank=false)
Append a BSON Object ID (OID type).
Definition: bsonobjbuilder.h:318
A StringData object wraps a 'const string&' or a 'const char*' without copying its contents...
Definition: string_data.h:43
Utility functions for parsing numbers from strings.
Definition: compare_numbers.h:20
int size(int maxLen) const
Size of the element.
Definition: bsonmisc.h:122
static BSONObj takeOwnership(char *holderPrefixedData)
Given a pointer to a region of un-owned memory containing BSON data, prefixed by sufficient space for...
Definition: bsonobj.h:545
BSONObj obj()
destructive The returned BSONObj will free the buffer when it is finished.
Definition: bsonobjbuilder.h:618
Object ID type.
Definition: oid.h:60
BSONObjBuilder & appendTimestamp(const StringData &fieldName, const Timestamp_t &ts=Timestamp_t())
Append a Timestamp element to the object.
Definition: bsonobjbuilder.h:481
const char * objdata() const
Definition: bsonobj.h:303
Definition: data_view.h:30
BSONObjBuilder & append(const BSONElement &e)
append element to the object we are building
Definition: bsonobjbuilder.h:124
Definition: bsonmisc.h:86
Updated to a Date with value next OpTime on insert.
Definition: bsontypes.h:76
BSONObjBuilder & appendBool(const StringData &fieldName, int val)
Append a boolean element.
Definition: bsonobjbuilder.h:208
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 char *str)
Append a string element.
Definition: bsonobjbuilder.h:422
BSONObjBuilder & appendBinDataArrayDeprecated(const char *fieldName, const void *data, int len)
Subtype 2 is deprecated.
Definition: bsonobjbuilder.h:548
used in conjuction with BSONObjBuilder, allows for proper buffer size to prevent crazy memory usage ...
Definition: bsonmisc.h:259
BSONObjBuilder & appendNull(const StringData &fieldName)
Append a Null element to the object.
Definition: bsonobjbuilder.h:458
date type
Definition: bsontypes.h:60
boolean type
Definition: bsontypes.h:58
BSONObjBuilder & append(const StringData &fieldName, double n)
Append a double element.
Definition: bsonobjbuilder.h:301
smaller than all other types
Definition: bsontypes.h:40
Utility for creating a BSONObj.
Definition: bsonobjbuilder.h:53
BSONObj done()
Fetch the object we have built.
Definition: bsonobjbuilder.h:631
BSONObj asTempObj()
Peek at what is in the builder, but leave the builder ready for more appends.
Definition: bsonobjbuilder.h:644
const char * value() const
raw data of the element's value (so be careful).
Definition: bsonelement.h:212
BSONType type() const
Returns the type of the element.
Definition: bsonelement.h:154
Definition: time_support.h:39
ObjectId.
Definition: bsontypes.h:56
an embedded object
Definition: bsontypes.h:48
BSONObjBuilder & append(const StringData &fieldName, const char *str, int sz)
Append a string element.
Definition: bsonobjbuilder.h:413
32 bit signed integer
Definition: bsontypes.h:74
double precision floating point value
Definition: bsontypes.h:44
null type
Definition: bsontypes.h:62
a programming language (e.g., Python) symbol
Definition: bsontypes.h:70
Definition: data_cursor.h:101
javascript code that can execute on the database server, with SavedContext
Definition: bsontypes.h:72
iterator for a BSONObj
Definition: bsonobjiterator.h:37
void init()
sets the contents to a new oid / randomized value
MONGO_CLIENT_API bool isArray(const StringData &str)
Tests whether the JSON string is an Array.
Definition: shared_buffer.h:67
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
Definition: bsonmisc.h:169
int valuesize() const
size in bytes of the element's value (when applicable).
Definition: bsonelement.h:216
Undefined type.
Definition: bsontypes.h:54
BSONObjBuilder & append(const StringData &fieldName, OID oid)
Append a BSON Object ID.
Definition: bsonobjbuilder.h:342
BSONObjBuilder & genOID()
Generate and assign an object id for the _id field.
Definition: bsonobjbuilder.h:354
Definition: bsonmisc.h:162
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
BSONObjBuilder & appendRegex(const StringData &fieldName, const StringData ®ex, const StringData &options="")
Append a regular expression value.
Definition: bsonobjbuilder.h:382
BSONObjBuilder & appendTimeT(const StringData &fieldName, time_t dt)
Append a time_t date.
Definition: bsonobjbuilder.h:362
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
void appendNull()
Implements builder interface but no-op in ObjBuilder.
Definition: bsonobjbuilder.h:453
regular expression, a pattern with options
Definition: bsontypes.h:64
64 bit integer
Definition: bsontypes.h:78
BSONObjBuilder & appendArray(const StringData &fieldName, const BSONObj &subObj)
add a subobject as a member with type Array.
Definition: bsonobjbuilder.h:187
BSONObjBuilder & appendAs(const BSONElement &e, const StringData &fieldName)
append an element but with a new name
Definition: bsonobjbuilder.h:132
an embedded array
Definition: bsontypes.h:50
BSONObjBuilder & append(const StringData &fieldName, unsigned n)
Append a 32 bit unsigned element - cast to a signed int.
Definition: bsonobjbuilder.h:235
deprecated / use CodeWScope
Definition: bsontypes.h:68
BSONObjBuilder & appendObject(const StringData &fieldName, const char *objdata, int size=0)
add a subobject as a member
Definition: bsonobjbuilder.h:151
BSONObjBuilder(int initsize=512)
Definition: bsonobjbuilder.h:56
BSONElement represents an "element" in a BSONObj.
Definition: bsonelement.h:55
deprecated / will be redesigned
Definition: bsontypes.h:66
BSONObjBuilderValueStream & operator<<(const StringData &name)
Stream oriented way to add field names and values.
Definition: bsonobjbuilder.h:678
BSONObjBuilder & append(const StringData &fieldName, int n)
Append a 32 bit integer element.
Definition: bsonobjbuilder.h:226
Definition: bsonobj.h:581
BSONObjBuilder & appendBinData(const StringData &fieldName, int len, BinDataType type, const void *data)
Append a binary data element.
Definition: bsonobjbuilder.h:525
BSONObjBuilder & appendIntOrLL(const StringData &fieldName, long long n)
appends a number.
Definition: bsonobjbuilder.h:249
BSONObjBuilder & append(const StringData &fieldName, const StringData &str)
Append a string element.
Definition: bsonobjbuilder.h:430
int len() const
Definition: builder.h:222
Definition: bsonmisc.h:120
Definition: bsonobjbuilder.h:765
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 & operator<<(GENOIDLabeler)
Stream oriented way to add field names and values.
Definition: bsonobjbuilder.h:684
binary data
Definition: bsontypes.h:52
BSONObjBuilder & append(const StringData &fieldName, bool val)
Append a boolean element.
Definition: bsonobjbuilder.h:217
void clear()
initialize to 'null'
Definition: oid.h:86
C++ representation of a "BSON" object – that is, an extended JSON-style object in a binary represent...
Definition: bsonobj.h:78
BSONObjBuilder & append(const StringData &fieldName, const std::string &str)
Append a string element.
Definition: bsonobjbuilder.h:426
Definition: bsonmisc.h:208
BSONObjBuilder(BufBuilder &baseBuilder)
Definition: bsonobjbuilder.h:76
character string, stored in utf8
Definition: bsontypes.h:46