MongoDB  2.7.0
embedded_builder.h
1 // embedded_builder.h
2 
3 /* Copyright 2009 10gen Inc.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #pragma once
19 
20 namespace mongo {
21 
22  // utility class for assembling hierarchical objects
24  public:
26  _builders.push_back( make_pair( "", b ) );
27  }
28  // It is assumed that the calls to prepareContext will be made with the 'name'
29  // parameter in lex ascending order.
30  void prepareContext( string &name ) {
31  int i = 1, n = _builders.size();
32  while( i < n &&
33  name.substr( 0, _builders[ i ].first.length() ) == _builders[ i ].first &&
34  ( name[ _builders[i].first.length() ] == '.' || name[ _builders[i].first.length() ] == 0 )
35  ) {
36  name = name.substr( _builders[ i ].first.length() + 1 );
37  ++i;
38  }
39  for( int j = n - 1; j >= i; --j ) {
40  popBuilder();
41  }
42  for( string next = splitDot( name ); !next.empty(); next = splitDot( name ) ) {
43  addBuilder( next );
44  }
45  }
46  void appendAs( const BSONElement &e, string name ) {
47  if ( e.type() == Object && e.valuesize() == 5 ) { // empty object -- this way we can add to it later
48  string dummyName = name + ".foo";
49  prepareContext( dummyName );
50  return;
51  }
52  prepareContext( name );
53  back()->appendAs( e, name );
54  }
55  BufBuilder &subarrayStartAs( string name ) {
56  prepareContext( name );
57  return back()->subarrayStart( name );
58  }
59  void done() {
60  while( ! _builderStorage.empty() )
61  popBuilder();
62  }
63 
64  static string splitDot( string & str ) {
65  size_t pos = str.find( '.' );
66  if ( pos == string::npos )
67  return "";
68  string ret = str.substr( 0, pos );
69  str = str.substr( pos + 1 );
70  return ret;
71  }
72 
73  private:
74  void addBuilder( const string &name ) {
75  shared_ptr< BSONObjBuilder > newBuilder( new BSONObjBuilder( back()->subobjStart( name ) ) );
76  _builders.push_back( make_pair( name, newBuilder.get() ) );
77  _builderStorage.push_back( newBuilder );
78  }
79  void popBuilder() {
80  back()->done();
81  _builders.pop_back();
82  _builderStorage.pop_back();
83  }
84 
85  BSONObjBuilder *back() { return _builders.back().second; }
86 
87  vector< pair< string, BSONObjBuilder * > > _builders;
88  vector< shared_ptr< BSONObjBuilder > > _builderStorage;
89 
90  };
91 
92 } //namespace mongo
Utility for creating a BSONObj.
Definition: bsonobjbuilder.h:52
BSONObj done()
Fetch the object we have built.
Definition: bsonobjbuilder.h:587
BSONType type() const
Returns the type of the element.
Definition: bsonelement.h:112
Definition: embedded_builder.h:23
BufBuilder & subarrayStart(const StringData &fieldName)
add header for a new subarray and return bufbuilder for writing to the subarray's body ...
Definition: bsonobjbuilder.h:155
int valuesize() const
size in bytes of the element's value (when applicable).
Definition: bsonelement.h:166
an embedded object
Definition: bsontypes.h:53
BSONObjBuilder & appendAs(const BSONElement &e, const StringData &fieldName)
append an element but with a new name
Definition: bsonobjbuilder.h:92
BSONElement represents an "element" in a BSONObj.
Definition: bsonelement.h:62