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 
63  class BSONElement {
64  public:
71  string String() const { return chk(bson::String).valuestr(); }
72  Date_t Date() const { return chk(bson::Date).date(); }
73  double Number() const { return chk(isNumber()).number(); }
74  double Double() const { return chk(NumberDouble)._numberDouble(); }
75  long long Long() const { return chk(NumberLong)._numberLong(); }
76  bsonDecimal Decimal() const { return chk(NumberDecimal).numberDecimal(); }
77  int Int() const { return chk(NumberInt)._numberInt(); }
78  bool Bool() const { return chk(bson::Bool).boolean(); }
79  vector<BSONElement> Array() const; // see implementation for detailed comments
80  bson::OID OID() const { return chk(jstOID).__oid(); }
81  void Null() const { chk(isNull()); } // throw UserException if not null
82  void OK() const { chk(ok()); } // throw UserException if element DNE
83 
90  BSONObj Obj() const;
91 
96  void Val(Date_t& v) const { v = Date(); }
97  void Val(long long& v) const { v = Long(); }
98  void Val(bool& v) const { v = Bool(); }
99  void Val(BSONObj& v) const;
100  void Val(bson::OID& v) const { v = OID(); }
101  void Val(int& v) const { v = Int(); }
102  void Val(double& v) const { v = Double(); }
103  void Val(string& v) const { v = String(); }
104  void Val(bsonDecimal& v) const { v = Decimal(); }
105 
109  bool ok() const { return !eoo(); }
110 
111  string toString( bool includeFieldName = true, bool full=false) const;
112  void toString(StringBuilder& s, bool includeFieldName = true,
113  bool full=false) const;
114  string jsonString( JsonStringFormat format,
115  bool includeFieldNames = true, int pretty = 0 ) const;
116  operator string() const { return toString(); }
117 
119  BSONType type() const { return (BSONType) (signed char)*data; }
120 
124  BSONElement operator[] (const string& field) const;
125 
133  int canonicalType() const;
134 
138  bool eoo() const { return type() == EOO; }
139 
144  int size( int maxLen ) const;
145  int size() const;
146 
148  BSONObj wrap() const;
149 
151  BSONObj wrap( const char* newName) const;
152 
157  const char * fieldName() const {
158  if ( eoo() ) return ""; // no fieldname for it.
159  return data + 1;
160  }
161 
163  const char * value() const {
164  return (data + fieldNameSize() + 1);
165  }
167  int valuesize() const {
168  return size() - fieldNameSize() - 1;
169  }
170 
171  bool isBoolean() const { return type() == bson::Bool; }
172 
176  bool boolean() const {
177  return *value() ? true : false;
178  }
179 
180  bool booleanSafe() const { return isBoolean() && boolean(); }
181 
186  Date_t date() const {
187  return *reinterpret_cast< const Date_t* >( value() );
188  }
189 
194  bool trueValue() const;
195 
197  bool isSimpleType() const;
198 
200  bool isNumber() const;
201 
203  double _numberDouble() const
204  {return *reinterpret_cast< const double* >( value() ); }
206  int _numberInt() const
207  {return *reinterpret_cast< const int* >( value() ); }
209  long long _numberLong() const
210  {return *reinterpret_cast< const long long* >( value() ); }
211 
214  int numberInt() const;
217  long long numberLong() const;
220  bsonDecimal numberDecimal() const;
226  double numberDouble() const;
232  double number() const { return numberDouble(); }
233 
236  const bson::OID &__oid() const
237  { return *reinterpret_cast< const bson::OID* >( value() ); }
238 
240  bool isNull() const {
241  return type() == jstNULL;
242  }
243 
248  int valuestrsize() const {
249  return *reinterpret_cast< const int* >( value() );
250  }
251 
252  // for objects the size *includes* the size of the size field
253  int objsize() const {
254  return *reinterpret_cast< const int* >( value() );
255  }
256 
261  const char * valuestr() const {
262  return value() + 4;
263  }
264 
266  const char *valuestrsafe() const {
267  return type() == bson::String ? valuestr() : "";
268  }
270  string str() const {
271  return type() == bson::String ?
272  string(valuestr(), valuestrsize()-1) : string();
273  }
274 
276  const char * codeWScopeCode() const {
277  return value() + 8;
278  }
280  const char * codeWScopeScopeData() const {
281  // TODO fix
282  return codeWScopeCode() + strlen( codeWScopeCode() ) + 1;
283  }
284 
286  BSONObj embeddedObject() const;
287 
288  /* uasserts if not an object */
289  BSONObj embeddedObjectUserCheck() const;
290 
291  BSONObj codeWScopeObject() const;
292 
295  const char *binData(int& len) const {
296  // BinData: <int len> <byte subtype> <byte[len] data>
297  assert( type() == BinData );
298  len = valuestrsize();
299  return value() + 5;
300  }
302  const char *binDataClean(int& len) const {
303  // BinData: <int len> <byte subtype> <byte[len] data>
304  if (binDataType() != ByteArrayDeprecated) {
305  return binData(len);
306  }
307  else {
308  // Skip extra size
309  len = valuestrsize() - 4;
310  return value() + 5 + 4;
311  }
312  }
313 
314  BinDataType binDataType() const {
315  // BinData: <int len> <byte subtype> <byte[len] data>
316  assert( type() == BinData );
317  unsigned char c = (value() + 4)[0];
318  return (BinDataType)c;
319  }
320 
322  const char *regex() const {
323  assert(type() == RegEx);
324  return value();
325  }
326 
328  const char *regexFlags() const {
329  const char *p = regex();
330  return p + strlen(p) + 1;
331  }
332 
334  string code() const {
335  assert(type() == Code);
336  return _asCode() ;
337  }
338 
342  bool valuesEqual(const BSONElement& r) const {
343  return woCompare( r , false ) == 0;
344  }
345 
347  bool operator==(const BSONElement& r) const {
348  return woCompare( r , true ) == 0;
349  }
350 
356  int woCompare( const BSONElement &e, bool considerFieldName = true )
357  const;
358 
359  const char * rawdata() const { return data; }
360 
362  int getGtLtOp( int def = 0 ) const;
363 
365  BSONElement();
366 
368  void validate() const;
369 
371  bool mayEncapsulate() const {
372  switch ( type() ) {
373  case Object:
374  case bson::Array:
375  case CodeWScope:
376  return true;
377  default:
378  return false;
379  }
380  }
381 
383  bool isABSONObj() const {
384  switch( type() ) {
385  case Object:
386  case bson::Array:
387  return true;
388  default:
389  return false;
390  }
391  }
392 
393  Date_t timestampTime() const {
394  long long t = ((int*)(value() + 4 ))[0];
395  return t * 1000;
396  }
397  unsigned int timestampInc() const {
398  return ((unsigned int*)(value() ))[0];
399  }
400 
401  const char * dbrefNS() const {
402  uassert( 10063 , "not a dbref" , type() == DBRef );
403  return value() + 4;
404  }
405 
406  const bson::OID& dbrefOID() const {
407  uassert( 10064 , "not a dbref" , type() == DBRef );
408  const char * start = value();
409  start += 4 + *reinterpret_cast< const int* >( start );
410  return *reinterpret_cast< const bson::OID* >( start );
411  }
412 
414  bool operator<( const BSONElement& other ) const {
415  int x = (int)canonicalType() - (int)other.canonicalType();
416  if ( x < 0 ) return true;
417  else if ( x > 0 ) return false;
418  return compareElementValues(*this,other) < 0;
419  }
420 
421  // @param maxLen don't scan more than maxLen bytes
422  explicit BSONElement(const char *d, int maxLen) : data(d) {
423  if ( eoo() ) {
424  totalSize = 1;
425  fieldNameSize_ = 0;
426  }
427  else {
428  totalSize = -1;
429  fieldNameSize_ = -1;
430  if ( maxLen != -1 ) {
431  int size = (int) strnlen( fieldName(), maxLen - 1 );
432  massert( 10333 , "Invalid field name", size != -1 );
433  fieldNameSize_ = size + 1;
434  }
435  }
436  }
437 
438  explicit BSONElement(const char *d) : data(d) {
439  fieldNameSize_ = -1;
440  totalSize = -1;
441  if ( eoo() ) {
442  fieldNameSize_ = 0;
443  totalSize = 1;
444  }
445  }
446 
447  string _asCode() const;
448  OpTime _opTime() const;
449 
450  private:
451  const char *data;
452  mutable int fieldNameSize_; // cached value
453  int fieldNameSize() const {
454  if ( fieldNameSize_ == -1 )
455  fieldNameSize_ = (int)strlen( fieldName() ) + 1;
456  return fieldNameSize_;
457  }
458  mutable int totalSize; /* caches the computed size */
459 
460  friend class BSONObjIterator;
461  friend class BSONObj;
462  const BSONElement& chk(int t) const {
463  if ( t != type() ) {
464  StringBuilder ss;
465  if( eoo() )
466  ss << "field not found, expected type " << t;
467  else
468  ss << "wrong type for field (" << fieldName() << ") "
469  << type() << " != " << t;
470  uasserted(13111, ss.str() );
471  }
472  return *this;
473  }
474  const BSONElement& chk(bool expr) const {
475  uassert(13118, "unexpected or missing type value in BSON object",
476  expr);
477  return *this;
478  }
479 
480  inline string _numberDecimalStr() const ;
481  };
482 
483 
484  inline int BSONElement::canonicalType() const {
485  BSONType t = type() ;
486  switch ( t ) {
487  case MinKey:
488  case MaxKey:
489  return t;
490  case EOO:
491  case Undefined:
492  return 0;
493  case jstNULL:
494  return 5;
495  case NumberDouble:
496  case NumberInt:
497  case NumberLong:
498  case NumberDecimal:
499  return 10;
500  case bson::String:
501  case Symbol:
502  return 15;
503  case Object:
504  return 20;
505  case bson::Array:
506  return 25;
507  case BinData:
508  return 30;
509  case jstOID:
510  return 35;
511  case bson::Bool:
512  return 40;
513  case bson::Date:
514  case Timestamp:
515  return 45;
516  case RegEx:
517  return 50;
518  case DBRef:
519  return 55;
520  case Code:
521  return 60;
522  case CodeWScope:
523  return 65;
524  default:
525  assert(0);
526  return -1;
527  }
528  }
529 
530  inline bool BSONElement::trueValue() const {
531  switch( type() ) {
532  case NumberLong:
533  return *reinterpret_cast< const long long* >( value() ) != 0;
534  case NumberDecimal:
535  return ( numberDecimal().compare(0) ) != 0 ;
536  case NumberDouble:
537  return *reinterpret_cast< const double* >( value() ) != 0;
538  case NumberInt:
539  return *reinterpret_cast< const int* >( value() ) != 0;
540  case bson::Bool:
541  return boolean();
542  case EOO:
543  case jstNULL:
544  case Undefined:
545  return false;
546 
547  default:
548  ;
549  }
550  return true;
551  }
552 
554  inline bool BSONElement::isNumber() const {
555  switch( type() ) {
556  case NumberLong:
557  case NumberDouble:
558  case NumberInt:
559  case NumberDecimal:
560  return true;
561  default:
562  return false;
563  }
564  }
565 
566  inline bool BSONElement::isSimpleType() const {
567  switch( type() ) {
568  case NumberLong:
569  case NumberDouble:
570  case NumberInt:
571  case bson::String:
572  case bson::Bool:
573  case bson::Date:
574  case jstOID:
575  return true;
576  default:
577  return false;
578  }
579  }
580 
581  inline double BSONElement::numberDouble() const {
582  switch( type() ) {
583  case NumberDouble:
584  return _numberDouble();
585  case NumberInt:
586  return *reinterpret_cast< const int* >( value() );
587  case NumberLong:
588  return (double) *reinterpret_cast< const long long* >( value() );
589  case NumberDecimal:
590  {
591  bsonDecimal decimal ;
592  double tempValue = 0.0 ;
593  decimal.fromBsonValue( value() ) ;
594  decimal.toDouble( &tempValue ) ;
595  return tempValue ;
596  }
597  default:
598  return 0;
599  }
600  }
601 
604  inline int BSONElement::numberInt() const {
605  switch( type() ) {
606  case NumberDouble:
607  return (int) _numberDouble();
608  case NumberInt:
609  return _numberInt();
610  case NumberLong:
611  return (int) _numberLong();
612  case NumberDecimal:
613  {
614  bsonDecimal decimal ;
615  int tempValue = 0 ;
616  decimal.fromBsonValue( value() ) ;
617  decimal.toInt( &tempValue ) ;
618  return tempValue ;
619  }
620  default:
621  return 0;
622  }
623  }
624 
627  inline long long BSONElement::numberLong() const {
628  switch( type() ) {
629  case NumberDouble:
630  return (long long) _numberDouble();
631  case NumberInt:
632  return _numberInt();
633  case NumberLong:
634  return _numberLong();
635  case NumberDecimal:
636  {
637  bsonDecimal decimal ;
638  long long tempValue = 0 ;
639  decimal.fromBsonValue( value() ) ;
640  decimal.toLong( &tempValue ) ;
641  return tempValue ;
642  }
643  default:
644  return 0;
645  }
646  }
647 
648  inline bsonDecimal BSONElement::numberDecimal() const {
649  bsonDecimal decimal ;
650  switch( type() ) {
651  case NumberDouble:
652  decimal.fromDouble( _numberDouble() ) ;
653  break ;
654  case NumberInt:
655  decimal.fromInt( _numberInt() ) ;
656  break ;
657  case NumberLong:
658  decimal.fromLong( _numberLong() ) ;
659  break ;
660  case NumberDecimal:
661  decimal.fromBsonValue( value() ) ;
662  break ;
663  default:
664  break ;
665  }
666 
667  return decimal ;
668  }
669 
671  static char z = 0;
672  data = &z;
673  fieldNameSize_ = 0;
674  totalSize = 1;
675  }
676 
677 }