diff options
Diffstat (limited to 'src/mongo/util/embedded_builder.h')
-rw-r--r-- | src/mongo/util/embedded_builder.h | 125 |
1 files changed, 63 insertions, 62 deletions
diff --git a/src/mongo/util/embedded_builder.h b/src/mongo/util/embedded_builder.h index 3ef84f427e0..29c42e5144b 100644 --- a/src/mongo/util/embedded_builder.h +++ b/src/mongo/util/embedded_builder.h @@ -32,74 +32,75 @@ namespace mongo { - // utility class for assembling hierarchical objects - class EmbeddedBuilder { - public: - EmbeddedBuilder( BSONObjBuilder *b ) { - _builders.push_back( std::make_pair( "", b ) ); +// utility class for assembling hierarchical objects +class EmbeddedBuilder { +public: + EmbeddedBuilder(BSONObjBuilder* b) { + _builders.push_back(std::make_pair("", b)); + } + // It is assumed that the calls to prepareContext will be made with the 'name' + // parameter in lex ascending order. + void prepareContext(std::string& name) { + int i = 1, n = _builders.size(); + while ( + i < n && name.substr(0, _builders[i].first.length()) == _builders[i].first && + (name[_builders[i].first.length()] == '.' || name[_builders[i].first.length()] == 0)) { + name = name.substr(_builders[i].first.length() + 1); + ++i; } - // It is assumed that the calls to prepareContext will be made with the 'name' - // parameter in lex ascending order. - void prepareContext( std::string &name ) { - int i = 1, n = _builders.size(); - while( i < n && - name.substr( 0, _builders[ i ].first.length() ) == _builders[ i ].first && - ( name[ _builders[i].first.length() ] == '.' || name[ _builders[i].first.length() ] == 0 ) - ) { - name = name.substr( _builders[ i ].first.length() + 1 ); - ++i; - } - for( int j = n - 1; j >= i; --j ) { - popBuilder(); - } - for( std::string next = splitDot( name ); !next.empty(); next = splitDot( name ) ) { - addBuilder( next ); - } + for (int j = n - 1; j >= i; --j) { + popBuilder(); } - void appendAs( const BSONElement &e, std::string name ) { - if ( e.type() == Object && e.valuesize() == 5 ) { // empty object -- this way we can add to it later - std::string dummyName = name + ".foo"; - prepareContext( dummyName ); - return; - } - prepareContext( name ); - back()->appendAs( e, name ); + for (std::string next = splitDot(name); !next.empty(); next = splitDot(name)) { + addBuilder(next); } - BufBuilder &subarrayStartAs( std::string name ) { - prepareContext( name ); - return back()->subarrayStart( name ); - } - void done() { - while( ! _builderStorage.empty() ) - popBuilder(); - } - - static std::string splitDot( std::string & str ) { - size_t pos = str.find( '.' ); - if ( pos == std::string::npos ) - return ""; - std::string ret = str.substr( 0, pos ); - str = str.substr( pos + 1 ); - return ret; + } + void appendAs(const BSONElement& e, std::string name) { + if (e.type() == Object && + e.valuesize() == 5) { // empty object -- this way we can add to it later + std::string dummyName = name + ".foo"; + prepareContext(dummyName); + return; } + prepareContext(name); + back()->appendAs(e, name); + } + BufBuilder& subarrayStartAs(std::string name) { + prepareContext(name); + return back()->subarrayStart(name); + } + void done() { + while (!_builderStorage.empty()) + popBuilder(); + } - private: - void addBuilder( const std::string &name ) { - std::shared_ptr< BSONObjBuilder > newBuilder( new BSONObjBuilder( back()->subobjStart( name ) ) ); - _builders.push_back( std::make_pair( name, newBuilder.get() ) ); - _builderStorage.push_back( newBuilder ); - } - void popBuilder() { - back()->done(); - _builders.pop_back(); - _builderStorage.pop_back(); - } + static std::string splitDot(std::string& str) { + size_t pos = str.find('.'); + if (pos == std::string::npos) + return ""; + std::string ret = str.substr(0, pos); + str = str.substr(pos + 1); + return ret; + } - BSONObjBuilder *back() { return _builders.back().second; } +private: + void addBuilder(const std::string& name) { + std::shared_ptr<BSONObjBuilder> newBuilder(new BSONObjBuilder(back()->subobjStart(name))); + _builders.push_back(std::make_pair(name, newBuilder.get())); + _builderStorage.push_back(newBuilder); + } + void popBuilder() { + back()->done(); + _builders.pop_back(); + _builderStorage.pop_back(); + } - std::vector< std::pair< std::string, BSONObjBuilder * > > _builders; - std::vector< std::shared_ptr< BSONObjBuilder > > _builderStorage; + BSONObjBuilder* back() { + return _builders.back().second; + } - }; + std::vector<std::pair<std::string, BSONObjBuilder*>> _builders; + std::vector<std::shared_ptr<BSONObjBuilder>> _builderStorage; +}; -} //namespace mongo +} // namespace mongo |