MongoType
MongoDB Collection Data Dump with BSON Types
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
BSONObjectParser.hpp
Go to the documentation of this file.
1 
29 //----------------------------------------------------------------------------
30 
31 #ifndef BSONOBJECTPARSER_HPP_
32 #define BSONOBJECTPARSER_HPP_
33 
34 //----------------------------------------------------------------------------
35 
36 #include <mongotype.hpp>
37 
38 //----------------------------------------------------------------------------
39 
40 namespace mongotype {
41 
42 //----------------------------------------------------------------------------
43 
52 public:
56  enum ItemType {
60  };
61 
62 private:
67 
73  union Item {
77  const BSONObj* object;
82  Item(const BSONObj* pobject) : object(pobject) {}
86  const BSONElement* element;
91  Item(const BSONElement* pelement) : element(pelement) {}
92  } item;
93 
97  const string& key;
98 
103 
108 
115 
122 
123 private:
129  void validate(ItemType t) const {
130  if (t != type) {
131  throw std::logic_error( string("Illegal Stack Item Type Access: ") + (t == OBJECT ? string("OBJECT") : string("ELEMENT")) );
132  }
133  }
134 
135 public:
145  BSONParserStackItem(const BSONObj* object, const string& pkey, int pelementIndex, int pelementCount, int parrayIndex, int parrayCount)
146  : type(OBJECT), item(object), key(pkey), elementIndex(pelementIndex), elementCount(pelementCount), arrayIndex(parrayIndex), arrayCount(parrayCount) {}
159  BSONParserStackItem(ItemType ptype, const BSONElement* element, const string& pkey, int pelementIndex, int pelementCount, int parrayIndex, int parrayCount)
160  : type(ptype), item(element), key(pkey), elementIndex(pelementIndex), elementCount(pelementCount), arrayIndex(parrayIndex), arrayCount(parrayCount) {}
161 
162  ItemType getType() const {
163  return type;
164  }
165 
166  const BSONObj& getObject() const {
167  validate(OBJECT);
168  return *item.object;
169  }
170 
171  const BSONElement& getElement() const {
172  validate(ELEMENT);
173  return *item.element;
174  }
175 
176  const BSONElement& getArray() const {
177  validate(ARRAY);
178  return *item.element;
179  }
180 
181  const string& getKey() const {
182  return key;
183  }
184 
185  int getElementIndex() const {
186  return elementIndex;
187  }
188 
189  int getElementCount() const {
190  return elementCount;
191  }
192 
193  int getArrayIndex() const {
194  return arrayIndex;
195  }
196 
197  int getArrayCount() const {
198  return arrayCount;
199  }
200 
201  string toString() const {
202  string s("{");
203  switch (type) {
204  case OBJECT:
205  s += "OBJECT";
206  break;
207  case ARRAY:
208  s += "ARRAY";
209  break;
210  case ELEMENT:
211  s += "ELEMENT";
212  break;
213  default:
214  throw std::logic_error(string("toString Undefined ItemType!"));
215  }
216  s += ",\"" + key + "\"",
217  s += "," + to_string(elementIndex);
218  s += "," + to_string(elementCount);
219  s += "," + to_string(arrayIndex);
220  s += "," + to_string(arrayCount);
221  s += "}";
222  return s;
223  }
224 };
225 
226 //----------------------------------------------------------------------------
227 
238  typedef std::deque<std::unique_ptr<const BSONParserStackItem>> Stack;
239 
241 
242 public:
243  int depth() const { return stack.size(); }
244 
245 private:
246  void throwCount(int count) const {
247  if (depth() < count) {
248  throw std::logic_error( string("ISE: Insufficient BSONParserStack Stack Entries:(" + to_string(count)) + "," + to_string(depth()) + ")" );
249  }
250  }
251 
252 protected:
253 
261  throwCount(1);
262  const BSONParserStackItem* rv = stack.back().release();
263  stack.pop_back();
264  return rv;
265  }
266 
273  stack.push_back(unique_ptr<const BSONParserStackItem>(item));
274  }
275 
276 public:
287  const BSONParserStackItem& item(int index) const {
288  if (index >= 0) {
289  throwCount(index+1);
290  return *(stack[index].get());
291  } else {
292  int i = depth() + index;
293  return item(i);
294  }
295  }
296 
303  const BSONParserStackItem& top() const { // Item ownership unaffected.
304  return item(depth()-1);
305  }
306 
317  void push(const BSONObj& object, const string& key = string(), int elementIndex=0, int elementCount=1, int arrayIndex=-1, int arrayCount=0) {
318  push(new BSONParserStackItem(&object, key, elementIndex, elementCount, arrayIndex, arrayCount));
319  }
320 
332  void push(BSONParserStackItem::ItemType type, const BSONElement& element, const string& key = string(), int elementIndex=0, int elementCount=1, int arrayIndex=-1, int arrayCount=0) {
333  push(new BSONParserStackItem(type, &element, key, elementIndex, elementCount, arrayIndex, arrayCount));
334  }
335 
340  void drop() {
341  delete pop();
342  }
343 
344  string toString() const {
345  string s("<<");
346  for (int i=0; i < depth(); i++) {
347  if (i > 0) s += ",";
348  s += item(i).toString();
349  }
350  s += ">>";
351  return s;
352  }
353 };
354 
355 //----------------------------------------------------------------------------
356 
371 public:
372  virtual ~IBSONObjectVisitor() {}
373 
380  virtual void onParseStart() = 0;
387  virtual void onParseEnd() = 0;
388 
396  virtual void onObjectStart(const BSONParserStack& stack) = 0;
404  virtual void onObjectEnd(const BSONParserStack& stack) = 0;
405 
413  virtual void onArrayStart(const BSONParserStack& stack) = 0;
421  virtual void onArrayEnd(const BSONParserStack& stack) = 0;
422 
430  virtual void onElement(const BSONParserStack& stack) = 0;
431 };
432 
433 //----------------------------------------------------------------------------
434 
448 
449 protected:
455 
456  //----------------------------------------------------------------------------
457 
472  virtual void parseElementRecursive(const BSONElement& element, string& key, int elementIndex=0, int elementCount=1, int arrayIndex = -1, int arrayCount = 0) {
473  BSONType btype = element.type();
474  switch (btype) {
475  case BSONType::Object:
476  {
477  const BSONObj& bobj = element.Obj();
478  string k(element.fieldName());
479  parseObjectRecursive(bobj, k, elementIndex, elementCount, arrayIndex, arrayCount);
480  }
481  break;
482  case BSONType::Array:
483  {
484  stack.push(BSONParserStackItem::ItemType::ARRAY, element, key, elementIndex, elementCount, arrayIndex, arrayCount);
485  std::vector<BSONElement> elementArray = element.Array();
486  int elementArrayCount = elementArray.size();
488  int elementArrayIndex = 0;
489  for (BSONElement e : elementArray) {
490  string k(e.fieldName());
491  parseElementRecursive(e, k, elementIndex, elementCount, elementArrayIndex++, elementArrayCount);
492  }
494  stack.drop();
495  }
496  break;
497  default:
498  {
499  stack.push(BSONParserStackItem::ItemType::ELEMENT, element, key, elementIndex, elementCount, arrayIndex, arrayCount);
501  stack.drop();
502  }
503  break;
504  }
505  }
506 
507  //----------------------------------------------------------------------------
508 
523  virtual void parseObjectRecursive(const BSONObj& object, string& key, int elementIndex=0, int elementCount=1, int arrayIndex = -1, int arrayCount = 0) {
524  stack.push(object, key, elementIndex, elementCount, arrayIndex, arrayCount);
526  set<string> keys;
527  object.getFieldNames(keys); // Get the key names of the BSON object.
528  int ei = 0;
529  int ec = keys.size();
530  for (string key : keys) {
531  BSONElement e = object.getField(key);
532  parseElementRecursive(e, key, ei++, ec, arrayIndex);
533  }
535  stack.drop();
536  }
537 
538 public:
539  //----------------------------------------------------------------------------
540 
548  BSONObjectParser(IBSONObjectVisitor& pvisitor) : visitor(pvisitor) {}
549  virtual ~BSONObjectParser() {}
550 
551  //----------------------------------------------------------------------------
552 
560  virtual void parse(const BSONObj& object) {
562  string emptyString("");
563  parseObjectRecursive(object, emptyString);
565  }
566 
567  //----------------------------------------------------------------------------
568 };
569 
570 //----------------------------------------------------------------------------
571 
572 } /* namespace mongotype */
573 
574 //----------------------------------------------------------------------------
575 
576 #endif /* BSONOBJECTPARSER_HPP_ */