SequoiaDB
 All Classes Namespaces Files Functions Macros Pages
bsonelement.h
Go to the documentation of this file.
1 
6 /* Copyright 2009 10gen Inc.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #pragma once
22 
23 #include <vector>
24 #include <string.h>
25 #include "oid.h"
26 #include "util/builder.h"
27 #include "bsontypes.h"
28 #include "bsonassert.h"
29 #include "util/optime.h"
30 #include "bsonDecimal.h"
34 namespace bson {
35 
36  class BSONElement;
37  class BSONObj;
38  class BSONObjBuilder;
39 
40  typedef bson::BSONElement be;
41  typedef bson::BSONObj bo;
42  typedef bson::BSONObjBuilder bob;
43 
44  /* l and r MUST have same type when called: check that first. */
45  int compareElementValues(const BSONElement& l, const BSONElement& r);
46 
47  inline int getBSONCanonicalType( BSONType t )
48  {
49  switch ( t ) {
50  case MinKey:
51  case MaxKey:
52  return t;
53  case EOO:
54  case Undefined:
55  return 0;
56  case jstNULL:
57  return 5;
58  case NumberDouble:
59  case NumberInt:
60  case NumberLong:
61  case NumberDecimal:
62  return 10;
63  case bson::String:
64  case Symbol:
65  return 15;
66  case Object:
67  return 20;
68  case bson::Array:
69  return 25;
70  case BinData:
71  return 30;
72  case jstOID:
73  return 35;
74  case bson::Bool:
75  return 40;
76  case bson::Date:
77  case Timestamp:
78  return 45;
79  case RegEx:
80  return 50;
81  case DBRef:
82  return 55;
83  case Code:
84  return 60;
85  case CodeWScope:
86  return 65;
87  default:
88  assert(0);
89  return -1;
90  }
91  }
92 
108  class BSONElement {
109  public:
116  string String() const { return chk(bson::String).valuestr(); }
117  Date_t Date() const { return chk(bson::Date).date(); }
118  double Number() const { return chk(isNumber()).number(); }
119  double Double() const { return chk(NumberDouble)._numberDouble(); }
120  long long Long() const { return chk(NumberLong)._numberLong(); }
121  bsonDecimal Decimal() const { return chk(NumberDecimal).numberDecimal(); }
122  int Int() const { return chk(NumberInt)._numberInt(); }
123  bool Bool() const { return chk(bson::Bool).boolean(); }
124  vector<BSONElement> Array() const; // see implementation for detailed comments
125  bson::OID OID() const { return chk(jstOID).__oid(); }
126  void Null() const { chk(isNull()); } // throw UserException if not null
127  void OK() const { chk(ok()); } // throw UserException if element DNE
128 
135  BSONObj Obj() const;
136 
141  void Val(Date_t& v) const { v = Date(); }
142  void Val(long long& v) const { v = Long(); }
143  void Val(bool& v) const { v = Bool(); }
144  void Val(BSONObj& v) const;
145  void Val(bson::OID& v) const { v = OID(); }
146  void Val(int& v) const { v = Int(); }
147  void Val(double& v) const { v = Double(); }
148  void Val(string& v) const { v = String(); }
149  void Val(bsonDecimal& v) const { v = Decimal(); }
150 
154  bool ok() const { return !eoo(); }
155 
156  string toString( bool includeFieldName = true,
157  bool full=false) const;
158  void toString( StringBuilder& s, bool
159  includeFieldName = true,
160  bool full=false) const;
161  string jsonString( JsonStringFormat format,
162  bool includeFieldNames = true,
163  int pretty = 0 ) const;
164  operator string() const { return toString(); }
165 
166 #if defined ( SDB_ENGINE ) || defined ( SDB_FMP ) || defined ( SDB_TOOL )
167  ossPoolString poolString() const { return chk(bson::String).valuestr(); }
168  void Val(ossPoolString& v) const { v = poolString(); }
169 
170  ossPoolString toPoolString( bool includeFieldName = true,
171  bool full=false) const;
172  operator ossPoolString() const { return toPoolString() ; }
173 
175  ossPoolString poolStr() const {
176  return type() == bson::String ?
177  ossPoolString(valuestr(), valuestrsize()-1) : ossPoolString();
178  }
179 #endif //SDB_ENGINE || SDB_FMP || SDB_TOOL
180 
182  BSONType type() const { return (BSONType) (signed char)*data; }
183 
187  BSONElement operator[] (const string& field) const;
188 
196  int canonicalType() const;
197 
201  bool eoo() const { return type() == EOO; }
202 
207  int size( int maxLen ) const;
208  int size() const;
209 
211  BSONObj wrap() const;
212 
214  BSONObj wrap( const char* newName) const;
215 
220  const char * fieldName() const {
221  if ( eoo() ) return ""; // no fieldname for it.
222  return data + 1;
223  }
224 
226  const char * value() const {
227  return (data + fieldNameSize() + 1);
228  }
230  int valuesize() const {
231  return size() - fieldNameSize() - 1;
232  }
233 
234  bool isBoolean() const { return type() == bson::Bool; }
235 
239  bool boolean() const {
240  return *value() ? true : false;
241  }
242 
243  bool booleanSafe() const { return isBoolean() && boolean(); }
244 
249  Date_t date() const {
250  return *reinterpret_cast< const Date_t* >( value() );
251  }
252 
257  bool trueValue() const;
258 
260  bool isSimpleType() const;
261 
263  bool isNumber() const;
264 
266  double _numberDouble() const
267  {return *reinterpret_cast< const double* >( value() ); }
269  int _numberInt() const
270  {return *reinterpret_cast< const int* >( value() ); }
272  long long _numberLong() const
273  {return *reinterpret_cast< const long long* >( value() ); }
274 
277  int numberInt() const;
280  long long numberLong() const;
283  bsonDecimal numberDecimal() const;
289  double numberDouble() const;
295  double number() const { return numberDouble(); }
296 
299  const bson::OID &__oid() const
300  { return *reinterpret_cast< const bson::OID* >( value() ); }
301 
303  bool isNull() const {
304  return type() == jstNULL;
305  }
306 
311  int valuestrsize() const {
312  return *reinterpret_cast< const int* >( value() );
313  }
314 
315  // for objects the size *includes* the size of the size field
316  int objsize() const {
317  return *reinterpret_cast< const int* >( value() );
318  }
319 
324  const char * valuestr() const {
325  return value() + 4;
326  }
327 
329  const char *valuestrsafe() const {
330  return type() == bson::String ? valuestr() : "";
331  }
333  string str() const {
334  return type() == bson::String ?
335  string(valuestr(), valuestrsize()-1) : string();
336  }
337 
339  const char * codeWScopeCode() const {
340  return value() + 8;
341  }
343  const char * codeWScopeScopeData() const {
344  // TODO fix
345  return codeWScopeCode() + strlen( codeWScopeCode() ) + 1;
346  }
347 
349  BSONObj embeddedObject() const;
350 
351  /* uasserts if not an object */
352  BSONObj embeddedObjectUserCheck() const;
353 
354  BSONObj codeWScopeObject() const;
355 
358  const char *binData(int& len) const {
359  // BinData: <int len> <byte subtype> <byte[len] data>
360  assert( type() == BinData );
361  len = valuestrsize();
362  return value() + 5;
363  }
365  const char *binDataClean(int& len) const {
366  // BinData: <int len> <byte subtype> <byte[len] data>
367  if (binDataType() != ByteArrayDeprecated) {
368  return binData(len);
369  }
370  else {
371  // Skip extra size
372  len = valuestrsize() - 4;
373  return value() + 5 + 4;
374  }
375  }
376 
377  BinDataType binDataType() const {
378  // BinData: <int len> <byte subtype> <byte[len] data>
379  assert( type() == BinData );
380  unsigned char c = (value() + 4)[0];
381  return (BinDataType)c;
382  }
383 
385  const char *regex() const {
386  assert(type() == RegEx);
387  return value();
388  }
389 
391  const char *regexFlags() const {
392  const char *p = regex();
393  return p + strlen(p) + 1;
394  }
395 
397  string code() const {
398  assert(type() == Code);
399  return _asCode() ;
400  }
401 
405  bool valuesEqual(const BSONElement& r) const {
406  return woCompare( r , false ) == 0;
407  }
408 
410  bool operator==(const BSONElement& r) const {
411  return woCompare( r , true ) == 0;
412  }
413 
419  int woCompare( const BSONElement &e, bool considerFieldName = true )
420  const;
421 
422  const char * rawdata() const { return data; }
423 
425  int getGtLtOp( int def = 0 ) const;
426 
428  BSONElement();
429 
431  void validate() const;
432 
434  bool mayEncapsulate() const {
435  switch ( type() ) {
436  case Object:
437  case bson::Array:
438  case CodeWScope:
439  return true;
440  default:
441  return false;
442  }
443  }
444 
446  bool isABSONObj() const {
447  switch( type() ) {
448  case Object:
449  case bson::Array:
450  return true;
451  default:
452  return false;
453  }
454  }
455 
456  Date_t timestampTime() const {
457  long long t = ((int*)(value() + 4 ))[0];
458  return t * 1000;
459  }
460  unsigned int timestampInc() const {
461  return ((unsigned int*)(value() ))[0];
462  }
463 
464  const char * dbrefNS() const {
465  uassert( 10063 , "not a dbref" , type() == DBRef );
466  return value() + 4;
467  }
468 
469  const bson::OID& dbrefOID() const {
470  uassert( 10064 , "not a dbref" , type() == DBRef );
471  const char * start = value();
472  start += 4 + *reinterpret_cast< const int* >( start );
473  return *reinterpret_cast< const bson::OID* >( start );
474  }
475 
477  bool operator<( const BSONElement& other ) const {
478  int x = (int)canonicalType() - (int)other.canonicalType();
479  if ( x < 0 ) return true;
480  else if ( x > 0 ) return false;
481  return compareElementValues(*this,other) < 0;
482  }
483 
484  // @param maxLen don't scan more than maxLen bytes
485  explicit BSONElement(const char *d, int maxLen) : data(d) {
486  if ( eoo() ) {
487  totalSize = 1;
488  fieldNameSize_ = 0;
489  }
490  else {
491  totalSize = -1;
492  fieldNameSize_ = -1;
493  if ( maxLen != -1 ) {
494  int size = (int) strnlen( fieldName(), maxLen - 1 );
495  massert( 10333 , "Invalid field name", size != -1 );
496  fieldNameSize_ = size + 1;
497  }
498  }
499  }
500 
501  explicit BSONElement(const char *d) : data(d) {
502  fieldNameSize_ = -1;
503  totalSize = -1;
504  if ( eoo() ) {
505  fieldNameSize_ = 0;
506  totalSize = 1;
507  }
508  }
509 
510  string _asCode() const;
511  OpTime _opTime() const;
512 
513  private:
514  const char *data;
515  mutable int fieldNameSize_; // cached value
516  int fieldNameSize() const {
517  if ( fieldNameSize_ == -1 )
518  fieldNameSize_ = (int)strlen( fieldName() ) + 1;
519  return fieldNameSize_;
520  }
521  mutable int totalSize; /* caches the computed size */
522 
523  friend class BSONObjIterator;
524  friend class BSONObj;
525  const BSONElement& chk(int t) const {
526  if ( t != type() ) {
527  StringBuilder ss;
528  if( eoo() )
529  ss << "field not found, expected type " << t;
530  else
531  ss << "wrong type for field (" << fieldName() << ") "
532  << type() << " != " << t;
533  uasserted(13111, ss.str() );
534  }
535  return *this;
536  }
537  const BSONElement& chk(bool expr) const {
538  uassert(13118, "unexpected or missing type value in BSON object",
539  expr);
540  return *this;
541  }
542 
543  inline string _numberDecimalStr() const ;
544 
545 #if defined ( SDB_ENGINE ) || defined ( SDB_FMP ) || defined ( SDB_TOOL )
546  inline ossPoolString _numberDecimalPoolStr() const ;
547 #endif //SDB_ENGINE || SDB_FMP || SDB_TOOL
548  };
549 
550 
551  inline int BSONElement::canonicalType() const {
552  return getBSONCanonicalType( type() ) ;
553  }
554 
555  inline bool BSONElement::trueValue() const {
556  switch( type() ) {
557  case NumberLong:
558  return *reinterpret_cast< const long long* >( value() ) != 0;
559  case NumberDecimal:
560  return ( numberDecimal().compare(0) ) != 0 ;
561  case NumberDouble:
562  return *reinterpret_cast< const double* >( value() ) != 0;
563  case NumberInt:
564  return *reinterpret_cast< const int* >( value() ) != 0;
565  case bson::Bool:
566  return boolean();
567  case EOO:
568  case jstNULL:
569  case Undefined:
570  return false;
571 
572  default:
573  ;
574  }
575  return true;
576  }
577 
579  inline bool BSONElement::isNumber() const {
580  switch( type() ) {
581  case NumberLong:
582  case NumberDouble:
583  case NumberInt:
584  case NumberDecimal:
585  return true;
586  default:
587  return false;
588  }
589  }
590 
591  inline bool BSONElement::isSimpleType() const {
592  switch( type() ) {
593  case NumberLong:
594  case NumberDouble:
595  case NumberInt:
596  case bson::String:
597  case bson::Bool:
598  case bson::Date:
599  case jstOID:
600  return true;
601  default:
602  return false;
603  }
604  }
605 
606  inline double BSONElement::numberDouble() const {
607  switch( type() ) {
608  case NumberDouble:
609  return _numberDouble();
610  case NumberInt:
611  return *reinterpret_cast< const int* >( value() );
612  case NumberLong:
613  return (double) *reinterpret_cast< const long long* >( value() );
614  case NumberDecimal:
615  {
616  int rc = 0 ;
617  bsonDecimal decimal ;
618  double tempValue = 0.0 ;
619  rc = decimal.fromBsonValue( value() ) ;
620  uassert( rc, "Failed to parse decimal from bson value",
621  0 == rc ) ;
622  rc = decimal.toDouble( &tempValue ) ;
623  uassert( rc, "Failed to parse decimal to double", 0 == rc ) ;
624  return tempValue ;
625  }
626  default:
627  return 0;
628  }
629  }
630 
633  inline int BSONElement::numberInt() const {
634  switch( type() ) {
635  case NumberDouble:
636  return (int) _numberDouble();
637  case NumberInt:
638  return _numberInt();
639  case NumberLong:
640  return (int) _numberLong();
641  case NumberDecimal:
642  {
643  int rc = 0 ;
644  bsonDecimal decimal ;
645  int tempValue = 0 ;
646  rc = decimal.fromBsonValue( value() ) ;
647  uassert( rc, "Failed to parse decimal from bson value",
648  0 == rc ) ;
649  rc = decimal.toInt( &tempValue ) ;
650  uassert( rc, "Failed to parse decimal to int",
651  0 == rc ) ;
652  return tempValue ;
653  }
654  default:
655  return 0;
656  }
657  }
658 
661  inline long long BSONElement::numberLong() const {
662  switch( type() ) {
663  case NumberDouble:
664  return (long long) _numberDouble();
665  case NumberInt:
666  return _numberInt();
667  case NumberLong:
668  return _numberLong();
669  case NumberDecimal:
670  {
671  int rc = 0 ;
672  bsonDecimal decimal ;
673  long long tempValue = 0 ;
674  rc = decimal.fromBsonValue( value() ) ;
675  uassert( rc, "Failed to parse decimal from bson value",
676  0 == rc) ;
677  rc = decimal.toLong( &tempValue ) ;
678  uassert( rc, "Failed to parse decimal to long",
679  0 == rc) ;
680  return tempValue ;
681  }
682  default:
683  return 0;
684  }
685  }
686 
687  inline bsonDecimal BSONElement::numberDecimal() const {
688  int rc = 0 ;
689  bsonDecimal decimal ;
690  switch( type() ) {
691  case NumberDouble:
692  rc = decimal.fromDouble( _numberDouble() ) ;
693  uassert( rc, "Failed to parse decimal from double",
694  0 == rc ) ;
695  break ;
696  case NumberInt:
697  rc = decimal.fromInt( _numberInt() ) ;
698  uassert( rc, "Failed to parse decimal from int",
699  0 == rc ) ;
700  break ;
701  case NumberLong:
702  rc = decimal.fromLong( _numberLong() ) ;
703  uassert( rc, "Failed to parse decimal from long",
704  0 == rc ) ;
705  break ;
706  case NumberDecimal:
707  rc = decimal.fromBsonValue( value() ) ;
708  uassert( rc, "Failed to parse decimal from bson value",
709  0 == rc ) ;
710  break ;
711  default:
712  break ;
713  }
714 
715  return decimal ;
716  }
717 
719  static char z = 0;
720  data = &z;
721  fieldNameSize_ = 0;
722  totalSize = 1;
723  }
724 
725 }