Document.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. //
  2. // Document.cpp
  3. //
  4. // $Id$
  5. //
  6. // Library: MongoDB
  7. // Package: MongoDB
  8. // Module: Document
  9. //
  10. // Implementation of the Document class.
  11. //
  12. // Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
  13. // and Contributors.
  14. //
  15. // Permission is hereby granted, free of charge, to any person or organization
  16. // obtaining a copy of the software and accompanying documentation covered by
  17. // this license (the "Software") to use, reproduce, display, distribute,
  18. // execute, and transmit the Software, and to prepare derivative works of the
  19. // Software, and to permit third-parties to whom the Software is furnished to
  20. // do so, all subject to the following:
  21. //
  22. // The copyright notices in the Software and this entire statement, including
  23. // the above license grant, this restriction and the following disclaimer,
  24. // must be included in all copies of the Software, in whole or in part, and
  25. // all derivative works of the Software, unless such copies or derivative
  26. // works are solely in the form of machine-executable object code generated by
  27. // a source language processor.
  28. //
  29. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  30. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  31. // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
  32. // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
  33. // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
  34. // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  35. // DEALINGS IN THE SOFTWARE.
  36. //
  37. #include <sstream>
  38. #include "Poco/MongoDB/Document.h"
  39. #include "Poco/MongoDB/Binary.h"
  40. #include "Poco/MongoDB/ObjectId.h"
  41. #include "Poco/MongoDB/Array.h"
  42. namespace Poco
  43. {
  44. namespace MongoDB
  45. {
  46. Document::Document()
  47. {
  48. }
  49. Document::~Document()
  50. {
  51. }
  52. void Document::read(BinaryReader& reader)
  53. {
  54. int size;
  55. reader >> size;
  56. unsigned char type;
  57. reader >> type;
  58. while( type != '\0' )
  59. {
  60. Element::Ptr element;
  61. std::string name = BSONReader(reader).readCString();
  62. switch(type)
  63. {
  64. case ElementTraits<double>::TypeId:
  65. element = new ConcreteElement<double>(name, 0);
  66. break;
  67. case ElementTraits<Int32>::TypeId:
  68. element = new ConcreteElement<Int32>(name, 0);
  69. break;
  70. case ElementTraits<std::string>::TypeId:
  71. element = new ConcreteElement<std::string>(name, "");
  72. break;
  73. case ElementTraits<Document::Ptr>::TypeId:
  74. element = new ConcreteElement<Document::Ptr>(name, new Document());
  75. break;
  76. case ElementTraits<Array::Ptr>::TypeId:
  77. element = new ConcreteElement<Array::Ptr>(name, new Array());
  78. break;
  79. case ElementTraits<Binary::Ptr>::TypeId:
  80. element = new ConcreteElement<Binary::Ptr>(name, new Binary());
  81. break;
  82. case ElementTraits<ObjectId::Ptr>::TypeId:
  83. element = new ConcreteElement<ObjectId::Ptr>(name, new ObjectId());
  84. break;
  85. case ElementTraits<bool>::TypeId:
  86. element = new ConcreteElement<bool>(name, false);
  87. break;
  88. case ElementTraits<Poco::Timestamp>::TypeId:
  89. element = new ConcreteElement<Poco::Timestamp>(name, Poco::Timestamp());
  90. break;
  91. case ElementTraits<NullValue>::TypeId:
  92. element = new ConcreteElement<NullValue>(name, NullValue(0));
  93. break;
  94. case ElementTraits<RegularExpression::Ptr>::TypeId:
  95. element = new ConcreteElement<RegularExpression::Ptr>(name, new RegularExpression());
  96. break;
  97. case ElementTraits<JavaScriptCode::Ptr>::TypeId:
  98. element = new ConcreteElement<JavaScriptCode::Ptr>(name, new JavaScriptCode());
  99. break;
  100. case ElementTraits<Int64>::TypeId:
  101. element = new ConcreteElement<Int64>(name, 0);
  102. break;
  103. default:
  104. {
  105. std::stringstream ss;
  106. ss << "Element " << name << " contains an unsupported type " << std::hex << (int) type;
  107. throw Poco::NotImplementedException(ss.str());
  108. }
  109. //TODO: x0F -> JavaScript code with scope
  110. // xFF -> Min Key
  111. // x7F -> Max Key
  112. }
  113. element->read(reader);
  114. _elements.insert(element);
  115. reader >> type;
  116. }
  117. }
  118. std::string Document::toString() const
  119. {
  120. std::ostringstream oss;
  121. for(ElementSet::iterator it = _elements.begin(); it != _elements.end(); ++it)
  122. {
  123. oss << (*it)->name() << " ";
  124. }
  125. return oss.str();
  126. }
  127. void Document::write(BinaryWriter& writer)
  128. {
  129. if ( _elements.empty() )
  130. {
  131. writer << 5;
  132. }
  133. else
  134. {
  135. std::stringstream sstream;
  136. Poco::BinaryWriter tempWriter(sstream);
  137. for(ElementSet::iterator it = _elements.begin(); it != _elements.end(); ++it)
  138. {
  139. tempWriter << (unsigned char) (*it)->type();
  140. BSONWriter(tempWriter).writeCString((*it)->name());
  141. Element::Ptr element = *it;
  142. element->write(tempWriter);
  143. }
  144. tempWriter.flush();
  145. Poco::Int32 len = 5 + sstream.tellp(); /* 5 = sizeof(len) + 0-byte */
  146. writer << len;
  147. writer.writeRaw(sstream.str());
  148. }
  149. writer << '\0';
  150. }
  151. void Document::addElement(Element::Ptr element)
  152. {
  153. _elements.insert(element);
  154. }
  155. }} // Namespace Poco::MongoDB