MongoDB  2.7.0
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/intrusive_ptr.hpp>
21 #include <boost/noncopyable.hpp>
22 #include <set>
23 #include <list>
24 #include <string>
25 #include <vector>
26 
27 #include "mongo/bson/bsonelement.h"
28 #include "mongo/base/string_data.h"
29 #include "mongo/bson/util/atomic_int.h"
30 #include "mongo/bson/util/builder.h"
31 #include "mongo/client/export_macros.h"
32 #include "mongo/util/bufreader.h"
33 
34 namespace mongo {
35 
36  typedef std::set< BSONElement, BSONElementCmpWithoutField > BSONElementSet;
37  typedef std::multiset< BSONElement, BSONElementCmpWithoutField > BSONElementMSet;
38 
77  class MONGO_CLIENT_API BSONObj {
78  public:
79 
83  explicit BSONObj(const char *msgdata) {
84  init(msgdata);
85  }
86 
91  class Holder;
92  explicit BSONObj(Holder* holder) {
93  init(holder);
94  }
95 
97  BSONObj();
98 
99  ~BSONObj() {
100  _objdata = 0; // defensive
101  }
102 
131  bool isOwned() const { return _holder.get() != 0; }
132 
136  BSONObj getOwned() const;
137 
139  BSONObj copy() const;
140 
144  enum { maxToStringRecursionDepth = 100 };
145 
146  std::string toString( bool isArray = false, bool full=false ) const;
147  void toString( StringBuilder& s, bool isArray = false, bool full=false, int depth=0 ) const;
148 
152  std::string jsonString( JsonStringFormat format = Strict, int pretty = 0 ) const;
153 
155  int addFields(BSONObj& from, std::set<std::string>& fields); /* returns n added */
156 
160  BSONObj removeField(const StringData& name) const;
161 
165  int nFields() const;
166 
168  int getFieldNames(std::set<std::string>& fields) const;
169 
174  BSONElement getFieldDotted(const StringData &name) const;
175 
180  void getFieldsDotted(const StringData& name, BSONElementSet &ret, bool expandLastArray = true ) const;
181  void getFieldsDotted(const StringData& name, BSONElementMSet &ret, bool expandLastArray = true ) const;
182 
186  BSONElement getFieldDottedOrArray(const char *&name) const;
187 
191  BSONElement getField(const StringData& name) const;
192 
199  void getFields(unsigned n, const char **fieldNames, BSONElement *fields) const;
200 
204  BSONElement operator[] (const StringData& field) const {
205  return getField(field);
206  }
207 
208  BSONElement operator[] (int field) const {
209  StringBuilder ss;
210  ss << field;
211  std::string s = ss.str();
212  return getField(s.c_str());
213  }
214 
216  bool hasField( const StringData& name ) const { return !getField(name).eoo(); }
218  bool hasElement(const StringData& name) const { return hasField(name); }
219 
221  const char * getStringField(const StringData& name) const;
222 
224  BSONObj getObjectField(const StringData& name) const;
225 
227  int getIntField(const StringData& name) const;
228 
232  bool getBoolField(const StringData& name) const;
233 
246  BSONObj extractFieldsUnDotted(const BSONObj& pattern) const;
247 
253  BSONObj extractFields(const BSONObj &pattern , bool fillWithNull=false) const;
254 
255  BSONObj filterFieldsUndotted(const BSONObj &filter, bool inFilter) const;
256 
257  BSONElement getFieldUsingIndexNames(const StringData& fieldName,
258  const BSONObj &indexKey) const;
259 
263  bool couldBeArray() const;
264 
266  const char *objdata() const {
267  return _objdata;
268  }
270  int objsize() const { return *(reinterpret_cast<const int*>(objdata())); }
271 
273  bool isValid() const;
274 
281  inline bool okForStorage() const {
282  return _okForStorage(false, true).isOK();
283  }
284 
291  inline bool okForStorageAsRoot() const {
292  return _okForStorage(true, true).isOK();
293  }
294 
303  inline Status storageValidEmbedded(const bool deep = true) const {
304  return _okForStorage(false, deep);
305  }
306 
315  inline Status storageValid(const bool deep = true) const {
316  return _okForStorage(true, deep);
317  }
318 
320  bool isEmpty() const { return objsize() <= 5; }
321 
322  void dump() const;
323 
325  std::string hexDump() const;
326 
332  int woCompare(const BSONObj& r, const Ordering &o,
333  bool considerFieldName=true) const;
334 
340  int woCompare(const BSONObj& r, const BSONObj &ordering = BSONObj(),
341  bool considerFieldName=true) const;
342 
343  bool operator<( const BSONObj& other ) const { return woCompare( other ) < 0; }
344  bool operator<=( const BSONObj& other ) const { return woCompare( other ) <= 0; }
345  bool operator>( const BSONObj& other ) const { return woCompare( other ) > 0; }
346  bool operator>=( const BSONObj& other ) const { return woCompare( other ) >= 0; }
347 
351  int woSortOrder( const BSONObj& r , const BSONObj& sortKey , bool useDotted=false ) const;
352 
353  bool equal(const BSONObj& r) const;
354 
361  bool isPrefixOf( const BSONObj& otherObj ) const;
362 
369  bool isFieldNamePrefixOf( const BSONObj& otherObj ) const;
370 
374  bool binaryEqual(const BSONObj& r) const {
375  int os = objsize();
376  if ( os == r.objsize() ) {
377  return (os == 0 || memcmp(objdata(),r.objdata(),os)==0);
378  }
379  return false;
380  }
381 
383  BSONElement firstElement() const { return BSONElement(objdata() + 4); }
384 
388  const char * firstElementFieldName() const {
389  const char *p = objdata() + 4;
390  return *p == EOO ? "" : p+1;
391  }
392 
393  BSONType firstElementType() const {
394  const char *p = objdata() + 4;
395  return (BSONType) *p;
396  }
397 
403  bool getObjectID(BSONElement& e) const;
404 
406  int hash() const {
407  unsigned x = 0;
408  const char *p = objdata();
409  for ( int i = 0; i < objsize(); i++ )
410  x = x * 131 + p[i];
411  return (x & 0x7fffffff) | 0x8000000; // must be > 0
412  }
413 
414  // Return a version of this object where top level elements of types
415  // that are not part of the bson wire protocol are replaced with
416  // string identifier equivalents.
417  // TODO Support conversion of element types other than min and max.
418  BSONObj clientReadable() const;
419 
422  BSONObj replaceFieldNames( const BSONObj &obj ) const;
423 
425  bool valid() const;
426 
428  std::string md5() const;
429 
430  bool operator==( const BSONObj& other ) const { return equal( other ); }
431  bool operator!=(const BSONObj& other) const { return !operator==( other); }
432 
433  enum MatchType {
434  Equality = 0,
435  LT = 0x1,
436  LTE = 0x3,
437  GTE = 0x6,
438  GT = 0x4,
439  opIN = 0x8, // { x : { $in : [1,2,3] } }
440  NE = 0x9,
441  opSIZE = 0x0A,
442  opALL = 0x0B,
443  NIN = 0x0C,
444  opEXISTS = 0x0D,
445  opMOD = 0x0E,
446  opTYPE = 0x0F,
447  opREGEX = 0x10,
448  opOPTIONS = 0x11,
449  opELEM_MATCH = 0x12,
450  opNEAR = 0x13,
451  opWITHIN = 0x14,
452  opMAX_DISTANCE = 0x15,
453  opGEO_INTERSECTS = 0x16,
454  };
455 
457  void elems(std::vector<BSONElement> &) const;
459  void elems(std::list<BSONElement> &) const;
460 
469  template <class T>
470  void Vals(std::vector<T> &) const;
472  template <class T>
473  void Vals(std::list<T> &) const;
474 
476  template <class T>
477  void vals(std::vector<T> &) const;
479  template <class T>
480  void vals(std::list<T> &) const;
481 
482  friend class BSONObjIterator;
483  typedef BSONObjIterator iterator;
484 
491  BSONObjIterator begin() const;
492 
493  void appendSelfToBufBuilder(BufBuilder& b) const {
494  verify( objsize() );
495  b.appendBuf(reinterpret_cast<const void *>( objdata() ), objsize());
496  }
497 
498  template<typename T> bool coerceVector( std::vector<T>* out ) const;
499 
500 #pragma pack(1)
501  class Holder : boost::noncopyable {
502  private:
503  Holder(); // this class should never be explicitly created
504  AtomicUInt refCount;
505  public:
506  char data[4]; // start of object
507 
508  void zero() { refCount.zero(); }
509 
510  // these are called automatically by boost::intrusive_ptr
511  friend void intrusive_ptr_add_ref(Holder* h) { h->refCount++; }
512  friend void intrusive_ptr_release(Holder* h) {
513 #if defined(_DEBUG) // cant use dassert or DEV here
514  verify((int)h->refCount > 0); // make sure we haven't already freed the buffer
515 #endif
516  if(--(h->refCount) == 0){
517 #if defined(_DEBUG)
518  unsigned sz = (unsigned&) *h->data;
519  verify(sz < BSONObjMaxInternalSize * 3);
520  memset(h->data, 0xdd, sz);
521 #endif
522  free(h);
523  }
524  }
525  };
526 #pragma pack()
527 
528  BSONObj(const BSONObj &rO):
529  _objdata(rO._objdata), _holder(rO._holder) {
530  }
531 
532  BSONObj &operator=(const BSONObj &rRHS) {
533  if (this != &rRHS) {
534  _objdata = rRHS._objdata;
535  _holder = rRHS._holder;
536  }
537  return *this;
538  }
539 
541  struct SorterDeserializeSettings {}; // unused
542  void serializeForSorter(BufBuilder& buf) const { buf.appendBuf(objdata(), objsize()); }
543  static BSONObj deserializeForSorter(BufReader& buf, const SorterDeserializeSettings&) {
544  const int size = buf.peek<int>();
545  const void* ptr = buf.skip(size);
546  return BSONObj(static_cast<const char*>(ptr));
547  }
548  int memUsageForSorter() const {
549  // TODO consider ownedness?
550  return sizeof(BSONObj) + objsize();
551  }
552 
553  private:
554  const char *_objdata;
555  boost::intrusive_ptr< Holder > _holder;
556 
557  void _assertInvalid() const;
558 
559  void init(Holder *holder) {
560  _holder = holder; // holder is now managed by intrusive_ptr
561  init(holder->data);
562  }
563  void init(const char *data) {
564  _objdata = data;
565  if ( !isValid() )
566  _assertInvalid();
567  }
568 
575  Status _okForStorage(bool root, bool deep) const;
576  };
577 
578  std::ostream& operator<<( std::ostream &s, const BSONObj &o );
579  std::ostream& operator<<( std::ostream &s, const BSONElement &e );
580 
581  StringBuilder& operator<<( StringBuilder &s, const BSONObj &o );
582  StringBuilder& operator<<( StringBuilder &s, const BSONElement &e );
583 
584 
585  struct BSONArray : BSONObj {
586  // Don't add anything other than forwarding constructors!!!
587  BSONArray(): BSONObj() {}
588  explicit BSONArray(const BSONObj& obj): BSONObj(obj) {}
589  };
590 
591 }
Definition: bsonobj.h:501
BSONObj()
Construct an empty BSONObj – that is, {}.
Definition: bson-inl.h:792
end of object
Definition: bsontypes.h:47
JsonStringFormat
Formatting mode for generating JSON from BSON.
Definition: oid.h:152
const char * objdata() const
Definition: bsonobj.h:266
LogstreamBuilder out()
Synonym for log().
Definition: log.h:79
int objsize() const
Definition: bsonobj.h:270
bool isEmpty() const
Definition: bsonobj.h:320
helper to read and parse a block of memory methods throw the eof exception if the operation would pas...
Definition: bufreader.h:44
A generic pointer type for function arguments.
Definition: goodies.h:176
void peek(T &t) const
read in the object specified, but do not advance buffer pointer
Definition: bufreader.h:76
const void * skip(unsigned len)
return current position pointer, and advance by len
Definition: bufreader.h:104
bool isOwned() const
A BSONObj can use a buffer it "owns" or one it does not.
Definition: bsonobj.h:131
strict RFC format
Definition: oid.h:154
bool hasElement(const StringData &name) const
Definition: bsonobj.h:218
const char * firstElementFieldName() const
faster than firstElement().fieldName() - for the first element we can easily find the fieldname witho...
Definition: bsonobj.h:388
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:303
BSONType
the complete list of valid BSON types see also bsonspec.org
Definition: bsontypes.h:43
bool hasField(const StringData &name) const
Definition: bsonobj.h:216
bool okForStorage() const
Definition: bsonobj.h:281
BSONElement firstElement() const
Definition: bsonobj.h:383
bool okForStorageAsRoot() const
Same as above with the following extra restrictions Not valid if:
Definition: bsonobj.h:291
members for Sorter
Definition: bsonobj.h:541
BSONObj(const char *msgdata)
Construct a BSONObj from data in the proper format.
Definition: bsonobj.h:83
bool binaryEqual(const BSONObj &r) const
This is "shallow equality" – ints and doubles won't match.
Definition: bsonobj.h:374
stringstream deals with locale so this is a lot faster than std::stringstream for UTF8 ...
Definition: builder.h:61
int hash() const
Definition: bsonobj.h:406
BSONElement represents an "element" in a BSONObj.
Definition: bsonelement.h:62
C++ representation of a "BSON" object – that is, an extended JSON-style object in a binary representa...
Definition: bsonobj.h:77
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:315
Definition: bsonobj.h:585
A precomputation of a BSON index or sort key pattern.
Definition: ordering.h:32