summaryrefslogtreecommitdiff
path: root/cpp/src/Ice/BasicStream.cpp
diff options
context:
space:
mode:
authorMark Spruiell <mes@zeroc.com>2016-01-19 16:46:11 -0800
committerMark Spruiell <mes@zeroc.com>2016-01-19 16:46:11 -0800
commitd5dd7c866e9e1dc59dc7e127eb39f641530bf823 (patch)
tree61771e4f322a7138b643d5325a6d10acea30fb84 /cpp/src/Ice/BasicStream.cpp
parentDeprecate ice_name and add ice_id (diff)
downloadice-d5dd7c866e9e1dc59dc7e127eb39f641530bf823.tar.bz2
ice-d5dd7c866e9e1dc59dc7e127eb39f641530bf823.tar.xz
ice-d5dd7c866e9e1dc59dc7e127eb39f641530bf823.zip
ICE-6861 - removing public stream API
Diffstat (limited to 'cpp/src/Ice/BasicStream.cpp')
-rw-r--r--cpp/src/Ice/BasicStream.cpp3441
1 files changed, 0 insertions, 3441 deletions
diff --git a/cpp/src/Ice/BasicStream.cpp b/cpp/src/Ice/BasicStream.cpp
deleted file mode 100644
index 7599b6b8223..00000000000
--- a/cpp/src/Ice/BasicStream.cpp
+++ /dev/null
@@ -1,3441 +0,0 @@
-// **********************************************************************
-//
-// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved.
-//
-// This copy of Ice is licensed to you under the terms described in the
-// ICE_LICENSE file included in this distribution.
-//
-// **********************************************************************
-
-#include <IceUtil/DisableWarnings.h>
-#include <Ice/BasicStream.h>
-#include <Ice/DefaultsAndOverrides.h>
-#include <Ice/Instance.h>
-#include <Ice/Object.h>
-#include <Ice/Proxy.h>
-#include <Ice/ProxyFactory.h>
-#include <Ice/ValueFactory.h>
-#include <Ice/ValueFactoryManager.h>
-#include <Ice/UserExceptionFactory.h>
-#include <Ice/LocalException.h>
-#include <Ice/Protocol.h>
-#include <Ice/FactoryTableInit.h>
-#include <Ice/TraceUtil.h>
-#include <Ice/TraceLevels.h>
-#include <Ice/LoggerUtil.h>
-#include <Ice/SlicedData.h>
-#include <IceUtil/StringConverter.h>
-#include <iterator>
-
-using namespace std;
-using namespace Ice;
-using namespace IceInternal;
-
-namespace
-{
-
-class StreamUTF8BufferI : public IceUtil::UTF8Buffer
-{
-public:
-
- StreamUTF8BufferI(BasicStream& stream) :
- _stream(stream)
- {
- }
-
- Ice::Byte*
- getMoreBytes(size_t howMany, Ice::Byte* firstUnused)
- {
- assert(howMany > 0);
-
- if(firstUnused != 0)
- {
- //
- // Return unused bytes
- //
- _stream.resize(firstUnused - _stream.b.begin());
- }
-
- //
- // Index of first unused byte
- //
- Buffer::Container::size_type pos = _stream.b.size();
-
- //
- // Since resize may reallocate the buffer, when firstUnused != 0, the
- // return value can be != firstUnused
- //
- _stream.resize(pos + howMany);
-
- return &_stream.b[pos];
- }
-
-private:
-
- BasicStream& _stream;
-};
-
-const Byte OPTIONAL_END_MARKER = 0xFF;
-
-const Byte FLAG_HAS_TYPE_ID_STRING = (1<<0);
-const Byte FLAG_HAS_TYPE_ID_INDEX = (1<<1);
-const Byte FLAG_HAS_TYPE_ID_COMPACT = (1<<0) | (1<<1);
-const Byte FLAG_HAS_OPTIONAL_MEMBERS = (1<<2);
-const Byte FLAG_HAS_INDIRECTION_TABLE = (1<<3);
-const Byte FLAG_HAS_SLICE_SIZE = (1<<4);
-const Byte FLAG_IS_LAST_SLICE = (1<<5);
-
-}
-
-
-IceInternal::BasicStream::BasicStream(Instance* instance, const EncodingVersion& encoding) :
- _instance(instance),
- _closure(0),
- _encoding(encoding),
- _currentReadEncaps(0),
- _currentWriteEncaps(0),
- _sliceObjects(true),
- _stringConverter(instance->getStringConverter()),
- _wstringConverter(instance->getWstringConverter()),
- _startSeq(-1),
- _minSeqSize(0)
-{
- //
- // Initialize the encoding members of our pre-allocated encapsulations, in case
- // this stream is used without an explicit encapsulation.
- //
- _preAllocatedReadEncaps.encoding = encoding;
- _preAllocatedWriteEncaps.encoding = encoding;
-}
-
-IceInternal::BasicStream::BasicStream(Instance* instance, const EncodingVersion& encoding, const Byte* begin,
- const Byte* end) :
- IceInternal::Buffer(begin, end),
- _instance(instance),
- _closure(0),
- _encoding(encoding),
- _currentReadEncaps(0),
- _currentWriteEncaps(0),
- _sliceObjects(true),
- _stringConverter(instance->getStringConverter()),
- _wstringConverter(instance->getWstringConverter()),
- _startSeq(-1),
- _minSeqSize(0)
-{
- //
- // Initialize the encoding members of our pre-allocated encapsulations, in case
- // this stream is used without an explicit encapsulation.
- //
- _preAllocatedReadEncaps.encoding = encoding;
- _preAllocatedWriteEncaps.encoding = encoding;
-}
-
-void
-IceInternal::BasicStream::clear()
-{
- while(_currentReadEncaps && _currentReadEncaps != &_preAllocatedReadEncaps)
- {
- ReadEncaps* oldEncaps = _currentReadEncaps;
- _currentReadEncaps = _currentReadEncaps->previous;
- delete oldEncaps;
- }
-
- while(_currentWriteEncaps && _currentWriteEncaps != &_preAllocatedWriteEncaps)
- {
- WriteEncaps* oldEncaps = _currentWriteEncaps;
- _currentWriteEncaps = _currentWriteEncaps->previous;
- delete oldEncaps;
- }
-
- _startSeq = -1;
- _sliceObjects = true;
-}
-
-void*
-IceInternal::BasicStream::closure() const
-{
- return _closure;
-}
-
-void*
-IceInternal::BasicStream::closure(void* p)
-{
- void* prev = _closure;
- _closure = p;
- return prev;
-}
-
-void
-IceInternal::BasicStream::swap(BasicStream& other)
-{
- assert(_instance == other._instance);
-
- swapBuffer(other);
-
- std::swap(_closure, other._closure);
-
- //
- // Swap is never called for BasicStreams that have encapsulations being read/write. However,
- // encapsulations might still be set in case marhsalling or un-marhsalling failed. We just
- // reset the encapsulations if there are still some set.
- //
- resetEncaps();
- other.resetEncaps();
-
- std::swap(_startSeq, other._startSeq);
- std::swap(_minSeqSize, other._minSeqSize);
-}
-
-void
-IceInternal::BasicStream::resetEncaps()
-{
- while(_currentReadEncaps && _currentReadEncaps != &_preAllocatedReadEncaps)
- {
- ReadEncaps* oldEncaps = _currentReadEncaps;
- _currentReadEncaps = _currentReadEncaps->previous;
- delete oldEncaps;
- }
-
- while(_currentWriteEncaps && _currentWriteEncaps != &_preAllocatedWriteEncaps)
- {
- WriteEncaps* oldEncaps = _currentWriteEncaps;
- _currentWriteEncaps = _currentWriteEncaps->previous;
- delete oldEncaps;
- }
-
- _preAllocatedReadEncaps.reset();
- _preAllocatedWriteEncaps.reset();
-}
-
-void
-IceInternal::BasicStream::startWriteEncaps()
-{
- //
- // If no encoding version is specified, use the current write
- // encapsulation encoding version if there's a current write
- // encapsulation, otherwise, use the stream encoding version.
- //
-
- if(_currentWriteEncaps)
- {
- startWriteEncaps(_currentWriteEncaps->encoding, _currentWriteEncaps->format);
- }
- else
- {
- startWriteEncaps(_encoding, Ice::DefaultFormat);
- }
-}
-
-void
-IceInternal::BasicStream::endWriteEncapsChecked()
-{
- if(!_currentWriteEncaps)
- {
- throw EncapsulationException(__FILE__, __LINE__, "not in an encapsulation");
- }
- endWriteEncaps();
-}
-
-void
-IceInternal::BasicStream::endReadEncapsChecked()
-{
- if(!_currentReadEncaps)
- {
- throw EncapsulationException(__FILE__, __LINE__, "not in an encapsulation");
- }
- endReadEncaps();
-}
-
-Int
-IceInternal::BasicStream::getReadEncapsSize()
-{
- assert(_currentReadEncaps);
- return _currentReadEncaps->sz - static_cast<Int>(sizeof(Int)) - 2;
-}
-
-EncodingVersion
-IceInternal::BasicStream::skipEncaps()
-{
- Int sz;
- read(sz);
- if(sz < 6)
- {
- throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
- }
- if(i - sizeof(Int) + sz > b.end())
- {
- throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
- }
- EncodingVersion encoding;
- read(encoding.major);
- read(encoding.minor);
- i += sz - sizeof(Int) - 2;
- return encoding;
-}
-
-void
-IceInternal::BasicStream::readPendingObjects()
-{
- if(_currentReadEncaps && _currentReadEncaps->decoder)
- {
- _currentReadEncaps->decoder->readPendingObjects();
- }
- else if(getReadEncoding() == Ice::Encoding_1_0)
- {
- //
- // If using the 1.0 encoding and no objects were read, we
- // still read an empty sequence of pending objects if
- // requested (i.e.: if this is called).
- //
- // This is required by the 1.0 encoding, even if no objects
- // are written we do marshal an empty sequence if marshaled
- // data types use classes.
- //
- skipSize();
- }
-}
-
-void
-IceInternal::BasicStream::writePendingObjects()
-{
- if(_currentWriteEncaps && _currentWriteEncaps->encoder)
- {
- _currentWriteEncaps->encoder->writePendingObjects();
- }
- else if(getWriteEncoding() == Ice::Encoding_1_0)
- {
- //
- // If using the 1.0 encoding and no objects were written, we
- // still write an empty sequence for pending objects if
- // requested (i.e.: if this is called).
- //
- // This is required by the 1.0 encoding, even if no objects
- // are written we do marshal an empty sequence if marshaled
- // data types use classes.
- //
- writeSize(0);
- }
-}
-
-Int
-IceInternal::BasicStream::readAndCheckSeqSize(int minSize)
-{
- Int sz = readSize();
-
- if(sz == 0)
- {
- return sz;
- }
-
- //
- // The _startSeq variable points to the start of the sequence for which
- // we expect to read at least _minSeqSize bytes from the stream.
- //
- // If not initialized or if we already read more data than _minSeqSize,
- // we reset _startSeq and _minSeqSize for this sequence (possibly a
- // top-level sequence or enclosed sequence it doesn't really matter).
- //
- // Otherwise, we are reading an enclosed sequence and we have to bump
- // _minSeqSize by the minimum size that this sequence will require on
- // the stream.
- //
- // The goal of this check is to ensure that when we start un-marshalling
- // a new sequence, we check the minimal size of this new sequence against
- // the estimated remaining buffer size. This estimatation is based on
- // the minimum size of the enclosing sequences, it's _minSeqSize.
- //
- if(_startSeq == -1 || i > (b.begin() + _startSeq + _minSeqSize))
- {
- _startSeq = static_cast<int>(i - b.begin());
- _minSeqSize = sz * minSize;
- }
- else
- {
- _minSeqSize += sz * minSize;
- }
-
- //
- // If there isn't enough data to read on the stream for the sequence (and
- // possibly enclosed sequences), something is wrong with the marshalled
- // data: it's claiming having more data that what is possible to read.
- //
- if(_startSeq + _minSeqSize > static_cast<int>(b.size()))
- {
- throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
- }
-
- return sz;
-}
-
-void
-IceInternal::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
-IceInternal::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
-IceInternal::BasicStream::write(const Byte* begin, const Byte* end)
-{
- Int sz = static_cast<Int>(end - begin);
- writeSize(sz);
- if(sz > 0)
- {
- Container::size_type pos = b.size();
- resize(pos + sz);
- memcpy(&b[pos], begin, sz);
- }
-}
-
-void
-IceInternal::BasicStream::read(std::vector<Ice::Byte>& v)
-{
- std::pair<const Ice::Byte*, const Ice::Byte*> p;
- read(p);
- if(p.first != p.second)
- {
- v.resize(static_cast<Ice::Int>(p.second - p.first));
- copy(p.first, p.second, v.begin());
- }
- else
- {
- v.clear();
- }
-}
-
-void
-IceInternal::BasicStream::read(pair<const Byte*, const Byte*>& v)
-{
- Int sz = readAndCheckSeqSize(1);
- if(sz > 0)
- {
- v.first = i;
- v.second = i + sz;
- i += sz;
- }
- else
- {
- v.first = v.second = i;
- }
-}
-
-void
-IceInternal::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);
- }
-}
-
-namespace
-{
-
-template<size_t boolSize>
-struct BasicStreamWriteBoolHelper
-{
- static void write(const bool* begin, BasicStream::Container::size_type pos, BasicStream::Container& b, Int sz)
- {
- for(int idx = 0; idx < sz; ++idx)
- {
- b[pos + idx] = static_cast<Byte>(*(begin + idx));
- }
- }
-};
-
-template<>
-struct BasicStreamWriteBoolHelper<1>
-{
- static void write(const bool* begin, BasicStream::Container::size_type pos, BasicStream::Container& b, Int sz)
- {
- memcpy(&b[pos], begin, sz);
- }
-};
-
-}
-
-void
-IceInternal::BasicStream::write(const bool* begin, const bool* end)
-{
- Int sz = static_cast<Int>(end - begin);
- writeSize(sz);
- if(sz > 0)
- {
- Container::size_type pos = b.size();
- resize(pos + sz);
- BasicStreamWriteBoolHelper<sizeof(bool)>::write(begin, pos, b, sz);
- }
-}
-
-void
-IceInternal::BasicStream::read(vector<bool>& v)
-{
- Int sz = readAndCheckSeqSize(1);
- if(sz > 0)
- {
- v.resize(sz);
- copy(i, i + sz, v.begin());
- i += sz;
- }
- else
- {
- v.clear();
- }
-}
-
-namespace
-{
-
-template<size_t boolSize>
-struct BasicStreamReadBoolHelper
-{
- static bool* read(pair<const bool*, const bool*>& v, Int sz, BasicStream::Container::iterator& i)
- {
- bool* array = new bool[sz];
- for(int idx = 0; idx < sz; ++idx)
- {
- array[idx] = static_cast<bool>(*(i + idx));
- }
- v.first = array;
- v.second = array + sz;
- return array;
- }
-};
-
-template<>
-struct BasicStreamReadBoolHelper<1>
-{
- static bool* read(pair<const bool*, const bool*>& v, Int sz, BasicStream::Container::iterator& i)
- {
- v.first = reinterpret_cast<bool*>(i);
- v.second = reinterpret_cast<bool*>(i) + sz;
- return 0;
- }
-};
-
-}
-
-void
-IceInternal::BasicStream::read(pair<const bool*, const bool*>& v, IceUtil::ScopedArray<bool>& result)
-{
- Int sz = readAndCheckSeqSize(1);
- if(sz > 0)
- {
- result.reset(BasicStreamReadBoolHelper<sizeof(bool)>::read(v, sz, i));
- i += sz;
- }
- else
- {
- result.reset();
- v.first = v.second = reinterpret_cast<bool*>(i);
- }
-}
-
-void
-IceInternal::BasicStream::write(Short v)
-{
- Container::size_type pos = b.size();
- resize(pos + sizeof(Short));
- Byte* dest = &b[pos];
-#ifdef ICE_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
-IceInternal::BasicStream::write(const Short* begin, const Short* end)
-{
- Int sz = static_cast<Int>(end - begin);
- writeSize(sz);
- if(sz > 0)
- {
- Container::size_type pos = b.size();
- resize(pos + sz * sizeof(Short));
-#ifdef ICE_BIG_ENDIAN
- const Byte* src = reinterpret_cast<const Byte*>(begin) + 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*>(begin), sz * sizeof(Short));
-#endif
- }
-}
-
-void
-IceInternal::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 ICE_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
-IceInternal::BasicStream::read(vector<Short>& v)
-{
- Int sz = readAndCheckSeqSize(static_cast<int>(sizeof(Short)));
- if(sz > 0)
- {
- Container::iterator begin = i;
- i += sz * static_cast<int>(sizeof(Short));
- v.resize(sz);
-#ifdef ICE_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
-IceInternal::BasicStream::read(pair<const Short*, const Short*>& v, IceUtil::ScopedArray<Short>& result)
-{
- Int sz = readAndCheckSeqSize(static_cast<int>(sizeof(Short)));
- if(sz > 0)
- {
-#if defined(__i386) || defined(_M_IX86) || defined(__x86_64) || defined(_M_X64)
- v.first = reinterpret_cast<Short*>(i);
- i += sz * static_cast<int>(sizeof(Short));
- v.second = reinterpret_cast<Short*>(i);
-#else
- result.reset(new Short[sz]);
- v.first = result.get();
- v.second = result.get() + sz;
-
- Container::iterator begin = i;
- i += sz * static_cast<int>(sizeof(Short));
-# ifdef ICE_BIG_ENDIAN
- const Byte* src = &(*begin);
- Byte* dest = reinterpret_cast<Byte*>(&result[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*>(&result[0]));
-# endif
-#endif
- }
- else
- {
- result.reset();
- v.first = v.second = 0;
- }
-}
-
-void
-IceInternal::BasicStream::write(const Int* begin, const Int* end)
-{
- Int sz = static_cast<Int>(end - begin);
- writeSize(sz);
- if(sz > 0)
- {
- Container::size_type pos = b.size();
- resize(pos + sz * sizeof(Int));
-#ifdef ICE_BIG_ENDIAN
- const Byte* src = reinterpret_cast<const Byte*>(begin) + 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*>(begin), sz * sizeof(Int));
-#endif
- }
-}
-
-void
-IceInternal::BasicStream::read(vector<Int>& v)
-{
- Int sz = readAndCheckSeqSize(static_cast<int>(sizeof(Int)));
- if(sz > 0)
- {
- Container::iterator begin = i;
- i += sz * static_cast<int>(sizeof(Int));
- v.resize(sz);
-#ifdef ICE_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
-IceInternal::BasicStream::read(pair<const Int*, const Int*>& v, ::IceUtil::ScopedArray<Int>& result)
-{
- Int sz = readAndCheckSeqSize(static_cast<int>(sizeof(Int)));
- if(sz > 0)
- {
-#if defined(__i386) || defined(_M_IX86) || defined(__x86_64) || defined(_M_X64)
- v.first = reinterpret_cast<Int*>(i);
- i += sz * static_cast<int>(sizeof(Int));
- v.second = reinterpret_cast<Int*>(i);
-#else
- result.reset(new Int[sz]);
- v.first = result.get();
- v.second = result.get() + sz;
-
- Container::iterator begin = i;
- i += sz * static_cast<int>(sizeof(Int));
-# ifdef ICE_BIG_ENDIAN
- const Byte* src = &(*begin);
- Byte* dest = reinterpret_cast<Byte*>(&result[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*>(&result[0]));
-# endif
-#endif
- }
- else
- {
- result.reset();
- v.first = v.second = 0;
- }
-}
-
-void
-IceInternal::BasicStream::write(Long v)
-{
- Container::size_type pos = b.size();
- resize(pos + sizeof(Long));
- Byte* dest = &b[pos];
-#ifdef ICE_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
-IceInternal::BasicStream::write(const Long* begin, const Long* end)
-{
- Int sz = static_cast<Int>(end - begin);
- writeSize(sz);
- if(sz > 0)
- {
- Container::size_type pos = b.size();
- resize(pos + sz * sizeof(Long));
-#ifdef ICE_BIG_ENDIAN
- const Byte* src = reinterpret_cast<const Byte*>(begin) + 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*>(begin), sz * sizeof(Long));
-#endif
- }
-}
-
-void
-IceInternal::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 ICE_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
-IceInternal::BasicStream::read(vector<Long>& v)
-{
- Int sz = readAndCheckSeqSize(static_cast<int>(sizeof(Long)));
- if(sz > 0)
- {
- Container::iterator begin = i;
- i += sz * static_cast<int>(sizeof(Long));
- v.resize(sz);
-#ifdef ICE_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
-IceInternal::BasicStream::read(pair<const Long*, const Long*>& v, IceUtil::ScopedArray<Long>& result)
-{
- Int sz = readAndCheckSeqSize(static_cast<int>(sizeof(Long)));
- if(sz > 0)
- {
-#if defined(__i386) || defined(_M_IX86) || defined(__x86_64) || defined(_M_X64)
- v.first = reinterpret_cast<Long*>(i);
- i += sz * static_cast<int>(sizeof(Long));
- v.second = reinterpret_cast<Long*>(i);
-#else
- result.reset(new Long[sz]);
- v.first = result.get();
- v.second = result.get() + sz;
-
- Container::iterator begin = i;
- i += sz * static_cast<int>(sizeof(Long));
-# ifdef ICE_BIG_ENDIAN
- const Byte* src = &(*begin);
- Byte* dest = reinterpret_cast<Byte*>(&result[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*>(&result[0]));
-# endif
-#endif
- }
- else
- {
- result.reset();
- v.first = v.second = 0;
- }
-}
-
-void
-IceInternal::BasicStream::write(Float v)
-{
- Container::size_type pos = b.size();
- resize(pos + sizeof(Float));
- Byte* dest = &b[pos];
-#ifdef ICE_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
-IceInternal::BasicStream::write(const Float* begin, const Float* end)
-{
- Int sz = static_cast<Int>(end - begin);
- writeSize(sz);
- if(sz > 0)
- {
- Container::size_type pos = b.size();
- resize(pos + sz * sizeof(Float));
-#ifdef ICE_BIG_ENDIAN
- const Byte* src = reinterpret_cast<const Byte*>(begin) + 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*>(begin), sz * sizeof(Float));
-#endif
- }
-}
-
-void
-IceInternal::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 ICE_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
-IceInternal::BasicStream::read(vector<Float>& v)
-{
- Int sz = readAndCheckSeqSize(static_cast<int>(sizeof(Float)));
- if(sz > 0)
- {
- Container::iterator begin = i;
- i += sz * static_cast<int>(sizeof(Float));
- v.resize(sz);
-#ifdef ICE_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
-IceInternal::BasicStream::read(pair<const Float*, const Float*>& v, IceUtil::ScopedArray<Float>& result)
-{
- Int sz = readAndCheckSeqSize(static_cast<int>(sizeof(Float)));
- if(sz > 0)
- {
-#if defined(__i386) || defined(_M_IX86) || defined(__x86_64) || defined(_M_X64)
- v.first = reinterpret_cast<Float*>(i);
- i += sz * static_cast<int>(sizeof(Float));
- v.second = reinterpret_cast<Float*>(i);
-#else
- result.reset(new Float[sz]);
- v.first = result.get();
- v.second = result.get() + sz;
-
- Container::iterator begin = i;
- i += sz * static_cast<int>(sizeof(Float));
-# ifdef ICE_BIG_ENDIAN
- const Byte* src = &(*begin);
- Byte* dest = reinterpret_cast<Byte*>(&result[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*>(&result[0]));
-# endif
-#endif
- }
- else
- {
- result.reset();
- v.first = v.second = 0;
- }
-}
-
-void
-IceInternal::BasicStream::write(Double v)
-{
- Container::size_type pos = b.size();
- resize(pos + sizeof(Double));
- Byte* dest = &b[pos];
-#ifdef ICE_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);
-# if defined(ICE_LITTLEBYTE_BIGWORD)
- dest[4] = *src++;
- dest[5] = *src++;
- dest[6] = *src++;
- dest[7] = *src++;
- dest[0] = *src++;
- dest[1] = *src++;
- dest[2] = *src++;
- dest[3] = *src;
-# else
- *dest++ = *src++;
- *dest++ = *src++;
- *dest++ = *src++;
- *dest++ = *src++;
- *dest++ = *src++;
- *dest++ = *src++;
- *dest++ = *src++;
- *dest = *src;
-# endif
-#endif
-}
-
-void
-IceInternal::BasicStream::write(const Double* begin, const Double* end)
-{
- Int sz = static_cast<Int>(end - begin);
- writeSize(sz);
- if(sz > 0)
- {
- Container::size_type pos = b.size();
- resize(pos + sz * sizeof(Double));
-#ifdef ICE_BIG_ENDIAN
- const Byte* src = reinterpret_cast<const Byte*>(begin) + 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);
- }
-#elif defined(ICE_LITTLEBYTE_BIGWORD)
- const Byte* src = reinterpret_cast<const Byte*>(begin);
- Byte* dest = &(*(b.begin() + pos));
- for(int j = 0 ; j < sz ; ++j)
- {
- dest[4] = *src++;
- dest[5] = *src++;
- dest[6] = *src++;
- dest[7] = *src++;
- dest[0] = *src++;
- dest[1] = *src++;
- dest[2] = *src++;
- dest[3] = *src++;
- dest += sizeof(Double);
- }
-#else
- memcpy(&b[pos], reinterpret_cast<const Byte*>(begin), sz * sizeof(Double));
-#endif
- }
-}
-
-void
-IceInternal::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 ICE_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);
-# if defined(ICE_LITTLEBYTE_BIGWORD)
- dest[4] = *src++;
- dest[5] = *src++;
- dest[6] = *src++;
- dest[7] = *src++;
- dest[0] = *src++;
- dest[1] = *src++;
- dest[2] = *src++;
- dest[3] = *src;
-# else
- *dest++ = *src++;
- *dest++ = *src++;
- *dest++ = *src++;
- *dest++ = *src++;
- *dest++ = *src++;
- *dest++ = *src++;
- *dest++ = *src++;
- *dest = *src;
-# endif
-#endif
-}
-
-void
-IceInternal::BasicStream::read(vector<Double>& v)
-{
- Int sz = readAndCheckSeqSize(static_cast<int>(sizeof(Double)));
- if(sz > 0)
- {
- Container::iterator begin = i;
- i += sz * static_cast<int>(sizeof(Double));
- v.resize(sz);
-#ifdef ICE_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);
- }
-#elif defined(ICE_LITTLEBYTE_BIGWORD)
- const Byte* src = &(*begin);
- Byte* dest = reinterpret_cast<Byte*>(&v[0]);
- for(int j = 0 ; j < sz ; ++j)
- {
- dest[4] = *src++;
- dest[5] = *src++;
- dest[6] = *src++;
- dest[7] = *src++;
- dest[0] = *src++;
- dest[1] = *src++;
- dest[2] = *src++;
- dest[3] = *src++;
- dest += sizeof(Double);
- }
-#else
- copy(begin, i, reinterpret_cast<Byte*>(&v[0]));
-#endif
- }
- else
- {
- v.clear();
- }
-}
-
-void
-IceInternal::BasicStream::read(pair<const Double*, const Double*>& v, IceUtil::ScopedArray<Double>& result)
-{
- Int sz = readAndCheckSeqSize(static_cast<int>(sizeof(Double)));
- if(sz > 0)
- {
-#if defined(__i386) || defined(_M_IX86) || defined(__x86_64) || defined(_M_X64)
- v.first = reinterpret_cast<Double*>(i);
- i += sz * static_cast<int>(sizeof(Double));
- v.second = reinterpret_cast<Double*>(i);
-#else
- result.reset(new Double[sz]);
- v.first = result.get();
- v.second = result.get() + sz;
-
- Container::iterator begin = i;
- i += sz * static_cast<int>(sizeof(Double));
-# ifdef ICE_BIG_ENDIAN
- const Byte* src = &(*begin);
- Byte* dest = reinterpret_cast<Byte*>(&result[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);
- }
-# elif defined(ICE_LITTLEBYTE_BIGWORD)
- const Byte* src = &(*begin);
- Byte* dest = reinterpret_cast<Byte*>(&result[0]);
- for(int j = 0 ; j < sz ; ++j)
- {
- dest[4] = *src++;
- dest[5] = *src++;
- dest[6] = *src++;
- dest[7] = *src++;
- dest[0] = *src++;
- dest[1] = *src++;
- dest[2] = *src++;
- dest[3] = *src++;
- dest += sizeof(Double);
- }
-
-# else
- copy(begin, i, reinterpret_cast<Byte*>(&result[0]));
-# endif
-#endif
- }
- else
- {
- result.reset();
- v.first = v.second = 0;
- }
-}
-
-//
-// 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
-IceInternal::BasicStream::write(const char*)
-{
-}
-*/
-
-void
-IceInternal::BasicStream::writeConverted(const char* vdata, size_t vsize)
-{
- //
- // What is the size of the resulting UTF-8 encoded string?
- // Impossible to tell, so we guess. If we don't guess correctly,
- // we'll have to fix the mistake afterwards
- //
- try
- {
- Int guessedSize = static_cast<Int>(vsize);
- writeSize(guessedSize); // writeSize() only writes the size; it does not reserve any buffer space.
-
- size_t firstIndex = b.size();
- StreamUTF8BufferI buffer(*this);
-
- Byte* lastByte = _stringConverter->toUTF8(vdata, vdata + vsize, buffer);
- if(lastByte != b.end())
- {
- resize(lastByte - b.begin());
- }
- size_t lastIndex = b.size();
-
- Int actualSize = static_cast<Int>(lastIndex - firstIndex);
-
- //
- // Check against the guess
- //
- if(guessedSize != actualSize)
- {
- if(guessedSize <= 254 && actualSize > 254)
- {
- //
- // Move the UTF-8 sequence 4 bytes further
- // Use memmove instead of memcpy since the source and destination typically overlap.
- //
- resize(b.size() + 4);
- memmove(b.begin() + firstIndex + 4, b.begin() + firstIndex, actualSize);
- }
- else if(guessedSize > 254 && actualSize <= 254)
- {
- //
- // Move the UTF-8 sequence 4 bytes back
- //
- memmove(b.begin() + firstIndex - 4, b.begin() + firstIndex, actualSize);
- resize(b.size() - 4);
- }
-
- if(guessedSize <= 254)
- {
- rewriteSize(actualSize, b.begin() + firstIndex - 1);
- }
- else
- {
- rewriteSize(actualSize, b.begin() + firstIndex - 1 - 4);
- }
- }
- }
- catch(const IceUtil::IllegalConversionException& ex)
- {
- throw StringConversionException(__FILE__, __LINE__, ex.reason());
- }
-}
-
-void
-IceInternal::BasicStream::write(const string* begin, const string* end, bool convert)
-{
- Int sz = static_cast<Int>(end - begin);
- writeSize(sz);
- if(sz > 0)
- {
- for(int i = 0; i < sz; ++i)
- {
- write(begin[i], convert);
- }
- }
-}
-
-void
-IceInternal::BasicStream::readConverted(string& v, int sz)
-{
- try
- {
- _stringConverter->fromUTF8(i, i + sz, v);
- }
- catch(const IceUtil::IllegalConversionException& ex)
- {
- throw StringConversionException(__FILE__, __LINE__, ex.reason());
- }
-}
-
-void
-IceInternal::BasicStream::read(vector<string>& v, bool convert)
-{
- Int sz = readAndCheckSeqSize(1);
- if(sz > 0)
- {
- v.resize(sz);
- for(int j = 0; j < sz; ++j)
- {
- read(v[j], convert);
- }
- }
- else
- {
- v.clear();
- }
-}
-
-void
-IceInternal::BasicStream::write(const wstring& v)
-{
- if(v.empty())
- {
- writeSize(0);
- return;
- }
-
- //
- // What is the size of the resulting UTF-8 encoded string?
- // Impossible to tell, so we guess. If we don't guess correctly,
- // we'll have to fix the mistake afterwards
- //
- try
- {
- Int guessedSize = static_cast<Int>(v.size());
- writeSize(guessedSize); // writeSize() only writes the size; it does not reserve any buffer space.
-
- size_t firstIndex = b.size();
- StreamUTF8BufferI buffer(*this);
-
- Byte* lastByte = _wstringConverter->toUTF8(v.data(), v.data() + v.size(), buffer);
- if(lastByte != b.end())
- {
- resize(lastByte - b.begin());
- }
- size_t lastIndex = b.size();
-
- Int actualSize = static_cast<Int>(lastIndex - firstIndex);
-
- //
- // Check against the guess
- //
- if(guessedSize != actualSize)
- {
- if(guessedSize <= 254 && actualSize > 254)
- {
- //
- // Move the UTF-8 sequence 4 bytes further
- // Use memmove instead of memcpy since the source and destination typically overlap.
- //
- resize(b.size() + 4);
- memmove(b.begin() + firstIndex + 4, b.begin() + firstIndex, actualSize);
- }
- else if(guessedSize > 254 && actualSize <= 254)
- {
- //
- // Move the UTF-8 sequence 4 bytes back
- //
- memmove(b.begin() + firstIndex - 4, b.begin() + firstIndex, actualSize);
- resize(b.size() - 4);
- }
-
- if(guessedSize <= 254)
- {
- rewriteSize(actualSize, b.begin() + firstIndex - 1);
- }
- else
- {
- rewriteSize(actualSize, b.begin() + firstIndex - 1 - 4);
- }
- }
- }
- catch(const IceUtil::IllegalConversionException& ex)
- {
- throw StringConversionException(__FILE__, __LINE__, ex.reason());
- }
-}
-
-void
-IceInternal::BasicStream::write(const wstring* begin, const wstring* end)
-{
- Int sz = static_cast<Int>(end - begin);
- writeSize(sz);
- if(sz > 0)
- {
- for(int i = 0; i < sz; ++i)
- {
- write(begin[i]);
- }
- }
-}
-
-void
-IceInternal::BasicStream::read(wstring& v)
-{
- Int sz = readSize();
- if(sz > 0)
- {
- if(b.end() - i < sz)
- {
- throwUnmarshalOutOfBoundsException(__FILE__, __LINE__);
- }
-
- try
- {
- _wstringConverter->fromUTF8(i, i + sz, v);
- i += sz;
- }
- catch(const IceUtil::IllegalConversionException& ex)
- {
- throw StringConversionException(__FILE__, __LINE__, ex.reason());
- }
- }
- else
- {
- v.clear();
- }
-}
-
-void
-IceInternal::BasicStream::read(vector<wstring>& v)
-{
- Int sz = readAndCheckSeqSize(1);
- if(sz > 0)
- {
- v.resize(sz);
- for(int j = 0; j < sz; ++j)
- {
- read(v[j]);
- }
- }
- else
- {
- v.clear();
- }
-}
-
-void
-#ifdef ICE_CPP11_MAPPING
-IceInternal::BasicStream::writeProxy(const shared_ptr<ObjectPrx>& v)
-#else
-IceInternal::BasicStream::write(const ObjectPrx& v)
-#endif
-{
- _instance->proxyFactory()->proxyToStream(v, this);
-}
-
-#ifdef ICE_CPP11_MAPPING
-shared_ptr<ObjectPrx>
-IceInternal::BasicStream::readProxy()
-{
- return _instance->proxyFactory()->streamToProxy(this);
-}
-#else
-void
-IceInternal::BasicStream::read(ObjectPrx& v)
-{
- v = _instance->proxyFactory()->streamToProxy(this);
-}
-#endif
-
-Int
-IceInternal::BasicStream::readEnum(Int maxValue)
-{
- if(getReadEncoding() == Encoding_1_0)
- {
- if(maxValue < 127)
- {
- Byte value;
- read(value);
- return value;
- }
- else if(maxValue < 32767)
- {
- Short value;
- read(value);
- return value;
- }
- else
- {
- Int value;
- read(value);
- return value;
- }
- }
- else
- {
- return readSize();
- }
-}
-
-void
-IceInternal::BasicStream::writeEnum(Int v, Int maxValue)
-{
- if(getWriteEncoding() == Encoding_1_0)
- {
- if(maxValue < 127)
- {
- write(static_cast<Byte>(v));
- }
- else if(maxValue < 32767)
- {
- write(static_cast<Short>(v));
- }
- else
- {
- write(v);
- }
- }
- else
- {
- writeSize(v);
- }
-}
-
-void
-IceInternal::BasicStream::writeException(const UserException& e)
-{
- initWriteEncaps();
- _currentWriteEncaps->encoder->write(e);
-}
-
-void
-IceInternal::BasicStream::throwException(const UserExceptionFactoryPtr& factory)
-{
- initReadEncaps();
- _currentReadEncaps->decoder->throwException(factory);
-}
-
-void
-IceInternal::BasicStream::sliceObjects(bool doSlice)
-{
- _sliceObjects = doSlice;
-}
-
-bool
-IceInternal::BasicStream::readOptImpl(Int readTag, OptionalFormat expectedFormat)
-{
- if(getReadEncoding() == Encoding_1_0)
- {
- return false; // Optional members aren't supported with the 1.0 encoding.
- }
-
- while(true)
- {
- if(i >= b.begin() + _currentReadEncaps->start + _currentReadEncaps->sz)
- {
- return false; // End of encapsulation also indicates end of optionals.
- }
-
- Byte v;
- read(v);
- if(v == OPTIONAL_END_MARKER)
- {
- --i; // Rewind
- return false;
- }
-
- OptionalFormat format = static_cast<OptionalFormat>(v & 0x07); // First 3 bits.
- Int tag = static_cast<Int>(v >> 3);
- if(tag == 30)
- {
- tag = readSize();
- }
-
- if(tag > readTag)
- {
- i -= tag < 30 ? 1 : (tag < 255 ? 2 : 6); // Rewind
- return false; // No optional data members with the requested tag.
- }
- else if(tag < readTag)
- {
- skipOpt(format); // Skip optional data members
- }
- else
- {
- if(format != expectedFormat)
- {
- ostringstream os;
- os << "invalid optional data member `" << tag << "': unexpected format";
- throw MarshalException(__FILE__, __LINE__, os.str());
- }
- return true;
- }
- }
- return true; // Keep the compiler happy.
-}
-
-bool
-IceInternal::BasicStream::writeOptImpl(Int tag, OptionalFormat type)
-{
- if(getWriteEncoding() == Encoding_1_0)
- {
- return false; // Optional members aren't supported with the 1.0 encoding.
- }
-
- Byte v = static_cast<Byte>(type);
- if(tag < 30)
- {
- v |= static_cast<Byte>(tag << 3);
- write(v);
- }
- else
- {
- v |= 0xF0; // tag = 30
- write(v);
- writeSize(tag);
- }
- return true;
-}
-
-void
-IceInternal::BasicStream::skipOpt(OptionalFormat type)
-{
- switch(type)
- {
- case Ice::OptionalFormatF1:
- {
- skip(1);
- break;
- }
- case Ice::OptionalFormatF2:
- {
- skip(2);
- break;
- }
- case Ice::OptionalFormatF4:
- {
- skip(4);
- break;
- }
- case Ice::OptionalFormatF8:
- {
- skip(8);
- break;
- }
- case Ice::OptionalFormatSize:
- {
- skipSize();
- break;
- }
- case Ice::OptionalFormatVSize:
- {
- skip(readSize());
- break;
- }
- case Ice::OptionalFormatFSize:
- {
- Int sz;
- read(sz);
- skip(sz);
- break;
- }
- case Ice::OptionalFormatClass:
- {
- read(0, 0);
- break;
- }
- }
-}
-
-void
-BasicStream::skipOpts()
-{
- //
- // Skip remaining un-read optional members.
- //
- while(true)
- {
- if(i >= b.begin() + _currentReadEncaps->start + _currentReadEncaps->sz)
- {
- return; // End of encapsulation also indicates end of optionals.
- }
-
- Byte v;
- read(v);
- if(v == OPTIONAL_END_MARKER)
- {
- return;
- }
-
- OptionalFormat format = static_cast<OptionalFormat>(v & 0x07); // Read first 3 bits.
- if(static_cast<Int>(v >> 3) == 30)
- {
- skipSize();
- }
- skipOpt(format);
- }
-}
-
-void
-IceInternal::BasicStream::throwUnmarshalOutOfBoundsException(const char* file, int line)
-{
- throw UnmarshalOutOfBoundsException(file, line);
-}
-
-void
-IceInternal::BasicStream::throwEncapsulationException(const char* file, int line)
-{
- throw EncapsulationException(file, line);
-}
-
-void
-IceInternal::BasicStream::initReadEncaps()
-{
- if(!_currentReadEncaps) // Lazy initialization.
- {
- _currentReadEncaps = &_preAllocatedReadEncaps;
- _currentReadEncaps->sz = static_cast<Ice::Int>(b.size());
- }
-
- if(!_currentReadEncaps->decoder) // Lazy initialization.
- {
- ValueFactoryManagerPtr factoryManager = _instance->servantFactoryManager();
- if(_currentReadEncaps->encoding == Encoding_1_0)
- {
- _currentReadEncaps->decoder = new EncapsDecoder10(this, _currentReadEncaps, _sliceObjects, factoryManager);
- }
- else
- {
- _currentReadEncaps->decoder = new EncapsDecoder11(this, _currentReadEncaps, _sliceObjects, factoryManager);
- }
- }
-}
-
-void
-IceInternal::BasicStream::initWriteEncaps()
-{
- if(!_currentWriteEncaps) // Lazy initialization.
- {
- _currentWriteEncaps = &_preAllocatedWriteEncaps;
- _currentWriteEncaps->start = b.size();
- }
-
- if(_currentWriteEncaps->format == Ice::DefaultFormat)
- {
- _currentWriteEncaps->format = _instance->defaultsAndOverrides()->defaultFormat;
- }
-
- if(!_currentWriteEncaps->encoder) // Lazy initialization.
- {
- if(_currentWriteEncaps->encoding == Encoding_1_0)
- {
- _currentWriteEncaps->encoder = new EncapsEncoder10(this, _currentWriteEncaps);
- }
- else
- {
- _currentWriteEncaps->encoder = new EncapsEncoder11(this, _currentWriteEncaps);
- }
- }
-}
-
-string
-IceInternal::BasicStream::EncapsDecoder::readTypeId(bool isIndex)
-{
- if(isIndex)
- {
- Int index = _stream->readSize();
- TypeIdReadMap::const_iterator k = _typeIdMap.find(index);
- if(k == _typeIdMap.end())
- {
- throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
- }
- return k->second;
- }
- else
- {
- string typeId;
- _stream->read(typeId, false);
- _typeIdMap.insert(make_pair(++_typeIdIndex, typeId));
- return typeId;
- }
-}
-
-Ice::ValuePtr
-IceInternal::BasicStream::EncapsDecoder::newInstance(const string& typeId)
-{
- Ice::ValuePtr v;
-
- //
- // Try to find a factory registered for the specific type.
- //
-#ifdef ICE_CPP11_MAPPING
- function<ValuePtr (const string&)> userFactory = _servantFactoryManager->find(typeId);
- if(userFactory)
- {
- v = userFactory(typeId);
- }
-#else
- ValueFactoryPtr userFactory = _servantFactoryManager->find(typeId);
- if(userFactory)
- {
- v = userFactory->create(typeId);
- }
-#endif
- //
- // If that fails, invoke the default factory if one has been
- // registered.
- //
- if(!v)
- {
- userFactory = _servantFactoryManager->find("");
- if(userFactory)
- {
-#ifdef ICE_CPP11_MAPPING
- v = userFactory(typeId);
-#else
- v = userFactory->create(typeId);
-#endif
- }
- }
-
- //
- // Last chance: check the table of static factories (i.e.,
- // automatically generated factories for concrete classes).
- //
- if(!v)
- {
-#ifdef ICE_CPP11_MAPPING
- function<ValuePtr (const string&)> of = IceInternal::factoryTable->getValueFactory(typeId);
- if(of)
- {
- v = of(typeId);
- assert(v);
- }
-#else
- ValueFactoryPtr of = IceInternal::factoryTable->getValueFactory(typeId);
- if(of)
- {
- v = of->create(typeId);
- assert(v);
- }
-#endif
- }
- return v;
-}
-
-void
-IceInternal::BasicStream::EncapsDecoder::addPatchEntry(Int index, PatchFunc patchFunc, void* patchAddr)
-{
- assert(index > 0);
-
- //
- // Check if already un-marshalled the object. If that's the case,
- // just patch the object smart pointer and we're done.
- //
- IndexToPtrMap::iterator p = _unmarshaledMap.find(index);
- if(p != _unmarshaledMap.end())
- {
- (*patchFunc)(patchAddr, p->second);
- return;
- }
-
- //
- // Add patch entry if the object isn't un-marshalled yet, the
- // smart pointer will be patched when the instance is
- // un-marshalled.
- //
-
- PatchMap::iterator q = _patchMap.find(index);
- if(q == _patchMap.end())
- {
- //
- // We have no outstanding instances to be patched for this
- // index, so make a new entry in the patch map.
- //
- q = _patchMap.insert(make_pair(index, PatchList())).first;
- }
-
- //
- // Append a patch entry for this instance.
- //
- PatchEntry e;
- e.patchFunc = patchFunc;
- e.patchAddr = patchAddr;
- q->second.push_back(e);
-}
-
-void
-IceInternal::BasicStream::EncapsDecoder::unmarshal(Int index, const Ice::ValuePtr& v)
-{
- //
- // Add the object to the map of un-marshalled objects, this must
- // be done before reading the objects (for circular references).
- //
- _unmarshaledMap.insert(make_pair(index, v));
-
- //
- // Read the object.
- //
- v->__read(_stream);
-
- //
- // Patch all instances now that the object is un-marshalled.
- //
- PatchMap::iterator patchPos = _patchMap.find(index);
- if(patchPos != _patchMap.end())
- {
- assert(patchPos->second.size() > 0);
-
- //
- // Patch all pointers that refer to the instance.
- //
- for(PatchList::iterator k = patchPos->second.begin(); k != patchPos->second.end(); ++k)
- {
- (*k->patchFunc)(k->patchAddr, v);
- }
-
- //
- // Clear out the patch map for that index -- there is nothing left
- // to patch for that index for the time being.
- //
- _patchMap.erase(patchPos);
- }
-
- if(_objectList.empty() && _patchMap.empty())
- {
- try
- {
-#ifndef ICE_CPP11_MAPPING
- if(_stream->instance()->collectObjects())
- {
- v->ice_collectable(true);
- }
-#endif
- v->ice_postUnmarshal();
- }
- catch(const std::exception& ex)
- {
- Warning out(_stream->instance()->initializationData().logger);
- out << "std::exception raised by ice_postUnmarshal:\n" << ex;
- }
- catch(...)
- {
- Warning out(_stream->instance()->initializationData().logger);
- out << "unknown exception raised by ice_postUnmarshal";
- }
- }
- else
- {
- _objectList.push_back(v);
-
- if(_patchMap.empty())
- {
- //
- // Iterate over the object list and invoke ice_postUnmarshal on
- // each object. We must do this after all objects have been
- // unmarshaled in order to ensure that any object data members
- // have been properly patched.
- //
- for(ObjectList::iterator p = _objectList.begin(); p != _objectList.end(); ++p)
- {
- try
- {
-#ifndef ICE_CPP11_MAPPING
- if(_stream->instance()->collectObjects())
- {
- (*p)->ice_collectable(true);
- }
-#endif
- (*p)->ice_postUnmarshal();
- }
- catch(const std::exception& ex)
- {
- Warning out(_stream->instance()->initializationData().logger);
- out << "std::exception raised by ice_postUnmarshal:\n" << ex;
- }
- catch(...)
- {
- Warning out(_stream->instance()->initializationData().logger);
- out << "unknown exception raised by ice_postUnmarshal";
- }
- }
- _objectList.clear();
- }
- }
-}
-
-void
-IceInternal::BasicStream::EncapsDecoder10::read(PatchFunc patchFunc, void* patchAddr)
-{
- assert(patchFunc && patchAddr);
-
- //
- // Object references are encoded as a negative integer in 1.0.
- //
- Int index;
- _stream->read(index);
- if(index > 0)
- {
- throw MarshalException(__FILE__, __LINE__, "invalid object id");
- }
- index = -index;
-
- if(index == 0)
- {
- //
- // Calling the patch function for null instances is necessary for correct functioning of Ice for
- // Python and Ruby.
- //
- ValuePtr nil;
- patchFunc(patchAddr, nil);
- }
- else
- {
- addPatchEntry(index, patchFunc, patchAddr);
- }
-}
-
-void
-IceInternal::BasicStream::EncapsDecoder10::throwException(const UserExceptionFactoryPtr& factory)
-{
- assert(_sliceType == NoSlice);
-
- //
- // User exception with the 1.0 encoding start with a boolean flag
- // that indicates whether or not the exception has classes.
- //
- // This allows reading the pending objects even if some part of
- // the exception was sliced.
- //
- bool usesClasses;
- _stream->read(usesClasses);
-
- _sliceType = ExceptionSlice;
- _skipFirstSlice = false;
-
- //
- // Read the first slice header.
- //
- startSlice();
- const string mostDerivedId = _typeId;
- UserExceptionFactoryPtr exceptionFactory = factory;
- while(true)
- {
- //
- // Look for a statically-generated factory for this ID.
- //
- if(!exceptionFactory)
- {
- exceptionFactory = factoryTable->getExceptionFactory(_typeId);
- }
-
- //
- // We found a factory, we get out of this loop.
- //
- if(exceptionFactory)
- {
- //
- // Got factory -- ask the factory to instantiate the
- // exception, initialize the exception members, and throw
- // the exception.
- //
- try
- {
- exceptionFactory->createAndThrow(_typeId);
- }
- catch(UserException& ex)
- {
- ex.__read(_stream);
- if(usesClasses)
- {
- readPendingObjects();
- }
- throw;
-
- // Never reached.
- }
- }
-
- //
- // Slice off what we don't understand.
- //
- skipSlice();
- try
- {
- startSlice();
- }
- catch(UnmarshalOutOfBoundsException& ex)
- {
- //
- // An oversight in the 1.0 encoding means there is no marker to indicate
- // the last slice of an exception. As a result, we just try to read the
- // next type ID, which raises UnmarshalOutOfBoundsException when the
- // input buffer underflows.
- //
- // Set the reason member to a more helpful message.
- //
- ex.reason = "unknown exception type `" + mostDerivedId + "'";
- throw;
- }
- }
-}
-
-void
-#ifndef NDEBUG
-IceInternal::BasicStream::EncapsDecoder10::startInstance(SliceType sliceType)
-#else
-IceInternal::BasicStream::EncapsDecoder10::startInstance(SliceType)
-#endif
-{
- assert(_sliceType == sliceType);
- _skipFirstSlice = true;
-}
-
-SlicedDataPtr
-IceInternal::BasicStream::EncapsDecoder10::endInstance(bool)
-{
- //
- // Read the Ice::Object slice.
- //
- if(_sliceType == ObjectSlice)
- {
- startSlice();
- Int sz = _stream->readSize(); // For compatibility with the old AFM.
- if(sz != 0)
- {
- throw MarshalException(__FILE__, __LINE__, "invalid Object slice");
- }
- endSlice();
- }
- _sliceType = NoSlice;
- return 0;
-}
-
-const std::string&
-IceInternal::BasicStream::EncapsDecoder10::startSlice()
-{
- //
- // If first slice, don't read the header, it was already read in
- // readInstance or throwException to find the factory.
- //
- if(_skipFirstSlice)
- {
- _skipFirstSlice = false;
- return _typeId;
- }
-
- //
- // For objects, first read the type ID boolean which indicates
- // whether or not the type ID is encoded as a string or as an
- // index. For exceptions, the type ID is always encoded as a
- // string.
- //
- if(_sliceType == ObjectSlice)
- {
- bool isIndex;
- _stream->read(isIndex);
- _typeId = readTypeId(isIndex);
- }
- else
- {
- _stream->read(_typeId, false);
- }
-
- _stream->read(_sliceSize);
- if(_sliceSize < 4)
- {
- throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
- }
- return _typeId;
-}
-
-void
-IceInternal::BasicStream::EncapsDecoder10::endSlice()
-{
-}
-
-void
-IceInternal::BasicStream::EncapsDecoder10::skipSlice()
-{
- if(_stream->instance()->traceLevels()->slicing > 0)
- {
- const Ice::LoggerPtr& logger = _stream->instance()->initializationData().logger;
- if(_sliceType == ExceptionSlice)
- {
- traceSlicing("exception", _typeId, _stream->instance()->traceLevels()->slicingCat, logger);
- }
- else
- {
- traceSlicing("object", _typeId, _stream->instance()->traceLevels()->slicingCat, logger);
- }
- }
- assert(_sliceSize >= 4);
- _stream->skip(_sliceSize - sizeof(Int));
-}
-
-void
-IceInternal::BasicStream::EncapsDecoder10::readPendingObjects()
-{
- Int num;
- do
- {
- num = _stream->readSize();
- for(Int k = num; k > 0; --k)
- {
- readInstance();
- }
- }
- while(num);
-
- if(!_patchMap.empty())
- {
- //
- // If any entries remain in the patch map, the sender has sent an index for an object, but failed
- // to supply the object.
- //
- throw MarshalException(__FILE__, __LINE__, "index for class received, but no instance");
- }
-}
-
-void
-IceInternal::BasicStream::EncapsDecoder10::readInstance()
-{
- Int index;
- _stream->read(index);
-
- if(index <= 0)
- {
- throw MarshalException(__FILE__, __LINE__, "invalid object id");
- }
-
- _sliceType = ObjectSlice;
- _skipFirstSlice = false;
-
- //
- // Read the first slice header.
- //
- startSlice();
- const string mostDerivedId = _typeId;
- ValuePtr v;
- while(true)
- {
- //
- // For the 1.0 encoding, the type ID for the base Object class
- // marks the last slice.
- //
- if(_typeId == Object::ice_staticId())
- {
- throw NoValueFactoryException(__FILE__, __LINE__, "", mostDerivedId);
- }
-
- v = newInstance(_typeId);
-
- //
- // We found a factory, we get out of this loop.
- //
- if(v)
- {
- break;
- }
-
- //
- // If object slicing is disabled, stop un-marshalling.
- //
- if(!_sliceObjects)
- {
- throw NoValueFactoryException(__FILE__, __LINE__, "no value factory found and object slicing is disabled",
- _typeId);
- }
-
- //
- // Slice off what we don't understand.
- //
- skipSlice();
- startSlice(); // Read next Slice header for next iteration.
- }
-
- //
- // Un-marshal the object and add-it to the map of un-marshaled objects.
- //
- unmarshal(index, v);
-}
-
-void
-IceInternal::BasicStream::EncapsDecoder11::read(PatchFunc patchFunc, void* patchAddr)
-{
- Int index = _stream->readSize();
- if(index < 0)
- {
- throw MarshalException(__FILE__, __LINE__, "invalid object id");
- }
- else if(index == 0)
- {
- //
- // Calling the patch function for null instances is necessary for correct functioning of Ice for
- // Python and Ruby.
- //
- if(patchFunc)
- {
- ValuePtr nil;
- patchFunc(patchAddr, nil);
- }
- }
- else if(_current && _current->sliceFlags & FLAG_HAS_INDIRECTION_TABLE)
- {
- //
- // When reading an object within a slice and there's an
- // indirect object table, always read an indirect reference
- // that points to an object from the indirect object table
- // marshaled at the end of the Slice.
- //
- // Maintain a list of indirect references. Note that the
- // indirect index starts at 1, so we decrement it by one to
- // derive an index into the indirection table that we'll read
- // at the end of the slice.
- //
- if(patchFunc)
- {
- IndirectPatchEntry e;
- e.index = index - 1;
- e.patchFunc = patchFunc;
- e.patchAddr = patchAddr;
- _current->indirectPatchList.push_back(e);
- }
- }
- else
- {
- readInstance(index, patchFunc, patchAddr);
- }
-}
-
-void
-IceInternal::BasicStream::EncapsDecoder11::throwException(const UserExceptionFactoryPtr& factory)
-{
- assert(!_current);
-
- push(ExceptionSlice);
-
- //
- // Read the first slice header.
- //
- startSlice();
- const string mostDerivedId = _current->typeId;
- UserExceptionFactoryPtr exceptionFactory = factory;
- while(true)
- {
- //
- // Look for a statically-generated factory for this ID.
- //
- if(!exceptionFactory)
- {
- exceptionFactory = factoryTable->getExceptionFactory(_current->typeId);
- }
-
- //
- // We found a factory, we get out of this loop.
- //
- if(exceptionFactory)
- {
- //
- // Got factory -- ask the factory to instantiate the
- // exception, initialize the exception members, and throw
- // the exception.
- //
- try
- {
- exceptionFactory->createAndThrow(_current->typeId);
- }
- catch(UserException& ex)
- {
- ex.__read(_stream);
- throw;
-
- // Never reached.
- }
- }
-
- //
- // Slice off what we don't understand.
- //
- skipSlice();
-
- //
- // If this is the last slice, raise an exception and stop un-marshalling.
- //
- if(_current->sliceFlags & FLAG_IS_LAST_SLICE)
- {
- if(mostDerivedId.length() > 2 && mostDerivedId[0] == ':' && mostDerivedId[1] == ':')
- {
- throw UnknownUserException(__FILE__, __LINE__, mostDerivedId.substr(2));
- }
- else
- {
- throw UnknownUserException(__FILE__, __LINE__, mostDerivedId);
- }
- }
-
- startSlice();
- }
-}
-
-void
-#ifndef NDEBUG
-IceInternal::BasicStream::EncapsDecoder11::startInstance(SliceType sliceType)
-#else
-IceInternal::BasicStream::EncapsDecoder11::startInstance(SliceType)
-#endif
-{
- assert(_current->sliceType == sliceType);
- _current->skipFirstSlice = true;
-}
-
-SlicedDataPtr
-IceInternal::BasicStream::EncapsDecoder11::endInstance(bool preserve)
-{
- SlicedDataPtr slicedData;
- if(preserve)
- {
- slicedData = readSlicedData();
- }
- _current->slices.clear();
- _current->indirectionTables.clear();
- _current = _current->previous;
- return slicedData;
-}
-
-const std::string&
-IceInternal::BasicStream::EncapsDecoder11::startSlice()
-{
- //
- // If first slice, don't read the header, it was already read in
- // readInstance or throwException to find the factory.
- //
- if(_current->skipFirstSlice)
- {
- _current->skipFirstSlice = false;
- return _current->typeId;
- }
-
- _stream->read(_current->sliceFlags);
-
- //
- // Read the type ID, for object slices the type ID is encoded as a
- // string or as an index, for exceptions it's always encoded as a
- // string.
- //
- if(_current->sliceType == ObjectSlice)
- {
- if((_current->sliceFlags & FLAG_HAS_TYPE_ID_COMPACT) == FLAG_HAS_TYPE_ID_COMPACT) // Must be checked first!
- {
- _current->typeId.clear();
- _current->compactId = _stream->readSize();
- }
- else if(_current->sliceFlags & (FLAG_HAS_TYPE_ID_STRING | FLAG_HAS_TYPE_ID_INDEX))
- {
- _current->typeId = readTypeId(_current->sliceFlags & FLAG_HAS_TYPE_ID_INDEX);
- _current->compactId = -1;
- }
- else
- {
- // Only the most derived slice encodes the type ID for the compact format.
- _current->typeId.clear();
- _current->compactId = -1;
- }
- }
- else
- {
- _stream->read(_current->typeId, false);
- }
-
- //
- // Read the slice size if necessary.
- //
- if(_current->sliceFlags & FLAG_HAS_SLICE_SIZE)
- {
- _stream->read(_current->sliceSize);
- if(_current->sliceSize < 4)
- {
- throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
- }
- }
- else
- {
- _current->sliceSize = 0;
- }
-
- return _current->typeId;
-}
-
-void
-IceInternal::BasicStream::EncapsDecoder11::endSlice()
-{
- if(_current->sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS)
- {
- _stream->skipOpts();
- }
-
- //
- // Read the indirect object table if one is present.
- //
- if(_current->sliceFlags & FLAG_HAS_INDIRECTION_TABLE)
- {
- IndexList indirectionTable(_stream->readAndCheckSeqSize(1));
- for(IndexList::iterator p = indirectionTable.begin(); p != indirectionTable.end(); ++p)
- {
- *p = readInstance(_stream->readSize(), 0, 0);
- }
-
- //
- // Sanity checks. If there are optional members, it's possible
- // that not all object references were read if they are from
- // unknown optional data members.
- //
- if(indirectionTable.empty())
- {
- throw MarshalException(__FILE__, __LINE__, "empty indirection table");
- }
- if(_current->indirectPatchList.empty() && !(_current->sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS))
- {
- throw MarshalException(__FILE__, __LINE__, "no references to indirection table");
- }
-
- //
- // Convert indirect references into direct references.
- //
- IndirectPatchList::iterator p;
- for(p = _current->indirectPatchList.begin(); p != _current->indirectPatchList.end(); ++p)
- {
- assert(p->index >= 0);
- if(p->index >= static_cast<Int>(indirectionTable.size()))
- {
- throw MarshalException(__FILE__, __LINE__, "indirection out of range");
- }
- addPatchEntry(indirectionTable[p->index], p->patchFunc, p->patchAddr);
- }
- _current->indirectPatchList.clear();
- }
-}
-
-void
-IceInternal::BasicStream::EncapsDecoder11::skipSlice()
-{
- if(_stream->instance()->traceLevels()->slicing > 0)
- {
- const Ice::LoggerPtr& logger = _stream->instance()->initializationData().logger;
- if(_current->sliceType == ExceptionSlice)
- {
- traceSlicing("exception", _current->typeId, _stream->instance()->traceLevels()->slicingCat, logger);
- }
- else
- {
- traceSlicing("object", _current->typeId, _stream->instance()->traceLevels()->slicingCat, logger);
- }
- }
-
- Container::iterator start = _stream->i;
-
- if(_current->sliceFlags & FLAG_HAS_SLICE_SIZE)
- {
- assert(_current->sliceSize >= 4);
- _stream->skip(_current->sliceSize - sizeof(Int));
- }
- else
- {
- if(_current->sliceType == ObjectSlice)
- {
- throw NoValueFactoryException(__FILE__, __LINE__,
- "no value factory found and compact format prevents "
- "slicing (the sender should use the sliced format instead)",
- _current->typeId);
- }
- else
- {
- if(_current->typeId.length() > 2 && _current->typeId[0] == ':' && _current->typeId[1] == ':')
- {
- throw UnknownUserException(__FILE__, __LINE__, _current->typeId.substr(2));
- }
- else
- {
- throw UnknownUserException(__FILE__, __LINE__, _current->typeId);
- }
- }
- }
-
- //
- // Preserve this slice.
- //
- SliceInfoPtr info = ICE_MAKE_SHARED(SliceInfo);
- info->typeId = _current->typeId;
- info->compactId = _current->compactId;
- info->hasOptionalMembers = _current->sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS;
- info->isLastSlice = _current->sliceFlags & FLAG_IS_LAST_SLICE;
- if(info->hasOptionalMembers)
- {
- //
- // Don't include the optional member end marker. It will be re-written by
- // endSlice when the sliced data is re-written.
- //
- vector<Byte>(start, _stream->i - 1).swap(info->bytes);
- }
- else
- {
- vector<Byte>(start, _stream->i).swap(info->bytes);
- }
-
- _current->indirectionTables.push_back(IndexList());
-
- //
- // Read the indirect object table. We read the instances or their
- // IDs if the instance is a reference to an already un-marhsaled
- // object.
- //
- // The SliceInfo object sequence is initialized only if
- // readSlicedData is called.
- //
- if(_current->sliceFlags & FLAG_HAS_INDIRECTION_TABLE)
- {
- IndexList& table = _current->indirectionTables.back();
- table.resize(_stream->readAndCheckSeqSize(1));
- for(IndexList::iterator p = table.begin(); p != table.end(); ++p)
- {
- *p = readInstance(_stream->readSize(), 0, 0);
- }
- }
-
- _current->slices.push_back(info);
-}
-
-bool
-IceInternal::BasicStream::EncapsDecoder11::readOpt(Ice::Int readTag, Ice::OptionalFormat expectedFormat)
-{
- if(!_current)
- {
- return _stream->readOptImpl(readTag, expectedFormat);
- }
- else if(_current->sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS)
- {
- return _stream->readOptImpl(readTag, expectedFormat);
- }
- return false;
-}
-
-Int
-IceInternal::BasicStream::EncapsDecoder11::readInstance(Int index, PatchFunc patchFunc, void* patchAddr)
-{
- assert(index > 0);
-
- if(index > 1)
- {
- if(patchFunc)
- {
- addPatchEntry(index, patchFunc, patchAddr);
- }
- return index;
- }
-
- push(ObjectSlice);
-
- //
- // Get the object ID before we start reading slices. If some
- // slices are skiped, the indirect object table are still read and
- // might read other objects.
- //
- index = ++_objectIdIndex;
-
- //
- // Read the first slice header.
- //
- startSlice();
- const string mostDerivedId = _current->typeId;
- Ice::ValuePtr v;
-#ifdef ICE_CPP11_MAPPING
- function<string (int)> compactIdResolver = _stream->instance()->initializationData().compactIdResolver;
-#else
- const CompactIdResolverPtr& compactIdResolver = _stream->instance()->initializationData().compactIdResolver;
-#endif
- while(true)
- {
- if(_current->compactId >= 0)
- {
- //
- // Translate a compact (numeric) type ID into a string type ID.
- //
- _current->typeId.clear();
- if(compactIdResolver)
- {
- try
- {
-#ifdef ICE_CPP11_MAPPING
- _current->typeId = compactIdResolver(_current->compactId);
-#else
- _current->typeId = compactIdResolver->resolve(_current->compactId);
-#endif
- }
- catch(const LocalException&)
- {
- throw;
- }
- catch(const std::exception& ex)
- {
- ostringstream ostr;
- ostr << "exception in CompactIdResolver for ID " << _current->compactId;
- string msg = ostr.str();
- string what = ex.what();
- if(!what.empty())
- {
- msg += ":\n" + what;
- }
- throw MarshalException(__FILE__, __LINE__, msg);
- }
- catch(...)
- {
- ostringstream ostr;
- ostr << "unknown exception in CompactIdResolver for ID " << _current->compactId;
- throw MarshalException(__FILE__, __LINE__, ostr.str());
- }
- }
- if(_current->typeId.empty())
- {
- _current->typeId = IceInternal::factoryTable->getTypeId(_current->compactId);
- }
- }
-
- if(!_current->typeId.empty())
- {
- v = newInstance(_current->typeId);
-
- //
- // We found a factory, we get out of this loop.
- //
- if(v)
- {
- break;
- }
- }
-
- //
- // If object slicing is disabled, stop un-marshalling.
- //
- if(!_sliceObjects)
- {
- throw NoValueFactoryException(__FILE__, __LINE__, "no value factory found and object slicing is disabled",
- _current->typeId);
- }
-
- //
- // Slice off what we don't understand.
- //
- skipSlice();
-
- //
- // If this is the last slice, keep the object as an opaque UnknownSlicedObject.
- //
- if(_current->sliceFlags & FLAG_IS_LAST_SLICE)
- {
- //
- // Provide a factory with an opportunity to supply the object.
- // We pass the "::Ice::Object" ID to indicate that this is the
- // last chance to preserve the object.
- //
- v = newInstance(Object::ice_staticId());
- if(!v)
- {
- v = ICE_MAKE_SHARED(UnknownSlicedObject, mostDerivedId);
- }
-
- break;
- }
-
- startSlice(); // Read next Slice header for next iteration.
- }
-
- //
- // Un-marshal the object
- //
- unmarshal(index, v);
-
- if(!_current && !_patchMap.empty())
- {
- //
- // If any entries remain in the patch map, the sender has sent an index for an object, but failed
- // to supply the object.
- //
- throw MarshalException(__FILE__, __LINE__, "index for class received, but no instance");
- }
-
- if(patchFunc)
- {
- patchFunc(patchAddr, v);
- }
- return index;
-}
-
-SlicedDataPtr
-IceInternal::BasicStream::EncapsDecoder11::readSlicedData()
-{
- if(_current->slices.empty()) // No preserved slices.
- {
- return 0;
- }
-
- //
- // The indirectionTables member holds the indirection table for
- // each slice in slices.
- //
- assert(_current->slices.size() == _current->indirectionTables.size());
- for(SliceInfoSeq::size_type n = 0; n < _current->slices.size(); ++n)
- {
- //
- // We use the "objects" list in SliceInfo to hold references
- // to the target objects. Note that the objects might not have
- // been read yet in the case of a circular reference to an
- // enclosing object.
- //
- const IndexList& table = _current->indirectionTables[n];
- vector<ValuePtr>& objects = _current->slices[n]->objects;
- objects.resize(table.size());
- IndexList::size_type j = 0;
- for(IndexList::const_iterator p = table.begin(); p != table.end(); ++p)
- {
-#ifdef ICE_CPP11_MAPPING
- addPatchEntry(*p, &patchHandle<Value>, &objects[j++]);
-#else
- addPatchEntry(*p, &patchHandle<Object>, &objects[j++]);
-#endif
- }
- }
- return ICE_MAKE_SHARED(SlicedData, _current->slices);
-}
-
-Int
-IceInternal::BasicStream::EncapsEncoder::registerTypeId(const string& typeId)
-{
- TypeIdWriteMap::const_iterator p = _typeIdMap.find(typeId);
- if(p != _typeIdMap.end())
- {
- return p->second;
- }
- else
- {
- _typeIdMap.insert(make_pair(typeId, ++_typeIdIndex));
- return -1;
- }
-}
-
-void
-IceInternal::BasicStream::EncapsEncoder10::write(const ValuePtr& v)
-{
- //
- // Object references are encoded as a negative integer in 1.0.
- //
- if(v)
- {
- _stream->write(-registerObject(v));
- }
- else
- {
- _stream->write(0);
- }
-}
-
-void
-IceInternal::BasicStream::EncapsEncoder10::write(const UserException& v)
-{
- //
- // User exception with the 1.0 encoding start with a boolean
- // flag that indicates whether or not the exception uses
- // classes.
- //
- // This allows reading the pending objects even if some part of
- // the exception was sliced.
- //
- bool usesClasses = v.__usesClasses();
- _stream->write(usesClasses);
- v.__write(_stream);
- if(usesClasses)
- {
- writePendingObjects();
- }
-}
-
-void
-IceInternal::BasicStream::EncapsEncoder10::startInstance(SliceType sliceType, const SlicedDataPtr&)
-{
- _sliceType = sliceType;
-}
-
-void
-IceInternal::BasicStream::EncapsEncoder10::endInstance()
-{
- if(_sliceType == ObjectSlice)
- {
- //
- // Write the Object slice.
- //
- startSlice(Object::ice_staticId(), -1, true);
- _stream->writeSize(0); // For compatibility with the old AFM.
- endSlice();
- }
- _sliceType = NoSlice;
-}
-
-void
-IceInternal::BasicStream::EncapsEncoder10::startSlice(const string& typeId, int, bool /*last*/)
-{
- //
- // For object slices, encode a boolean to indicate how the type ID
- // is encoded and the type ID either as a string or index. For
- // exception slices, always encode the type ID as a string.
- //
- if(_sliceType == ObjectSlice)
- {
- Int index = registerTypeId(typeId);
- if(index < 0)
- {
- _stream->write(false);
- _stream->write(typeId, false);
- }
- else
- {
- _stream->write(true);
- _stream->writeSize(index);
- }
- }
- else
- {
- _stream->write(typeId, false);
- }
-
- _stream->write(Int(0)); // Placeholder for the slice length.
-
- _writeSlice = _stream->b.size();
-}
-
-void
-IceInternal::BasicStream::EncapsEncoder10::endSlice()
-{
- //
- // Write the slice length.
- //
- Int sz = static_cast<Int>(_stream->b.size() - _writeSlice + sizeof(Int));
- Byte* dest = &(*(_stream->b.begin() + _writeSlice - sizeof(Int)));
- _stream->write(sz, dest);
-}
-
-void
-IceInternal::BasicStream::EncapsEncoder10::writePendingObjects()
-{
- while(!_toBeMarshaledMap.empty())
- {
- //
- // Consider the to be marshalled objects as marshalled now,
- // this is necessary to avoid adding again the "to be
- // marshalled objects" into _toBeMarshaledMap while writing
- // objects.
- //
- _marshaledMap.insert(_toBeMarshaledMap.begin(), _toBeMarshaledMap.end());
-
- PtrToIndexMap savedMap;
- savedMap.swap(_toBeMarshaledMap);
- _stream->writeSize(static_cast<Int>(savedMap.size()));
- for(PtrToIndexMap::iterator p = savedMap.begin(); p != savedMap.end(); ++p)
- {
- //
- // Ask the instance to marshal itself. Any new class
- // instances that are triggered by the classes marshaled
- // are added to toBeMarshaledMap.
- //
- _stream->write(p->second);
-
- try
- {
- p->first->ice_preMarshal();
- }
- catch(const std::exception& ex)
- {
- Warning out(_stream->instance()->initializationData().logger);
- out << "std::exception raised by ice_preMarshal:\n" << ex;
- }
- catch(...)
- {
- Warning out(_stream->instance()->initializationData().logger);
- out << "unknown exception raised by ice_preMarshal";
- }
-
- p->first->__write(_stream);
- }
- }
- _stream->writeSize(0); // Zero marker indicates end of sequence of sequences of instances.
-}
-
-Int
-IceInternal::BasicStream::EncapsEncoder10::registerObject(const ValuePtr& v)
-{
- assert(v);
-
- //
- // Look for this instance in the to-be-marshaled map.
- //
- PtrToIndexMap::const_iterator p = _toBeMarshaledMap.find(v);
- if(p != _toBeMarshaledMap.end())
- {
- return p->second;
- }
-
- //
- // Didn't find it, try the marshaled map next.
- //
- PtrToIndexMap::const_iterator q = _marshaledMap.find(v);
- if(q != _marshaledMap.end())
- {
- return q->second;
- }
-
- //
- // We haven't seen this instance previously, create a new
- // index, and insert it into the to-be-marshaled map.
- //
- _toBeMarshaledMap.insert(make_pair(v, ++_objectIdIndex));
- return _objectIdIndex;
-}
-
-void
-IceInternal::BasicStream::EncapsEncoder11::write(const ValuePtr& v)
-{
- if(!v)
- {
- _stream->writeSize(0); // Nil reference.
- }
- else if(_current && _encaps->format == SlicedFormat)
- {
- //
- // If writting an object within a slice and using the sliced
- // format, write an index from the object indirection
- // table. The indirect object table is encoded at the end of
- // each slice and is always read (even if the Slice is
- // unknown).
- //
- PtrToIndexMap::const_iterator p = _current->indirectionMap.find(v);
- if(p == _current->indirectionMap.end())
- {
- _current->indirectionTable.push_back(v);
- Int idx = static_cast<Int>(_current->indirectionTable.size()); // Position + 1 (0 is reserved for nil)
- _current->indirectionMap.insert(make_pair(v, idx));
- _stream->writeSize(idx);
- }
- else
- {
- _stream->writeSize(p->second);
- }
- }
- else
- {
- writeInstance(v); // Write the instance or a reference if already marshaled.
- }
-}
-
-void
-IceInternal::BasicStream::EncapsEncoder11::write(const UserException& v)
-{
- v.__write(_stream);
-}
-
-void
-IceInternal::BasicStream::EncapsEncoder11::startInstance(SliceType sliceType, const SlicedDataPtr& data)
-{
- if(!_current)
- {
- _current = &_preAllocatedInstanceData;
- }
- else
- {
- _current = _current->next ? _current->next : new InstanceData(_current);
- }
- _current->sliceType = sliceType;
- _current->firstSlice = true;
-
- if(data)
- {
- writeSlicedData(data);
- }
-}
-
-void
-IceInternal::BasicStream::EncapsEncoder11::endInstance()
-{
- _current = _current->previous;
-}
-
-void
-IceInternal::BasicStream::EncapsEncoder11::startSlice(const string& typeId, int compactId, bool last)
-{
- assert(_current->indirectionTable.empty() && _current->indirectionMap.empty());
-
- _current->sliceFlagsPos = _stream->b.size();
-
- _current->sliceFlags = 0;
- if(_encaps->format == SlicedFormat)
- {
- _current->sliceFlags |= FLAG_HAS_SLICE_SIZE; // Encode the slice size if using the sliced format.
- }
- if(last)
- {
- _current->sliceFlags |= FLAG_IS_LAST_SLICE; // This is the last slice.
- }
-
- _stream->write(Byte(0)); // Placeholder for the slice flags
-
- //
- // For object slices, encode the flag and the type ID either as a
- // string or index. For exception slices, always encode the type
- // ID a string.
- //
- if(_current->sliceType == ObjectSlice)
- {
- //
- // Encode the type ID (only in the first slice for the compact
- // encoding).
- //
- if(_encaps->format == SlicedFormat || _current->firstSlice)
- {
- if(compactId >= 0)
- {
- _current->sliceFlags |= FLAG_HAS_TYPE_ID_COMPACT;
- _stream->writeSize(compactId);
- }
- else
- {
- Int index = registerTypeId(typeId);
- if(index < 0)
- {
- _current->sliceFlags |= FLAG_HAS_TYPE_ID_STRING;
- _stream->write(typeId, false);
- }
- else
- {
- _current->sliceFlags |= FLAG_HAS_TYPE_ID_INDEX;
- _stream->writeSize(index);
- }
- }
- }
- }
- else
- {
- _stream->write(typeId, false);
- }
-
- if(_current->sliceFlags & FLAG_HAS_SLICE_SIZE)
- {
- _stream->write(Int(0)); // Placeholder for the slice length.
- }
-
- _current->writeSlice = _stream->b.size();
- _current->firstSlice = false;
-}
-
-void
-IceInternal::BasicStream::EncapsEncoder11::endSlice()
-{
- //
- // Write the optional member end marker if some optional members
- // were encoded. Note that the optional members are encoded before
- // the indirection table and are included in the slice size.
- //
- if(_current->sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS)
- {
- _stream->write(OPTIONAL_END_MARKER);
- }
-
- //
- // Write the slice length if necessary.
- //
- if(_current->sliceFlags & FLAG_HAS_SLICE_SIZE)
- {
- Int sz = static_cast<Int>(_stream->b.size() - _current->writeSlice + sizeof(Int));
- Byte* dest = &(*(_stream->b.begin() + _current->writeSlice - sizeof(Int)));
- _stream->write(sz, dest);
- }
-
- //
- // Only write the indirection table if it contains entries.
- //
- if(!_current->indirectionTable.empty())
- {
- assert(_encaps->format == SlicedFormat);
- _current->sliceFlags |= FLAG_HAS_INDIRECTION_TABLE;
-
- //
- // Write the indirection object table.
- //
- _stream->writeSize(static_cast<Int>(_current->indirectionTable.size()));
- ObjectList::const_iterator p;
- for(p = _current->indirectionTable.begin(); p != _current->indirectionTable.end(); ++p)
- {
- writeInstance(*p);
- }
- _current->indirectionTable.clear();
- _current->indirectionMap.clear();
- }
-
- //
- // Finally, update the slice flags.
- //
- Byte* dest = &(*(_stream->b.begin() + _current->sliceFlagsPos));
- *dest = _current->sliceFlags;
-}
-
-bool
-IceInternal::BasicStream::EncapsEncoder11::writeOpt(Ice::Int tag, Ice::OptionalFormat format)
-{
- if(!_current)
- {
- return _stream->writeOptImpl(tag, format);
- }
- else
- {
- if(_stream->writeOptImpl(tag, format))
- {
- _current->sliceFlags |= FLAG_HAS_OPTIONAL_MEMBERS;
- return true;
- }
- else
- {
- return false;
- }
- }
-}
-
-void
-IceInternal::BasicStream::EncapsEncoder11::writeSlicedData(const SlicedDataPtr& slicedData)
-{
- assert(slicedData);
-
- //
- // We only remarshal preserved slices if we are using the sliced
- // format. Otherwise, we ignore the preserved slices, which
- // essentially "slices" the object into the most-derived type
- // known by the sender.
- //
- if(_encaps->format != SlicedFormat)
- {
- return;
- }
-
- for(SliceInfoSeq::const_iterator p = slicedData->slices.begin(); p != slicedData->slices.end(); ++p)
- {
- startSlice((*p)->typeId, (*p)->compactId, (*p)->isLastSlice);
-
- //
- // Write the bytes associated with this slice.
- //
- _stream->writeBlob((*p)->bytes);
-
- if((*p)->hasOptionalMembers)
- {
- _current->sliceFlags |= FLAG_HAS_OPTIONAL_MEMBERS;
- }
-
- //
- // Make sure to also re-write the object indirection table.
- //
- _current->indirectionTable = (*p)->objects;
-
- endSlice();
- }
-}
-
-void
-IceInternal::BasicStream::EncapsEncoder11::writeInstance(const ValuePtr& v)
-{
- assert(v);
-
- //
- // If the instance was already marshaled, just write it's ID.
- //
- PtrToIndexMap::const_iterator q = _marshaledMap.find(v);
- if(q != _marshaledMap.end())
- {
- _stream->writeSize(q->second);
- return;
- }
-
- //
- // We haven't seen this instance previously, create a new ID,
- // insert it into the marshaled map, and write the instance.
- //
- _marshaledMap.insert(make_pair(v, ++_objectIdIndex));
-
- try
- {
- v->ice_preMarshal();
- }
- catch(const std::exception& ex)
- {
- Warning out(_stream->instance()->initializationData().logger);
- out << "std::exception raised by ice_preMarshal:\n" << ex;
- }
- catch(...)
- {
- Warning out(_stream->instance()->initializationData().logger);
- out << "unknown exception raised by ice_preMarshal";
- }
-
- _stream->writeSize(1); // Object instance marker.
- v->__write(_stream);
-}