// // Document.cpp // // $Id$ // // Library: MongoDB // Package: MongoDB // Module: Document // // Implementation of the Document class. // // Copyright (c) 2012, Applied Informatics Software Engineering GmbH. // and Contributors. // // Permission is hereby granted, free of charge, to any person or organization // obtaining a copy of the software and accompanying documentation covered by // this license (the "Software") to use, reproduce, display, distribute, // execute, and transmit the Software, and to prepare derivative works of the // Software, and to permit third-parties to whom the Software is furnished to // do so, all subject to the following: // // The copyright notices in the Software and this entire statement, including // the above license grant, this restriction and the following disclaimer, // must be included in all copies of the Software, in whole or in part, and // all derivative works of the Software, unless such copies or derivative // works are solely in the form of machine-executable object code generated by // a source language processor. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. // #include #include "Poco/MongoDB/Document.h" #include "Poco/MongoDB/Binary.h" #include "Poco/MongoDB/ObjectId.h" #include "Poco/MongoDB/Array.h" #include "Poco/MongoDB/RegularExpression.h" #include "Poco/MongoDB/JavaScriptCode.h" namespace Poco { namespace MongoDB { Document::Document() { } Document::~Document() { } Element::Ptr Document::get(const std::string& name) const { Element::Ptr element; ElementSet::const_iterator it = std::find_if(_elements.begin(), _elements.end(), ElementFindByName(name)); if ( it != _elements.end() ) { return *it; } return element; } void Document::read(BinaryReader& reader) { int size; reader >> size; unsigned char type; reader >> type; while( type != '\0' ) { Element::Ptr element; std::string name = BSONReader(reader).readCString(); switch(type) { case ElementTraits::TypeId: element = new ConcreteElement(name, 0); break; case ElementTraits::TypeId: element = new ConcreteElement(name, 0); break; case ElementTraits::TypeId: element = new ConcreteElement(name, ""); break; case ElementTraits::TypeId: element = new ConcreteElement(name, new Document()); break; case ElementTraits::TypeId: element = new ConcreteElement(name, new Array()); break; case ElementTraits::TypeId: element = new ConcreteElement(name, new Binary()); break; case ElementTraits::TypeId: element = new ConcreteElement(name, new ObjectId()); break; case ElementTraits::TypeId: element = new ConcreteElement(name, false); break; case ElementTraits::TypeId: element = new ConcreteElement(name, Poco::Timestamp()); break; case ElementTraits::TypeId: element = new ConcreteElement(name, NullValue(0)); break; case ElementTraits::TypeId: element = new ConcreteElement(name, new RegularExpression()); break; case ElementTraits::TypeId: element = new ConcreteElement(name, new JavaScriptCode()); break; case ElementTraits::TypeId: element = new ConcreteElement(name, 0); break; default: { std::stringstream ss; ss << "Element " << name << " contains an unsupported type " << std::hex << (int) type; throw Poco::NotImplementedException(ss.str()); } //TODO: x0F -> JavaScript code with scope // xFF -> Min Key // x7F -> Max Key } element->read(reader); _elements.insert(element); reader >> type; } } std::string Document::toString(int indent) const { std::ostringstream oss; oss << "{" << std::endl; for(ElementSet::const_iterator it = _elements.begin(); it != _elements.end(); ++it) { if ( it != _elements.begin() ) { oss << ","; if ( indent > 0 ) { oss << std::endl; } } if ( indent > 0 ) { for(int i = 0; i < indent; ++i) { oss << ' '; } } oss << '"' << (*it)->name() << '"' << " : "; if ( indent > 0 ) { oss << (*it)->toString(indent + 2); } else { oss << (*it)->toString(); } } if ( indent > 0 ) { oss << std::endl; indent -= 2; for(int i = 0; i < indent; ++i) { oss << ' '; } } oss << "}" << std::endl; return oss.str(); } void Document::write(BinaryWriter& writer) { if ( _elements.empty() ) { writer << 5; } else { std::stringstream sstream; Poco::BinaryWriter tempWriter(sstream); for(ElementSet::iterator it = _elements.begin(); it != _elements.end(); ++it) { tempWriter << (unsigned char) (*it)->type(); BSONWriter(tempWriter).writeCString((*it)->name()); Element::Ptr element = *it; element->write(tempWriter); } tempWriter.flush(); Poco::Int32 len = 5 + sstream.tellp(); /* 5 = sizeof(len) + 0-byte */ writer << len; writer.writeRaw(sstream.str()); } writer << '\0'; } }} // Namespace Poco::MongoDB