From 64c2ab5a0627653551d177fda60c36bcc37d6b8b Mon Sep 17 00:00:00 2001 From: Eliot Horowitz Date: Wed, 21 Apr 2010 15:02:37 -0400 Subject: [PATCH] can iterate over a BSONObjBuilder without commiting --- db/jsobj.h | 35 +++++++++++++++++++++++++---------- dbtests/jsobjtests.cpp | 33 +++++++++++++++++++++++++++++++++ util/builder.h | 4 ---- 3 files changed, 58 insertions(+), 14 deletions(-) diff --git a/db/jsobj.h b/db/jsobj.h index b7a9d999ca6..62c278813b7 100644 --- a/db/jsobj.h +++ b/db/jsobj.h @@ -44,6 +44,7 @@ namespace mongo { class BSONObjBuilder; class BSONArrayBuilder; class BSONObjBuilderValueStream; + class BSONObjIterator; #pragma pack(1) @@ -1627,6 +1628,8 @@ namespace mongo { bool owned() const { return &b == &buf_; } + + BSONObjIterator iterator() const ; private: // Append the provided arr object as an array. @@ -1751,29 +1754,35 @@ namespace mongo { BSONObjIterator(const BSONObj& jso) { int sz = jso.objsize(); if ( sz == 0 ) { - pos = theend = 0; + _pos = _theend = 0; return; } - pos = jso.objdata() + 4; - theend = jso.objdata() + sz; + _pos = jso.objdata() + 4; + _theend = jso.objdata() + sz; } + + BSONObjIterator( const char * start , const char * end ){ + _pos = start + 4; + _theend = end; + } + /** @return true if more elements exist to be enumerated. */ bool moreWithEOO() { - return pos < theend; + return _pos < _theend; } bool more(){ - return pos < theend && pos[0]; + return _pos < _theend && _pos[0]; } /** @return the next element in the object. For the final element, element.eoo() will be true. */ BSONElement next( bool checkEnd = false ) { - assert( pos < theend ); - BSONElement e( pos, checkEnd ? (int)(theend - pos) : -1 ); - pos += e.size( checkEnd ? (int)(theend - pos) : -1 ); + assert( _pos < _theend ); + BSONElement e( _pos, checkEnd ? (int)(_theend - _pos) : -1 ); + _pos += e.size( checkEnd ? (int)(_theend - _pos) : -1 ); 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. @@ -1988,6 +1997,12 @@ namespace mongo { dotted2nested(b, obj); return b.obj(); } + + inline BSONObjIterator BSONObjBuilder::iterator() const { + const char * s = b.buf() + offset_; + const char * e = b.buf() + b.len(); + return BSONObjIterator( s , e ); + } /* WARNING: nested/dotted conversions are not 100% reversible * nested2dotted(dotted2nested({a.b: {c:1}})) -> {a.b.c: 1} diff --git a/dbtests/jsobjtests.cpp b/dbtests/jsobjtests.cpp index 6f038941807..8f9991b435f 100644 --- a/dbtests/jsobjtests.cpp +++ b/dbtests/jsobjtests.cpp @@ -1480,6 +1480,38 @@ namespace JsobjTests { } }; + class BuilderPartialItearte { + public: + void run(){ + { + BSONObjBuilder b; + b.append( "x" , 1 ); + b.append( "y" , 2 ); + + BSONObjIterator i = b.iterator(); + ASSERT( i.more() ); + ASSERT_EQUALS( 1 , i.next().numberInt() ); + ASSERT( i.more() ); + ASSERT_EQUALS( 2 , i.next().numberInt() ); + ASSERT( ! i.more() ); + + b.append( "z" , 3 ); + + i = b.iterator(); + ASSERT( i.more() ); + ASSERT_EQUALS( 1 , i.next().numberInt() ); + ASSERT( i.more() ); + ASSERT_EQUALS( 2 , i.next().numberInt() ); + ASSERT( i.more() ); + ASSERT_EQUALS( 3 , i.next().numberInt() ); + ASSERT( ! i.more() ); + + ASSERT_EQUALS( BSON( "x" << 1 << "y" << 2 << "z" << 3 ) , b.obj() ); + } + + } + }; + class All : public Suite { public: All() : Suite( "jsobj" ){ @@ -1574,6 +1606,7 @@ namespace JsobjTests { add< InvalidIDFind >(); add< ElementSetTest >(); add< EmbeddedNumbers >(); + add< BuilderPartialItearte >(); } } myall; diff --git a/util/builder.h b/util/builder.h index f9d351414f1..a0ba6acfe32 100644 --- a/util/builder.h +++ b/util/builder.h @@ -102,10 +102,6 @@ namespace mongo { append( (void *)str.c_str(), str.length() + 1 ); } - void append( int val , int padding ){ - - } - int len() const { return l; }