summaryrefslogtreecommitdiff
path: root/cppe/src/IceE/BasicStream.cpp
diff options
context:
space:
mode:
authorDwayne Boone <dwayne@zeroc.com>2005-07-05 11:09:55 +0000
committerDwayne Boone <dwayne@zeroc.com>2005-07-05 11:09:55 +0000
commit9b8cc712d4a41d71840416776bc94ee8485bb9b3 (patch)
tree7d467fdd6a66bc2b5878d82070d45adbd5c20414 /cppe/src/IceE/BasicStream.cpp
parentcleaning the cache method out of ReferenceFactory (diff)
downloadice-9b8cc712d4a41d71840416776bc94ee8485bb9b3.tar.bz2
ice-9b8cc712d4a41d71840416776bc94ee8485bb9b3.tar.xz
ice-9b8cc712d4a41d71840416776bc94ee8485bb9b3.zip
Changed Ice to IceE EVERYWHERE!!!
Diffstat (limited to 'cppe/src/IceE/BasicStream.cpp')
-rw-r--r--cppe/src/IceE/BasicStream.cpp1409
1 files changed, 1409 insertions, 0 deletions
diff --git a/cppe/src/IceE/BasicStream.cpp b/cppe/src/IceE/BasicStream.cpp
new file mode 100644
index 00000000000..1633774379b
--- /dev/null
+++ b/cppe/src/IceE/BasicStream.cpp
@@ -0,0 +1,1409 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICEE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <IceE/BasicStream.h>
+#include <IceE/Instance.h>
+#include <IceE/Proxy.h>
+#include <IceE/ProxyFactory.h>
+#include <IceE/UserExceptionFactory.h>
+#include <IceE/LocalException.h>
+#include <IceE/Protocol.h>
+#include <IceE/FactoryTable.h>
+#include <IceE/LoggerUtil.h>
+
+using namespace std;
+using namespace IceE;
+using namespace IceEInternal;
+
+IceEInternal::BasicStream::BasicStream(Instance* instance) :
+ _instance(instance),
+ _currentReadEncaps(0),
+ _currentWriteEncaps(0),
+ _messageSizeMax(_instance->messageSizeMax()), // Cached for efficiency.
+ _seqDataStack(0)
+{
+}
+
+IceEInternal::BasicStream::~BasicStream()
+{
+ while(_currentReadEncaps && _currentReadEncaps != &_preAllocatedReadEncaps)
+ {
+ ReadEncaps* oldEncaps = _currentReadEncaps;
+ _currentReadEncaps = _currentReadEncaps->previous;
+ delete oldEncaps;
+ }
+
+ while(_currentWriteEncaps && _currentWriteEncaps != &_preAllocatedWriteEncaps)
+ {
+ WriteEncaps* oldEncaps = _currentWriteEncaps;
+ _currentWriteEncaps = _currentWriteEncaps->previous;
+ delete oldEncaps;
+ }
+
+ while(_seqDataStack)
+ {
+ SeqData* oldSeqData = _seqDataStack;
+ _seqDataStack = _seqDataStack->previous;
+ delete oldSeqData;
+ }
+}
+
+Instance*
+IceEInternal::BasicStream::instance() const
+{
+ return _instance;
+}
+
+void
+IceEInternal::BasicStream::swap(BasicStream& other)
+{
+ assert(_instance == other._instance);
+
+ Buffer::swap(other);
+
+ //
+ // Swap is never called for BasicStreams that have more than one
+ // encaps.
+ //
+ assert(!_currentReadEncaps || _currentReadEncaps == &_preAllocatedReadEncaps);
+ assert(!_currentWriteEncaps || _currentWriteEncaps == &_preAllocatedWriteEncaps);
+ assert(!other._currentReadEncaps || other._currentReadEncaps == &other._preAllocatedReadEncaps);
+ assert(!other._currentWriteEncaps || other._currentWriteEncaps == &other._preAllocatedWriteEncaps);
+
+ if(_currentReadEncaps || other._currentReadEncaps)
+ {
+ _preAllocatedReadEncaps.swap(other._preAllocatedReadEncaps);
+
+ if(!_currentReadEncaps)
+ {
+ _currentReadEncaps = &_preAllocatedReadEncaps;
+ other._currentReadEncaps = 0;
+ }
+ else if(!other._currentReadEncaps)
+ {
+ other._currentReadEncaps = &other._preAllocatedReadEncaps;
+ _currentReadEncaps = 0;
+ }
+ }
+
+ if(_currentWriteEncaps || other._currentWriteEncaps)
+ {
+ _preAllocatedWriteEncaps.swap(other._preAllocatedWriteEncaps);
+
+ if(!_currentWriteEncaps)
+ {
+ _currentWriteEncaps = &_preAllocatedWriteEncaps;
+ other._currentWriteEncaps = 0;
+ }
+ else if(!other._currentWriteEncaps)
+ {
+ other._currentWriteEncaps = &other._preAllocatedWriteEncaps;
+ _currentWriteEncaps = 0;
+ }
+ }
+
+ std::swap(_seqDataStack, other._seqDataStack);
+}
+
+//
+// startSeq() and endSeq() sanity-check sequence sizes during
+// unmarshaling and prevent malicious messages with incorrect sequence
+// sizes from causing the receiver to use up all available memory by
+// allocating sequences with an impossibly large number of elements.
+//
+// The code generator inserts calls to startSeq() and endSeq() around
+// the code to unmarshal a sequence of a variable-length type. startSeq()
+// is called immediately after reading the sequence size, and endSeq() is
+// called after reading the final element of a sequence.
+//
+// For a sequence of a fixed-length type, the code generator inserts a
+// call to checkFixedSeq(), which does not cause any memory allocations.
+//
+// For sequences that contain constructed types that, in turn, contain
+// sequences, the code generator also inserts a call to endElement()
+// (inlined in BasicStream.h) after unmarshaling each element.
+//
+// startSeq() is passed the unmarshaled element count, plus the
+// minimum size (in bytes) occupied by the sequence's element
+// type. numElements * minSize is the smallest possible number of
+// bytes that the sequence will occupy on the wire.
+//
+// Every time startSeq() is called, it pushes the element count and
+// the minimum size on a stack. Every time endSeq() is called, it pops
+// the stack.
+//
+// For an ordinary sequence (one that does not (recursively) contain
+// nested sequences), numElements * minSize must be less than the
+// number of bytes remaining in the stream.
+//
+// For a sequence that is nested within some other sequence, there
+// must be enough bytes remaining in the stream for this sequence
+// (numElements + minSize), plus the sum of the bytes required by the
+// remaining elements of all the enclosing sequences.
+//
+// For the enclosing sequences, numElements - 1 is the number of
+// elements for which unmarshaling has not started yet. (The call to
+// endElement() in the generated code decrements that number whenever
+// a sequence element is unmarshaled.)
+//
+// For sequences that have variable-length elements, checkSeq() is called
+// whenever an element is unmarshaled. checkSeq() also checks whether
+// the stream has a sufficient number of bytes remaining. This means
+// that, for messages with bogus sequence sizes, unmarshaling is
+// aborted at the earliest possible point.
+//
+
+void
+IceEInternal::BasicStream::startSeq(int numElements, int minSize)
+{
+ if(numElements == 0) // Optimization to avoid pushing a useless stack frame.
+ {
+ return;
+ }
+
+ //
+ // Push the current sequence details on the stack.
+ //
+ SeqData* sd = new SeqData(numElements, minSize);
+ sd->previous = _seqDataStack;
+ _seqDataStack = sd;
+
+ int bytesLeft = static_cast<int>(b.end() - i);
+ if(_seqDataStack->previous == 0) // Outermost sequence
+ {
+ //
+ // The sequence must fit within the message.
+ //
+ if(numElements * minSize > bytesLeft)
+ {
+ throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
+ }
+ }
+ else // Nested sequence
+ {
+ checkSeq(bytesLeft);
+ }
+}
+
+//
+// Check, given the number of elements requested for this sequence,
+// that this sequence, plus the sum of the sizes of the remaining
+// number of elements of all enclosing sequences, would still fit
+// within the message.
+//
+void
+IceEInternal::BasicStream::checkSeq()
+{
+ checkSeq(static_cast<int>(b.end() - i));
+}
+
+void
+IceEInternal::BasicStream::checkSeq(int bytesLeft)
+{
+ int size = 0;
+ SeqData* sd = _seqDataStack;
+ do
+ {
+ size += (sd->numElements - 1) * sd->minSize;
+ sd = sd->previous;
+ }
+ while(sd);
+
+ if(size > bytesLeft)
+ {
+ throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
+ }
+}
+
+void
+IceEInternal::BasicStream::checkFixedSeq(int numElements, int elemSize)
+{
+ int bytesLeft = static_cast<int>(b.end() - i);
+ if(_seqDataStack == 0) // Outermost sequence
+ {
+ //
+ // The sequence must fit within the message.
+ //
+ if(numElements * elemSize > bytesLeft)
+ {
+ throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
+ }
+ }
+ else // Nested sequence
+ {
+ checkSeq(bytesLeft - numElements * elemSize);
+ }
+}
+
+void
+IceEInternal::BasicStream::endSeq(int sz)
+{
+ if(sz == 0) // Pop only if something was pushed previously.
+ {
+ return;
+ }
+
+ //
+ // Pop the sequence stack.
+ //
+ SeqData* oldSeqData = _seqDataStack;
+ assert(oldSeqData);
+ _seqDataStack = oldSeqData->previous;
+ delete oldSeqData;
+}
+
+IceEInternal::BasicStream::WriteEncaps::WriteEncaps()
+ : writeIndex(0), previous(0)
+{
+}
+
+IceEInternal::BasicStream::WriteEncaps::~WriteEncaps()
+{
+}
+
+void
+IceEInternal::BasicStream::WriteEncaps::reset()
+{
+ writeIndex = 0;
+ previous = 0;
+}
+
+void
+IceEInternal::BasicStream::WriteEncaps::swap(WriteEncaps& other)
+{
+ std::swap(start, other.start);
+
+ std::swap(writeIndex, other.writeIndex);
+ std::swap(previous, other.previous);
+}
+
+void
+IceEInternal::BasicStream::startWriteEncaps()
+{
+ WriteEncaps* oldEncaps = _currentWriteEncaps;
+ if(!oldEncaps) // First allocated encaps?
+ {
+ _currentWriteEncaps = &_preAllocatedWriteEncaps;
+ }
+ else
+ {
+ _currentWriteEncaps = new WriteEncaps();
+ _currentWriteEncaps->previous = oldEncaps;
+ }
+ _currentWriteEncaps->start = b.size();
+
+ write(Int(0)); // Placeholder for the encapsulation length.
+ write(encodingMajor);
+ write(encodingMinor);
+}
+
+void
+IceEInternal::BasicStream::endWriteEncaps()
+{
+ assert(_currentWriteEncaps);
+ Container::size_type start = _currentWriteEncaps->start;
+ Int sz = static_cast<Int>(b.size() - start); // Size includes size and version.
+ Byte* dest = &(*(b.begin() + start));
+
+#ifdef ICEE_BIG_ENDIAN
+ const Byte* src = reinterpret_cast<const Byte*>(&sz) + sizeof(Int) - 1;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest = *src;
+#else
+ const Byte* src = reinterpret_cast<const Byte*>(&sz);
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest = *src;
+#endif
+
+ WriteEncaps* oldEncaps = _currentWriteEncaps;
+ _currentWriteEncaps = _currentWriteEncaps->previous;
+ if(oldEncaps == &_preAllocatedWriteEncaps)
+ {
+ oldEncaps->reset();
+ }
+ else
+ {
+ delete oldEncaps;
+ }
+}
+
+IceEInternal::BasicStream::ReadEncaps::ReadEncaps()
+ : previous(0)
+{
+}
+
+IceEInternal::BasicStream::ReadEncaps::~ReadEncaps()
+{
+}
+
+void
+IceEInternal::BasicStream::ReadEncaps::reset()
+{
+ previous = 0;
+}
+
+void
+IceEInternal::BasicStream::ReadEncaps::swap(ReadEncaps& other)
+{
+ std::swap(start, other.start);
+ std::swap(sz, other.sz);
+
+ std::swap(encodingMajor, other.encodingMajor);
+ std::swap(encodingMinor, other.encodingMinor);
+
+ std::swap(previous, other.previous);
+}
+
+void
+IceEInternal::BasicStream::startReadEncaps()
+{
+ ReadEncaps* oldEncaps = _currentReadEncaps;
+ if(!oldEncaps) // First allocated encaps?
+ {
+ _currentReadEncaps = &_preAllocatedReadEncaps;
+ }
+ else
+ {
+ _currentReadEncaps = new ReadEncaps();
+ _currentReadEncaps->previous = oldEncaps;
+ }
+ _currentReadEncaps->start = i - b.begin();
+
+ //
+ // I don't use readSize() and writeSize() for encapsulations,
+ // because when creating an encapsulation, I must know in advance
+ // how many bytes the size information will require in the data
+ // stream. If I use an Int, it is always 4 bytes. For
+ // readSize()/writeSize(), it could be 1 or 5 bytes.
+ //
+ Int sz;
+ read(sz);
+ if(sz < 0)
+ {
+ throw NegativeSizeException(__FILE__, __LINE__);
+ }
+ if(i - sizeof(Int) + sz > b.end())
+ {
+ throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
+ }
+ _currentReadEncaps->sz = sz;
+
+ Byte eMajor;
+ Byte eMinor;
+ read(eMajor);
+ read(eMinor);
+ if(eMajor != encodingMajor
+ || static_cast<unsigned char>(eMinor) > static_cast<unsigned char>(encodingMinor))
+ {
+ UnsupportedEncodingException ex(__FILE__, __LINE__);
+ ex.badMajor = static_cast<unsigned char>(eMajor);
+ ex.badMinor = static_cast<unsigned char>(eMinor);
+ ex.major = static_cast<unsigned char>(encodingMajor);
+ ex.minor = static_cast<unsigned char>(encodingMinor);
+ throw ex;
+ }
+ _currentReadEncaps->encodingMajor = eMajor;
+ _currentReadEncaps->encodingMinor = eMinor;
+}
+
+void
+IceEInternal::BasicStream::endReadEncaps()
+{
+ assert(_currentReadEncaps);
+ Container::size_type start = _currentReadEncaps->start;
+ Int sz = _currentReadEncaps->sz;
+ i = b.begin() + start + sz;
+
+ ReadEncaps* oldEncaps = _currentReadEncaps;
+ _currentReadEncaps = _currentReadEncaps->previous;
+ if(oldEncaps == &_preAllocatedReadEncaps)
+ {
+ oldEncaps->reset();
+ }
+ else
+ {
+ delete oldEncaps;
+ }
+}
+
+void
+IceEInternal::BasicStream::checkReadEncaps()
+{
+ assert(_currentReadEncaps);
+ Container::size_type start = _currentReadEncaps->start;
+ Int sz = _currentReadEncaps->sz;
+ if(i != b.begin() + start + sz)
+ {
+ throw EncapsulationException(__FILE__, __LINE__);
+ }
+}
+
+Int
+IceEInternal::BasicStream::getReadEncapsSize()
+{
+ assert(_currentReadEncaps);
+ return _currentReadEncaps->sz - static_cast<Int>(sizeof(Int)) - 2;
+}
+
+void
+IceEInternal::BasicStream::skipEncaps()
+{
+ Int sz;
+ read(sz);
+ if(sz < 0)
+ {
+ throw NegativeSizeException(__FILE__, __LINE__);
+ }
+ if(i - sizeof(Int) + sz > b.end())
+ {
+ throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
+ }
+ i += sz - sizeof(Int);
+}
+
+void
+IceEInternal::BasicStream::startWriteSlice()
+{
+ write(Int(0)); // Placeholder for the slice length.
+ _writeSlice = b.size();
+}
+
+void
+IceEInternal::BasicStream::endWriteSlice()
+{
+ Int sz = static_cast<Int>(b.size() - _writeSlice + sizeof(Int));
+ Byte* dest = &(*(b.begin() + _writeSlice - sizeof(Int)));
+#ifdef ICEE_BIG_ENDIAN
+ const Byte* src = reinterpret_cast<const Byte*>(&sz) + sizeof(Int) - 1;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest = *src;
+#else
+ const Byte* src = reinterpret_cast<const Byte*>(&sz);
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest = *src;
+#endif
+}
+
+void
+IceEInternal::BasicStream::startReadSlice()
+{
+ Int sz;
+ read(sz);
+ if(sz < 0)
+ {
+ throw NegativeSizeException(__FILE__, __LINE__);
+ }
+ _readSlice = i - b.begin();
+}
+
+void
+IceEInternal::BasicStream::endReadSlice()
+{
+}
+
+void
+IceEInternal::BasicStream::skipSlice()
+{
+ Int sz;
+ read(sz);
+ if(sz < 0)
+ {
+ throw NegativeSizeException(__FILE__, __LINE__);
+ }
+ i += sz - sizeof(Int);
+ if(i > b.end())
+ {
+ throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
+ }
+}
+
+void
+IceEInternal::BasicStream::writeSize(Int v)
+{
+ assert(v >= 0);
+ if(v > 254)
+ {
+ write(Byte(255));
+ write(v);
+ }
+ else
+ {
+ write(static_cast<Byte>(v));
+ }
+}
+
+void
+IceEInternal::BasicStream::readSize(IceE::Int& v)
+{
+ Byte byte;
+ read(byte);
+ unsigned val = static_cast<unsigned char>(byte);
+ if(val == 255)
+ {
+ read(v);
+ if(v < 0)
+ {
+ throw NegativeSizeException(__FILE__, __LINE__);
+ }
+ }
+ else
+ {
+ v = static_cast<Int>(static_cast<unsigned char>(byte));
+ }
+}
+
+void
+IceEInternal::BasicStream::writeBlob(const vector<Byte>& v)
+{
+ if(!v.empty())
+ {
+ Container::size_type pos = b.size();
+ resize(pos + v.size());
+ memcpy(&b[pos], &v[0], v.size());
+ }
+}
+
+void
+IceEInternal::BasicStream::readBlob(vector<Byte>& v, Int sz)
+{
+ if(sz > 0)
+ {
+ if(b.end() - i < sz)
+ {
+ throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
+ }
+ vector<Byte>(i, i + sz).swap(v);
+ i += sz;
+ }
+ else
+ {
+ v.clear();
+ }
+}
+
+void
+IceEInternal::BasicStream::writeBlob(const IceE::Byte* v, Container::size_type sz)
+{
+ if(sz > 0)
+ {
+ Container::size_type pos = b.size();
+ resize(pos + sz);
+ memcpy(&b[pos], v, sz);
+ }
+}
+
+void
+IceEInternal::BasicStream::readBlob(IceE::Byte* v, Container::size_type sz)
+{
+ if(sz > 0)
+ {
+ if(static_cast<Container::size_type>(b.end() - i) < sz)
+ {
+ throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
+ }
+ memcpy(v, &*i, sz);
+ i += sz;
+ }
+}
+
+void
+IceEInternal::BasicStream::read(vector<Byte>& v)
+{
+ Int sz;
+ readSize(sz);
+ if(sz > 0)
+ {
+ checkFixedSeq(sz, 1);
+ vector<Byte>(i, i + sz).swap(v);
+ i += sz;
+ }
+ else
+ {
+ v.clear();
+ }
+}
+
+void
+IceEInternal::BasicStream::write(const vector<Byte>& v)
+{
+ Int sz = static_cast<Int>(v.size());
+ writeSize(sz);
+ if(sz > 0)
+ {
+ Container::size_type pos = b.size();
+ resize(pos + sz);
+ memcpy(&b[pos], &v[0], sz);
+ }
+}
+
+void
+IceEInternal::BasicStream::write(const vector<bool>& v)
+{
+ Int sz = static_cast<Int>(v.size());
+ writeSize(sz);
+ if(sz > 0)
+ {
+ Container::size_type pos = b.size();
+ resize(pos + sz);
+ copy(v.begin(), v.end(), b.begin() + pos);
+ }
+}
+
+void
+IceEInternal::BasicStream::read(vector<bool>& v)
+{
+ Int sz;
+ readSize(sz);
+ if(sz > 0)
+ {
+ checkFixedSeq(sz, 1);
+ v.resize(sz);
+ copy(i, i + sz, v.begin());
+ i += sz;
+ }
+ else
+ {
+ v.clear();
+ }
+}
+
+void
+IceEInternal::BasicStream::write(Short v)
+{
+ Container::size_type pos = b.size();
+ resize(pos + sizeof(Short));
+ Byte* dest = &b[pos];
+#ifdef ICEE_BIG_ENDIAN
+ const Byte* src = reinterpret_cast<const Byte*>(&v) + sizeof(Short) - 1;
+ *dest++ = *src--;
+ *dest = *src;
+#else
+ const Byte* src = reinterpret_cast<const Byte*>(&v);
+ *dest++ = *src++;
+ *dest = *src;
+#endif
+}
+
+
+void
+IceEInternal::BasicStream::read(Short& v)
+{
+ if(b.end() - i < static_cast<int>(sizeof(Short)))
+ {
+ throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
+ }
+ const Byte* src = &(*i);
+ i += sizeof(Short);
+#ifdef ICEE_BIG_ENDIAN
+ Byte* dest = reinterpret_cast<Byte*>(&v) + sizeof(Short) - 1;
+ *dest-- = *src++;
+ *dest = *src;
+#else
+ Byte* dest = reinterpret_cast<Byte*>(&v);
+ *dest++ = *src++;
+ *dest = *src;
+#endif
+}
+
+void
+IceEInternal::BasicStream::write(const vector<Short>& v)
+{
+ Int sz = static_cast<Int>(v.size());
+ writeSize(sz);
+ if(sz > 0)
+ {
+ Container::size_type pos = b.size();
+ resize(pos + sz * sizeof(Short));
+#ifdef ICEE_BIG_ENDIAN
+ const Byte* src = reinterpret_cast<const Byte*>(&v[0]) + sizeof(Short) - 1;
+ Byte* dest = &(*(b.begin() + pos));
+ for(int j = 0 ; j < sz ; ++j)
+ {
+ *dest++ = *src--;
+ *dest++ = *src--;
+ src += 2 * sizeof(Short);
+ }
+#else
+ memcpy(&b[pos], reinterpret_cast<const Byte*>(&v[0]), sz * sizeof(Short));
+#endif
+ }
+}
+
+void
+IceEInternal::BasicStream::read(vector<Short>& v)
+{
+ Int sz;
+ readSize(sz);
+ if(sz > 0)
+ {
+ checkFixedSeq(sz, static_cast<int>(sizeof(Short)));
+ Container::iterator begin = i;
+ i += sz * static_cast<int>(sizeof(Short));
+ v.resize(sz);
+#ifdef ICEE_BIG_ENDIAN
+ const Byte* src = &(*begin);
+ Byte* dest = reinterpret_cast<Byte*>(&v[0]) + sizeof(Short) - 1;
+ for(int j = 0 ; j < sz ; ++j)
+ {
+ *dest-- = *src++;
+ *dest-- = *src++;
+ dest += 2 * sizeof(Short);
+ }
+#else
+ copy(begin, i, reinterpret_cast<Byte*>(&v[0]));
+#endif
+ }
+ else
+ {
+ v.clear();
+ }
+}
+
+void
+IceEInternal::BasicStream::write(Int v)
+{
+ Container::size_type pos = b.size();
+ resize(pos + sizeof(Int));
+ Byte* dest = &b[pos];
+#ifdef ICEE_BIG_ENDIAN
+ const Byte* src = reinterpret_cast<const Byte*>(&v) + sizeof(Int) - 1;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest = *src;
+#else
+ const Byte* src = reinterpret_cast<const Byte*>(&v);
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest = *src;
+#endif
+}
+
+void
+IceEInternal::BasicStream::read(Int& v)
+{
+ if(b.end() - i < static_cast<int>(sizeof(Int)))
+ {
+ throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
+ }
+ const Byte* src = &(*i);
+ i += sizeof(Int);
+#ifdef ICEE_BIG_ENDIAN
+ Byte* dest = reinterpret_cast<Byte*>(&v) + sizeof(Int) - 1;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest = *src;
+#else
+ Byte* dest = reinterpret_cast<Byte*>(&v);
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest = *src;
+#endif
+}
+
+void
+IceEInternal::BasicStream::write(const vector<Int>& v)
+{
+ Int sz = static_cast<Int>(v.size());
+ writeSize(sz);
+ if(sz > 0)
+ {
+ Container::size_type pos = b.size();
+ resize(pos + sz * sizeof(Int));
+#ifdef ICEE_BIG_ENDIAN
+ const Byte* src = reinterpret_cast<const Byte*>(&v[0]) + sizeof(Int) - 1;
+ Byte* dest = &(*(b.begin() + pos));
+ for(int j = 0 ; j < sz ; ++j)
+ {
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ src += 2 * sizeof(Int);
+ }
+#else
+ memcpy(&b[pos], reinterpret_cast<const Byte*>(&v[0]), sz * sizeof(Int));
+#endif
+ }
+}
+
+void
+IceEInternal::BasicStream::read(vector<Int>& v)
+{
+ Int sz;
+ readSize(sz);
+ if(sz > 0)
+ {
+ checkFixedSeq(sz, static_cast<int>(sizeof(Int)));
+ Container::iterator begin = i;
+ i += sz * static_cast<int>(sizeof(Int));
+ v.resize(sz);
+#ifdef ICEE_BIG_ENDIAN
+ const Byte* src = &(*begin);
+ Byte* dest = reinterpret_cast<Byte*>(&v[0]) + sizeof(Int) - 1;
+ for(int j = 0 ; j < sz ; ++j)
+ {
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ dest += 2 * sizeof(Int);
+ }
+#else
+ copy(begin, i, reinterpret_cast<Byte*>(&v[0]));
+#endif
+ }
+ else
+ {
+ v.clear();
+ }
+}
+
+void
+IceEInternal::BasicStream::write(Long v)
+{
+ Container::size_type pos = b.size();
+ resize(pos + sizeof(Long));
+ Byte* dest = &b[pos];
+#ifdef ICEE_BIG_ENDIAN
+ const Byte* src = reinterpret_cast<const Byte*>(&v) + sizeof(Long) - 1;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest = *src;
+#else
+ const Byte* src = reinterpret_cast<const Byte*>(&v);
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest = *src;
+#endif
+}
+
+void
+IceEInternal::BasicStream::read(Long& v)
+{
+ if(b.end() - i < static_cast<int>(sizeof(Long)))
+ {
+ throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
+ }
+ const Byte* src = &(*i);
+ i += sizeof(Long);
+#ifdef ICEE_BIG_ENDIAN
+ Byte* dest = reinterpret_cast<Byte*>(&v) + sizeof(Long) - 1;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest = *src;
+#else
+ Byte* dest = reinterpret_cast<Byte*>(&v);
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest = *src;
+#endif
+}
+
+void
+IceEInternal::BasicStream::write(const vector<Long>& v)
+{
+ Int sz = static_cast<Int>(v.size());
+ writeSize(sz);
+ if(sz > 0)
+ {
+ Container::size_type pos = b.size();
+ resize(pos + sz * sizeof(Long));
+#ifdef ICEE_BIG_ENDIAN
+ const Byte* src = reinterpret_cast<const Byte*>(&v[0]) + sizeof(Long) - 1;
+ Byte* dest = &(*(b.begin() + pos));
+ for(int j = 0 ; j < sz ; ++j)
+ {
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ src += 2 * sizeof(Long);
+ }
+#else
+ memcpy(&b[pos], reinterpret_cast<const Byte*>(&v[0]), sz * sizeof(Long));
+#endif
+ }
+}
+
+void
+IceEInternal::BasicStream::read(vector<Long>& v)
+{
+ Int sz;
+ readSize(sz);
+ if(sz > 0)
+ {
+ checkFixedSeq(sz, static_cast<int>(sizeof(Long)));
+ Container::iterator begin = i;
+ i += sz * static_cast<int>(sizeof(Long));
+ v.resize(sz);
+#ifdef ICEE_BIG_ENDIAN
+ const Byte* src = &(*begin);
+ Byte* dest = reinterpret_cast<Byte*>(&v[0]) + sizeof(Long) - 1;
+ for(int j = 0 ; j < sz ; ++j)
+ {
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ dest += 2 * sizeof(Long);
+ }
+#else
+ copy(begin, i, reinterpret_cast<Byte*>(&v[0]));
+#endif
+ }
+ else
+ {
+ v.clear();
+ }
+}
+
+void
+IceEInternal::BasicStream::write(Float v)
+{
+ Container::size_type pos = b.size();
+ resize(pos + sizeof(Float));
+ Byte* dest = &b[pos];
+#ifdef ICEE_BIG_ENDIAN
+ const Byte* src = reinterpret_cast<const Byte*>(&v) + sizeof(Float) - 1;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest = *src;
+#else
+ const Byte* src = reinterpret_cast<const Byte*>(&v);
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest = *src;
+#endif
+}
+
+void
+IceEInternal::BasicStream::read(Float& v)
+{
+ if(b.end() - i < static_cast<int>(sizeof(Float)))
+ {
+ throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
+ }
+ const Byte* src = &(*i);
+ i += sizeof(Float);
+#ifdef ICEE_BIG_ENDIAN
+ Byte* dest = reinterpret_cast<Byte*>(&v) + sizeof(Float) - 1;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest = *src;
+#else
+ Byte* dest = reinterpret_cast<Byte*>(&v);
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest = *src;
+#endif
+}
+
+void
+IceEInternal::BasicStream::write(const vector<Float>& v)
+{
+ Int sz = static_cast<Int>(v.size());
+ writeSize(sz);
+ if(sz > 0)
+ {
+ Container::size_type pos = b.size();
+ resize(pos + sz * sizeof(Float));
+#ifdef ICEE_BIG_ENDIAN
+ const Byte* src = reinterpret_cast<const Byte*>(&v[0]) + sizeof(Float) - 1;
+ Byte* dest = &(*(b.begin() + pos));
+ for(int j = 0 ; j < sz ; ++j)
+ {
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ src += 2 * sizeof(Float);
+ }
+#else
+ memcpy(&b[pos], reinterpret_cast<const Byte*>(&v[0]), sz * sizeof(Float));
+#endif
+ }
+}
+
+void
+IceEInternal::BasicStream::read(vector<Float>& v)
+{
+ Int sz;
+ readSize(sz);
+ if(sz > 0)
+ {
+ checkFixedSeq(sz, static_cast<int>(sizeof(Float)));
+ Container::iterator begin = i;
+ i += sz * static_cast<int>(sizeof(Float));
+ v.resize(sz);
+#ifdef ICEE_BIG_ENDIAN
+ const Byte* src = &(*begin);
+ Byte* dest = reinterpret_cast<Byte*>(&v[0]) + sizeof(Float) - 1;
+ for(int j = 0 ; j < sz ; ++j)
+ {
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ dest += 2 * sizeof(Float);
+ }
+#else
+ copy(begin, i, reinterpret_cast<Byte*>(&v[0]));
+#endif
+ }
+ else
+ {
+ v.clear();
+ }
+}
+
+void
+IceEInternal::BasicStream::write(Double v)
+{
+ Container::size_type pos = b.size();
+ resize(pos + sizeof(Double));
+ Byte* dest = &b[pos];
+#ifdef ICEE_BIG_ENDIAN
+ const Byte* src = reinterpret_cast<const Byte*>(&v) + sizeof(Double) - 1;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest = *src;
+#else
+ const Byte* src = reinterpret_cast<const Byte*>(&v);
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest = *src;
+#endif
+}
+
+void
+IceEInternal::BasicStream::read(Double& v)
+{
+ if(b.end() - i < static_cast<int>(sizeof(Double)))
+ {
+ throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
+ }
+ const Byte* src = &(*i);
+ i += sizeof(Double);
+#ifdef ICEE_BIG_ENDIAN
+ Byte* dest = reinterpret_cast<Byte*>(&v) + sizeof(Double) - 1;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest = *src;
+#else
+ Byte* dest = reinterpret_cast<Byte*>(&v);
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest = *src;
+#endif
+}
+
+void
+IceEInternal::BasicStream::write(const vector<Double>& v)
+{
+ Int sz = static_cast<Int>(v.size());
+ writeSize(sz);
+ if(sz > 0)
+ {
+ Container::size_type pos = b.size();
+ resize(pos + sz * sizeof(Double));
+#ifdef ICEE_BIG_ENDIAN
+ const Byte* src = reinterpret_cast<const Byte*>(&v[0]) + sizeof(Double) - 1;
+ Byte* dest = &(*(b.begin() + pos));
+ for(int j = 0 ; j < sz ; ++j)
+ {
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ src += 2 * sizeof(Double);
+ }
+#else
+ memcpy(&b[pos], reinterpret_cast<const Byte*>(&v[0]), sz * sizeof(Double));
+#endif
+ }
+}
+
+void
+IceEInternal::BasicStream::read(vector<Double>& v)
+{
+ Int sz;
+ readSize(sz);
+ if(sz > 0)
+ {
+ checkFixedSeq(sz, static_cast<int>(sizeof(Double)));
+ Container::iterator begin = i;
+ i += sz * static_cast<int>(sizeof(Double));
+ v.resize(sz);
+#ifdef ICEE_BIG_ENDIAN
+ const Byte* src = &(*begin);
+ Byte* dest = reinterpret_cast<Byte*>(&v[0]) + sizeof(Double) - 1;
+ for(int j = 0 ; j < sz ; ++j)
+ {
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ dest += 2 * sizeof(Double);
+ }
+#else
+ copy(begin, i, reinterpret_cast<Byte*>(&v[0]));
+#endif
+ }
+ else
+ {
+ v.clear();
+ }
+}
+
+//
+// NOTE: This member function is intentionally omitted in order to
+// cause a link error if it is used. This is for efficiency reasons:
+// writing a const char * requires a traversal of the string to get
+// the string length first, which takes O(n) time, whereas getting the
+// string length from a std::string takes constant time.
+//
+/*
+void
+IceEInternal::BasicStream::write(const char*)
+{
+}
+*/
+
+void
+IceEInternal::BasicStream::write(const string& v)
+{
+ Int sz = static_cast<Int>(v.size());
+ writeSize(sz);
+ if(sz > 0)
+ {
+ Container::size_type pos = b.size();
+ resize(pos + sz);
+ memcpy(&b[pos], v.c_str(), sz);
+ }
+}
+
+void
+IceEInternal::BasicStream::write(const vector<string>& v)
+{
+ Int sz = static_cast<Int>(v.size());
+ writeSize(sz);
+ if(sz > 0)
+ {
+ vector<string>::const_iterator p;
+ for(p = v.begin(); p != v.end(); ++p)
+ {
+ write(*p);
+ }
+ }
+}
+
+void
+IceEInternal::BasicStream::read(string& v)
+{
+ Int sz;
+ readSize(sz);
+ if(sz > 0)
+ {
+ if(b.end() - i < sz)
+ {
+ throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
+ }
+ string(reinterpret_cast<const char*>(&*i), reinterpret_cast<const char*>(&*i) + sz).swap(v);
+// v.assign(reinterpret_cast<const char*>(&(*i)), sz);
+ i += sz;
+ }
+ else
+ {
+ v.clear();
+ }
+}
+
+void
+IceEInternal::BasicStream::read(vector<string>& v)
+{
+ Int sz;
+ readSize(sz);
+ if(sz > 0)
+ {
+ startSeq(sz, 1);
+ v.resize(sz);
+ for(int i = 0; i < sz; ++i)
+ {
+ read(v[i]);
+ checkSeq();
+ endElement();
+ }
+ endSeq(sz);
+ }
+ else
+ {
+ v.clear();
+ }
+}
+
+void
+IceEInternal::BasicStream::write(const ObjectPrx& v)
+{
+ _instance->proxyFactory()->proxyToStream(v, this);
+}
+
+void
+IceEInternal::BasicStream::read(ObjectPrx& v)
+{
+ v = _instance->proxyFactory()->streamToProxy(this);
+}
+
+void
+IceEInternal::BasicStream::write(const UserException& v)
+{
+ write(v.__usesClasses());
+ v.__write(this);
+#ifdef never
+ if(v.__usesClasses())
+ {
+ writePendingObjects();
+ }
+#endif
+}
+
+void
+IceEInternal::BasicStream::throwException()
+{
+ bool usesClasses;
+ read(usesClasses);
+
+ string id;
+ read(id);
+ for(;;)
+ {
+ //
+ // Look for a factory for this ID.
+ //
+ UserExceptionFactoryPtr factory = factoryTable->getExceptionFactory(id);
+ if(factory)
+ {
+ //
+ // Got factory -- get the factory to instantiate the
+ // exception, initialize the exception members, and throw
+ // the exception.
+ //
+ try
+ {
+ factory->createAndThrow();
+ }
+ catch(UserException& ex)
+ {
+ ex.__read(this, false);
+ assert(!usesClasses);
+ ex.ice_throw();
+ }
+ }
+ else
+ {
+ skipSlice(); // Slice off what we don't understand.
+ read(id); // Read type id for next slice.
+ }
+ }
+
+ //
+ // The only way out of the loop above is to find an exception for
+ // which the receiver has a factory. If this does not happen,
+ // sender and receiver disagree about the Slice definitions they
+ // use. In that case, the receiver will eventually fail to read
+ // another type ID and throw a MarshalException.
+ //
+}
+
+void
+IceEInternal::BasicStream::throwUnmarshalOutOfBoundsException(const char* file, int line)
+{
+ throw UnmarshalOutOfBoundsException(file, line);
+}
+
+void
+IceEInternal::BasicStream::throwMemoryLimitException(const char* file, int line)
+{
+ throw MemoryLimitException(file, line);
+}
+
+IceEInternal::BasicStream::SeqData::SeqData(int num, int sz) : numElements(num), minSize(sz)
+{
+}