mirror of
https://github.com/mongodb/mongo.git
synced 2024-12-01 09:32:32 +01:00
formatting
This commit is contained in:
parent
c0081cc3c5
commit
bb90349ac1
@ -1,5 +1,5 @@
|
||||
// BSONElement
|
||||
|
||||
// BSONElement
|
||||
|
||||
/* Copyright 2009 10gen Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -14,487 +14,487 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace mongo {
|
||||
|
||||
/** BSONElement represents an "element" in a BSONObj. So for the object { a : 3, b : "abc" },
|
||||
'a : 3' is the first element (key+value).
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace mongo {
|
||||
|
||||
/** BSONElement represents an "element" in a BSONObj. So for the object { a : 3, b : "abc" },
|
||||
'a : 3' is the first element (key+value).
|
||||
|
||||
The BSONElement object points into the BSONObj's data. Thus the BSONObj must stay in scope
|
||||
for the life of the BSONElement.
|
||||
The BSONElement object points into the BSONObj's data. Thus the BSONObj must stay in scope
|
||||
for the life of the BSONElement.
|
||||
|
||||
internals:
|
||||
<type><fieldName ><value>
|
||||
-------- size() ------------
|
||||
-fieldNameSize-
|
||||
value()
|
||||
type()
|
||||
internals:
|
||||
<type><fieldName ><value>
|
||||
-------- size() ------------
|
||||
-fieldNameSize-
|
||||
value()
|
||||
type()
|
||||
*/
|
||||
class BSONElement {
|
||||
public:
|
||||
/** These functions, which start with a capital letter, throw a UserException if the
|
||||
element is not of the required type. Example:
|
||||
|
||||
string foo = obj["foo"].String(); // exception if not a string type or DNE
|
||||
*/
|
||||
class BSONElement {
|
||||
public:
|
||||
/** These functions, which start with a capital letter, throw a UserException if the
|
||||
element is not of the required type. Example:
|
||||
string String() const { return chk(mongo::String).toString(); }
|
||||
Date_t Date() const { return chk(mongo::Date).date(); }
|
||||
double Number() const { return chk(isNumber()).number(); }
|
||||
double Double() const { return chk(NumberDouble)._numberDouble(); }
|
||||
long long Long() const { return chk(NumberLong)._numberLong(); }
|
||||
int Int() const { return chk(NumberInt)._numberInt(); }
|
||||
bool Bool() const { return chk(mongo::Bool).boolean(); }
|
||||
BSONObj Obj() const;
|
||||
mongo::OID OID() const { return chk(jstOID).__oid(); }
|
||||
void Null() const { chk(isNull()); }
|
||||
|
||||
string foo = obj["foo"].String(); // exception if not a string type or DNE
|
||||
*/
|
||||
string String() const { return chk(mongo::String).toString(); }
|
||||
Date_t Date() const { return chk(mongo::Date).date(); }
|
||||
double Number() const { return chk(isNumber()).number(); }
|
||||
double Double() const { return chk(NumberDouble)._numberDouble(); }
|
||||
long long Long() const { return chk(NumberLong)._numberLong(); }
|
||||
int Int() const { return chk(NumberInt)._numberInt(); }
|
||||
bool Bool() const { return chk(mongo::Bool).boolean(); }
|
||||
BSONObj Obj() const;
|
||||
mongo::OID OID() const { return chk(jstOID).__oid(); }
|
||||
void Null() const { chk(isNull()); }
|
||||
string toString( bool includeFieldName = true ) const;
|
||||
operator string() const { return toString(); }
|
||||
string jsonString( JsonStringFormat format, bool includeFieldNames = true, int pretty = 0 ) const;
|
||||
|
||||
string toString( bool includeFieldName = true ) const;
|
||||
operator string() const { return toString(); }
|
||||
string jsonString( JsonStringFormat format, bool includeFieldNames = true, int pretty = 0 ) const;
|
||||
|
||||
/** Returns the type of the element */
|
||||
BSONType type() const { return (BSONType) *data; }
|
||||
/** Returns the type of the element */
|
||||
BSONType type() const { return (BSONType) *data; }
|
||||
|
||||
/** returns the tyoe of the element fixed for the main type
|
||||
the main purpose is numbers. any numeric type will return NumberDouble
|
||||
Note: if the order changes, indexes have to be re-built or than can be corruption
|
||||
*/
|
||||
int canonicalType() const;
|
||||
/** returns the tyoe of the element fixed for the main type
|
||||
the main purpose is numbers. any numeric type will return NumberDouble
|
||||
Note: if the order changes, indexes have to be re-built or than can be corruption
|
||||
*/
|
||||
int canonicalType() const;
|
||||
|
||||
/** Indicates if it is the end-of-object element, which is present at the end of
|
||||
every BSON object.
|
||||
*/
|
||||
bool eoo() const {
|
||||
return type() == EOO;
|
||||
}
|
||||
/** Indicates if it is the end-of-object element, which is present at the end of
|
||||
every BSON object.
|
||||
*/
|
||||
bool eoo() const {
|
||||
return type() == EOO;
|
||||
}
|
||||
|
||||
/** Size of the element.
|
||||
@param maxLen If maxLen is specified, don't scan more than maxLen bytes to calculate size.
|
||||
*/
|
||||
int size( int maxLen = -1 ) const;
|
||||
/** Size of the element.
|
||||
@param maxLen If maxLen is specified, don't scan more than maxLen bytes to calculate size.
|
||||
*/
|
||||
int size( int maxLen = -1 ) const;
|
||||
|
||||
/** Wrap this element up as a singleton object. */
|
||||
BSONObj wrap() const;
|
||||
/** Wrap this element up as a singleton object. */
|
||||
BSONObj wrap() const;
|
||||
|
||||
/** Wrap this element up as a singleton object with a new name. */
|
||||
BSONObj wrap( const char* newName) const;
|
||||
/** Wrap this element up as a singleton object with a new name. */
|
||||
BSONObj wrap( const char* newName) const;
|
||||
|
||||
/** field name of the element. e.g., for
|
||||
name : "Joe"
|
||||
"name" is the fieldname
|
||||
*/
|
||||
const char * fieldName() const {
|
||||
if ( eoo() ) return ""; // no fieldname for it.
|
||||
return data + 1;
|
||||
}
|
||||
/** field name of the element. e.g., for
|
||||
name : "Joe"
|
||||
"name" is the fieldname
|
||||
*/
|
||||
const char * fieldName() const {
|
||||
if ( eoo() ) return ""; // no fieldname for it.
|
||||
return data + 1;
|
||||
}
|
||||
|
||||
/** raw data of the element's value (so be careful). */
|
||||
const char * value() const {
|
||||
return (data + fieldNameSize() + 1);
|
||||
}
|
||||
/** size in bytes of the element's value (when applicable). */
|
||||
int valuesize() const {
|
||||
return size() - fieldNameSize() - 1;
|
||||
}
|
||||
/** raw data of the element's value (so be careful). */
|
||||
const char * value() const {
|
||||
return (data + fieldNameSize() + 1);
|
||||
}
|
||||
/** size in bytes of the element's value (when applicable). */
|
||||
int valuesize() const {
|
||||
return size() - fieldNameSize() - 1;
|
||||
}
|
||||
|
||||
bool isBoolean() const { return type() == mongo::Bool; }
|
||||
bool isBoolean() const { return type() == mongo::Bool; }
|
||||
|
||||
/** @return value of a boolean element.
|
||||
You must assure element is a boolean before
|
||||
calling. */
|
||||
bool boolean() const {
|
||||
return *value() ? true : false;
|
||||
}
|
||||
/** @return value of a boolean element.
|
||||
You must assure element is a boolean before
|
||||
calling. */
|
||||
bool boolean() const {
|
||||
return *value() ? true : false;
|
||||
}
|
||||
|
||||
/** Retrieve a java style date value from the element.
|
||||
Ensure element is of type Date before calling.
|
||||
*/
|
||||
Date_t date() const {
|
||||
return *reinterpret_cast< const Date_t* >( value() );
|
||||
}
|
||||
/** Retrieve a java style date value from the element.
|
||||
Ensure element is of type Date before calling.
|
||||
*/
|
||||
Date_t date() const {
|
||||
return *reinterpret_cast< const Date_t* >( value() );
|
||||
}
|
||||
|
||||
/** Convert the value to boolean, regardless of its type, in a javascript-like fashion
|
||||
(i.e., treat zero and null as false).
|
||||
*/
|
||||
bool trueValue() const;
|
||||
/** Convert the value to boolean, regardless of its type, in a javascript-like fashion
|
||||
(i.e., treat zero and null as false).
|
||||
*/
|
||||
bool trueValue() const;
|
||||
|
||||
/** True if number, string, bool, date, OID */
|
||||
bool isSimpleType() const;
|
||||
/** True if number, string, bool, date, OID */
|
||||
bool isSimpleType() const;
|
||||
|
||||
/** True if element is of a numeric type. */
|
||||
bool isNumber() const;
|
||||
/** True if element is of a numeric type. */
|
||||
bool isNumber() const;
|
||||
|
||||
/** Return double value for this field. MUST be NumberDouble type. */
|
||||
double _numberDouble() const {return *reinterpret_cast< const double* >( value() ); }
|
||||
/** Return double value for this field. MUST be NumberInt type. */
|
||||
int _numberInt() const {return *reinterpret_cast< const int* >( value() ); }
|
||||
/** Return double value for this field. MUST be NumberLong type. */
|
||||
long long _numberLong() const {return *reinterpret_cast< const long long* >( value() ); }
|
||||
/** Return double value for this field. MUST be NumberDouble type. */
|
||||
double _numberDouble() const {return *reinterpret_cast< const double* >( value() ); }
|
||||
/** Return double value for this field. MUST be NumberInt type. */
|
||||
int _numberInt() const {return *reinterpret_cast< const int* >( value() ); }
|
||||
/** Return double value for this field. MUST be NumberLong type. */
|
||||
long long _numberLong() const {return *reinterpret_cast< const long long* >( value() ); }
|
||||
|
||||
/** Retrieve int value for the element safely. Zero returned if not a number. */
|
||||
int numberInt() const;
|
||||
/** Retrieve long value for the element safely. Zero returned if not a number. */
|
||||
long long numberLong() const;
|
||||
/** Retrieve the numeric value of the element. If not of a numeric type, returns 0.
|
||||
Note: casts to double, data loss may occur with large (>52 bit) NumberLong values.
|
||||
*/
|
||||
double numberDouble() const;
|
||||
/** Retrieve the numeric value of the element. If not of a numeric type, returns 0.
|
||||
Note: casts to double, data loss may occur with large (>52 bit) NumberLong values.
|
||||
*/
|
||||
double number() const { return numberDouble(); }
|
||||
/** Retrieve int value for the element safely. Zero returned if not a number. */
|
||||
int numberInt() const;
|
||||
/** Retrieve long value for the element safely. Zero returned if not a number. */
|
||||
long long numberLong() const;
|
||||
/** Retrieve the numeric value of the element. If not of a numeric type, returns 0.
|
||||
Note: casts to double, data loss may occur with large (>52 bit) NumberLong values.
|
||||
*/
|
||||
double numberDouble() const;
|
||||
/** Retrieve the numeric value of the element. If not of a numeric type, returns 0.
|
||||
Note: casts to double, data loss may occur with large (>52 bit) NumberLong values.
|
||||
*/
|
||||
double number() const { return numberDouble(); }
|
||||
|
||||
/** Retrieve the object ID stored in the object.
|
||||
You must ensure the element is of type jstOID first. */
|
||||
const mongo::OID &__oid() const { return *reinterpret_cast< const mongo::OID* >( value() ); }
|
||||
/** Retrieve the object ID stored in the object.
|
||||
You must ensure the element is of type jstOID first. */
|
||||
const mongo::OID &__oid() const { return *reinterpret_cast< const mongo::OID* >( value() ); }
|
||||
|
||||
/** True if element is null. */
|
||||
bool isNull() const {
|
||||
return type() == jstNULL;
|
||||
}
|
||||
/** True if element is null. */
|
||||
bool isNull() const {
|
||||
return type() == jstNULL;
|
||||
}
|
||||
|
||||
/** Size (length) of a string element.
|
||||
You must assure of type String first. */
|
||||
int valuestrsize() const {
|
||||
return *reinterpret_cast< const int* >( value() );
|
||||
/** Size (length) of a string element.
|
||||
You must assure of type String first. */
|
||||
int valuestrsize() const {
|
||||
return *reinterpret_cast< const int* >( value() );
|
||||
}
|
||||
|
||||
// for objects the size *includes* the size of the size field
|
||||
int objsize() const {
|
||||
return *reinterpret_cast< const int* >( value() );
|
||||
}
|
||||
|
||||
/** Get a string's value. Also gives you start of the real data for an embedded object.
|
||||
You must assure data is of an appropriate type first -- see also valuestrsafe().
|
||||
*/
|
||||
const char * valuestr() const {
|
||||
return value() + 4;
|
||||
}
|
||||
|
||||
/** Get the string value of the element. If not a string returns "". */
|
||||
const char *valuestrsafe() const {
|
||||
return type() == mongo::String ? valuestr() : "";
|
||||
}
|
||||
/** Get the string value of the element. If not a string returns "". */
|
||||
string str() const { return valuestrsafe(); }
|
||||
|
||||
/** Get javascript code of a CodeWScope data element. */
|
||||
const char * codeWScopeCode() const {
|
||||
return value() + 8;
|
||||
}
|
||||
/** Get the scope SavedContext of a CodeWScope data element. */
|
||||
const char * codeWScopeScopeData() const {
|
||||
// TODO fix
|
||||
return codeWScopeCode() + strlen( codeWScopeCode() ) + 1;
|
||||
}
|
||||
|
||||
/** Get the embedded object this element holds. */
|
||||
BSONObj embeddedObject() const;
|
||||
|
||||
/* uasserts if not an object */
|
||||
BSONObj embeddedObjectUserCheck() const;
|
||||
|
||||
BSONObj codeWScopeObject() const;
|
||||
|
||||
string ascode() const {
|
||||
switch( type() ){
|
||||
case mongo::String:
|
||||
case Code:
|
||||
return valuestr();
|
||||
case CodeWScope:
|
||||
return codeWScopeCode();
|
||||
default:
|
||||
log() << "can't convert type: " << (int)(type()) << " to code" << endl;
|
||||
}
|
||||
uassert( 10062 , "not code" , 0 );
|
||||
return "";
|
||||
}
|
||||
|
||||
// for objects the size *includes* the size of the size field
|
||||
int objsize() const {
|
||||
return *reinterpret_cast< const int* >( value() );
|
||||
}
|
||||
|
||||
/** Get a string's value. Also gives you start of the real data for an embedded object.
|
||||
You must assure data is of an appropriate type first -- see also valuestrsafe().
|
||||
*/
|
||||
const char * valuestr() const {
|
||||
return value() + 4;
|
||||
}
|
||||
|
||||
/** Get the string value of the element. If not a string returns "". */
|
||||
const char *valuestrsafe() const {
|
||||
return type() == mongo::String ? valuestr() : "";
|
||||
}
|
||||
/** Get the string value of the element. If not a string returns "". */
|
||||
string str() const { return valuestrsafe(); }
|
||||
|
||||
/** Get javascript code of a CodeWScope data element. */
|
||||
const char * codeWScopeCode() const {
|
||||
return value() + 8;
|
||||
}
|
||||
/** Get the scope SavedContext of a CodeWScope data element. */
|
||||
const char * codeWScopeScopeData() const {
|
||||
// TODO fix
|
||||
return codeWScopeCode() + strlen( codeWScopeCode() ) + 1;
|
||||
}
|
||||
|
||||
/** Get the embedded object this element holds. */
|
||||
BSONObj embeddedObject() const;
|
||||
|
||||
/* uasserts if not an object */
|
||||
BSONObj embeddedObjectUserCheck() const;
|
||||
|
||||
BSONObj codeWScopeObject() const;
|
||||
|
||||
string ascode() const {
|
||||
switch( type() ){
|
||||
case mongo::String:
|
||||
case Code:
|
||||
return valuestr();
|
||||
case CodeWScope:
|
||||
return codeWScopeCode();
|
||||
default:
|
||||
log() << "can't convert type: " << (int)(type()) << " to code" << endl;
|
||||
}
|
||||
uassert( 10062 , "not code" , 0 );
|
||||
return "";
|
||||
}
|
||||
|
||||
/** Get binary data. Element must be of type BinData */
|
||||
const char *binData(int& len) const {
|
||||
// BinData: <int len> <byte subtype> <byte[len] data>
|
||||
assert( type() == BinData );
|
||||
len = valuestrsize();
|
||||
return value() + 5;
|
||||
}
|
||||
/** Get binary data. Element must be of type BinData */
|
||||
const char *binData(int& len) const {
|
||||
// BinData: <int len> <byte subtype> <byte[len] data>
|
||||
assert( type() == BinData );
|
||||
len = valuestrsize();
|
||||
return value() + 5;
|
||||
}
|
||||
|
||||
BinDataType binDataType() const {
|
||||
// BinData: <int len> <byte subtype> <byte[len] data>
|
||||
assert( type() == BinData );
|
||||
unsigned char c = (value() + 4)[0];
|
||||
return (BinDataType)c;
|
||||
}
|
||||
BinDataType binDataType() const {
|
||||
// BinData: <int len> <byte subtype> <byte[len] data>
|
||||
assert( type() == BinData );
|
||||
unsigned char c = (value() + 4)[0];
|
||||
return (BinDataType)c;
|
||||
}
|
||||
|
||||
/** Retrieve the regex string for a Regex element */
|
||||
const char *regex() const {
|
||||
assert(type() == RegEx);
|
||||
return value();
|
||||
}
|
||||
/** Retrieve the regex string for a Regex element */
|
||||
const char *regex() const {
|
||||
assert(type() == RegEx);
|
||||
return value();
|
||||
}
|
||||
|
||||
/** Retrieve the regex flags (options) for a Regex element */
|
||||
const char *regexFlags() const {
|
||||
const char *p = regex();
|
||||
return p + strlen(p) + 1;
|
||||
}
|
||||
/** Retrieve the regex flags (options) for a Regex element */
|
||||
const char *regexFlags() const {
|
||||
const char *p = regex();
|
||||
return p + strlen(p) + 1;
|
||||
}
|
||||
|
||||
/** like operator== but doesn't check the fieldname,
|
||||
just the value.
|
||||
*/
|
||||
bool valuesEqual(const BSONElement& r) const {
|
||||
return woCompare( r , false ) == 0;
|
||||
}
|
||||
/** like operator== but doesn't check the fieldname,
|
||||
just the value.
|
||||
*/
|
||||
bool valuesEqual(const BSONElement& r) const {
|
||||
return woCompare( r , false ) == 0;
|
||||
}
|
||||
|
||||
/** Returns true if elements are equal. */
|
||||
bool operator==(const BSONElement& r) const {
|
||||
return woCompare( r , true ) == 0;
|
||||
}
|
||||
/** Returns true if elements are equal. */
|
||||
bool operator==(const BSONElement& r) const {
|
||||
return woCompare( r , true ) == 0;
|
||||
}
|
||||
|
||||
|
||||
/** Well ordered comparison.
|
||||
@return <0: l<r. 0:l==r. >0:l>r
|
||||
order by type, field name, and field value.
|
||||
If considerFieldName is true, pay attention to the field name.
|
||||
*/
|
||||
int woCompare( const BSONElement &e, bool considerFieldName = true ) const;
|
||||
/** Well ordered comparison.
|
||||
@return <0: l<r. 0:l==r. >0:l>r
|
||||
order by type, field name, and field value.
|
||||
If considerFieldName is true, pay attention to the field name.
|
||||
*/
|
||||
int woCompare( const BSONElement &e, bool considerFieldName = true ) const;
|
||||
|
||||
const char * rawdata() const {
|
||||
return data;
|
||||
}
|
||||
const char * rawdata() const {
|
||||
return data;
|
||||
}
|
||||
|
||||
/** 0 == Equality, just not defined yet */
|
||||
int getGtLtOp( int def = 0 ) const;
|
||||
/** 0 == Equality, just not defined yet */
|
||||
int getGtLtOp( int def = 0 ) const;
|
||||
|
||||
/** Constructs an empty element */
|
||||
BSONElement();
|
||||
/** Constructs an empty element */
|
||||
BSONElement();
|
||||
|
||||
/** Check that data is internally consistent. */
|
||||
void validate() const;
|
||||
/** Check that data is internally consistent. */
|
||||
void validate() const;
|
||||
|
||||
/** True if this element may contain subobjects. */
|
||||
bool mayEncapsulate() const {
|
||||
switch ( type() ){
|
||||
case Object:
|
||||
case Array:
|
||||
case CodeWScope:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
/** True if this element may contain subobjects. */
|
||||
bool mayEncapsulate() const {
|
||||
switch ( type() ){
|
||||
case Object:
|
||||
case Array:
|
||||
case CodeWScope:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** True if this element can be a BSONObj */
|
||||
bool isABSONObj() const {
|
||||
switch( type() ){
|
||||
case Object:
|
||||
case Array:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
OpTime optime() const {
|
||||
return OpTime( *reinterpret_cast< const unsigned long long* >( value() ) );
|
||||
}
|
||||
|
||||
Date_t timestampTime() const{
|
||||
unsigned long long t = ((unsigned int*)(value() + 4 ))[0];
|
||||
return t * 1000;
|
||||
}
|
||||
unsigned int timestampInc() const{
|
||||
return ((unsigned int*)(value() ))[0];
|
||||
}
|
||||
|
||||
const char * dbrefNS() const {
|
||||
uassert( 10063 , "not a dbref" , type() == DBRef );
|
||||
return value() + 4;
|
||||
}
|
||||
|
||||
const mongo::OID& dbrefOID() const {
|
||||
uassert( 10064 , "not a dbref" , type() == DBRef );
|
||||
const char * start = value();
|
||||
start += 4 + *reinterpret_cast< const int* >( start );
|
||||
return *reinterpret_cast< const mongo::OID* >( start );
|
||||
}
|
||||
|
||||
bool operator<( const BSONElement& other ) const {
|
||||
int x = (int)canonicalType() - (int)other.canonicalType();
|
||||
if ( x < 0 ) return true;
|
||||
else if ( x > 0 ) return false;
|
||||
return compareElementValues(*this,other) < 0;
|
||||
}
|
||||
|
||||
// If maxLen is specified, don't scan more than maxLen bytes.
|
||||
BSONElement(const char *d, int maxLen = -1) : data(d) {
|
||||
fieldNameSize_ = -1;
|
||||
if ( eoo() )
|
||||
fieldNameSize_ = 0;
|
||||
else {
|
||||
if ( maxLen != -1 ) {
|
||||
int size = strnlen( fieldName(), maxLen - 1 );
|
||||
massert( 10333 , "Invalid field name", size != -1 );
|
||||
fieldNameSize_ = size + 1;
|
||||
}
|
||||
}
|
||||
totalSize = -1;
|
||||
}
|
||||
private:
|
||||
const char *data;
|
||||
mutable int fieldNameSize_; // cached value
|
||||
int fieldNameSize() const {
|
||||
if ( fieldNameSize_ == -1 )
|
||||
fieldNameSize_ = (int)strlen( fieldName() ) + 1;
|
||||
return fieldNameSize_;
|
||||
}
|
||||
mutable int totalSize; /* caches the computed size */
|
||||
|
||||
/** True if this element can be a BSONObj */
|
||||
bool isABSONObj() const {
|
||||
switch( type() ){
|
||||
case Object:
|
||||
case Array:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
OpTime optime() const {
|
||||
return OpTime( *reinterpret_cast< const unsigned long long* >( value() ) );
|
||||
}
|
||||
|
||||
Date_t timestampTime() const{
|
||||
unsigned long long t = ((unsigned int*)(value() + 4 ))[0];
|
||||
return t * 1000;
|
||||
}
|
||||
unsigned int timestampInc() const{
|
||||
return ((unsigned int*)(value() ))[0];
|
||||
}
|
||||
|
||||
const char * dbrefNS() const {
|
||||
uassert( 10063 , "not a dbref" , type() == DBRef );
|
||||
return value() + 4;
|
||||
}
|
||||
|
||||
const mongo::OID& dbrefOID() const {
|
||||
uassert( 10064 , "not a dbref" , type() == DBRef );
|
||||
const char * start = value();
|
||||
start += 4 + *reinterpret_cast< const int* >( start );
|
||||
return *reinterpret_cast< const mongo::OID* >( start );
|
||||
}
|
||||
|
||||
bool operator<( const BSONElement& other ) const {
|
||||
int x = (int)canonicalType() - (int)other.canonicalType();
|
||||
if ( x < 0 ) return true;
|
||||
else if ( x > 0 ) return false;
|
||||
return compareElementValues(*this,other) < 0;
|
||||
}
|
||||
|
||||
// If maxLen is specified, don't scan more than maxLen bytes.
|
||||
BSONElement(const char *d, int maxLen = -1) : data(d) {
|
||||
fieldNameSize_ = -1;
|
||||
if ( eoo() )
|
||||
fieldNameSize_ = 0;
|
||||
else {
|
||||
if ( maxLen != -1 ) {
|
||||
int size = strnlen( fieldName(), maxLen - 1 );
|
||||
massert( 10333 , "Invalid field name", size != -1 );
|
||||
fieldNameSize_ = size + 1;
|
||||
}
|
||||
}
|
||||
totalSize = -1;
|
||||
}
|
||||
private:
|
||||
const char *data;
|
||||
mutable int fieldNameSize_; // cached value
|
||||
int fieldNameSize() const {
|
||||
if ( fieldNameSize_ == -1 )
|
||||
fieldNameSize_ = (int)strlen( fieldName() ) + 1;
|
||||
return fieldNameSize_;
|
||||
}
|
||||
mutable int totalSize; /* caches the computed size */
|
||||
|
||||
friend class BSONObjIterator;
|
||||
friend class BSONObj;
|
||||
const BSONElement& chk(int t) const {
|
||||
uassert(13111, "unexpected or missing type value in BSON object", t == type());
|
||||
return *this;
|
||||
}
|
||||
const BSONElement& chk(bool expr) const {
|
||||
uassert(13118, "unexpected or missing type value in BSON object", expr);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
friend class BSONObjIterator;
|
||||
friend class BSONObj;
|
||||
const BSONElement& chk(int t) const {
|
||||
uassert(13111, "unexpected or missing type value in BSON object", t == type());
|
||||
return *this;
|
||||
}
|
||||
const BSONElement& chk(bool expr) const {
|
||||
uassert(13118, "unexpected or missing type value in BSON object", expr);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
inline int BSONElement::canonicalType() const {
|
||||
BSONType t = type();
|
||||
switch ( t ){
|
||||
case MinKey:
|
||||
case MaxKey:
|
||||
return t;
|
||||
case EOO:
|
||||
case Undefined:
|
||||
return 0;
|
||||
case jstNULL:
|
||||
return 5;
|
||||
case NumberDouble:
|
||||
case NumberInt:
|
||||
case NumberLong:
|
||||
return 10;
|
||||
case mongo::String:
|
||||
case Symbol:
|
||||
return 15;
|
||||
case Object:
|
||||
return 20;
|
||||
case Array:
|
||||
return 25;
|
||||
case BinData:
|
||||
return 30;
|
||||
case jstOID:
|
||||
return 35;
|
||||
case mongo::Bool:
|
||||
return 40;
|
||||
case mongo::Date:
|
||||
case Timestamp:
|
||||
return 45;
|
||||
case RegEx:
|
||||
return 50;
|
||||
case DBRef:
|
||||
return 55;
|
||||
case Code:
|
||||
return 60;
|
||||
case CodeWScope:
|
||||
return 65;
|
||||
default:
|
||||
assert(0);
|
||||
return -1;
|
||||
}
|
||||
BSONType t = type();
|
||||
switch ( t ){
|
||||
case MinKey:
|
||||
case MaxKey:
|
||||
return t;
|
||||
case EOO:
|
||||
case Undefined:
|
||||
return 0;
|
||||
case jstNULL:
|
||||
return 5;
|
||||
case NumberDouble:
|
||||
case NumberInt:
|
||||
case NumberLong:
|
||||
return 10;
|
||||
case mongo::String:
|
||||
case Symbol:
|
||||
return 15;
|
||||
case Object:
|
||||
return 20;
|
||||
case Array:
|
||||
return 25;
|
||||
case BinData:
|
||||
return 30;
|
||||
case jstOID:
|
||||
return 35;
|
||||
case mongo::Bool:
|
||||
return 40;
|
||||
case mongo::Date:
|
||||
case Timestamp:
|
||||
return 45;
|
||||
case RegEx:
|
||||
return 50;
|
||||
case DBRef:
|
||||
return 55;
|
||||
case Code:
|
||||
return 60;
|
||||
case CodeWScope:
|
||||
return 65;
|
||||
default:
|
||||
assert(0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool BSONElement::trueValue() const {
|
||||
switch( type() ) {
|
||||
case NumberLong:
|
||||
return *reinterpret_cast< const long long* >( value() ) != 0;
|
||||
case NumberDouble:
|
||||
return *reinterpret_cast< const double* >( value() ) != 0;
|
||||
case NumberInt:
|
||||
return *reinterpret_cast< const int* >( value() ) != 0;
|
||||
case mongo::Bool:
|
||||
return boolean();
|
||||
case EOO:
|
||||
case jstNULL:
|
||||
case Undefined:
|
||||
return false;
|
||||
switch( type() ) {
|
||||
case NumberLong:
|
||||
return *reinterpret_cast< const long long* >( value() ) != 0;
|
||||
case NumberDouble:
|
||||
return *reinterpret_cast< const double* >( value() ) != 0;
|
||||
case NumberInt:
|
||||
return *reinterpret_cast< const int* >( value() ) != 0;
|
||||
case mongo::Bool:
|
||||
return boolean();
|
||||
case EOO:
|
||||
case jstNULL:
|
||||
case Undefined:
|
||||
return false;
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
default:
|
||||
;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** True if element is of a numeric type. */
|
||||
inline bool BSONElement::isNumber() const {
|
||||
switch( type() ) {
|
||||
case NumberLong:
|
||||
case NumberDouble:
|
||||
case NumberInt:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** True if element is of a numeric type. */
|
||||
inline bool BSONElement::isNumber() const {
|
||||
switch( type() ) {
|
||||
case NumberLong:
|
||||
case NumberDouble:
|
||||
case NumberInt:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
inline bool BSONElement::isSimpleType() const {
|
||||
switch( type() ){
|
||||
case NumberLong:
|
||||
case NumberDouble:
|
||||
case NumberInt:
|
||||
case mongo::String:
|
||||
case mongo::Bool:
|
||||
case mongo::Date:
|
||||
case jstOID:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool BSONElement::isSimpleType() const {
|
||||
switch( type() ){
|
||||
case NumberLong:
|
||||
case NumberDouble:
|
||||
case NumberInt:
|
||||
case mongo::String:
|
||||
case mongo::Bool:
|
||||
case mongo::Date:
|
||||
case jstOID:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
inline double BSONElement::numberDouble() const {
|
||||
switch( type() ) {
|
||||
case NumberDouble:
|
||||
return _numberDouble();
|
||||
case NumberInt:
|
||||
return *reinterpret_cast< const int* >( value() );
|
||||
case NumberLong:
|
||||
return (double) *reinterpret_cast< const long long* >( value() );
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline double BSONElement::numberDouble() const {
|
||||
switch( type() ) {
|
||||
case NumberDouble:
|
||||
return _numberDouble();
|
||||
case NumberInt:
|
||||
return *reinterpret_cast< const int* >( value() );
|
||||
case NumberLong:
|
||||
return (double) *reinterpret_cast< const long long* >( value() );
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
/** Retrieve int value for the element safely. Zero returned if not a number. */
|
||||
inline int BSONElement::numberInt() const {
|
||||
switch( type() ) {
|
||||
case NumberDouble:
|
||||
return (int) _numberDouble();
|
||||
case NumberInt:
|
||||
return _numberInt();
|
||||
case NumberLong:
|
||||
return (int) _numberLong();
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/** Retrieve int value for the element safely. Zero returned if not a number. */
|
||||
inline int BSONElement::numberInt() const {
|
||||
switch( type() ) {
|
||||
case NumberDouble:
|
||||
return (int) _numberDouble();
|
||||
case NumberInt:
|
||||
return _numberInt();
|
||||
case NumberLong:
|
||||
return (int) _numberLong();
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
/** Retrieve long value for the element safely. Zero returned if not a number. */
|
||||
inline long long BSONElement::numberLong() const {
|
||||
switch( type() ) {
|
||||
case NumberDouble:
|
||||
return (long long) _numberDouble();
|
||||
case NumberInt:
|
||||
return _numberInt();
|
||||
case NumberLong:
|
||||
return _numberLong();
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Retrieve long value for the element safely. Zero returned if not a number. */
|
||||
inline long long BSONElement::numberLong() const {
|
||||
switch( type() ) {
|
||||
case NumberDouble:
|
||||
return (long long) _numberDouble();
|
||||
case NumberInt:
|
||||
return _numberInt();
|
||||
case NumberLong:
|
||||
return _numberLong();
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
118
bson/bsontypes.h
118
bson/bsontypes.h
@ -1,5 +1,5 @@
|
||||
// bsontypes.h
|
||||
|
||||
// bsontypes.h
|
||||
|
||||
/* Copyright 2009 10gen Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -14,66 +14,66 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace mongo {
|
||||
|
||||
/**
|
||||
the complete list of valid BSON types
|
||||
see also bsonspec.org
|
||||
*/
|
||||
enum BSONType {
|
||||
/** smaller than all other types */
|
||||
MinKey=-1,
|
||||
/** end of object */
|
||||
EOO=0,
|
||||
/** double precision floating point value */
|
||||
NumberDouble=1,
|
||||
/** character string, stored in utf8 */
|
||||
String=2,
|
||||
/** an embedded object */
|
||||
Object=3,
|
||||
/** an embedded array */
|
||||
Array=4,
|
||||
/** binary data */
|
||||
BinData=5,
|
||||
/** Undefined type */
|
||||
Undefined=6,
|
||||
/** ObjectId */
|
||||
jstOID=7,
|
||||
/** boolean type */
|
||||
Bool=8,
|
||||
/** date type */
|
||||
Date=9,
|
||||
/** null type */
|
||||
jstNULL=10,
|
||||
/** regular expression, a pattern with options */
|
||||
RegEx=11,
|
||||
/** deprecated / will be redesigned */
|
||||
DBRef=12,
|
||||
/** deprecated / use CodeWScope */
|
||||
Code=13,
|
||||
/** a programming language (e.g., Python) symbol */
|
||||
Symbol=14,
|
||||
/** javascript code that can execute on the database server, with SavedContext */
|
||||
CodeWScope=15,
|
||||
/** 32 bit signed integer */
|
||||
NumberInt = 16,
|
||||
/** Updated to a Date with value next OpTime on insert */
|
||||
Timestamp = 17,
|
||||
/** 64 bit integer */
|
||||
NumberLong = 18,
|
||||
/** max type that is not MaxKey */
|
||||
JSTypeMax=18,
|
||||
/** larger than all other types */
|
||||
MaxKey=127
|
||||
};
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace mongo {
|
||||
|
||||
/**
|
||||
the complete list of valid BSON types
|
||||
see also bsonspec.org
|
||||
*/
|
||||
enum BSONType {
|
||||
/** smaller than all other types */
|
||||
MinKey=-1,
|
||||
/** end of object */
|
||||
EOO=0,
|
||||
/** double precision floating point value */
|
||||
NumberDouble=1,
|
||||
/** character string, stored in utf8 */
|
||||
String=2,
|
||||
/** an embedded object */
|
||||
Object=3,
|
||||
/** an embedded array */
|
||||
Array=4,
|
||||
/** binary data */
|
||||
BinData=5,
|
||||
/** Undefined type */
|
||||
Undefined=6,
|
||||
/** ObjectId */
|
||||
jstOID=7,
|
||||
/** boolean type */
|
||||
Bool=8,
|
||||
/** date type */
|
||||
Date=9,
|
||||
/** null type */
|
||||
jstNULL=10,
|
||||
/** regular expression, a pattern with options */
|
||||
RegEx=11,
|
||||
/** deprecated / will be redesigned */
|
||||
DBRef=12,
|
||||
/** deprecated / use CodeWScope */
|
||||
Code=13,
|
||||
/** a programming language (e.g., Python) symbol */
|
||||
Symbol=14,
|
||||
/** javascript code that can execute on the database server, with SavedContext */
|
||||
CodeWScope=15,
|
||||
/** 32 bit signed integer */
|
||||
NumberInt = 16,
|
||||
/** Updated to a Date with value next OpTime on insert */
|
||||
Timestamp = 17,
|
||||
/** 64 bit integer */
|
||||
NumberLong = 18,
|
||||
/** max type that is not MaxKey */
|
||||
JSTypeMax=18,
|
||||
/** larger than all other types */
|
||||
MaxKey=127
|
||||
};
|
||||
|
||||
/* subtypes of BinData.
|
||||
bdtCustom and above are ones that the JS compiler understands, but are
|
||||
opaque to the database.
|
||||
*/
|
||||
enum BinDataType { Function=1, ByteArray=2, bdtUUID = 3, MD5Type=5, bdtCustom=128 };
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user