MongoDB C++ Driver legacy-1.1.2
Loading...
Searching...
No Matches
bsonobj.h
1// @file bsonobj.h
2
3/* Copyright 2009 10gen Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#pragma once
19
20#include <boost/noncopyable.hpp>
21#include <set>
22#include <list>
23#include <string>
24#include <vector>
25#include <utility>
26
27#include "mongo/bson/bsonelement.h"
28#include "mongo/base/data_view.h"
29#include "mongo/base/string_data.h"
30#include "mongo/bson/util/builder.h"
31#include "mongo/client/export_macros.h"
32#include "mongo/platform/atomic_word.h"
33#include "mongo/util/shared_buffer.h"
34
35namespace mongo {
36
37typedef std::set<BSONElement, BSONElementCmpWithoutField> BSONElementSet;
38typedef std::multiset<BSONElement, BSONElementCmpWithoutField> BSONElementMSet;
39
78class MONGO_CLIENT_API BSONObj {
79public:
82 // Little endian ordering here, but that is ok regardless as BSON is spec'd to be
83 // little endian external to the system. (i.e. the rest of the implementation of
84 // bson, not this part, fails to support big endian)
85 static const char kEmptyObjectPrototype[] = {/*size*/ 5, 0, 0, 0, /*eoo*/ 0};
86 _objdata = kEmptyObjectPrototype;
87 }
88
92 explicit BSONObj(const char* bsonData) {
93 init(bsonData);
94 }
95
96 explicit BSONObj(SharedBuffer ownedBuffer)
97 : _objdata(ownedBuffer.get() ? ownedBuffer.get() : BSONObj().objdata()),
98 _ownedBuffer(ownedBuffer.moveFrom()) {}
99
100#if __cplusplus >= 201103L
102 BSONObj(BSONObj&& other)
103 : _objdata(std::move(other._objdata)), _ownedBuffer(std::move(other._ownedBuffer)) {
104 other._objdata = BSONObj()._objdata; // To return to an empty state.
105 }
106
107 // The explicit move constructor above will inhibit generation of the copy ctor, so
108 // explicitly request the default implementation.
109
111 BSONObj(const BSONObj&) = default;
112#endif
113
118 this->swap(otherCopy);
119 return *this;
120 }
121
123 void swap(BSONObj& other) {
124 using std::swap;
125 swap(_objdata, other._objdata);
126 swap(_ownedBuffer, other._ownedBuffer);
127 }
128
157 bool isOwned() const {
158 return _ownedBuffer.get() != 0;
159 }
160
165
167 BSONObj copy() const;
168
172 enum { maxToStringRecursionDepth = 100 };
173
174 std::string toString(bool isArray = false, bool full = false) const;
175 void toString(StringBuilder& s, bool isArray = false, bool full = false, int depth = 0) const;
176
180 std::string jsonString(JsonStringFormat format = Strict,
181 int pretty = 0,
182 bool isArray = false) const;
183
185 int addFields(BSONObj& from, std::set<std::string>& fields); /* returns n added */
186
190 BSONObj removeField(const StringData& name) const;
191
195 int nFields() const;
196
198 int getFieldNames(std::set<std::string>& fields) const;
199
205
210 void getFieldsDotted(const StringData& name,
211 BSONElementSet& ret,
212 bool expandLastArray = true) const;
213 void getFieldsDotted(const StringData& name,
214 BSONElementMSet& ret,
215 bool expandLastArray = true) const;
216
220 BSONElement getFieldDottedOrArray(const char*& name) const;
221
225 BSONElement getField(const StringData& name) const;
226
233 void getFields(unsigned n, const char** fieldNames, BSONElement* fields) const;
234
238 BSONElement operator[](const StringData& field) const {
239 return getField(field);
240 }
241
242 BSONElement operator[](int field) const {
243 StringBuilder ss;
244 ss << field;
245 std::string s = ss.str();
246 return getField(s.c_str());
247 }
248
250 bool hasField(const StringData& name) const {
251 return !getField(name).eoo();
252 }
254 bool hasElement(const StringData& name) const {
255 return hasField(name);
256 }
257
259 const char* getStringField(const StringData& name) const;
260
263
265 int getIntField(const StringData& name) const;
266
270 bool getBoolField(const StringData& name) const;
271
284 BSONObj extractFieldsUnDotted(const BSONObj& pattern) const;
285
291 BSONObj extractFields(const BSONObj& pattern, bool fillWithNull = false) const;
292
293 BSONObj filterFieldsUndotted(const BSONObj& filter, bool inFilter) const;
294
295 BSONElement getFieldUsingIndexNames(const StringData& fieldName, const BSONObj& indexKey) const;
296
300 bool couldBeArray() const;
301
303 const char* objdata() const {
304 return _objdata;
305 }
306
308 int objsize() const {
309 return ConstDataView(objdata()).readLE<int>();
310 }
311
313 bool isValid() const {
314 int x = objsize();
315 return x > 0 && x <= BSONObjMaxInternalSize;
316 }
317
324 inline bool okForStorage() const {
325 return _okForStorage(false, true).isOK();
326 }
327
334 inline bool okForStorageAsRoot() const {
335 return _okForStorage(true, true).isOK();
336 }
337
346 inline Status storageValidEmbedded(const bool deep = true) const {
347 return _okForStorage(false, deep);
348 }
349
358 inline Status storageValid(const bool deep = true) const {
359 return _okForStorage(true, deep);
360 }
361
363 bool isEmpty() const {
364 return objsize() <= 5;
365 }
366
367 void dump() const;
368
370 std::string hexDump() const;
371
377 int woCompare(const BSONObj& r, const Ordering& o, bool considerFieldName = true) const;
378
384 int woCompare(const BSONObj& r,
385 const BSONObj& ordering = BSONObj(),
386 bool considerFieldName = true) const;
387
388 bool operator<(const BSONObj& other) const {
389 return woCompare(other) < 0;
390 }
391 bool operator<=(const BSONObj& other) const {
392 return woCompare(other) <= 0;
393 }
394 bool operator>(const BSONObj& other) const {
395 return woCompare(other) > 0;
396 }
397 bool operator>=(const BSONObj& other) const {
398 return woCompare(other) >= 0;
399 }
400
404 int woSortOrder(const BSONObj& r, const BSONObj& sortKey, bool useDotted = false) const;
405
406 bool equal(const BSONObj& r) const;
407
413 struct Hasher {
414 size_t operator()(const BSONObj& obj) const;
415 };
416
423 bool isPrefixOf(const BSONObj& otherObj) const;
424
431 bool isFieldNamePrefixOf(const BSONObj& otherObj) const;
432
436 bool binaryEqual(const BSONObj& r) const {
437 int os = objsize();
438 if (os == r.objsize()) {
439 return (os == 0 || memcmp(objdata(), r.objdata(), os) == 0);
440 }
441 return false;
442 }
443
446 return BSONElement(objdata() + 4);
447 }
448
452 const char* firstElementFieldName() const {
453 const char* p = objdata() + 4;
454 return *p == EOO ? "" : p + 1;
455 }
456
457 BSONType firstElementType() const {
458 const char* p = objdata() + 4;
459 return (BSONType)*p;
460 }
461
467 bool getObjectID(BSONElement& e) const;
468
469 // Return a version of this object where top level elements of types
470 // that are not part of the bson wire protocol are replaced with
471 // string identifier equivalents.
472 // TODO Support conversion of element types other than min and max.
473 BSONObj clientReadable() const;
474
478
480 bool valid() const;
481
482 bool operator==(const BSONObj& other) const {
483 return equal(other);
484 }
485 bool operator!=(const BSONObj& other) const {
486 return !operator==(other);
487 }
488
489 enum MatchType {
490 Equality = 0,
491 LT = 0x1,
492 LTE = 0x3,
493 GTE = 0x6,
494 GT = 0x4,
495 opIN = 0x8, // { x : { $in : [1,2,3] } }
496 NE = 0x9,
497 opSIZE = 0x0A,
498 opALL = 0x0B,
499 NIN = 0x0C,
500 opEXISTS = 0x0D,
501 opMOD = 0x0E,
502 opTYPE = 0x0F,
503 opREGEX = 0x10,
504 opOPTIONS = 0x11,
505 opELEM_MATCH = 0x12,
506 opNEAR = 0x13,
507 opWITHIN = 0x14,
508 opMAX_DISTANCE = 0x15,
509 opGEO_INTERSECTS = 0x16,
510 };
511
513 void elems(std::vector<BSONElement>&) const;
515 void elems(std::list<BSONElement>&) const;
516
517 friend class BSONObjIterator;
519
527
528 void appendSelfToBufBuilder(BufBuilder& b) const {
529 verify(objsize());
530 b.appendBuf(objdata(), objsize());
531 }
532
533 template <typename T>
534 bool coerceVector(std::vector<T>* out) const;
535
536 typedef SharedBuffer::Holder Holder;
537
545 static BSONObj takeOwnership(char* holderPrefixedData) {
546 return BSONObj(SharedBuffer::takeOwnership(holderPrefixedData));
547 }
548
549private:
550 void _assertInvalid() const;
551
552 void init(const char* data) {
553 _objdata = data;
554 if (!isValid())
555 _assertInvalid();
556 }
557
564 Status _okForStorage(bool root, bool deep) const;
565
566 const char* _objdata;
567 SharedBuffer _ownedBuffer;
568};
569
570MONGO_CLIENT_API std::ostream& MONGO_CLIENT_FUNC operator<<(std::ostream& s, const BSONObj& o);
571MONGO_CLIENT_API std::ostream& MONGO_CLIENT_FUNC operator<<(std::ostream& s, const BSONElement& e);
572
573MONGO_CLIENT_API StringBuilder& MONGO_CLIENT_FUNC operator<<(StringBuilder& s, const BSONObj& o);
574MONGO_CLIENT_API StringBuilder& MONGO_CLIENT_FUNC
575operator<<(StringBuilder& s, const BSONElement& e);
576
577inline void swap(BSONObj& l, BSONObj& r) {
578 l.swap(r);
579}
580
582 // Don't add anything other than forwarding constructors!!!
583 BSONArray() : BSONObj() {}
584 explicit BSONArray(const BSONObj& obj) : BSONObj(obj) {}
585};
586}
BSONElement represents an "element" in a BSONObj.
Definition bsonelement.h:55
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
void getFields(unsigned n, const char **fieldNames, BSONElement *fields) const
Get several fields at once.
bool getObjectID(BSONElement &e) const
Get the _id field from the object.
BSONObj & operator=(BSONObj otherCopy)
Provide assignment semantics.
Definition bsonobj.h:117
bool okForStorage() const
Definition bsonobj.h:324
int woCompare(const BSONObj &r, const BSONObj &ordering=BSONObj(), bool considerFieldName=true) const
wo='well ordered'.
int addFields(BSONObj &from, std::set< std::string > &fields)
note: addFields always adds _id even if not specified
const char * firstElementFieldName() const
faster than firstElement().fieldName() - for the first element we can easily find the fieldname witho...
Definition bsonobj.h:452
bool isOwned() const
A BSONObj can use a buffer it "owns" or one it does not.
Definition bsonobj.h:157
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
bool getBoolField(const StringData &name) const
BSONObj getObjectField(const StringData &name) const
int getFieldNames(std::set< std::string > &fields) const
adds the field names to the fields set.
Status storageValidEmbedded(const bool deep=true) const
Validates that this can be stored as an embedded document See details above in okForStorage.
Definition bsonobj.h:346
bool okForStorageAsRoot() const
Same as above with the following extra restrictions Not valid if:
Definition bsonobj.h:334
bool couldBeArray() const
arrays are bson objects with numeric and increasing field names
BSONObjIterator begin() const
use something like this: for( BSONObj::iterator i = myObj.begin(); i.more(); ) { BSONElement e = i....
BSONElement getFieldDottedOrArray(const char *&name) const
Like getFieldDotted(), but returns first array encountered while traversing the dotted fields of name...
BSONObj copy() const
bool hasField(const StringData &name) const
Definition bsonobj.h:250
void getFieldsDotted(const StringData &name, BSONElementSet &ret, bool expandLastArray=true) const
Like getFieldDotted(), but expands arrays and returns all matching objects.
BSONObj extractFields(const BSONObj &pattern, bool fillWithNull=false) const
extract items from object which match a pattern object.
BSONElement operator[](const StringData &field) const
Get the field of the specified name.
Definition bsonobj.h:238
BSONObj getOwned() const
assure the data buffer is under the control of this BSONObj and not a remote buffer
std::string jsonString(JsonStringFormat format=Strict, int pretty=0, bool isArray=false) const
Properly formatted JSON string.
int objsize() const
Definition bsonobj.h:308
bool isValid() const
performs a cursory check on the object's size only.
Definition bsonobj.h:313
void elems(std::list< BSONElement > &) const
add all elements of the object to the specified list
BSONObj replaceFieldNames(const BSONObj &obj) const
Return new object with the field names replaced by those in the passed object.
BSONObj(const char *bsonData)
Construct a BSONObj from data in the proper format.
Definition bsonobj.h:92
bool isFieldNamePrefixOf(const BSONObj &otherObj) const
int woSortOrder(const BSONObj &r, const BSONObj &sortKey, bool useDotted=false) const
Status storageValid(const bool deep=true) const
Validates that this can be stored as a document (in a collection) See details above in okForStorageAs...
Definition bsonobj.h:358
void elems(std::vector< BSONElement > &) const
add all elements of the object to the specified vector
const char * getStringField(const StringData &name) const
bool binaryEqual(const BSONObj &r) const
This is "shallow equality" – ints and doubles won't match.
Definition bsonobj.h:436
void swap(BSONObj &other)
Swap this BSONObj with 'other'.
Definition bsonobj.h:123
BSONElement getFieldDotted(const StringData &name) const
bool isPrefixOf(const BSONObj &otherObj) const
const char * objdata() const
Definition bsonobj.h:303
bool isEmpty() const
Definition bsonobj.h:363
int woCompare(const BSONObj &r, const Ordering &o, bool considerFieldName=true) const
wo='well ordered'.
bool valid() const
true unless corrupt
int nFields() const
returns # of top level fields in the object note: iterates to count the fields
std::string hexDump() const
Alternative output format.
BSONObj()
Construct an empty BSONObj – that is, {}.
Definition bsonobj.h:81
int getIntField(const StringData &name) const
BSONObj removeField(const StringData &name) const
remove specified field and return a new object with the remaining fields.
BSONElement getField(const StringData &name) const
Get the field of the specified name.
bool hasElement(const StringData &name) const
Definition bsonobj.h:254
BSONObj extractFieldsUnDotted(const BSONObj &pattern) const
BSONElement firstElement() const
Definition bsonobj.h:445
Definition data_view.h:30
A precomputation of a BSON index or sort key pattern.
Definition ordering.h:32
Definition shared_buffer.h:67
Definition shared_buffer.h:25
Status represents an error state or the absence thereof.
Definition status.h:50
std::stringstream deals with locale so this is a lot faster than std::stringstream for UTF8
Definition builder.h:325
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
JsonStringFormat
Formatting mode for generating JSON from BSON.
Definition oid.h:205
BSONType
the complete list of valid BSON types see also bsonspec.org
Definition bsontypes.h:38
@ EOO
end of object
Definition bsontypes.h:42
Definition bsonobj.h:581
Functor compatible with std::hash for std::unordered_{map,set} Warning: The hash function is subject ...
Definition bsonobj.h:413