MongoDB C++ Driver  legacy-1.1.2
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 
35 namespace mongo {
36 
37 typedef std::set<BSONElement, BSONElementCmpWithoutField> BSONElementSet;
38 typedef std::multiset<BSONElement, BSONElementCmpWithoutField> BSONElementMSet;
39 
78 class MONGO_CLIENT_API BSONObj {
79 public:
81  BSONObj() {
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
101 
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 
117  BSONObj& operator=(BSONObj otherCopy) {
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 
164  BSONObj getOwned() const;
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 
204  BSONElement getFieldDotted(const StringData& name) const;
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 
262  BSONObj getObjectField(const StringData& name) const;
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 
477  BSONObj replaceFieldNames(const BSONObj& obj) const;
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;
518  typedef BSONObjIterator iterator;
519 
526  BSONObjIterator begin() const;
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 
549 private:
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 
570 MONGO_CLIENT_API std::ostream& MONGO_CLIENT_FUNC operator<<(std::ostream& s, const BSONObj& o);
571 MONGO_CLIENT_API std::ostream& MONGO_CLIENT_FUNC operator<<(std::ostream& s, const BSONElement& e);
572 
573 MONGO_CLIENT_API StringBuilder& MONGO_CLIENT_FUNC operator<<(StringBuilder& s, const BSONObj& o);
574 MONGO_CLIENT_API StringBuilder& MONGO_CLIENT_FUNC
575 operator<<(StringBuilder& s, const BSONElement& e);
576 
577 inline void swap(BSONObj& l, BSONObj& r) {
578  l.swap(r);
579 }
580 
581 struct BSONArray : BSONObj {
582  // Don't add anything other than forwarding constructors!!!
583  BSONArray() : BSONObj() {}
584  explicit BSONArray(const BSONObj& obj) : BSONObj(obj) {}
585 };
586 }
end of object
Definition: bsontypes.h:42
JsonStringFormat
Formatting mode for generating JSON from BSON.
Definition: oid.h:205
Status represents an error state or the absence thereof.
Definition: status.h:50
BSONElement firstElement() const
Definition: bsonobj.h:445
bool isOwned() const
A BSONObj can use a buffer it "owns" or one it does not.
Definition: bsonobj.h:157
std::stringstream deals with locale so this is a lot faster than std::stringstream for UTF8 ...
Definition: builder.h:53
int objsize() const
Definition: bsonobj.h:308
Definition: shared_buffer.h:25
bool hasField(const StringData &name) const
Definition: bsonobj.h:250
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
BSONObj(const char *bsonData)
Construct a BSONObj from data in the proper format.
Definition: bsonobj.h:92
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
const char * objdata() const
Definition: bsonobj.h:303
Definition: data_view.h:30
bool okForStorage() const
Definition: bsonobj.h:324
bool hasElement(const StringData &name) const
Definition: bsonobj.h:254
strict RFC format
Definition: oid.h:207
BSONObj & operator=(BSONObj otherCopy)
Provide assignment semantics.
Definition: bsonobj.h:117
void swap(BSONObj &other)
Swap this BSONObj with 'other'.
Definition: bsonobj.h:123
bool isValid() const
performs a cursory check on the object's size only.
Definition: bsonobj.h:313
BSONType
the complete list of valid BSON types see also bsonspec.org
Definition: bsontypes.h:38
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
MONGO_CLIENT_API bool isArray(const StringData &str)
Tests whether the JSON string is an Array.
bool okForStorageAsRoot() const
Same as above with the following extra restrictions Not valid if:
Definition: bsonobj.h:334
static SharedBuffer takeOwnership(char *holderPrefixedData)
Given a pointer to a region of un-owned data, prefixed by sufficient space for a SharedBuffer::Holder...
Definition: shared_buffer.h:54
const char * firstElementFieldName() const
faster than firstElement().fieldName() - for the first element we can easily find the fieldname witho...
Definition: bsonobj.h:452
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
BSONElement represents an "element" in a BSONObj.
Definition: bsonelement.h:55
Definition: bsonobj.h:581
BSONElement operator[](const StringData &field) const
Get the field of the specified name.
Definition: bsonobj.h:238
bool isEmpty() const
Definition: bsonobj.h:363
bool binaryEqual(const BSONObj &r) const
This is "shallow equality" – ints and doubles won't match.
Definition: bsonobj.h:436
BSONObj()
Construct an empty BSONObj – that is, {}.
Definition: bsonobj.h:81
A precomputation of a BSON index or sort key pattern.
Definition: ordering.h:32
C++ representation of a "BSON" object – that is, an extended JSON-style object in a binary represent...
Definition: bsonobj.h:78
MONGO_CLIENT_API Status(MONGO_CLIENT_FUNC *saslClientAuthenticate)(DBClientWithCommands *client
Attempts to authenticate "client" using the SASL protocol.
Functor compatible with std::hash for std::unordered_{map,set} Warning: The hash function is subject ...
Definition: bsonobj.h:413