MongoDB C++ Driver  legacy-1.1.2
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(std::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(std::string& name) {
31  int i = 1, n = _builders.size();
32  while (
33  i < n && name.substr(0, _builders[i].first.length()) == _builders[i].first &&
34  (name[_builders[i].first.length()] == '.' || name[_builders[i].first.length()] == 0)) {
35  name = name.substr(_builders[i].first.length() + 1);
36  ++i;
37  }
38  for (int j = n - 1; j >= i; --j) {
39  popBuilder();
40  }
41  for (std::string next = splitDot(name); !next.empty(); next = splitDot(name)) {
42  addBuilder(next);
43  }
44  }
45  void appendAs(const BSONElement& e, std::string name) {
46  if (e.type() == Object &&
47  e.valuesize() == 5) { // empty object -- this way we can add to it later
48  std::string dummyName = name + ".foo";
49  prepareContext(dummyName);
50  return;
51  }
52  prepareContext(name);
53  back()->appendAs(e, name);
54  }
55  BufBuilder& subarrayStartAs(std::string name) {
56  prepareContext(name);
57  return back()->subarrayStart(name);
58  }
59  void done() {
60  while (!_builderStorage.empty())
61  popBuilder();
62  }
63 
64  static std::string splitDot(std::string& str) {
65  size_t pos = str.find('.');
66  if (pos == std::string::npos)
67  return "";
68  std::string ret = str.substr(0, pos);
69  str = str.substr(pos + 1);
70  return ret;
71  }
72 
73 private:
74  void addBuilder(const std::string& name) {
75  boost::shared_ptr<BSONObjBuilder> newBuilder(new BSONObjBuilder(back()->subobjStart(name)));
76  _builders.push_back(std::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() {
86  return _builders.back().second;
87  }
88 
89  std::vector<std::pair<std::string, BSONObjBuilder*> > _builders;
90  std::vector<boost::shared_ptr<BSONObjBuilder> > _builderStorage;
91 };
92 
93 } // namespace mongo
Utility functions for parsing numbers from strings.
Definition: compare_numbers.h:20
BufBuilder & subarrayStart(const StringData &fieldName)
add header for a new subarray and return bufbuilder for writing to the subarray's body ...
Definition: bsonobjbuilder.h:200
Utility for creating a BSONObj.
Definition: bsonobjbuilder.h:53
BSONObj done()
Fetch the object we have built.
Definition: bsonobjbuilder.h:631
BSONType type() const
Returns the type of the element.
Definition: bsonelement.h:154
an embedded object
Definition: bsontypes.h:48
int valuesize() const
size in bytes of the element's value (when applicable).
Definition: bsonelement.h:216
BSONObjBuilder & appendAs(const BSONElement &e, const StringData &fieldName)
append an element but with a new name
Definition: bsonobjbuilder.h:132
BSONElement represents an "element" in a BSONObj.
Definition: bsonelement.h:55
Definition: embedded_builder.h:23