00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #pragma once
00019
00020 #include <vector>
00021 #include <string.h>
00022 #include "util/builder.h"
00023
00024 namespace bson {
00025 typedef mongo::BSONElement be;
00026 typedef mongo::BSONObj bo;
00027 typedef mongo::BSONObjBuilder bob;
00028 }
00029
00030 namespace mongo {
00031
00032 class OpTime;
00033 class BSONElement;
00034
00035
00036 int compareElementValues(const BSONElement& l, const BSONElement& r);
00037
00038
00052 class BSONElement {
00053 public:
00059 string String() const { return chk(mongo::String).valuestr(); }
00060 Date_t Date() const { return chk(mongo::Date).date(); }
00061 double Number() const { return chk(isNumber()).number(); }
00062 double Double() const { return chk(NumberDouble)._numberDouble(); }
00063 long long Long() const { return chk(NumberLong)._numberLong(); }
00064 int Int() const { return chk(NumberInt)._numberInt(); }
00065 bool Bool() const { return chk(mongo::Bool).boolean(); }
00066 vector<BSONElement> Array() const;
00067 mongo::OID OID() const { return chk(jstOID).__oid(); }
00068 void Null() const { chk(isNull()); }
00069 void OK() const { chk(ok()); }
00070
00077 BSONObj Obj() const;
00078
00082 void Val(Date_t& v) const { v = Date(); }
00083 void Val(long long& v) const { v = Long(); }
00084 void Val(bool& v) const { v = Bool(); }
00085 void Val(BSONObj& v) const;
00086 void Val(mongo::OID& v) const { v = OID(); }
00087 void Val(int& v) const { v = Int(); }
00088 void Val(double& v) const { v = Double(); }
00089 void Val(string& v) const { v = String(); }
00090
00094 bool ok() const { return !eoo(); }
00095
00096 string toString( bool includeFieldName = true, bool full=false) const;
00097 void toString(StringBuilder& s, bool includeFieldName = true, bool full=false) const;
00098 string jsonString( JsonStringFormat format, bool includeFieldNames = true, int pretty = 0 ) const;
00099 operator string() const { return toString(); }
00100
00102 BSONType type() const { return (BSONType) *data; }
00103
00107 BSONElement operator[] (const string& field) const;
00108
00113 int canonicalType() const;
00114
00118 bool eoo() const { return type() == EOO; }
00119
00123 int size( int maxLen = -1 ) const;
00124
00126 BSONObj wrap() const;
00127
00129 BSONObj wrap( const char* newName) const;
00130
00135 const char * fieldName() const {
00136 if ( eoo() ) return "";
00137 return data + 1;
00138 }
00139
00141 const char * value() const {
00142 return (data + fieldNameSize() + 1);
00143 }
00145 int valuesize() const {
00146 return size() - fieldNameSize() - 1;
00147 }
00148
00149 bool isBoolean() const { return type() == mongo::Bool; }
00150
00154 bool boolean() const {
00155 return *value() ? true : false;
00156 }
00157
00161 Date_t date() const {
00162 return *reinterpret_cast< const Date_t* >( value() );
00163 }
00164
00168 bool trueValue() const;
00169
00171 bool isSimpleType() const;
00172
00174 bool isNumber() const;
00175
00177 double _numberDouble() const {return *reinterpret_cast< const double* >( value() ); }
00179 int _numberInt() const {return *reinterpret_cast< const int* >( value() ); }
00181 long long _numberLong() const {return *reinterpret_cast< const long long* >( value() ); }
00182
00184 int numberInt() const;
00186 long long numberLong() const;
00190 double numberDouble() const;
00194 double number() const { return numberDouble(); }
00195
00198 const mongo::OID &__oid() const { return *reinterpret_cast< const mongo::OID* >( value() ); }
00199
00201 bool isNull() const {
00202 return type() == jstNULL;
00203 }
00204
00207 int valuestrsize() const {
00208 return *reinterpret_cast< const int* >( value() );
00209 }
00210
00211
00212 int objsize() const {
00213 return *reinterpret_cast< const int* >( value() );
00214 }
00215
00219 const char * valuestr() const {
00220 return value() + 4;
00221 }
00222
00224 const char *valuestrsafe() const {
00225 return type() == mongo::String ? valuestr() : "";
00226 }
00228 string str() const {
00229 return type() == mongo::String ? string(valuestr(), valuestrsize()-1) : string();
00230 }
00231
00233 const char * codeWScopeCode() const {
00234 return value() + 8;
00235 }
00237 const char * codeWScopeScopeData() const {
00238
00239 return codeWScopeCode() + strlen( codeWScopeCode() ) + 1;
00240 }
00241
00243 BSONObj embeddedObject() const;
00244
00245
00246 BSONObj embeddedObjectUserCheck() const;
00247
00248 BSONObj codeWScopeObject() const;
00249
00251 const char *binData(int& len) const {
00252
00253 assert( type() == BinData );
00254 len = valuestrsize();
00255 return value() + 5;
00256 }
00258 const char *binDataClean(int& len) const {
00259
00260 if (binDataType() != ByteArrayDeprecated) {
00261 return binData(len);
00262 }
00263 else {
00264
00265 len = valuestrsize() - 4;
00266 return value() + 5 + 4;
00267 }
00268 }
00269
00270 BinDataType binDataType() const {
00271
00272 assert( type() == BinData );
00273 unsigned char c = (value() + 4)[0];
00274 return (BinDataType)c;
00275 }
00276
00278 const char *regex() const {
00279 assert(type() == RegEx);
00280 return value();
00281 }
00282
00284 const char *regexFlags() const {
00285 const char *p = regex();
00286 return p + strlen(p) + 1;
00287 }
00288
00292 bool valuesEqual(const BSONElement& r) const {
00293 return woCompare( r , false ) == 0;
00294 }
00295
00297 bool operator==(const BSONElement& r) const {
00298 return woCompare( r , true ) == 0;
00299 }
00300
00306 int woCompare( const BSONElement &e, bool considerFieldName = true ) const;
00307
00308 const char * rawdata() const { return data; }
00309
00311 int getGtLtOp( int def = 0 ) const;
00312
00314 BSONElement();
00315
00317 void validate() const;
00318
00320 bool mayEncapsulate() const {
00321 switch ( type() ) {
00322 case Object:
00323 case mongo::Array:
00324 case CodeWScope:
00325 return true;
00326 default:
00327 return false;
00328 }
00329 }
00330
00332 bool isABSONObj() const {
00333 switch( type() ) {
00334 case Object:
00335 case mongo::Array:
00336 return true;
00337 default:
00338 return false;
00339 }
00340 }
00341
00342 Date_t timestampTime() const {
00343 unsigned long long t = ((unsigned int*)(value() + 4 ))[0];
00344 return t * 1000;
00345 }
00346 unsigned int timestampInc() const {
00347 return ((unsigned int*)(value() ))[0];
00348 }
00349
00350 const char * dbrefNS() const {
00351 uassert( 10063 , "not a dbref" , type() == DBRef );
00352 return value() + 4;
00353 }
00354
00355 const mongo::OID& dbrefOID() const {
00356 uassert( 10064 , "not a dbref" , type() == DBRef );
00357 const char * start = value();
00358 start += 4 + *reinterpret_cast< const int* >( start );
00359 return *reinterpret_cast< const mongo::OID* >( start );
00360 }
00361
00362 bool operator<( const BSONElement& other ) const {
00363 int x = (int)canonicalType() - (int)other.canonicalType();
00364 if ( x < 0 ) return true;
00365 else if ( x > 0 ) return false;
00366 return compareElementValues(*this,other) < 0;
00367 }
00368
00369
00370 explicit BSONElement(const char *d, int maxLen = -1) : data(d) {
00371 fieldNameSize_ = -1;
00372 if ( eoo() )
00373 fieldNameSize_ = 0;
00374 else {
00375 if ( maxLen != -1 ) {
00376 int size = (int) strnlen( fieldName(), maxLen - 1 );
00377 massert( 10333 , "Invalid field name", size != -1 );
00378 fieldNameSize_ = size + 1;
00379 }
00380 }
00381 totalSize = -1;
00382 }
00383
00384 string _asCode() const;
00385 OpTime _opTime() const;
00386
00387 private:
00388 const char *data;
00389 mutable int fieldNameSize_;
00390 int fieldNameSize() const {
00391 if ( fieldNameSize_ == -1 )
00392 fieldNameSize_ = (int)strlen( fieldName() ) + 1;
00393 return fieldNameSize_;
00394 }
00395 mutable int totalSize;
00396
00397 friend class BSONObjIterator;
00398 friend class BSONObj;
00399 const BSONElement& chk(int t) const {
00400 if ( t != type() ) {
00401 StringBuilder ss;
00402 ss << "wrong type for BSONElement (" << fieldName() << ") " << type() << " != " << t;
00403 uasserted(13111, ss.str() );
00404 }
00405 return *this;
00406 }
00407 const BSONElement& chk(bool expr) const {
00408 uassert(13118, "unexpected or missing type value in BSON object", expr);
00409 return *this;
00410 }
00411 };
00412
00413
00414 inline int BSONElement::canonicalType() const {
00415 BSONType t = type();
00416 switch ( t ) {
00417 case MinKey:
00418 case MaxKey:
00419 return t;
00420 case EOO:
00421 case Undefined:
00422 return 0;
00423 case jstNULL:
00424 return 5;
00425 case NumberDouble:
00426 case NumberInt:
00427 case NumberLong:
00428 return 10;
00429 case mongo::String:
00430 case Symbol:
00431 return 15;
00432 case Object:
00433 return 20;
00434 case mongo::Array:
00435 return 25;
00436 case BinData:
00437 return 30;
00438 case jstOID:
00439 return 35;
00440 case mongo::Bool:
00441 return 40;
00442 case mongo::Date:
00443 case Timestamp:
00444 return 45;
00445 case RegEx:
00446 return 50;
00447 case DBRef:
00448 return 55;
00449 case Code:
00450 return 60;
00451 case CodeWScope:
00452 return 65;
00453 default:
00454 assert(0);
00455 return -1;
00456 }
00457 }
00458
00459 inline bool BSONElement::trueValue() const {
00460 switch( type() ) {
00461 case NumberLong:
00462 return *reinterpret_cast< const long long* >( value() ) != 0;
00463 case NumberDouble:
00464 return *reinterpret_cast< const double* >( value() ) != 0;
00465 case NumberInt:
00466 return *reinterpret_cast< const int* >( value() ) != 0;
00467 case mongo::Bool:
00468 return boolean();
00469 case EOO:
00470 case jstNULL:
00471 case Undefined:
00472 return false;
00473
00474 default:
00475 ;
00476 }
00477 return true;
00478 }
00479
00481 inline bool BSONElement::isNumber() const {
00482 switch( type() ) {
00483 case NumberLong:
00484 case NumberDouble:
00485 case NumberInt:
00486 return true;
00487 default:
00488 return false;
00489 }
00490 }
00491
00492 inline bool BSONElement::isSimpleType() const {
00493 switch( type() ) {
00494 case NumberLong:
00495 case NumberDouble:
00496 case NumberInt:
00497 case mongo::String:
00498 case mongo::Bool:
00499 case mongo::Date:
00500 case jstOID:
00501 return true;
00502 default:
00503 return false;
00504 }
00505 }
00506
00507 inline double BSONElement::numberDouble() const {
00508 switch( type() ) {
00509 case NumberDouble:
00510 return _numberDouble();
00511 case NumberInt:
00512 return *reinterpret_cast< const int* >( value() );
00513 case NumberLong:
00514 return (double) *reinterpret_cast< const long long* >( value() );
00515 default:
00516 return 0;
00517 }
00518 }
00519
00521 inline int BSONElement::numberInt() const {
00522 switch( type() ) {
00523 case NumberDouble:
00524 return (int) _numberDouble();
00525 case NumberInt:
00526 return _numberInt();
00527 case NumberLong:
00528 return (int) _numberLong();
00529 default:
00530 return 0;
00531 }
00532 }
00533
00535 inline long long BSONElement::numberLong() const {
00536 switch( type() ) {
00537 case NumberDouble:
00538 return (long long) _numberDouble();
00539 case NumberInt:
00540 return _numberInt();
00541 case NumberLong:
00542 return _numberLong();
00543 default:
00544 return 0;
00545 }
00546 }
00547
00548 inline BSONElement::BSONElement() {
00549 static char z = 0;
00550 data = &z;
00551 fieldNameSize_ = 0;
00552 totalSize = 1;
00553 }
00554
00555 }