summaryrefslogtreecommitdiff
path: root/db/jsobj.h
diff options
context:
space:
mode:
authorAaron <aaron@10gen.com>2008-12-28 20:28:49 -0500
committerAaron <aaron@10gen.com>2008-12-28 20:28:49 -0500
commitb7cbd301124045fccab665f939a68d703e70629b (patch)
treee7796053c090b4ee242ef5d1d960e6d78f57ec2b /db/jsobj.h
parentb53f593e1bc3d13fc831089541f23116fcc1803a (diff)
downloadmongo-b7cbd301124045fccab665f939a68d703e70629b.tar.gz
Replace tab indentation with spaces
Diffstat (limited to 'db/jsobj.h')
-rw-r--r--db/jsobj.h993
1 files changed, 524 insertions, 469 deletions
diff --git a/db/jsobj.h b/db/jsobj.h
index 8e0fa247cbc..a7c2f85c1a5 100644
--- a/db/jsobj.h
+++ b/db/jsobj.h
@@ -8,16 +8,16 @@
/**
* Copyright (C) 2008 10gen Inc.
-*
+*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
-*
+*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
-*
+*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -36,17 +36,17 @@ class BSONObjBuilder;
#pragma pack(push,1)
-/* BinData = binary data types.
+/* BinData = binary data types.
EOO = end of object
*/
-enum BSONType {MinKey=-1, EOO=0, NumberDouble=1, String=2, Object=3, Array=4, BinData=5,
- Undefined=6, jstOID=7, Bool=8, Date=9 , jstNULL=10, RegEx=11 ,
- DBRef=12, Code=13, Symbol=14, CodeWScope=15 ,
- NumberInt = 16,
- JSTypeMax=16,
- MaxKey=127
+enum BSONType {MinKey=-1, EOO=0, NumberDouble=1, String=2, Object=3, Array=4, BinData=5,
+ Undefined=6, jstOID=7, Bool=8, Date=9 , jstNULL=10, RegEx=11 ,
+ DBRef=12, Code=13, Symbol=14, CodeWScope=15 ,
+ NumberInt = 16,
+ JSTypeMax=16,
+ MaxKey=127
-};
+ };
/* subtypes of BinData.
bdtCustom and above are ones that the JS compiler understands, but are
@@ -54,14 +54,18 @@ enum BSONType {MinKey=-1, EOO=0, NumberDouble=1, String=2, Object=3, Array=4, Bi
*/
enum BinDataType { Function=1, ByteArray=2, bdtCustom=128 };
-/* Object id's are optional for BSONObjects.
+/* Object id's are optional for BSONObjects.
When present they should be the first object member added.
*/
-struct OID {
- long long a;
- unsigned b;
- bool operator==(const OID& r) { return a==r.a&&b==r.b; }
- void out(){ cout << hex << a << hex << b << endl; };
+struct OID {
+ long long a;
+ unsigned b;
+ bool operator==(const OID& r) {
+ return a==r.a&&b==r.b;
+ }
+ void out() {
+ cout << hex << a << hex << b << endl;
+ };
};
/* marshalled js object format:
@@ -91,511 +95,557 @@ struct OID {
#pragma pack(pop)
-/* <type><fieldName ><value>
+/* <type><fieldName ><value>
-------- size() ------------
-fieldNameSize-
value()
type()
*/
class BSONElement {
- friend class BSONObjIterator;
- friend class BSONObj;
+ friend class BSONObjIterator;
+ friend class BSONObj;
public:
- string toString() const;
- BSONType type() const { return (BSONType) *data; }
- bool eoo() const { return type() == EOO; }
- int size() const;
+ string toString() const;
+ BSONType type() const {
+ return (BSONType) *data;
+ }
+ bool eoo() const {
+ return type() == EOO;
+ }
+ int size() const;
- // wrap this element up as a singleton object.
- BSONObj wrap();
+ // wrap this element up as a singleton object.
+ BSONObj wrap();
- const char * fieldName() const {
- if( eoo() ) return ""; // no fieldname for it.
- return data + 1;
- }
+ const char * fieldName() const {
+ if ( eoo() ) return ""; // no fieldname for it.
+ return data + 1;
+ }
- // raw data be careful:
- const char * value() const { return (data + fieldNameSize + 1); }
- int valuesize() const { return size() - fieldNameSize - 1; }
+ // raw data be careful:
+ const char * value() const {
+ return (data + fieldNameSize + 1);
+ }
+ int valuesize() const {
+ return size() - fieldNameSize - 1;
+ }
- bool isBoolean() const { return type() == Bool; }
- bool boolean() const { return *value() ? true : false; }
+ bool isBoolean() const {
+ return type() == Bool;
+ }
+ bool boolean() const {
+ return *value() ? true : false;
+ }
- unsigned long long date() const { return *((unsigned long long*) value()); }
- //double& number() { return *((double *) value()); }
+ unsigned long long date() const {
+ return *((unsigned long long*) value());
+ }
+ //double& number() { return *((double *) value()); }
- bool isNumber() const { return type() == NumberDouble || type() == NumberInt; }
- void setNumber(double d) {
- if( type() == NumberDouble ) *((double *) value()) = d;
- else if( type() == NumberInt ) *((int *) value()) = (int) d;
- }
- double number() const {
- if( type() == NumberDouble ) return *((double *) value());
- if( type() == NumberInt ) return *((int *) value());
- return 0;
- }
- OID& oid() const { return *((OID*) value()); }
+ bool isNumber() const {
+ return type() == NumberDouble || type() == NumberInt;
+ }
+ void setNumber(double d) {
+ if ( type() == NumberDouble ) *((double *) value()) = d;
+ else if ( type() == NumberInt ) *((int *) value()) = (int) d;
+ }
+ double number() const {
+ if ( type() == NumberDouble ) return *((double *) value());
+ if ( type() == NumberInt ) return *((int *) value());
+ return 0;
+ }
+ OID& oid() const {
+ return *((OID*) value());
+ }
- // for strings
- int valuestrsize() const {
- return *((int *) value());
- }
+ // for strings
+ int valuestrsize() const {
+ return *((int *) value());
+ }
- // for objects the size *includes* the size of the size field
- int objsize() const {
- return *((int *) value());
- }
+ // for objects the size *includes* the size of the size field
+ int objsize() const {
+ return *((int *) value());
+ }
- // for strings. also gives you start of the real data for an embedded object
- const char * valuestr() const { return value() + 4; }
+ // for strings. also gives you start of the real data for an embedded object
+ const char * valuestr() const {
+ return value() + 4;
+ }
- const char *valuestrsafe() const {
- return type() == String ? valuestr() : "";
- }
+ const char *valuestrsafe() const {
+ return type() == String ? valuestr() : "";
+ }
- const char * codeWScopeCode() const { return value() + 8; }
- const char * codeWScopeScopeData() const {
- // TODO fix
- return codeWScopeCode() + strlen( codeWScopeCode() ) + 1;
- }
-
- BSONObj embeddedObject() const;
+ const char * codeWScopeCode() const {
+ return value() + 8;
+ }
+ const char * codeWScopeScopeData() const {
+ // TODO fix
+ return codeWScopeCode() + strlen( codeWScopeCode() ) + 1;
+ }
+
+ BSONObj embeddedObject() const;
/* uassert if not an object */
- BSONObj embeddedObjectUserCheck();
+ BSONObj embeddedObjectUserCheck();
- const char *regex() const { assert(type() == RegEx); return value(); }
- const char *regexFlags() const {
- const char *p = regex();
- return p + strlen(p) + 1;
- }
+ const char *regex() const {
+ assert(type() == RegEx);
+ return value();
+ }
+ const char *regexFlags() const {
+ const char *p = regex();
+ return p + strlen(p) + 1;
+ }
- /* like operator== but doesn't check the fieldname,
- just the value.
- */
+ /* like operator== but doesn't check the fieldname,
+ just the value.
+ */
bool valuesEqual(const BSONElement& r) const {
- if( isNumber() )
+ if ( isNumber() )
return number() == r.number() && r.isNumber();
- bool match= valuesize() == r.valuesize() &&
- memcmp(value(),r.value(),valuesize()) == 0;
- return match;
- // todo: make "0" == 0.0, undefined==null
- }
+ bool match= valuesize() == r.valuesize() &&
+ memcmp(value(),r.value(),valuesize()) == 0;
+ return match;
+ // todo: make "0" == 0.0, undefined==null
+ }
- bool operator==(const BSONElement& r) const {
- if( strcmp(fieldName(), r.fieldName()) != 0 )
- return false;
- return valuesEqual(r);
-/*
- int sz = size();
- return sz == r.size() &&
- memcmp(data, r.data, sz) == 0;
-*/
- }
+ bool operator==(const BSONElement& r) const {
+ if ( strcmp(fieldName(), r.fieldName()) != 0 )
+ return false;
+ return valuesEqual(r);
+ /*
+ int sz = size();
+ return sz == r.size() &&
+ memcmp(data, r.data, sz) == 0;
+ */
+ }
+
+
+ /* <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() {
+ return data;
+ }
-
- /* <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() { return data; }
+ int getGtLtOp() const;
- int getGtLtOp() const;
-
- BSONElement();
+ BSONElement();
private:
- BSONElement(const char *d) : data(d) {
- fieldNameSize = eoo() ? 0 : strlen(fieldName()) + 1;
- totalSize = -1;
- }
- const char *data;
- int fieldNameSize;
- int totalSize; /* caches the computed size */
+ BSONElement(const char *d) : data(d) {
+ fieldNameSize = eoo() ? 0 : strlen(fieldName()) + 1;
+ totalSize = -1;
+ }
+ const char *data;
+ int fieldNameSize;
+ int totalSize; /* caches the computed size */
};
/* l and r MUST have same type when called: check that first. */
int compareElementValues(const BSONElement& l, const BSONElement& r);
int getGtLtOp(BSONElement& e);
-
+
class BSONObj {
- friend class BSONObjIterator;
- class Details {
- public:
- ~Details() {
- // note refCount means two different things (thus the assert here)
- assert(refCount <= 0);
- if (owned()) {
- free((void *)_objdata);
- }
- _objdata = 0;
- }
- const char *_objdata;
- int _objsize;
- int refCount; // -1 == don't free (we don't "own" the buffer)
- bool owned() { return refCount >= 0; }
- } *details;
- void init(const char *data, bool ifree) {
- details = new Details();
- details->_objdata = data;
- details->_objsize = *((int*) data);
- assert( details->_objsize > 0 );
- assert( details->_objsize <= 1024 * 1024 * 16 );
- details->refCount = ifree ? 1 : -1;
- }
+ friend class BSONObjIterator;
+ class Details {
+ public:
+ ~Details() {
+ // note refCount means two different things (thus the assert here)
+ assert(refCount <= 0);
+ if (owned()) {
+ free((void *)_objdata);
+ }
+ _objdata = 0;
+ }
+ const char *_objdata;
+ int _objsize;
+ int refCount; // -1 == don't free (we don't "own" the buffer)
+ bool owned() {
+ return refCount >= 0;
+ }
+ } *details;
+ void init(const char *data, bool ifree) {
+ details = new Details();
+ details->_objdata = data;
+ details->_objsize = *((int*) data);
+ assert( details->_objsize > 0 );
+ assert( details->_objsize <= 1024 * 1024 * 16 );
+ details->refCount = ifree ? 1 : -1;
+ }
public:
- explicit BSONObj(const char *msgdata, bool ifree = false) {
- init(msgdata, ifree);
- }
- BSONObj(Record *r);
- BSONObj() : details(0) { }
- ~BSONObj() {
- if( details ) {
- if( --details->refCount <= 0 )
- delete details;
- details = 0;
- }
- }
+ explicit BSONObj(const char *msgdata, bool ifree = false) {
+ init(msgdata, ifree);
+ }
+ BSONObj(Record *r);
+ BSONObj() : details(0) { }
+ ~BSONObj() {
+ if ( details ) {
+ if ( --details->refCount <= 0 )
+ delete details;
+ details = 0;
+ }
+ }
- void appendSelfToBufBuilder(BufBuilder& b) {
- assert( objsize() );
- b.append((void *) objdata(), objsize());
- }
+ void appendSelfToBufBuilder(BufBuilder& b) {
+ assert( objsize() );
+ b.append((void *) objdata(), objsize());
+ }
- /* switch the buffer's ownership to us. */
- void iWillFree() {
- assert( !details->owned() );
- details->refCount = 1;
- }
+ /* switch the buffer's ownership to us. */
+ void iWillFree() {
+ assert( !details->owned() );
+ details->refCount = 1;
+ }
- string toString() const;
- /* note: addFields always adds _id even if not specified */
- int addFields(BSONObj& from, set<string>& fields); /* returns n added */
+ string toString() const;
+ /* note: addFields always adds _id even if not specified */
+ int addFields(BSONObj& from, set<string>& fields); /* returns n added */
/* returns # of top level fields in the object
- note: iterates to count the fields
+ note: iterates to count the fields
*/
int nFields();
/* adds the field names to the fields set. does NOT clear it (appends). */
- int getFieldNames(set<string>& fields);
+ int getFieldNames(set<string>& fields);
- /* return has eoo() true if no match
- supports "." notation to reach into embedded objects
- */
- BSONElement getFieldDotted(const char *name) const;
- // Like above, but returns first array encountered while traversing the
- // dotted fields of name. The name variable is updated to represent field
- // names with respect to the returned element.
- BSONElement getFieldDottedOrArray(const char *&name) const;
+ /* return has eoo() true if no match
+ supports "." notation to reach into embedded objects
+ */
+ BSONElement getFieldDotted(const char *name) const;
+ // Like above, but returns first array encountered while traversing the
+ // dotted fields of name. The name variable is updated to represent field
+ // names with respect to the returned element.
+ BSONElement getFieldDottedOrArray(const char *&name) const;
- BSONElement getField(const char *name) const; /* return has eoo() true if no match */
+ BSONElement getField(const char *name) const; /* return has eoo() true if no match */
- // returns "" if DNE or wrong type
- const char * getStringField(const char *name);
+ // returns "" if DNE or wrong type
+ const char * getStringField(const char *name);
- BSONObj getObjectField(const char *name) const;
+ BSONObj getObjectField(const char *name) const;
int getIntField(const char *name); // INT_MIN if not present
- bool getBoolField(const char *name);
+ bool getBoolField(const char *name);
- /* makes a new BSONObj with the fields specified in pattern.
+ /* makes a new BSONObj with the fields specified in pattern.
fields returned in the order they appear in pattern.
- if any field missing, you get back an empty object overall.
- */
- // sets element field names to empty string
- // If an array is encountered while scanning the dotted names in pattern,
- // that array is added to the returned obj, rather than any subobjects
- // referenced within the array. The variable nameWithinArray is set to the
- // name of the requested field within the returned array.
- BSONObj extractFieldsDotted(BSONObj pattern, BSONObjBuilder& b, const char *&nameWithinArray) const; // this version, builder owns the returned obj buffer
- // sets element field names to empty string
+ if any field missing, you get back an empty object overall.
+ */
+ // sets element field names to empty string
+ // If an array is encountered while scanning the dotted names in pattern,
+ // that array is added to the returned obj, rather than any subobjects
+ // referenced within the array. The variable nameWithinArray is set to the
+ // name of the requested field within the returned array.
+ BSONObj extractFieldsDotted(BSONObj pattern, BSONObjBuilder& b, const char *&nameWithinArray) const; // this version, builder owns the returned obj buffer
+ // sets element field names to empty string
BSONObj extractFieldsUnDotted(BSONObj pattern);
- // returns elements with original field names
- BSONObj extractFields(BSONObj &pattern);
+ // returns elements with original field names
+ BSONObj extractFields(BSONObj &pattern);
- const char *objdata() const { return details->_objdata; }
- int objsize() const { return details ? details->_objsize : 0; } // includes the embedded size field
- bool isEmpty() const { return objsize() <= 5; }
+ const char *objdata() const {
+ return details->_objdata;
+ }
+ int objsize() const {
+ return details ? details->_objsize : 0; // includes the embedded size field
+ }
+ bool isEmpty() const {
+ return objsize() <= 5;
+ }
/* sigh...details == 0 is such a pain we have to eliminate that possibility */
void validateEmpty();
- void dump() {
+ void dump() {
cout << hex;
const char *p = objdata();
- for( int i = 0; i < objsize(); i++ ) {
+ for ( int i = 0; i < objsize(); i++ ) {
cout << i << '\t' << (unsigned) *p;
- if( *p >= 'A' && *p <= 'z' )
+ if ( *p >= 'A' && *p <= 'z' )
cout << '\t' << *p;
cout << endl;
p++;
}
}
- bool operator<(const BSONObj& r) const { return woCompare(r) < 0; }
+ bool operator<(const BSONObj& r) const {
+ return woCompare(r) < 0;
+ }
- /* <0: l<r. 0:l==r. >0:l>r
- wo='well ordered'. fields must be in same order in each object.
- */
- int woCompare(const BSONObj& r, bool considerFieldName=true) const;
+ /* <0: l<r. 0:l==r. >0:l>r
+ wo='well ordered'. fields must be in same order in each object.
+ */
+ int woCompare(const BSONObj& r, bool considerFieldName=true) const;
- /* note this is "shallow equality" -- ints and doubles won't match. for a
+ /* note this is "shallow equality" -- ints and doubles won't match. for a
deep equality test use woCompare (which is slower).
*/
- bool woEqual(const BSONObj& r) const {
- int os = objsize();
- if( os == r.objsize() ) {
+ bool woEqual(const BSONObj& r) const {
+ int os = objsize();
+ if ( os == r.objsize() ) {
return (os == 0 || memcmp(objdata(),r.objdata(),os)==0);
}
return false;
- }
- bool operator==(const BSONObj& r) const {
- return this->woEqual(r);
- }
- bool operator!=(const BSONObj& r) const {
- return !operator==( r );
- }
+ }
+ bool operator==(const BSONObj& r) const {
+ return this->woEqual(r);
+ }
+ bool operator!=(const BSONObj& r) const {
+ return !operator==( r );
+ }
- BSONElement firstElement() const {
- return BSONElement(objdata() + 4);
- }
- BSONElement findElement(const char *name);
- BSONElement findElement(string name) { return findElement(name.c_str()); }
- bool hasElement(const char *name);
-
- OID* getOID() {
- BSONElement e = firstElement();
- if( e.type() != jstOID )
- return 0;
- return &e.oid();
- }
+ BSONElement firstElement() const {
+ return BSONElement(objdata() + 4);
+ }
+ BSONElement findElement(const char *name);
+ BSONElement findElement(string name) {
+ return findElement(name.c_str());
+ }
+ bool hasElement(const char *name);
- BSONObj(const BSONObj& r) {
- if( r.details == 0 )
- details = 0;
- else if( r.details->owned() ) {
- details = r.details;
- details->refCount++;
- }
- else {
- details = new Details(*r.details);
- }
- }
- BSONObj& operator=(const BSONObj& r) {
- if( details && details->owned() ) {
- if( --details->refCount == 0 )
- delete details;
- }
-
- if( r.details == 0 )
- details = 0;
- else if( r.details->owned() ) {
- details = r.details;
- details->refCount++;
- }
- else {
- details = new Details(*r.details);
- }
- return *this;
- }
+ OID* getOID() {
+ BSONElement e = firstElement();
+ if ( e.type() != jstOID )
+ return 0;
+ return &e.oid();
+ }
- /* makes a copy of the object. Normally, a jsobj points to data "owned"
- by something else. this is a useful way to get your own copy of the buffer
- data (which is freed when the new jsobj destructs).
- */
- BSONObj copy();
-
- int hash() const {
- unsigned x = 0;
- const char *p = objdata();
- for( int i = 0; i < objsize(); i++ )
- x = x * 131 + p[i];
- return (x & 0x7fffffff) | 0x8000000; // must be > 0
- }
+ BSONObj(const BSONObj& r) {
+ if ( r.details == 0 )
+ details = 0;
+ else if ( r.details->owned() ) {
+ details = r.details;
+ details->refCount++;
+ }
+ else {
+ details = new Details(*r.details);
+ }
+ }
+ BSONObj& operator=(const BSONObj& r) {
+ if ( details && details->owned() ) {
+ if ( --details->refCount == 0 )
+ delete details;
+ }
+
+ if ( r.details == 0 )
+ details = 0;
+ else if ( r.details->owned() ) {
+ details = r.details;
+ details->refCount++;
+ }
+ else {
+ details = new Details(*r.details);
+ }
+ return *this;
+ }
+
+ /* makes a copy of the object. Normally, a jsobj points to data "owned"
+ by something else. this is a useful way to get your own copy of the buffer
+ data (which is freed when the new jsobj destructs).
+ */
+ BSONObj copy();
+
+ int hash() const {
+ unsigned x = 0;
+ const char *p = objdata();
+ for ( int i = 0; i < objsize(); i++ )
+ x = x * 131 + p[i];
+ return (x & 0x7fffffff) | 0x8000000; // must be > 0
+ }
// true unless corrupt
- bool valid() const;
+ bool valid() const;
};
ostream& operator<<( ostream &s, const BSONObj &o );
-
-class BSONObjBuilder {
+
+class BSONObjBuilder {
public:
- BSONObjBuilder(int initsize=512) : b(initsize) { b.skip(4); /*leave room for size field*/ }
+ BSONObjBuilder(int initsize=512) : b(initsize) {
+ b.skip(4); /*leave room for size field*/
+ }
- /* add all the fields from the object specified to this object */
- void appendElements(BSONObj x);
+ /* add all the fields from the object specified to this object */
+ void appendElements(BSONObj x);
- void append(BSONElement& e) {
- assert( !e.eoo() ); // do not append eoo, that would corrupt us. the builder auto appends when done() is called.
- b.append((void*) e.rawdata(), e.size());
- }
+ void append(BSONElement& e) {
+ assert( !e.eoo() ); // do not append eoo, that would corrupt us. the builder auto appends when done() is called.
+ b.append((void*) e.rawdata(), e.size());
+ }
- /* append an element but with a new name */
- void appendAs(const BSONElement& e, const char *as) {
- b.append((char) e.type());
- b.append(as);
- b.append((void *) e.value(), e.valuesize());
- }
+ /* append an element but with a new name */
+ void appendAs(const BSONElement& e, const char *as) {
+ b.append((char) e.type());
+ b.append(as);
+ b.append((void *) e.value(), e.valuesize());
+ }
- /* add a subobject as a member */
- void append(const char *fieldName, BSONObj subObj) {
- b.append((char) Object);
- b.append(fieldName);
- b.append((void *) subObj.objdata(), subObj.objsize());
- }
+ /* add a subobject as a member */
+ void append(const char *fieldName, BSONObj subObj) {
+ b.append((char) Object);
+ b.append(fieldName);
+ b.append((void *) subObj.objdata(), subObj.objsize());
+ }
- void appendBool(const char *fieldName, int val) {
- b.append((char) Bool);
- b.append(fieldName);
- b.append((char) (val?1:0));
- }
- void appendInt(const char *fieldName, int n) {
- b.append((char) NumberInt);
- b.append(fieldName);
- b.append(n);
- }
- void append(const char *fieldName, double n) {
- b.append((char) NumberDouble);
- b.append(fieldName);
- b.append(n);
- }
- void appendOID(const char *fieldName, OID *oid = 0) {
- b.append((char) jstOID);
- b.append(fieldName);
- b.append((long long) (oid ? oid->a : 0));
- b.append((unsigned) (oid ? oid->b : 0));
- }
- void appendDate(const char *fieldName, unsigned long long dt) {
- b.append((char) Date);
- b.append(fieldName);
- b.append(dt);
- }
- void appendRegex(const char *fieldName, const char *regex, const char *options = "") {
- b.append((char) RegEx);
- b.append(fieldName);
- b.append(regex);
- b.append(options);
- }
- void append(const char *fieldName, const char *str) {
- b.append((char) String);
- b.append(fieldName);
- b.append((int) strlen(str)+1);
- b.append(str);
- }
- void append(const char *fieldName, string str) {
- append(fieldName, str.c_str());
- }
- // Append an element that is less than all other keys.
- void appendMinKey( const char *fieldName ) {
- b.append( (char) MinKey );
- b.append( fieldName );
- }
- // Append an element that is greater than all other keys.
- void appendMaxKey( const char *fieldName ) {
- b.append( (char) MaxKey );
- b.append( fieldName );
- }
-
- template < class T >
- void append( const char *fieldName, const vector< T >& vals ) {
- BSONObjBuilder arrBuilder;
- for( unsigned int i = 0; i < vals.size(); ++i )
- arrBuilder.append( numStr( i ).c_str(), vals[ i ] );
- marshalArray( fieldName, arrBuilder.done() );
- }
-
- void appendIntArray( const char *fieldName, const vector< int >& vals ) {
- BSONObjBuilder arrBuilder;
- for( unsigned i = 0; i < vals.size(); ++i )
- arrBuilder.appendInt( numStr( i ).c_str(), vals[ i ] );
- marshalArray( fieldName, arrBuilder.done() );
- }
+ void appendBool(const char *fieldName, int val) {
+ b.append((char) Bool);
+ b.append(fieldName);
+ b.append((char) (val?1:0));
+ }
+ void appendInt(const char *fieldName, int n) {
+ b.append((char) NumberInt);
+ b.append(fieldName);
+ b.append(n);
+ }
+ void append(const char *fieldName, double n) {
+ b.append((char) NumberDouble);
+ b.append(fieldName);
+ b.append(n);
+ }
+ void appendOID(const char *fieldName, OID *oid = 0) {
+ b.append((char) jstOID);
+ b.append(fieldName);
+ b.append((long long) (oid ? oid->a : 0));
+ b.append((unsigned) (oid ? oid->b : 0));
+ }
+ void appendDate(const char *fieldName, unsigned long long dt) {
+ b.append((char) Date);
+ b.append(fieldName);
+ b.append(dt);
+ }
+ void appendRegex(const char *fieldName, const char *regex, const char *options = "") {
+ b.append((char) RegEx);
+ b.append(fieldName);
+ b.append(regex);
+ b.append(options);
+ }
+ void append(const char *fieldName, const char *str) {
+ b.append((char) String);
+ b.append(fieldName);
+ b.append((int) strlen(str)+1);
+ b.append(str);
+ }
+ void append(const char *fieldName, string str) {
+ append(fieldName, str.c_str());
+ }
+ // Append an element that is less than all other keys.
+ void appendMinKey( const char *fieldName ) {
+ b.append( (char) MinKey );
+ b.append( fieldName );
+ }
+ // Append an element that is greater than all other keys.
+ void appendMaxKey( const char *fieldName ) {
+ b.append( (char) MaxKey );
+ b.append( fieldName );
+ }
- /* BSONObj will free the buffer when it is finished. */
- BSONObj doneAndDecouple() {
- int l;
- return BSONObj(decouple(l), true);
- }
+ template < class T >
+ void append( const char *fieldName, const vector< T >& vals ) {
+ BSONObjBuilder arrBuilder;
+ for ( unsigned int i = 0; i < vals.size(); ++i )
+ arrBuilder.append( numStr( i ).c_str(), vals[ i ] );
+ marshalArray( fieldName, arrBuilder.done() );
+ }
- /* this version, jsobjbuilder still frees the jsobj
- when the builder goes out of scope. use it this way
- by default, that's simplest.
- */
- BSONObj done() {
- return BSONObj(_done());
- }
+ void appendIntArray( const char *fieldName, const vector< int >& vals ) {
+ BSONObjBuilder arrBuilder;
+ for ( unsigned i = 0; i < vals.size(); ++i )
+ arrBuilder.appendInt( numStr( i ).c_str(), vals[ i ] );
+ marshalArray( fieldName, arrBuilder.done() );
+ }
+
+ /* BSONObj will free the buffer when it is finished. */
+ BSONObj doneAndDecouple() {
+ int l;
+ return BSONObj(decouple(l), true);
+ }
+
+ /* this version, jsobjbuilder still frees the jsobj
+ when the builder goes out of scope. use it this way
+ by default, that's simplest.
+ */
+ BSONObj done() {
+ return BSONObj(_done());
+ }
- /* assume ownership of the buffer - you must then free it (with free()) */
- char* decouple(int& l) {
- char *x = _done();
+ /* assume ownership of the buffer - you must then free it (with free()) */
+ char* decouple(int& l) {
+ char *x = _done();
assert( x );
- l = b.len();
- b.decouple();
- return x;
- }
- void decouple() { b.decouple(); } // post done() call version. be sure jsobj frees...
+ l = b.len();
+ b.decouple();
+ return x;
+ }
+ void decouple() {
+ b.decouple(); // post done() call version. be sure jsobj frees...
+ }
private:
- // Append the provided arr object as an array.
- void marshalArray( const char *fieldName, const BSONObj &arr ) {
- b.append( (char) Array );
- b.append( fieldName );
- b.append( (void *) arr.objdata(), arr.objsize() );
- }
+ // Append the provided arr object as an array.
+ void marshalArray( const char *fieldName, const BSONObj &arr ) {
+ b.append( (char) Array );
+ b.append( fieldName );
+ b.append( (void *) arr.objdata(), arr.objsize() );
+ }
- string numStr( int i ) const {
- stringstream o;
- o << i;
- return o.str();
- }
-
- char* _done() {
- b.append((char) EOO);
- char *data = b.buf();
- *((int*)data) = b.len();
- return data;
- }
+ string numStr( int i ) const {
+ stringstream o;
+ o << i;
+ return o.str();
+ }
+
+ char* _done() {
+ b.append((char) EOO);
+ char *data = b.buf();
+ *((int*)data) = b.len();
+ return data;
+ }
- BufBuilder b;
+ BufBuilder b;
};
-/* iterator for a BSONObj
+/* iterator for a BSONObj
- Note each BSONObj ends with an EOO element: so you will get more() on an empty
+ Note each BSONObj ends with an EOO element: so you will get more() on an empty
object, although next().eoo() will be true.
*/
class BSONObjIterator {
public:
- BSONObjIterator(const BSONObj& jso) {
+ BSONObjIterator(const BSONObj& jso) {
int sz = jso.objsize();
- if( sz == 0 ) {
- pos = theend = 0; return;
+ if ( sz == 0 ) {
+ pos = theend = 0;
+ return;
}
- pos = jso.objdata() + 4;
- theend = jso.objdata() + sz;
- }
- bool more() { return pos < theend; }
- BSONElement next() {
- BSONElement e(pos);
- pos += e.size();
- return e;
- }
+ pos = jso.objdata() + 4;
+ theend = jso.objdata() + sz;
+ }
+ bool more() {
+ return pos < theend;
+ }
+ BSONElement next() {
+ BSONElement e(pos);
+ pos += e.size();
+ return e;
+ }
private:
- const char *pos;
- const char *theend;
+ const char *pos;
+ const char *theend;
};
-/* iterator a BSONObj which is an array, in array order.
+/* iterator a BSONObj which is an array, in array order.
class JSArrayIter {
public:
BSONObjIterator(const BSONObj& jso) {
...
}
- bool more() { return ... }
+ bool more() { return ... }
BSONElement next() {
...
}
@@ -606,97 +656,102 @@ public:
extern BSONObj maxKey;
extern BSONObj minKey;
-
+
/*- just for testing -- */
#pragma pack(push,1)
struct JSObj1 {
- JSObj1() {
- totsize=sizeof(JSObj1);
- n = NumberDouble; strcpy_s(nname, 5, "abcd"); N = 3.1;
- s = String; strcpy_s(sname, 7, "abcdef"); slen = 10;
- strcpy_s(sval, 10, "123456789"); eoo = EOO;
- }
- unsigned totsize;
+ JSObj1() {
+ totsize=sizeof(JSObj1);
+ n = NumberDouble;
+ strcpy_s(nname, 5, "abcd");
+ N = 3.1;
+ s = String;
+ strcpy_s(sname, 7, "abcdef");
+ slen = 10;
+ strcpy_s(sval, 10, "123456789");
+ eoo = EOO;
+ }
+ unsigned totsize;
- char n;
- char nname[5];
- double N;
+ char n;
+ char nname[5];
+ double N;
- char s;
- char sname[7];
- unsigned slen;
- char sval[10];
+ char s;
+ char sname[7];
+ unsigned slen;
+ char sval[10];
- char eoo;
+ char eoo;
};
#pragma pack(pop)
extern JSObj1 js1;
-inline BSONObj BSONElement::embeddedObjectUserCheck() {
- uassert( "invalid parameter: expected an object", type()==Object || type()==Array );
- return BSONObj(value());
+inline BSONObj BSONElement::embeddedObjectUserCheck() {
+ uassert( "invalid parameter: expected an object", type()==Object || type()==Array );
+ return BSONObj(value());
}
-inline BSONObj BSONElement::embeddedObject() const {
- assert( type()==Object || type()==Array );
- return BSONObj(value());
+inline BSONObj BSONElement::embeddedObject() const {
+ assert( type()==Object || type()==Array );
+ return BSONObj(value());
}
-inline BSONObj BSONObj::copy() {
- if( isEmpty() )
- return *this;
+inline BSONObj BSONObj::copy() {
+ if ( isEmpty() )
+ return *this;
- char *p = (char*) malloc(objsize());
- memcpy(p, objdata(), objsize());
- return BSONObj(p, true);
+ char *p = (char*) malloc(objsize());
+ memcpy(p, objdata(), objsize());
+ return BSONObj(p, true);
}
// wrap this element up as a singleton object.
-inline BSONObj BSONElement::wrap() {
- BSONObjBuilder b;
- b.append(*this);
- return b.doneAndDecouple();
+inline BSONObj BSONElement::wrap() {
+ BSONObjBuilder b;
+ b.append(*this);
+ return b.doneAndDecouple();
}
-inline bool BSONObj::hasElement(const char *name) {
- if( !isEmpty() ) {
- BSONObjIterator it(*this);
- while( it.more() ) {
- BSONElement e = it.next();
- if( strcmp(name, e.fieldName()) == 0 )
- return true;
- }
- }
+inline bool BSONObj::hasElement(const char *name) {
+ if ( !isEmpty() ) {
+ BSONObjIterator it(*this);
+ while ( it.more() ) {
+ BSONElement e = it.next();
+ if ( strcmp(name, e.fieldName()) == 0 )
+ return true;
+ }
+ }
return false;
}
-inline BSONElement BSONObj::findElement(const char *name) {
- if( !isEmpty() ) {
- BSONObjIterator it(*this);
- while( it.more() ) {
- BSONElement e = it.next();
- if( strcmp(name, e.fieldName()) == 0 )
- return e;
- }
- }
- return BSONElement();
+inline BSONElement BSONObj::findElement(const char *name) {
+ if ( !isEmpty() ) {
+ BSONObjIterator it(*this);
+ while ( it.more() ) {
+ BSONElement e = it.next();
+ if ( strcmp(name, e.fieldName()) == 0 )
+ return e;
+ }
+ }
+ return BSONElement();
}
/* add all the fields from the object specified to this object */
-inline void BSONObjBuilder::appendElements(BSONObj x) {
- BSONObjIterator it(x);
- while( it.more() ) {
- BSONElement e = it.next();
- if( e.eoo() ) break;
- append(e);
- }
+inline void BSONObjBuilder::appendElements(BSONObj x) {
+ BSONObjIterator it(x);
+ while ( it.more() ) {
+ BSONElement e = it.next();
+ if ( e.eoo() ) break;
+ append(e);
+ }
}
extern BSONObj emptyObj;
-
-inline void BSONObj::validateEmpty() {
- if( details == 0 )
+
+inline void BSONObj::validateEmpty() {
+ if ( details == 0 )
*this = emptyObj;
}