diff options
Diffstat (limited to 'cpp/src/Ice/IntStream.cpp')
-rw-r--r-- | cpp/src/Ice/IntStream.cpp | 850 |
1 files changed, 850 insertions, 0 deletions
diff --git a/cpp/src/Ice/IntStream.cpp b/cpp/src/Ice/IntStream.cpp new file mode 100644 index 00000000000..e3e5ab15091 --- /dev/null +++ b/cpp/src/Ice/IntStream.cpp @@ -0,0 +1,850 @@ +// ********************************************************************** +// +// Copyright (c) 2001 +// MutableRealms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#include <Ice/IntStream.h> +#include <Ice/Instance.h> +#include <Ice/Object.h> +#include <Ice/Proxy.h> +#include <Ice/ProxyFactory.h> +#include <Ice/ServantFactory.h> +#include <Ice/ServantFactoryManager.h> +#include <Ice/LocalException.h> + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +IceInternal::IntStream::IntStream(const InstancePtr& instance) : + _instance(instance), + _encapsStack(1) +{ + _encapsStack.resize(1); + _encapsStack.back().start = 0; + _encapsStack.back().encoding = 0; +} + +IceInternal::IntStream::~IntStream() +{ + // + // No check for exactly one, because an error might have aborted + // marshalling/unmarshalling + // + assert(_encapsStack.size() > 0); +} + +InstancePtr +IceInternal::IntStream::instance() const +{ + return _instance; +} + +void +IceInternal::IntStream::swap(IntStream& other) +{ + assert(_instance.get() == other._instance.get()); + + b.swap(other.b); + std::swap(i, other.i); + _encapsStack.swap(other._encapsStack); +} + +void +IceInternal::IntStream::resize(int total) +{ + if (total > 1024 * 1024) // TODO: configurable + { + throw MemoryLimitException(__FILE__, __LINE__); + } + b.resize(total); +} + +void +IceInternal::IntStream::reserve(int total) +{ + if (total > 1024 * 1024) // TODO: configurable + { + throw MemoryLimitException(__FILE__, __LINE__); + } + b.reserve(total); +} + +void +IceInternal::IntStream::startWriteEncaps() +{ + write(Int(0)); // Placeholder for the encapsulation length + _encapsStack.resize(_encapsStack.size() + 1); + _encapsStack.back().start = b.size(); + _encapsStack.back().encoding = 0; + write(_encapsStack.back().encoding); +} + +void +IceInternal::IntStream::endWriteEncaps() +{ + int start = _encapsStack.back().start; + _encapsStack.pop_back(); + Int sz = b.size() - start; + const Byte* p = reinterpret_cast<const Byte*>(&sz); +#ifdef ICE_BIGENDIAN + reverse_copy(p, p + sizeof(Int), b.begin() + start - sizeof(Int)); +#else + copy(p, p + sizeof(Int), b.begin() + start - sizeof(Int)); +#endif +} + +void +IceInternal::IntStream::startReadEncaps() +{ + Int sz; + read(sz); + _encapsStack.resize(_encapsStack.size() + 1); + _encapsStack.back().start = i - b.begin(); + read(_encapsStack.back().encoding); + if (_encapsStack.back().encoding != 0) + { + throw UnsupportedEncodingException(__FILE__, __LINE__); + } +} + +void +IceInternal::IntStream::endReadEncaps() +{ + int start = _encapsStack.back().start; + _encapsStack.pop_back(); + Container::iterator save = i; + i = b.begin() + start - sizeof(Int); + Int sz; + read(sz); + i = save; + if (sz != i - (b.begin() + start)) + { + throw EncapsulationException(__FILE__, __LINE__); + } +} + +void +IceInternal::IntStream::skipEncaps() +{ + Int sz; + read(sz); + i += sz; + if (i >= b.end()) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } +} + +void +IceInternal::IntStream::write(const vector<Byte>& v) +{ + int pos = b.size(); + Int sz = v.size(); + resize(pos + sizeof(Int) + sz); + const Byte* p = reinterpret_cast<const Byte*>(&sz); +#ifdef ICE_BIGENDIAN + reverse_copy(p, p + sizeof(Int), b.begin() + pos); +#else + copy(p, p + sizeof(Int), b.begin() + pos); +#endif + copy(v.begin(), v.end(), b.begin() + pos + sizeof(Int)); +} + +void +IceInternal::IntStream::read(Byte& v) +{ + if (i >= b.end()) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + v = *i++; +} + +void +IceInternal::IntStream::read(vector<Byte>& v) +{ + Int sz; + read(sz); + Container::iterator begin = i; + i += sz; + if (i > b.end()) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + v.resize(sz); + copy(begin, i, v.begin()); +} + +void +IceInternal::IntStream::write(const vector<bool>& v) +{ + int pos = b.size(); + Int sz = v.size(); + resize(pos + sizeof(Int) + sz); + const Byte* p = reinterpret_cast<const Byte*>(&sz); +#ifdef ICE_BIGENDIAN + reverse_copy(p, p + sizeof(Int), b.begin() + pos); +#else + copy(p, p + sizeof(Int), b.begin() + pos); +#endif + copy(v.begin(), v.end(), b.begin() + pos + sizeof(Int)); +} + +void +IceInternal::IntStream::read(bool& v) +{ + if (i >= b.end()) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + v = *i++; +} + +void +IceInternal::IntStream::read(vector<bool>& v) +{ + Int sz; + read(sz); + Container::iterator begin = i; + i += sz; + if (i > b.end()) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + v.resize(sz); + copy(begin, i, v.begin()); +} + +void +IceInternal::IntStream::write(Short v) +{ + int pos = b.size(); + resize(pos + sizeof(Short)); + const Byte* p = reinterpret_cast<const Byte*>(&v); +#ifdef ICE_BIGENDIAN + reverse_copy(p, p + sizeof(Short), b.begin() + pos); +#else + copy(p, p + sizeof(Short), b.begin() + pos); +#endif +} + +void +IceInternal::IntStream::write(const vector<Short>& v) +{ + int pos = b.size(); + Int sz = v.size(); + resize(pos + sizeof(Int) + sz * sizeof(Short)); + const Byte* p = reinterpret_cast<const Byte*>(&sz); +#ifdef ICE_BIGENDIAN + reverse_copy(p, p + sizeof(Int), b.begin() + pos); + pos += sizeof(Int); + p = reinterpret_cast<const Byte*>(v.begin()); + for (int j = 0 ; j < sz ; ++j) + { + reverse_copy(p, p + sizeof(Short), b.begin() + pos); + p += sizeof(Short); + pos += sizeof(Short); + } +#else + copy(p, p + sizeof(Int), b.begin() + pos); + p = reinterpret_cast<const Byte*>(v.begin()); + copy(p, p + sz * sizeof(Short), b.begin() + pos + sizeof(Int)); +#endif +} + +void +IceInternal::IntStream::read(Short& v) +{ + Container::iterator begin = i; + i += sizeof(Short); + if (i > b.end()) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } +#ifdef ICE_BIGENDIAN + reverse_copy(begin, i, reinterpret_cast<Byte*>(&v)); +#else + copy(begin, i, reinterpret_cast<Byte*>(&v)); +#endif +} + +void +IceInternal::IntStream::read(vector<Short>& v) +{ + Int sz; + read(sz); + Container::iterator begin = i; + i += sz * sizeof(Short); + if (i > b.end()) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + v.resize(sz); +#ifdef ICE_BIGENDIAN + for (int j = 0 ; j < sz ; ++j) + { + reverse_copy(begin, begin + sizeof(Short), reinterpret_cast<Byte*>(&v[j])); + begin += sizeof(Short); + } +#else + copy(begin, i, reinterpret_cast<Byte*>(v.begin())); +#endif +} + +void +IceInternal::IntStream::write(Int v) +{ + int pos = b.size(); + resize(pos + sizeof(Int)); + const Byte* p = reinterpret_cast<const Byte*>(&v); +#ifdef ICE_BIGENDIAN + reverse_copy(p, p + sizeof(Int), b.begin() + pos); +#else + copy(p, p + sizeof(Int), b.begin() + pos); +#endif +} + +void +IceInternal::IntStream::write(const vector<Int>& v) +{ + int pos = b.size(); + Int sz = v.size(); + resize(pos + sizeof(Int) + sz * sizeof(Int)); + const Byte* p = reinterpret_cast<const Byte*>(&sz); +#ifdef ICE_BIGENDIAN + reverse_copy(p, p + sizeof(Int), b.begin() + pos); + pos += sizeof(Int); + p = reinterpret_cast<const Byte*>(v.begin()); + for (int j = 0 ; j < sz ; ++j) + { + reverse_copy(p, p + sizeof(Short), b.begin() + pos); + p += sizeof(Int); + pos += sizeof(Int); + } +#else + copy(p, p + sizeof(Int), b.begin() + pos); + p = reinterpret_cast<const Byte*>(v.begin()); + copy(p, p + sz * sizeof(Int), b.begin() + pos + sizeof(Int)); +#endif +} + +void +IceInternal::IntStream::read(Int& v) +{ + Container::iterator begin = i; + i += sizeof(Int); + if (i > b.end()) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } +#ifdef ICE_BIGENDIAN + reverse_copy(begin, i, reinterpret_cast<Byte*>(&v)); +#else + copy(begin, i, reinterpret_cast<Byte*>(&v)); +#endif +} + +void +IceInternal::IntStream::read(vector<Int>& v) +{ + Int sz; + read(sz); + Container::iterator begin = i; + i += sz * sizeof(Int); + if (i > b.end()) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + v.resize(sz); +#ifdef ICE_BIGENDIAN + for (int j = 0 ; j < sz ; ++j) + { + reverse_copy(begin, begin + sizeof(Int), reinterpret_cast<Byte*>(&v[j])); + begin += sizeof(Int); + } +#else + copy(begin, i, reinterpret_cast<Byte*>(v.begin())); +#endif +} + +void +IceInternal::IntStream::write(Long v) +{ + int pos = b.size(); + resize(pos + sizeof(Long)); + const Byte* p = reinterpret_cast<const Byte*>(&v); +#ifdef ICE_BIGENDIAN + reverse_copy(p, p + sizeof(Long), b.begin() + pos); +#else + copy(p, p + sizeof(Long), b.begin() + pos); +#endif +} + +void +IceInternal::IntStream::write(const vector<Long>& v) +{ + int pos = b.size(); + Int sz = v.size(); + resize(pos + sizeof(Int) + sz * sizeof(Long)); + const Byte* p = reinterpret_cast<const Byte*>(&sz); +#ifdef ICE_BIGENDIAN + reverse_copy(p, p + sizeof(Int), b.begin() + pos); + pos += sizeof(Int); + p = reinterpret_cast<const Byte*>(v.begin()); + for (int j = 0 ; j < sz ; ++j) + { + reverse_copy(p, p + sizeof(Long), b.begin() + pos); + p += sizeof(Long); + pos += sizeof(Long); + } +#else + copy(p, p + sizeof(Int), b.begin() + pos); + p = reinterpret_cast<const Byte*>(v.begin()); + copy(p, p + sz * sizeof(Long), b.begin() + pos + sizeof(Int)); +#endif +} + +void +IceInternal::IntStream::read(Long& v) +{ + Container::iterator begin = i; + i += sizeof(Long); + if (i > b.end()) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } +#ifdef ICE_BIGENDIAN + reverse_copy(begin, i, reinterpret_cast<Byte*>(&v)); +#else + copy(begin, i, reinterpret_cast<Byte*>(&v)); +#endif +} + +void +IceInternal::IntStream::read(vector<Long>& v) +{ + Int sz; + read(sz); + Container::iterator begin = i; + i += sz * sizeof(Long); + if (i > b.end()) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + v.resize(sz); +#ifdef ICE_BIGENDIAN + for (int j = 0 ; j < sz ; ++j) + { + reverse_copy(begin, begin + sizeof(Long), reinterpret_cast<Byte*>(&v[j])); + begin += sizeof(Long); + } +#else + copy(begin, i, reinterpret_cast<Byte*>(v.begin())); +#endif +} + +void +IceInternal::IntStream::write(Float v) +{ + int pos = b.size(); + resize(pos + sizeof(Float)); + const Byte* p = reinterpret_cast<const Byte*>(&v); +#ifdef ICE_BIGENDIAN + reverse_copy(p, p + sizeof(Float), b.begin() + pos); +#else + copy(p, p + sizeof(Float), b.begin() + pos); +#endif +} + +void +IceInternal::IntStream::write(const vector<Float>& v) +{ + int pos = b.size(); + Int sz = v.size(); + resize(pos + sizeof(Int) + sz * sizeof(Float)); + const Byte* p = reinterpret_cast<const Byte*>(&sz); +#ifdef ICE_BIGENDIAN + reverse_copy(p, p + sizeof(Int), b.begin() + pos); + pos += sizeof(Int); + p = reinterpret_cast<const Byte*>(v.begin()); + for (int j = 0 ; j < sz ; ++j) + { + reverse_copy(p, p + sizeof(Float), b.begin() + pos); + p += sizeof(Float); + pos += sizeof(Float); + } +#else + copy(p, p + sizeof(Int), b.begin() + pos); + p = reinterpret_cast<const Byte*>(v.begin()); + copy(p, p + sz * sizeof(Float), b.begin() + pos + sizeof(Int)); +#endif +} + +void +IceInternal::IntStream::read(Float& v) +{ + Container::iterator begin = i; + i += sizeof(Float); + if (i > b.end()) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } +#ifdef ICE_BIGENDIAN + reverse_copy(begin, i, reinterpret_cast<Byte*>(&v)); +#else + copy(begin, i, reinterpret_cast<Byte*>(&v)); +#endif +} + +void +IceInternal::IntStream::read(vector<Float>& v) +{ + Int sz; + read(sz); + Container::iterator begin = i; + i += sz * sizeof(Float); + if (i > b.end()) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + v.resize(sz); +#ifdef ICE_BIGENDIAN + for (int j = 0 ; j < sz ; ++j) + { + reverse_copy(begin, begin + sizeof(Float), reinterpret_cast<Byte*>(&v[j])); + begin += sizeof(Float); + } +#else + copy(begin, i, reinterpret_cast<Byte*>(v.begin())); +#endif +} + +void +IceInternal::IntStream::write(Double v) +{ + int pos = b.size(); + resize(pos + sizeof(Double)); + const Byte* p = reinterpret_cast<const Byte*>(&v); +#ifdef ICE_BIGENDIAN + reverse_copy(p, p + sizeof(Double), b.begin() + pos); +#else + copy(p, p + sizeof(Double), b.begin() + pos); +#endif +} + +void +IceInternal::IntStream::write(const vector<Double>& v) +{ + int pos = b.size(); + Int sz = v.size(); + resize(pos + sizeof(Int) + sz * sizeof(Double)); + const Byte* p = reinterpret_cast<const Byte*>(&sz); +#ifdef ICE_BIGENDIAN + reverse_copy(p, p + sizeof(Int), b.begin() + pos); + pos += sizeof(Int); + p = reinterpret_cast<const Byte*>(v.begin()); + for (int j = 0 ; j < sz ; ++j) + { + reverse_copy(p, p + sizeof(Double), b.begin() + pos); + p += sizeof(Double); + pos += sizeof(Double); + } +#else + copy(p, p + sizeof(Int), b.begin() + pos); + p = reinterpret_cast<const Byte*>(v.begin()); + copy(p, p + sz * sizeof(Double), b.begin() + pos + sizeof(Int)); +#endif +} + +void +IceInternal::IntStream::read(Double& v) +{ + Container::iterator begin = i; + i += sizeof(Double); + if (i > b.end()) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } +#ifdef ICE_BIGENDIAN + reverse_copy(begin, i, reinterpret_cast<Byte*>(&v)); +#else + copy(begin, i, reinterpret_cast<Byte*>(&v)); +#endif +} + +void +IceInternal::IntStream::read(vector<Double>& v) +{ + Int sz; + read(sz); + Container::iterator begin = i; + i += sz * sizeof(Double); + if (i > b.end()) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + v.resize(sz); +#ifdef ICE_BIGENDIAN + for (int j = 0 ; j < sz ; ++j) + { + reverse_copy(begin, begin + sizeof(Double), reinterpret_cast<Byte*>(&v[j])); + begin += sizeof(Double); + } +#else + copy(begin, i, reinterpret_cast<Byte*>(v.begin())); +#endif +} + +void +IceInternal::IntStream::write(const string& v) +{ + map<string, Int>::const_iterator p = _encapsStack.back().stringsWritten.find(v); + if (p != _encapsStack.back().stringsWritten.end()) + { + write(p->second); + } + else + { + write(Int(-1)); + int pos = b.size(); + resize(pos + v.size() + 1); + copy(v.begin(), v.end(), b.begin() + pos); + b.back() = 0; + Int sz = _encapsStack.back().stringsWritten.size(); + _encapsStack.back().stringsWritten[v] = sz; + } +} + +void +IceInternal::IntStream::write(const char* v) +{ + write(string(v)); +} + +void +IceInternal::IntStream::write(const vector<string>& v) +{ + write(Int(v.size())); + vector<string>::const_iterator p; + for (p = v.begin(); p != v.end(); ++p) + { + write(*p); + } +} + +void +IceInternal::IntStream::read(string& v) +{ + Int idx; + read(idx); + + if (idx >= 0) + { + if (static_cast<vector<string>::size_type>(idx) >= _encapsStack.back().stringsRead.size()) + { + throw StringEncodingException(__FILE__, __LINE__); + } + v = _encapsStack.back().stringsRead[idx]; + } + else if(idx == -1) + { + Container::iterator begin = i; + do + { + if (i >= b.end()) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + } + while (*i++); + v = begin; + _encapsStack.back().stringsRead.push_back(v); + } + else + { + throw StringEncodingException(__FILE__, __LINE__); + } +} + +void +IceInternal::IntStream::read(vector<string>& v) +{ + Int sz; + read(sz); + // Don't use v.resize(sz) or v.reserve(sz) here, as it cannot be + // checked whether sz is a reasonable value + while (sz--) + { +#ifdef WIN32 // STLBUG + v.push_back(string()); +#else + v.push_back(); +#endif + read(v.back()); + } +} + +void +IceInternal::IntStream::write(const wstring& v) +{ + map<wstring, Int>::const_iterator p = _encapsStack.back().wstringsWritten.find(v); + if (p != _encapsStack.back().wstringsWritten.end()) + { + write(p->second); + } + else + { + write(Int(-1)); + wstring::const_iterator p; + for (p = v.begin(); p != v.end(); ++p) + { + write(static_cast<Short>(*p)); + } + write(Short(0)); + Int sz = _encapsStack.back().wstringsWritten.size(); + _encapsStack.back().wstringsWritten[v] = sz; + } +} + +void +IceInternal::IntStream::write(const vector<wstring>& v) +{ + write(Int(v.size())); + vector<wstring>::const_iterator p; + for (p = v.begin(); p != v.end(); ++p) + { + write(*p); + } +} + +void +IceInternal::IntStream::read(wstring& v) +{ + Int idx; + read(idx); + + if (idx >= 0) + { + if (static_cast<vector<string>::size_type>(idx) >= _encapsStack.back().wstringsRead.size()) + { + throw StringEncodingException(__FILE__, __LINE__); + } + v = _encapsStack.back().wstringsRead[idx]; + } + else if(idx == -1) + { + v.erase(); + while (true) + { + Short s; + read(s); + if (!s) + { + break; + } + v += static_cast<wchar_t>(s); + } + _encapsStack.back().wstringsRead.push_back(v); + } + else + { + throw StringEncodingException(__FILE__, __LINE__); + } +} + +void +IceInternal::IntStream::write(const wchar_t* v) +{ + write(wstring(v)); +} + +void +IceInternal::IntStream::read(vector<wstring>& v) +{ + Int sz; + read(sz); + // Don't use v.resize(sz) or v.reserve(sz) here, as it cannot be + // checked whether sz is a reasonable value + while (sz--) + { +#ifdef WIN32 // STLBUG + v.push_back(wstring()); +#else + v.push_back(); +#endif + read(v.back()); + } +} + +void +IceInternal::IntStream::write(const ObjectPrx& v) +{ + _instance->proxyFactory()->proxyToStream(v, this); +} + +void +IceInternal::IntStream::read(ObjectPrx& v) +{ + v = _instance->proxyFactory()->streamToProxy(this); +} + +void +IceInternal::IntStream::write(const ObjectPtr& v) +{ + const string* classIds = v->_classIds(); + Int sz = 0; + while (classIds[sz] != "::Ice::Object") + { + ++sz; + } + write(sz); + for (int i = 0; i < sz; i++) + { + write(classIds[i]); + } + v->__write(this); +} + +void +IceInternal::IntStream::read(ObjectPtr& v, const string& type) +{ + vector<string> classIds; + read(classIds); + classIds.push_back("::Ice::Object"); + vector<string>::const_iterator p; + for (p = classIds.begin(); p != classIds.end(); ++p) + { + ServantFactoryPtr factory = _instance->servantFactoryManager()->find(*p); + + if (factory) + { + v = factory->create(*p); + v->__read(this); + + for (; p != classIds.end(); ++p) + { + if (*p == type) + { + return; + } + } + + throw ServantUnmarshalException(__FILE__, __LINE__); + } + + if (*p == type) + { + return; + } + + skipEncaps(); + } + + throw ServantUnmarshalException(__FILE__, __LINE__); +} |