diff options
Diffstat (limited to 'cpp/src/IceXML/StreamI.cpp')
-rw-r--r-- | cpp/src/IceXML/StreamI.cpp | 1468 |
1 files changed, 0 insertions, 1468 deletions
diff --git a/cpp/src/IceXML/StreamI.cpp b/cpp/src/IceXML/StreamI.cpp deleted file mode 100644 index 163ef795b4e..00000000000 --- a/cpp/src/IceXML/StreamI.cpp +++ /dev/null @@ -1,1468 +0,0 @@ -// ********************************************************************** -// -// Copyright (c) 2003 -// ZeroC, Inc. -// Billerica, MA, USA -// -// All Rights Reserved. -// -// Ice is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License version 2 as published by -// the Free Software Foundation. -// -// ********************************************************************** - -#include <Ice/Object.h> -#include <Ice/Communicator.h> -#include <Ice/Logger.h> -#include <Ice/LocalException.h> -#include <Ice/ObjectFactory.h> -#include <IceUtil/InputUtil.h> -#include <IceUtil/Unicode.h> - -#include <IceXML/StreamI.h> - -#include <list> - -// -// For input streaming -// -#include <Ice/Xerces.h> -#include <xercesc/framework/MemBufInputSource.hpp> -#include <xercesc/util/PlatformUtils.hpp> -#include <xercesc/util/XMLString.hpp> -#include <xercesc/dom/DOMException.hpp> -#include <xercesc/parsers/XercesDOMParser.hpp> -#include <xercesc/dom/DOMNode.hpp> -#include <xercesc/dom/DOMNamedNodeMap.hpp> -#include <xercesc/sax/ErrorHandler.hpp> -#include <xercesc/sax/SAXParseException.hpp> - -using namespace std; -using namespace IceXML; -using namespace IceUtil; - -// -// Utility to make the usage of xerces easier. -// -static string -toString(const XMLCh* s) -{ - // - // Some DOM Level 2 operations can return 0. - // - if(s) - { - char* t = ICE_XERCES_NS XMLString::transcode(s); - string r(t); - delete[] t; - return r; - } - else - { - return string(); - } -} - -// -// Error handling class for xerces. -// -class DOMTreeErrorReporter : public ICE_XERCES_NS ErrorHandler -{ -public: - - DOMTreeErrorReporter(const ::Ice::LoggerPtr logger) : - _logger(logger), - _sawErrors(false) - { - } - - virtual void - warning(const ICE_XERCES_NS SAXParseException& ex) - { - ostringstream os; - os << "xerces: file: \"" << toString(ex.getSystemId()) - << "\", line: " << ex.getLineNumber() - << ", column: " << ex.getColumnNumber() - << "\nmessage: " << toString(ex.getMessage()) << endl; - _logger->warning(os.str()); - } - - virtual void - error(const ICE_XERCES_NS SAXParseException& ex) - { - _sawErrors = true; - ostringstream os; - os << "xerces: file: \"" << toString(ex.getSystemId()) - << "\", line: " << ex.getLineNumber() - << ", column: " << ex.getColumnNumber() - << "\nmessage: " << toString(ex.getMessage()) << endl; - _logger->error(os.str()); - } - - virtual void - fatalError(const ICE_XERCES_NS SAXParseException& ex) - { - _sawErrors = true; - ostringstream os; - os << "xerces: file: \"" << toString(ex.getSystemId()) - << "\", line: " << ex.getLineNumber() - << ", column: " << ex.getColumnNumber() - << "\nmessage: " << toString(ex.getMessage()) << endl; - _logger->error(os.str()); - } - - virtual void - resetErrors() - { - } - - bool - getSawErrors() const - { - return _sawErrors; - } - -private: - - ::Ice::LoggerPtr _logger; - bool _sawErrors; -}; - -namespace IceXML -{ - -class XercesInitializer -{ -public: - - XercesInitializer() - { - try - { - ICE_XERCES_NS XMLPlatformUtils::Initialize(); - } - catch(const ICE_XERCES_NS XMLException& ex) - { - cerr << "IceXML: xerces initialize failed: " << toString(ex.getMessage()) << endl; - } - } - - ~XercesInitializer() - { - ICE_XERCES_NS XMLPlatformUtils::Terminate(); - } -}; - -static XercesInitializer _xercesInitializer; - -// -// This is used to reduce the external dependencies on the xerces -// headers. -// -struct StreamInputImpl -{ - StreamInputImpl() : - document(0) - { - } - - ~StreamInputImpl() - { - if(document) - { - document->release(); - } - } - - ICE_XERCES_NS DOMDocument* document; - - ICE_XERCES_NS DOMNode* current; - - list<ICE_XERCES_NS DOMNode*> nodeStack; - - map<string, ::Ice::ObjectPtr> readObjects; -}; - -} // End namespace IceXML - -// -// A constant string which is used as the name of collection elements. -// -const string IceXML::StreamI::seqElementName("e"); - -IceXML::StreamI::StreamI(const ::Ice::CommunicatorPtr& communicator, std::ostream& os) : - _communicator(communicator), - _input(0), - _os(os), - _level(0), - _nextId(0), - _dump(false), - _marshalFacets(true) -{ -} - -IceXML::StreamI::StreamI(const ::Ice::CommunicatorPtr& communicator, std::istream& is, bool schema) : - _communicator(communicator), - _input(0), - _nextId(0), - _dump(false), - _marshalFacets(true) -{ - // - // Read the contents of the stream into memory. - // - while(!is.eof()) - { - char buf[1000]; - is.read(buf, sizeof(buf)); - _content.append(buf, is.gcount()); - } - - ::Ice::LoggerPtr logger = communicator->getLogger(); - - // - // Create our parser, then attach an error handler to the parser. - // The parser will call back to methods of the ErrorHandler if it - // discovers errors during the course of parsing the XML - // document. - // - ICE_XERCES_NS XercesDOMParser parser; - parser.setValidationScheme(ICE_XERCES_NS AbstractDOMParser::Val_Auto); - if(schema) - { - parser.setDoNamespaces(true); - parser.setDoSchema(true); - } - //parser.setValidationSchemaFullChecking(true); - - DOMTreeErrorReporter errReporter(logger); - parser.setErrorHandler(&errReporter); - parser.setCreateEntityReferenceNodes(false); - - // - // Parse the XML file, catching any XML exceptions that might propagate - // out of it. - // - bool errorsOccured = false; - try - { - ICE_XERCES_NS MemBufInputSource source((const XMLByte*)_content.data(), (unsigned int) _content.size(), "inputsource"); - parser.parse(source); - if(parser.getErrorCount() > 0) - { - errorsOccured = true; - } - } - catch(const ICE_XERCES_NS XMLException& ex) - { - ostringstream os; - os << "xerces: parsing error: " << toString(ex.getMessage()); - logger->error(os.str()); - errorsOccured = true; - } - catch(const ICE_XERCES_NS DOMException& ex) - { - ostringstream os; - os << "xerces: DOM parsing error: " << toString(ex.msg); - logger->error(os.str()); - errorsOccured = true; - } - - if(errorsOccured) - { - throw ::Ice::MarshalException(__FILE__, __LINE__); - } - - // - // The first child of the document is the root node - ignore - // that. Move to the top-level node in the document content. - // - _input = new StreamInputImpl(); - _input->document = parser.adoptDocument(); - _input->current = _input->document->getFirstChild(); - _input->current = _input->current->getFirstChild(); -} - -IceXML::StreamI::~StreamI() -{ - delete _input; -} - -void -IceXML::StreamI::startWriteDictionary(const string& name, ::Ice::Int size) -{ - ostringstream os; - os << name << " length=\"" << size << "\""; - startWrite(os.str()); -} - -void -IceXML::StreamI::endWriteDictionary() -{ - endWrite(); -} - -void -IceXML::StreamI::startWriteDictionaryElement() -{ - startWrite(getWritePrefix() + seqElementName); -} - -void -IceXML::StreamI::endWriteDictionaryElement() -{ - endWrite(); -} - -::Ice::Int -IceXML::StreamI::startReadDictionary(const string& name) -{ - startRead(name); - ::Ice::Int size = readLength(); - _input->current = _input->current->getFirstChild(); - return size; -} - -void -IceXML::StreamI::endReadDictionary() -{ - endRead(); -} - -void -IceXML::StreamI::startReadDictionaryElement() -{ - startRead(getReadPrefix() + seqElementName); - _input->current = _input->current->getFirstChild(); -} - -void -IceXML::StreamI::endReadDictionaryElement() -{ - endRead(); -} - -void -IceXML::StreamI::startWriteSequence(const string& name, ::Ice::Int size) -{ - ostringstream os; - os << name << " length=\"" << size << "\""; - startWrite(os.str()); -} - -void -IceXML::StreamI::endWriteSequence() -{ - endWrite(); -} - -void -IceXML::StreamI::startWriteSequenceElement() -{ - startWrite(getWritePrefix() + seqElementName); -} - -void -IceXML::StreamI::endWriteSequenceElement() -{ - endWrite(); -} - -::Ice::Int -IceXML::StreamI::startReadSequence(const string& name) -{ - startRead(name); - ::Ice::Int size = readLength(); - _input->current = _input->current->getFirstChild(); - return size; -} - -void -IceXML::StreamI::endReadSequence() -{ - endRead(); -} - -void -IceXML::StreamI::startReadSequenceElement() -{ - startRead(getReadPrefix() + seqElementName); -} - -void -IceXML::StreamI::endReadSequenceElement() -{ - endRead(); -} - -void -IceXML::StreamI::startWriteStruct(const string& name) -{ - startWrite(name); -} - -void -IceXML::StreamI::endWriteStruct() -{ - endWrite(); -} - -void -IceXML::StreamI::startReadStruct(const string& name) -{ - startRead(name); - _input->current = _input->current->getFirstChild(); -} - -void -IceXML::StreamI::endReadStruct() -{ - endRead(); -} - -void -IceXML::StreamI::startWriteException(const string& name) -{ - startWrite(name); -} - -void -IceXML::StreamI::endWriteException() -{ - endWrite(); -} - -void -IceXML::StreamI::startReadException(const string& name) -{ - startRead(name); - _input->current = _input->current->getFirstChild(); -} - -void -IceXML::StreamI::endReadException() -{ - endRead(); -} - -void -IceXML::StreamI::writeEnum(const string& name, const ::Ice::StringSeq& table, ::Ice::Int ordinal) -{ - // No attributes - assert(name.find_first_of(" \t") == string::npos); - - _os << se(name); - _os << startEscapes << table[ordinal] << endEscapes; - _os << ee; -} - -::Ice::Int -IceXML::StreamI::readEnum(const string& name, const ::Ice::StringSeq& table) -{ - startRead(name); - - ICE_XERCES_NS DOMNode* child = _input->current->getFirstChild(); - if(child == 0 || child->getNodeType() != ICE_XERCES_NS DOMNode::TEXT_NODE) - { - throw ::Ice::MarshalException(__FILE__, __LINE__); - } - - string value = toString(child->getNodeValue()); - ::Ice::StringSeq::const_iterator p = find(table.begin(), table.end(), value); - if(p == table.end()) - { - throw ::Ice::MarshalException(__FILE__, __LINE__); - } - - endRead(); - - return ::Ice::Int(p - table.begin()); -} - -void -IceXML::StreamI::writeByte(const string& name, ::Ice::Byte value) -{ - // No attributes - assert(name.find_first_of(" \t") == string::npos); - - // The schema encoding for xs:byte is a value from -127 to 128. - _os << se(name); - _os << startEscapes << (int)value << endEscapes; - _os << ee; -} - -void -IceXML::StreamI::writeByteSeq(const string& name, const ::Ice::ByteSeq& seq) -{ - startWriteSequence(name, ::Ice::Int(seq.size())); - for(::Ice::ByteSeq::const_iterator p = seq.begin(); p != seq.end(); ++p) - { - startWriteSequenceElement(); - _os << startEscapes << (int)*p << endEscapes; - endWriteSequenceElement(); - } - endWriteSequence(); -} - -::Ice::Byte -IceXML::StreamI::readByte(const string& name) -{ - startRead(name); - - ICE_XERCES_NS DOMNode* child = _input->current->getFirstChild(); - if(child == 0 || child->getNodeType() != ICE_XERCES_NS DOMNode::TEXT_NODE) - { - throw ::Ice::MarshalException(__FILE__, __LINE__); - } - - string s = toString(child->getNodeValue()); - ::Ice::Int i = atoi(s.c_str()); - if(i < -128 || i > 127) - { - throw ::Ice::MarshalException(__FILE__, __LINE__); - } - - endRead(); - - return (::Ice::Byte)i; -} - -// -// None of the read*Seq methods are very efficient. It's possible to -// write them as follows in a much more efficient manner - but it's -// not as maintainable. -// -// startRead(name); -// ::Ice::Int size = readLength(); -// value.resize(size); -// value_type::iterator p = value.begin(); -// DOMNodeList* children = _input->current->getChildNodes(); -// -// int nchildren = children->getLength(); -// for(int i = 0; i < nchildren; ++i) -// { -// DOMNode* child = children->item(i); -// while(child->getNodeType() != DOMNode::ELEMENT_NODE) -// { -// child = child->getNextSibling(); -// } -// string name = toString(child->getNodeName()); -// if(name != seqElementName) -// { -// throw ::Ice::MarshalException(__FILE__, __LINE__); -// } -// -// child = child->getFirstChild(); -// if(child == 0 || child->getNodeType() != DOMNode::TEXT_NODE) -// { -// throw ::Ice::MarshalException(__FILE__, __LINE__); -// } -// -// string s = toString(child->getNodeValue()); -// *p++ = ???; -// } -// -// endRead(); -// -// -// - -::Ice::ByteSeq -IceXML::StreamI::readByteSeq(const string& name) -{ - ::Ice::ByteSeq value; - - startRead(name); - - string elem = getPrefix(name) + seqElementName; - ::Ice::Int size = readLength(); - value.resize(size); - if(size > 0) - { - _input->current = _input->current->getFirstChild(); - for(int i = 0; i < size; ++i) - { - value[i] = readByte(elem); - } - } - - endRead(); - - return value; -} - -void -IceXML::StreamI::writeBool(const string& name, bool value) -{ - // No attributes - assert(name.find_first_of(" \t") == string::npos); - _os << se(name) << (value ? "true" : "false") << ee; -} - -void -IceXML::StreamI::writeBoolSeq(const string& name, const ::Ice::BoolSeq& seq) -{ - startWriteSequence(name, ::Ice::Int(seq.size())); - for(::Ice::BoolSeq::const_iterator p = seq.begin(); p != seq.end(); ++p) - { - _os << se("e") << (*p ? "true" : "false") << ee; - } - endWriteSequence(); -} - -bool -IceXML::StreamI::readBool(const string& name) -{ - startRead(name); - - ICE_XERCES_NS DOMNode* child = _input->current->getFirstChild(); - if(child == 0 || child->getNodeType() != ICE_XERCES_NS DOMNode::TEXT_NODE) - { - throw ::Ice::MarshalException(__FILE__, __LINE__); - } - - string s = toString(child->getNodeValue()); - - endRead(); - - return (s == "true") ? true : false; -} - -::Ice::BoolSeq -IceXML::StreamI::readBoolSeq(const string& name) -{ - ::Ice::BoolSeq value; - - startRead(name); - - string elem = getPrefix(name) + seqElementName; - ::Ice::Int size = readLength(); - value.resize(size); - if(size > 0) - { - _input->current = _input->current->getFirstChild(); - for(int i = 0; i < size; ++i) - { - value[i] = readBool(elem); - } - } - - endRead(); - - return value; -} - -void -IceXML::StreamI::writeShort(const string& name, ::Ice::Short value) -{ - // No attributes - assert(name.find_first_of(" \t") == string::npos); - _os << se(name) << value << ee; -} - -void -IceXML::StreamI::writeShortSeq(const string& name, const ::Ice::ShortSeq& seq) -{ - startWriteSequence(name, ::Ice::Int(seq.size())); - for(::Ice::ShortSeq::const_iterator p = seq.begin(); p != seq.end(); ++p) - { - _os << se("e") << *p << ee; - } - endWriteSequence(); -} - -::Ice::Short -IceXML::StreamI::readShort(const string& name) -{ - startRead(name); - - ICE_XERCES_NS DOMNode* child = _input->current->getFirstChild(); - if(child == 0 || child->getNodeType() != ICE_XERCES_NS DOMNode::TEXT_NODE) - { - throw ::Ice::MarshalException(__FILE__, __LINE__); - } - - string s = toString(child->getNodeValue()); - ::Ice::Int i = atoi(s.c_str()); - if(i < -32768 || i > 32767) - { - throw ::Ice::MarshalException(__FILE__, __LINE__); - } - - endRead(); - - return (::Ice::Short)i; -} - -::Ice::ShortSeq -IceXML::StreamI::readShortSeq(const string& name) -{ - ::Ice::ShortSeq value; - - startRead(name); - - string elem = getPrefix(name) + seqElementName; - ::Ice::Int size = readLength(); - value.resize(size); - if(size > 0) - { - _input->current = _input->current->getFirstChild(); - for(int i = 0; i < size; ++i) - { - value[i] = readShort(elem); - } - } - - endRead(); - - return value; -} - -void -IceXML::StreamI::writeInt(const string& name, ::Ice::Int value) -{ - // No attributes - assert(name.find_first_of(" \t") == string::npos); - _os << se(name) << value << ee; -} - -void -IceXML::StreamI::writeIntSeq(const string& name, const ::Ice::IntSeq& seq) -{ - startWriteSequence(name, ::Ice::Int(seq.size())); - for(::Ice::IntSeq::const_iterator p = seq.begin(); p != seq.end(); ++p) - { - _os << se("e") << *p << ee; - } - endWriteSequence(); -} - -::Ice::Int -IceXML::StreamI::readInt(const string& name) -{ - startRead(name); - - ICE_XERCES_NS DOMNode* child = _input->current->getFirstChild(); - if(child == 0 || child->getNodeType() != ICE_XERCES_NS DOMNode::TEXT_NODE) - { - throw ::Ice::MarshalException(__FILE__, __LINE__); - } - - string s = toString(child->getNodeValue()); - - endRead(); - - return atoi(s.c_str()); -} - -::Ice::IntSeq -IceXML::StreamI::readIntSeq(const string& name) -{ - ::Ice::IntSeq value; - - startRead(name); - - string elem = getPrefix(name) + seqElementName; - ::Ice::Int size = readLength(); - value.resize(size); - if(size > 0) - { - _input->current = _input->current->getFirstChild(); - for(int i = 0; i < size; ++i) - { - value[i] = readInt(elem); - } - } - - endRead(); - - return value; -} - -void -IceXML::StreamI::writeLong(const string& name, ::Ice::Long value) -{ - // No attributes - assert(name.find_first_of(" \t") == string::npos); - _os << se(name) << value << ee; -} - -void -IceXML::StreamI::writeLongSeq(const string& name, const ::Ice::LongSeq& seq) -{ - startWriteSequence(name, ::Ice::Int(seq.size())); - for(::Ice::LongSeq::const_iterator p = seq.begin(); p != seq.end(); ++p) - { - _os << se("e") << *p << ee; - } - endWriteSequence(); -} - -::Ice::Long -IceXML::StreamI::readLong(const string& name) -{ - startRead(name); - - ICE_XERCES_NS DOMNode* child = _input->current->getFirstChild(); - if(child == 0 || child->getNodeType() != ICE_XERCES_NS DOMNode::TEXT_NODE) - { - throw ::Ice::MarshalException(__FILE__, __LINE__); - } - - string s = toString(child->getNodeValue()); - - endRead(); - - Ice::Long result; - string::size_type pos; - if(!IceUtil::stringToInt64(s, result, pos)) - { - throw ::Ice::MarshalException(__FILE__, __LINE__); - } - return result; -} - -::Ice::LongSeq -IceXML::StreamI::readLongSeq(const string& name) -{ - ::Ice::LongSeq value; - - startRead(name); - - string elem = getPrefix(name) + seqElementName; - ::Ice::Int size = readLength(); - value.resize(size); - if(size > 0) - { - _input->current = _input->current->getFirstChild(); - for(int i = 0; i < size; ++i) - { - value[i] = readLong(elem); - } - } - - endRead(); - - return value; -} - -void -IceXML::StreamI::writeFloat(const string& name, ::Ice::Float value) -{ - // No attributes - assert(name.find_first_of(" \t") == string::npos); - _os << se(name) << value << ee; -} - -void -IceXML::StreamI::writeFloatSeq(const string& name, const ::Ice::FloatSeq& seq) -{ - startWriteSequence(name, ::Ice::Int(seq.size())); - for(::Ice::FloatSeq::const_iterator p = seq.begin(); p != seq.end(); ++p) - { - _os << se("e") << *p << ee; - } - endWriteSequence(); -} - -::Ice::Float -IceXML::StreamI::readFloat(const string& name) -{ - startRead(name); - - ICE_XERCES_NS DOMNode* child = _input->current->getFirstChild(); - if(child == 0 || child->getNodeType() != ICE_XERCES_NS DOMNode::TEXT_NODE) - { - throw ::Ice::MarshalException(__FILE__, __LINE__); - } - - string s = toString(child->getNodeValue()); - - endRead(); - - return (::Ice::Float)atof(s.c_str()); -} - -::Ice::FloatSeq -IceXML::StreamI::readFloatSeq(const string& name) -{ - ::Ice::FloatSeq value; - - startRead(name); - - string elem = getPrefix(name) + seqElementName; - ::Ice::Int size = readLength(); - value.resize(size); - if(size > 0) - { - _input->current = _input->current->getFirstChild(); - for(int i = 0; i < size; ++i) - { - value[i] = readFloat(elem); - } - } - - endRead(); - - return value; -} - -void -IceXML::StreamI::writeDouble(const string& name, ::Ice::Double value) -{ - // No attributes - assert(name.find_first_of(" \t") == string::npos); - _os << se(name) << value << ee; -} - -void -IceXML::StreamI::writeDoubleSeq(const string& name, const ::Ice::DoubleSeq& seq) -{ - startWriteSequence(name, ::Ice::Int(seq.size())); - for(::Ice::DoubleSeq::const_iterator p = seq.begin(); p != seq.end(); ++p) - { - _os << se("e") << *p << ee; - } - endWriteSequence(); -} - -::Ice::Double -IceXML::StreamI::readDouble(const string& name) -{ - startRead(name); - - ICE_XERCES_NS DOMNode* child = _input->current->getFirstChild(); - if(child == 0 || child->getNodeType() != ICE_XERCES_NS DOMNode::TEXT_NODE) - { - throw ::Ice::MarshalException(__FILE__, __LINE__); - } - - string s = toString(child->getNodeValue()); - - endRead(); - - return atof(s.c_str()); -} - -::Ice::DoubleSeq -IceXML::StreamI::readDoubleSeq(const string& name) -{ - ::Ice::DoubleSeq value; - - startRead(name); - - string elem = getPrefix(name) + seqElementName; - ::Ice::Int size = readLength(); - value.resize(size); - if(size > 0) - { - _input->current = _input->current->getFirstChild(); - for(int i = 0; i < size; ++i) - { - value[i] = readDouble(elem); - } - } - - endRead(); - - return value; -} - -void -IceXML::StreamI::writeString(const string& name, const string& value) -{ - // No attributes - assert(name.find_first_of(" \t") == string::npos); - - _os << se(name); - if(!value.empty()) - { - _os << startEscapes << value << endEscapes; - } - _os << ee; -} - -void -IceXML::StreamI::writeStringSeq(const string& name, const ::Ice::StringSeq& seq) -{ - startWriteSequence(name, ::Ice::Int(seq.size())); - for(::Ice::StringSeq::const_iterator p = seq.begin(); p != seq.end(); ++p) - { - _os << se("e"); - if(!p->empty()) - { - _os << startEscapes << *p << endEscapes; - } - _os << ee; - } - endWriteSequence(); -} - -string -IceXML::StreamI::readString(const string& name) -{ - string value; - - startRead(name); - - ICE_XERCES_NS DOMNode* child = _input->current->getFirstChild(); - if(child) - { - if(child->getNodeType() != ICE_XERCES_NS DOMNode::TEXT_NODE) - { - throw ::Ice::MarshalException(__FILE__, __LINE__); - } - - // - // Convert string to UTF-8. Do NOT use toString() here. - // - const XMLCh* ch = child->getNodeValue(); - unsigned int len = ICE_XERCES_NS XMLString::stringLen(ch); - wstring ws; - for(unsigned int i = 0; i < len; ++i) - { - ws.push_back((wstring::value_type)ch[i]); - } - value = IceUtil::wstringToString(ws); - } - else - { - value = ""; - } - - endRead(); - - return value; -} - -::Ice::StringSeq -IceXML::StreamI::readStringSeq(const string& name) -{ - ::Ice::StringSeq value; - - startRead(name); - - string elem = getPrefix(name) + seqElementName; - ::Ice::Int size = readLength(); - value.resize(size); - if(size > 0) - { - _input->current = _input->current->getFirstChild(); - for(int i = 0; i < size; ++i) - { - value[i] = readString(elem); - } - } - - endRead(); - - return value; -} - -void -IceXML::StreamI::writeProxy(const string& name, const ::Ice::ObjectPrx& proxy) -{ - // No attributes - assert(name.find_first_of(" \t") == string::npos); - string s = _communicator->proxyToString(proxy); - - _os << se(name); - if(!s.empty()) - { - _os << startEscapes << s << endEscapes; - } - _os << ee; -} - -::Ice::ObjectPrx -IceXML::StreamI::readProxy(const string& name) -{ - startRead(name); - - ICE_XERCES_NS DOMNode* child = _input->current->getFirstChild(); - string s; - if(child) - { - if(child->getNodeType() != ICE_XERCES_NS DOMNode::TEXT_NODE) - { - throw ::Ice::MarshalException(__FILE__, __LINE__); - } - s = toString(child->getNodeValue()); - } - - endRead(); - - return _communicator->stringToProxy(s); -} - -void -IceXML::StreamI::writeObject(const string& name, const ::Ice::ObjectPtr& obj) -{ - // - // If at the top level of the document then the object itself must - // be written, otherwise write a reference. - // - bool writeReference = (_level != 0); - - // - // If the object doesn't exist in the map add it. - // - map<Ice::ObjectPtr, ObjectInfo>::iterator p = _objects.find(obj); - if(p == _objects.end()) - { - ostringstream os; - os << "object" << _nextId++; - p = _objects.insert(map<Ice::ObjectPtr, ObjectInfo>::value_type( - obj, ObjectInfo(os.str(), !writeReference))).first; - } - - if(writeReference) - { - _os << nl << "<" << name << " href=\"#" << p->second.id << "\"/>"; - } - else - { - // - // Precondition: If the actual object is being written the - // written flag should be true. - // - assert(p->second.written); - writeObjectData(name, p->second.id, obj); - } -} - -::Ice::ObjectPtr -IceXML::StreamI::readObject(const string& name, const string& signatureType, const ::Ice::ObjectFactoryPtr& factory) -{ - ::Ice::ObjectPtr value; - - startRead(name); - - // - // Node attributes. Either id & type will be set, or href. - // - string id, type, href; - readAttributes(id, type, href); - - // - // If this object is an href then locate the object. If the object - // has been previously read then it will be contained in the - // readObjects list. Otherwise, it should be in the object-set at - // the top-level of the document. - // - if(!href.empty()) - { - href = href.substr(1); // Skip the '#' - - map<string, ::Ice::ObjectPtr>::const_iterator p = _input->readObjects.find(href); - if(p != _input->readObjects.end()) - { - value = p->second; - endRead(); - return value; - } - - // - // The first child of the document is the root node - ignore - // that. Move to the top-level node in the document content. - // - _input->current = _input->document->getFirstChild(); - _input->current = _input->current->getFirstChild(); - while(_input->current) - { - if(_input->current->getNodeType() == ICE_XERCES_NS DOMNode::ELEMENT_NODE) - { - string dummy; - readAttributes(id, type, dummy); - if(id == href) - { - break; - } - } - _input->current = _input->current->getNextSibling(); - } - // - // If the object isn't found, that's an error. - // - if(_input->current == 0) - { - throw ::Ice::MarshalException(__FILE__, __LINE__); - } - } - - // - // Empty type indicates nil object. - // - if(type.empty()) - { - value = 0; - } - else - { - if(type == "::Ice::Object") - { - value = new ::Ice::Object; - } - else - { - // - // First, determine if there is an installed factory for this - // type. If so use that. If that factory doesn't exist, or it - // doesn't create an object of that type then use the supplied - // factory provided that the types are the same. If no value - // can be created then throw a NoObjectFactoryException. - // - ::Ice::ObjectFactoryPtr userFactory = _communicator->findObjectFactory(type); - if(userFactory) - { - value = userFactory->create(type); - } - - if(!value && type == signatureType) - { - assert(factory); - value = factory->create(type); - assert(value); - } - - if(!value) - { - ::Ice::NoObjectFactoryException ex(__FILE__, __LINE__); - ex.type = type; - throw ex; - } - } - - // - // Add the object to the readObjects map, move to the first - // child node & unmarshal the object. - // - _input->readObjects.insert(pair<const string, ::Ice::ObjectPtr>(id, value)); - _input->current = _input->current->getFirstChild(); - value->__unmarshal(this); - } - - endRead(); - - return value; -} - -void -IceXML::StreamI::marshalFacets(bool setting) -{ - _marshalFacets = setting; -} - -void -IceXML::StreamI::startWrite(const string& element) -{ - _os << se(element); - ++_level; -} - -void -IceXML::StreamI::endWrite() -{ - --_level; - - _os << ee; - - if(_level == 0 && !_dump) - { - dumpUnwrittenObjects(); - } -} - -void -IceXML::StreamI::startRead(const ::std::string& element) -{ - while(_input->current && _input->current->getNodeType() != ICE_XERCES_NS DOMNode::ELEMENT_NODE) - { - _input->current = _input->current->getNextSibling(); - } - if(_input->current == 0) - { - throw ::Ice::MarshalException(__FILE__, __LINE__); - } - - string nodeName = toString(_input->current->getNodeName()); - if(element != nodeName) - { - throw ::Ice::MarshalException(__FILE__, __LINE__); - } - - _input->nodeStack.push_back(_input->current); -} - -void -IceXML::StreamI::endRead() -{ - _input->current = _input->nodeStack.back(); - _input->nodeStack.pop_back(); - _input->current = _input->current->getNextSibling(); -} - -void -IceXML::StreamI::dumpUnwrittenObjects() -{ - // - // Precondition: Must be at the top-level. - // - assert(_level == 0 && !_dump); - - _dump = true; - - // - // It's necessary to run through the set of unwritten objects - // repeatedly until all referenced objects have been written - // (since referenced objects can themselves reference other - // objects). - // - unsigned int nwritten; - do - { - nwritten = 0; - map<Ice::ObjectPtr, ObjectInfo>::iterator p; - for(p = _objects.begin(); p != _objects.end(); ++p) - { - if(!p->second.written) - { - p->second.written = true; - writeObjectData("ice:object", p->second.id, p->first); - } - ++nwritten; - } - } - while(_objects.size() != nwritten); - - _dump = false; -} - -void -IceXML::StreamI::writeObjectData(const string& name, const string& id, const Ice::ObjectPtr& obj) -{ - string xsdType; - string typeId; - - if(obj) - { - // - // Convert the type-id to the equivalent schema type - // definition name. - // - typeId = obj->ice_id(); - - const string xsdPrefix = "_internal."; - const string xsdSuffix = "Type"; - xsdType.reserve(typeId.size() + xsdPrefix.size() + xsdSuffix.size()); - xsdType += xsdPrefix; - unsigned int i = 0; - if(typeId[0] == ':') // Skip the preceeding "::". - { - i = 2; - } - for(; i < typeId.size(); ++i) - { - if(typeId[i] == ':') - { - xsdType += '.'; - ++i; - } - else - { - xsdType += typeId[i]; - } - } - xsdType += xsdSuffix; - } - else - { - xsdType = ""; - } - - ostringstream os; - os << name << " id=\"" << id << "\" type=\"" << typeId << "\"" << " xsi:type=\"" << xsdType << "\""; - if(!obj) - { - os << " xsi:nil=\"true\""; - } - - startWrite(os.str()); - if(obj) - { - obj->__marshal(this, _marshalFacets); - } - endWrite(); -} - -void -IceXML::StreamI::readAttributes(::std::string& id, ::std::string& type, ::std::string& href) -{ - ICE_XERCES_NS DOMNamedNodeMap* attributes = _input->current->getAttributes(); - size_t attrCount = attributes->getLength(); - for(size_t i = 0; i < attrCount; i++) - { - ICE_XERCES_NS DOMNode* attribute = attributes->item(i); - string name = toString(attribute->getNodeName()); - if(name == "id") - { - id = toString(attribute->getNodeValue()); - } - else if(name == "type") - { - type = toString(attribute->getNodeValue()); - } - else if(name == "href") - { - href = toString(attribute->getNodeValue()); - } - } -} - -::Ice::Int -IceXML::StreamI::readLength() -{ - ICE_XERCES_NS DOMNamedNodeMap* attributes = _input->current->getAttributes(); - size_t attrCount = attributes->getLength(); - for(size_t i = 0; i < attrCount; i++) - { - ICE_XERCES_NS DOMNode* attribute = attributes->item(i); - string name = toString(attribute->getNodeName()); - if(name == "length") - { - return atoi(toString(attribute->getNodeValue()).c_str()); - } - } - - throw ::Ice::MarshalException(__FILE__, __LINE__); -} - -string -IceXML::StreamI::getWritePrefix() const -{ - string name = _os.currentElement(); - assert(!name.empty()); - return getPrefix(name); -} - -string -IceXML::StreamI::getReadPrefix() const -{ - assert(!_input->nodeStack.empty()); - return getPrefix(toString(_input->nodeStack.back()->getNodeName())); -} - -string -IceXML::StreamI::getPrefix(const string& s) -{ - string::size_type pos = s.find(':'); - if(pos != string::npos) - { - return s.substr(0, pos + 1); - } - else - { - return string(); - } -} |