MongoDB C++ Driver legacy-1.1.2
Loading...
Searching...
No Matches
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
20namespace mongo {
21
22// utility class for assembling hierarchical objects
24public:
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
73private:
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
BSONElement represents an "element" in a BSONObj.
Definition bsonelement.h:55
int valuesize() const
size in bytes of the element's value (when applicable).
Definition bsonelement.h:216
BSONType type() const
Returns the type of the element.
Definition bsonelement.h:154
Utility for creating a BSONObj.
Definition bsonobjbuilder.h:53
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
BSONObjBuilder & appendAs(const BSONElement &e, const StringData &fieldName)
append an element but with a new name
Definition bsonobjbuilder.h:132
BSONObj done()
Fetch the object we have built.
Definition bsonobjbuilder.h:631
Definition embedded_builder.h:23
Utility functions for parsing numbers from strings.
Definition compare_numbers.h:20
@ Object
an embedded object
Definition bsontypes.h:48