diff options
author | Marc Laukien <marc@zeroc.com> | 2001-08-14 11:52:47 +0000 |
---|---|---|
committer | Marc Laukien <marc@zeroc.com> | 2001-08-14 11:52:47 +0000 |
commit | 91a394a09d9684d20cfa4c941cebb6b3579b9666 (patch) | |
tree | eb99bdac118a23814e1dfcd8d4e5fc64a9c8f0cc /cpp/src/Ice/Stream.cpp | |
parent | locator (diff) | |
download | ice-91a394a09d9684d20cfa4c941cebb6b3579b9666.tar.bz2 ice-91a394a09d9684d20cfa4c941cebb6b3579b9666.tar.xz ice-91a394a09d9684d20cfa4c941cebb6b3579b9666.zip |
changed directory structure
Diffstat (limited to 'cpp/src/Ice/Stream.cpp')
-rw-r--r-- | cpp/src/Ice/Stream.cpp | 857 |
1 files changed, 857 insertions, 0 deletions
diff --git a/cpp/src/Ice/Stream.cpp b/cpp/src/Ice/Stream.cpp new file mode 100644 index 00000000000..adc744616fa --- /dev/null +++ b/cpp/src/Ice/Stream.cpp @@ -0,0 +1,857 @@ +// ********************************************************************** +// +// Copyright (c) 2001 +// MutableRealms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#include <Ice/Stream.h> +#include <Ice/Instance.h> +#include <Ice/Object.h> +#include <Ice/ValueFactory.h> +#include <Ice/ValueFactoryManager.h> +#include <Ice/LocalException.h> + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +static const Byte stringEncodingNormal = 0; +static const Byte stringEncodingRedirect = 1; + +IceInternal::Stream::Stream(const InstancePtr& instance) : + _instance(instance), + _bigendian(false), + _stringSet(CmpPosPos(b)) +{ +} + +InstancePtr +IceInternal::Stream::instance() const +{ + return _instance; +} + +void +IceInternal::Stream::swap(Stream& other) +{ + b.swap(other.b); + std::swap(i, other.i); + std::swap(_bigendian, other._bigendian); +} + +void +IceInternal::Stream::resize(int total) +{ + if (total > 1024 * 1024) // TODO: configurable + { + throw ::Ice::MemoryLimitException(__FILE__, __LINE__); + } + + b.resize(total); +} + +void +IceInternal::Stream::reserve(int total) +{ + if (total > 1024 * 1024) // TODO: configurable + { + throw ::Ice::MemoryLimitException(__FILE__, __LINE__); + } + + b.reserve(total); +} + +void +IceInternal::Stream::pushBigendian(bool bigendian) +{ + _bigendianStack.push(bigendian); + _bigendian = _bigendianStack.top(); +} + +void +IceInternal::Stream::popBigendian() +{ + _bigendianStack.pop(); + if (!_bigendianStack.empty()) + { + _bigendian = _bigendianStack.top(); + } + else + { + _bigendian = false; + } +} + +bool +IceInternal::Stream::bigendian() const +{ + return _bigendian; +} + +void +IceInternal::Stream::startWriteEncaps() +{ + write(_bigendian); + write(Byte(0)); // Encoding version + write(Int(0)); // Placeholder for the encapsulation length + _encapsStartStack.push(b.size()); +} + +void +IceInternal::Stream::endWriteEncaps() +{ + int start = _encapsStartStack.top(); + _encapsStartStack.pop(); + Int sz = b.size() - start; + const Byte* p = reinterpret_cast<const Byte*>(&sz); + copy(p, p + sizeof(Int), b.begin() + start - sizeof(Int)); +} + +void +IceInternal::Stream::startReadEncaps() +{ + bool bigendian; + read(bigendian); + pushBigendian(bigendian); + + // + // If in the future several encoding versions are supported, we + // need a pushEncoding() and popEncoding() operation, just like + // pushBigendian() and popBigendian(). + // + Byte encVer; + read(encVer); + if (encVer != 0) + { + throw UnsupportedEncodingException(__FILE__, __LINE__); + } + + Int sz; + read(sz); + _encapsStartStack.push(i - b.begin()); +} + +void +IceInternal::Stream::endReadEncaps() +{ + int start = _encapsStartStack.top(); + _encapsStartStack.pop(); + 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__); + } + popBigendian(); +} + +void +IceInternal::Stream::skipEncaps() +{ + bool bigendian; + read(bigendian); + pushBigendian(bigendian); + Byte encVer; + read(encVer); + + Int sz; + read(sz); + i += sz; + if (i >= b.end()) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + + popBigendian(); +} + +void +IceInternal::Stream::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); + copy(p, p + sizeof(Int), b.begin() + pos); + copy(v.begin(), v.end(), b.begin() + pos + sizeof(Int)); +} + +void +IceInternal::Stream::read(Byte& v) +{ + if (i >= b.end()) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + + v = *i++; +} + +void +IceInternal::Stream::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::Stream::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); + copy(p, p + sizeof(Int), b.begin() + pos); + copy(v.begin(), v.end(), b.begin() + pos + sizeof(Int)); +} + +void +IceInternal::Stream::read(bool& v) +{ + if (i >= b.end()) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + + v = *i++; +} + +void +IceInternal::Stream::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::Stream::write(Short v) +{ + int pos = b.size(); + resize(pos + sizeof(Short)); + const Byte* p = reinterpret_cast<const Byte*>(&v); + copy(p, p + sizeof(Short), b.begin() + pos); +} + +void +IceInternal::Stream::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); + 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)); +} + +void +IceInternal::Stream::read(Short& v) +{ + Container::iterator begin = i; + i += sizeof(Short); + if (i > b.end()) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + + if (_bigendian != ::IceInternal::bigendian) + { + reverse_copy(begin, i, reinterpret_cast<Byte*>(&v)); + } + else + { + copy(begin, i, reinterpret_cast<Byte*>(&v)); + } +} + +void +IceInternal::Stream::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); + if (_bigendian != ::IceInternal::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())); + } +} + +void +IceInternal::Stream::write(Int v) +{ + int pos = b.size(); + resize(pos + sizeof(Int)); + const Byte* p = reinterpret_cast<const Byte*>(&v); + copy(p, p + sizeof(Int), b.begin() + pos); +} + +void +IceInternal::Stream::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); + 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)); +} + +void +IceInternal::Stream::read(Int& v) +{ + Container::iterator begin = i; + i += sizeof(Int); + if (i > b.end()) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + + if (_bigendian != ::IceInternal::bigendian) + { + reverse_copy(begin, i, reinterpret_cast<Byte*>(&v)); + } + else + { + copy(begin, i, reinterpret_cast<Byte*>(&v)); + } +} + +void +IceInternal::Stream::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); + if (_bigendian != ::IceInternal::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())); + } +} + +void +IceInternal::Stream::write(Long v) +{ + int pos = b.size(); + resize(pos + sizeof(Long)); + const Byte* p = reinterpret_cast<const Byte*>(&v); + copy(p, p + sizeof(Long), b.begin() + pos); +} + +void +IceInternal::Stream::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); + 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)); +} + +void +IceInternal::Stream::read(Long& v) +{ + Container::iterator begin = i; + i += sizeof(Long); + if (i > b.end()) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + + if (_bigendian != ::IceInternal::bigendian) + { + reverse_copy(begin, i, reinterpret_cast<Byte*>(&v)); + } + else + { + copy(begin, i, reinterpret_cast<Byte*>(&v)); + } +} + +void +IceInternal::Stream::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); + if (_bigendian != ::IceInternal::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())); + } +} + +void +IceInternal::Stream::write(Float v) +{ + int pos = b.size(); + resize(pos + sizeof(Float)); + const Byte* p = reinterpret_cast<const Byte*>(&v); + copy(p, p + sizeof(Float), b.begin() + pos); +} + +void +IceInternal::Stream::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); + 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)); +} + +void +IceInternal::Stream::read(Float& v) +{ + Container::iterator begin = i; + i += sizeof(Float); + if (i > b.end()) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + + if (_bigendian != ::IceInternal::bigendian) + { + reverse_copy(begin, i, reinterpret_cast<Byte*>(&v)); + } + else + { + copy(begin, i, reinterpret_cast<Byte*>(&v)); + } +} + +void +IceInternal::Stream::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); + if (_bigendian != ::IceInternal::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())); + } +} + +void +IceInternal::Stream::write(Double v) +{ + int pos = b.size(); + resize(pos + sizeof(Double)); + const Byte* p = reinterpret_cast<const Byte*>(&v); + copy(p, p + sizeof(Double), b.begin() + pos); +} + +void +IceInternal::Stream::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); + 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)); +} + +void +IceInternal::Stream::read(Double& v) +{ + Container::iterator begin = i; + i += sizeof(Double); + if (i > b.end()) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + + if (_bigendian != ::IceInternal::bigendian) + { + reverse_copy(begin, i, reinterpret_cast<Byte*>(&v)); + } + else + { + copy(begin, i, reinterpret_cast<Byte*>(&v)); + } +} + +void +IceInternal::Stream::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); + if (_bigendian != ::IceInternal::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())); + } +} + +void +IceInternal::Stream::write(const string& v) +{ + pair<multiset<int, CmpPosPos>::const_iterator, multiset<int, CmpPosPos>::const_iterator> p = + equal_range(_stringSet.begin(), _stringSet.end(), v, CmpPosString(b)); + if (p.first != p.second) + { + write(stringEncodingRedirect); + Int diff = b.size() - *p.first; + write(diff); + } + else + { + write(stringEncodingNormal); + int pos = b.size(); + resize(pos + v.size() + 1); + copy(v.begin(), v.end(), b.begin() + pos); + b.back() = 0; + _stringSet.insert(pos); + } +} + +void +IceInternal::Stream::write(const char* v) +{ + write(stringEncodingNormal); + int pos = b.size(); + int len = strlen(v); + resize(pos + len + 1); + copy(v, v + len + 1, b.begin() + pos); + _stringSet.insert(pos); +} + +void +IceInternal::Stream::write(const vector<string>& v) +{ + write(Ice::Int(v.size())); + vector<string>::const_iterator p; + for (p = v.begin(); p != v.end(); ++p) + { + write(*p); + } +} + +void +IceInternal::Stream::read(string& v) +{ + Byte stringEnc; + read(stringEnc); + + switch (stringEnc) + { + case stringEncodingNormal: + { + Container::iterator begin = i; + do + { + if (i >= b.end()) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + } + while (*i++); + v = begin; + _stringSet.insert(begin - b.begin()); + break; + } + + case stringEncodingRedirect: + { + Int diff; + read(diff); + Container::iterator j = i - 4 - diff; + Container::iterator begin = j; + if (j < b.begin()) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + + do + { + if (j >= b.end()) + { + throw UnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + } + while (*j++); + v = begin; + break; + } + + default: + { + throw StringEncodingException(__FILE__, __LINE__); + } + } +} + +void +IceInternal::Stream::read(vector<string>& v) +{ + Ice::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::Stream::write(const wstring& v) +{ + write(stringEncodingNormal); + wstring::const_iterator p; + for (p = v.begin(); p != v.end(); ++p) + { + write(static_cast<Short>(*p)); + } + write(Short(0)); +} + +void +IceInternal::Stream::write(const vector<wstring>& v) +{ + write(Ice::Int(v.size())); + vector<wstring>::const_iterator p; + for (p = v.begin(); p != v.end(); ++p) + { + write(*p); + } +} + +void +IceInternal::Stream::read(wstring& v) +{ + Byte stringEnc; + read(stringEnc); + if (stringEnc != stringEncodingNormal) + { + throw StringEncodingException(__FILE__, __LINE__); + } + + // TODO: This can be optimized + while (true) + { + Short s; + read(s); + if (!s) + break; + v += static_cast<wchar_t>(s); + } +} + +void +IceInternal::Stream::read(vector<wstring>& v) +{ + Ice::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::Stream::write(const ObjectPtr& v) +{ + const string* classIds = v->_classIds(); + Ice::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::Stream::read(ObjectPtr& v, const string& signatureType) +{ + vector<string> classIds; + read(classIds); + classIds.push_back("::Ice::Object"); + vector<string>::const_iterator p; + for (p = classIds.begin(); p != classIds.end(); ++p) + { + ValueFactoryPtr factory = _instance->valueFactoryManager()->lookup(*p); + + if (factory) + { + v = factory->create(*p); + v->__read(this); + + for (; p != classIds.end(); ++p) + { + if (*p == signatureType) + { + return; + } + } + + throw ValueUnmarshalException(__FILE__, __LINE__); + } + + if (*p == signatureType) + { + return; + } + + skipEncaps(); + } + + throw ValueUnmarshalException(__FILE__, __LINE__); +} + +IceInternal::Stream::CmpPosPos::CmpPosPos(const Container& cont) : + _cont(cont) +{ +} + +bool +IceInternal::Stream::CmpPosPos::operator()(int p, int q) const +{ + return strcmp(_cont.begin() + p, _cont.begin() + q) < 0; +} + +IceInternal::Stream::CmpPosString::CmpPosString(const Container& cont) : + _cont(cont) +{ +} + +bool +IceInternal::Stream::CmpPosString::operator()(int i, const string& s) const +{ + return _cont.begin() + i < s; +} + +bool +IceInternal::Stream::CmpPosString::operator()(const string& s, int i) const +{ + return s < _cont.begin() + i; +} |