// // Document.cpp // // $Id$ // // Library: MongoDB // Package: MongoDB // Module: Document // // Implementation of the Document class. // // Copyright (c) 2012, Applied Informatics Software Engineering GmbH. // and Contributors. // // SPDX-License-Identifier: BSL-1.0 // #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" #include 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.push_back(element); reader >> type; } } std::string Document::toString(int indent) const { std::ostringstream oss; oss << '{'; if ( indent > 0 ) 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; } for(int i = 0; i < indent; ++i) oss << ' '; oss << '"' << (*it)->name() << '"'; oss << (( indent > 0 ) ? " : " : ":"); oss << (*it)->toString(indent > 0 ? indent + 2 : 0); } if ( indent > 0 ) { oss << std::endl; if ( indent >= 2 ) indent -= 2; for(int i = 0; i < indent; ++i) oss << ' '; } oss << '}'; 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 << static_cast((*it)->type()); BSONWriter(tempWriter).writeCString((*it)->name()); Element::Ptr element = *it; element->write(tempWriter); } tempWriter.flush(); Poco::Int32 len = static_cast(5 + sstream.tellp()); /* 5 = sizeof(len) + 0-byte */ writer << len; writer.writeRaw(sstream.str()); } writer << '\0'; } } } // namespace Poco::MongoDB