diff options
Diffstat (limited to 'cpp/include')
-rw-r--r-- | cpp/include/Ice/AsyncResult.h | 14 | ||||
-rw-r--r-- | cpp/include/Ice/BasicStream.h | 1376 | ||||
-rw-r--r-- | cpp/include/Ice/Buffer.h | 4 | ||||
-rw-r--r-- | cpp/include/Ice/Exception.h | 20 | ||||
-rw-r--r-- | cpp/include/Ice/FactoryTable.h | 7 | ||||
-rw-r--r-- | cpp/include/Ice/Ice.h | 1 | ||||
-rw-r--r-- | cpp/include/Ice/Incoming.h | 21 | ||||
-rw-r--r-- | cpp/include/Ice/Initialize.h | 22 | ||||
-rw-r--r-- | cpp/include/Ice/InputStream.h | 944 | ||||
-rw-r--r-- | cpp/include/Ice/InterfaceByValue.h | 15 | ||||
-rw-r--r-- | cpp/include/Ice/LocalObject.h | 7 | ||||
-rw-r--r-- | cpp/include/Ice/Object.h | 27 | ||||
-rw-r--r-- | cpp/include/Ice/Outgoing.h | 39 | ||||
-rw-r--r-- | cpp/include/Ice/OutgoingAsync.h | 31 | ||||
-rw-r--r-- | cpp/include/Ice/OutputStream.h | 715 | ||||
-rw-r--r-- | cpp/include/Ice/Protocol.h | 13 | ||||
-rw-r--r-- | cpp/include/Ice/Proxy.h | 14 | ||||
-rw-r--r-- | cpp/include/Ice/SlicedData.h | 4 | ||||
-rw-r--r-- | cpp/include/Ice/Stream.h | 485 | ||||
-rw-r--r-- | cpp/include/Ice/StreamF.h | 30 | ||||
-rw-r--r-- | cpp/include/Ice/UserExceptionFactory.h | 10 | ||||
-rw-r--r-- | cpp/include/Ice/Value.h | 22 | ||||
-rw-r--r-- | cpp/include/Ice/ValueFactoryManagerF.h | 26 |
23 files changed, 1780 insertions, 2067 deletions
diff --git a/cpp/include/Ice/AsyncResult.h b/cpp/include/Ice/AsyncResult.h index 82b6a49481d..35c307f0d27 100644 --- a/cpp/include/Ice/AsyncResult.h +++ b/cpp/include/Ice/AsyncResult.h @@ -21,7 +21,7 @@ #include <Ice/RequestHandlerF.h> #include <Ice/AsyncResultF.h> #include <Ice/ObserverHelper.h> -#include <Ice/BasicStream.h> +#include <Ice/InputStream.h> #include <Ice/VirtualShared.h> namespace IceInternal @@ -77,22 +77,22 @@ public: const std::string& getOperation() const; - ::IceInternal::BasicStream* __startReadParams() + ::Ice::InputStream* __startReadParams() { - _is.startReadEncaps(); + _is.startEncapsulation(); return &_is; } void __endReadParams() { - _is.endReadEncaps(); + _is.endEncapsulation(); } void __readEmptyParams() { - _is.skipEmptyEncaps(); + _is.skipEmptyEncapsulation(); } void __readParamEncaps(const ::Ice::Byte*& encaps, ::Ice::Int& sz) { - _is.readEncaps(encaps, sz); + _is.readEncapsulation(encaps, sz); } void __throwUserException(); @@ -137,7 +137,7 @@ protected: Ice::ConnectionPtr _cachedConnection; bool _sentSynchronously; - IceInternal::BasicStream _is; + Ice::InputStream _is; IceUtil::Monitor<IceUtil::Mutex> _monitor; diff --git a/cpp/include/Ice/BasicStream.h b/cpp/include/Ice/BasicStream.h deleted file mode 100644 index 3e84af32f81..00000000000 --- a/cpp/include/Ice/BasicStream.h +++ /dev/null @@ -1,1376 +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. -// -// ********************************************************************** - -#ifndef ICE_BASIC_STREAM_H -#define ICE_BASIC_STREAM_H - -#include <IceUtil/StringConverter.h> -#include <Ice/InstanceF.h> -#include <Ice/Object.h> -#include <Ice/ValueF.h> -#include <Ice/ProxyF.h> -#include <Ice/ValueFactory.h> -#include <Ice/ValueFactoryManagerF.h> -#include <Ice/Buffer.h> -#include <Ice/Protocol.h> -#include <Ice/SlicedDataF.h> -#include <Ice/UserExceptionFactory.h> -#include <Ice/StreamHelpers.h> -#include <Ice/FactoryTable.h> -#include <Ice/Traits.h> - -namespace Ice -{ - -class UserException; - -} - -namespace IceInternal -{ - -template<typename T> inline void -patchHandle(void* addr, const Ice::ValuePtr& v) -{ -#ifdef ICE_CPP11_MAPPING - ::std::shared_ptr<T>* handle = static_cast<::std::shared_ptr<T>*>(addr); - *handle = ::std::dynamic_pointer_cast<T>(v); - if(v && !(*handle)) - { - IceInternal::Ex::throwUOE(T::ice_staticId(), v); - } -#else - IceInternal::Handle<T>* p = static_cast<IceInternal::Handle<T>*>(addr); - __patch(*p, v); // Generated __patch method, necessary for forward declarations. -#endif -} - -class ICE_API BasicStream : public Buffer -{ -public: - - typedef size_t size_type; - typedef void (*PatchFunc)(void*, const Ice::ValuePtr&); - - BasicStream(Instance*, const Ice::EncodingVersion&); - BasicStream(Instance*, const Ice::EncodingVersion&, const Ice::Byte*, const Ice::Byte*); - ~BasicStream() - { - // Inlined for performance reasons. - - if(_currentReadEncaps != &_preAllocatedReadEncaps || _currentWriteEncaps != &_preAllocatedWriteEncaps) - { - clear(); // Not inlined. - } - } - - void clear(); - - // - // Must return Instance*, because we don't hold an InstancePtr for - // optimization reasons (see comments below). - // - Instance* instance() const { return _instance; } // Inlined for performance reasons. - - void* closure() const; - void* closure(void*); - - void swap(BasicStream&); - void resetEncaps(); - - void resize(Container::size_type sz) - { - b.resize(sz); - i = b.end(); - } - - void startWriteObject(const Ice::SlicedDataPtr& data) - { - assert(_currentWriteEncaps && _currentWriteEncaps->encoder); - _currentWriteEncaps->encoder->startInstance(ObjectSlice, data); - } - void endWriteObject() - { - assert(_currentWriteEncaps && _currentWriteEncaps->encoder); - _currentWriteEncaps->encoder->endInstance(); - } - - void startReadObject() - { - assert(_currentReadEncaps && _currentReadEncaps->decoder); - _currentReadEncaps->decoder->startInstance(ObjectSlice); - } - Ice::SlicedDataPtr endReadObject(bool preserve) - { - assert(_currentReadEncaps && _currentReadEncaps->decoder); - return _currentReadEncaps->decoder->endInstance(preserve); - } - - void startWriteException(const Ice::SlicedDataPtr& data) - { - assert(_currentWriteEncaps && _currentWriteEncaps->encoder); - _currentWriteEncaps->encoder->startInstance(ExceptionSlice, data); - } - void endWriteException() - { - assert(_currentWriteEncaps && _currentWriteEncaps->encoder); - _currentWriteEncaps->encoder->endInstance(); - } - - void startReadException() - { - assert(_currentReadEncaps && _currentReadEncaps->decoder); - _currentReadEncaps->decoder->startInstance(ExceptionSlice); - } - Ice::SlicedDataPtr endReadException(bool preserve) - { - assert(_currentReadEncaps && _currentReadEncaps->decoder); - return _currentReadEncaps->decoder->endInstance(preserve); - } - - void startWriteEncaps(); - - void startWriteEncaps(const Ice::EncodingVersion& encoding, Ice::FormatType format) - { - checkSupportedEncoding(encoding); - - WriteEncaps* oldEncaps = _currentWriteEncaps; - if(!oldEncaps) // First allocated encaps? - { - _currentWriteEncaps = &_preAllocatedWriteEncaps; - } - else - { - _currentWriteEncaps = new WriteEncaps(); - _currentWriteEncaps->previous = oldEncaps; - } - _currentWriteEncaps->format = format; - _currentWriteEncaps->encoding = encoding; - _currentWriteEncaps->start = b.size(); - - write(Ice::Int(0)); // Placeholder for the encapsulation length. - write(_currentWriteEncaps->encoding); - } - void endWriteEncaps() - { - assert(_currentWriteEncaps); - - // Size includes size and version. - const Ice::Int sz = static_cast<Ice::Int>(b.size() - _currentWriteEncaps->start); - write(sz, &(*(b.begin() + _currentWriteEncaps->start))); - - WriteEncaps* oldEncaps = _currentWriteEncaps; - _currentWriteEncaps = _currentWriteEncaps->previous; - if(oldEncaps == &_preAllocatedWriteEncaps) - { - oldEncaps->reset(); - } - else - { - delete oldEncaps; - } - } - void endWriteEncapsChecked(); // Used by public stream API. - void writeEmptyEncaps(const Ice::EncodingVersion& encoding) - { - checkSupportedEncoding(encoding); - write(Ice::Int(6)); // Size - write(encoding); - } - void writeEncaps(const Ice::Byte* v, Ice::Int sz) - { - if(sz < 6) - { - throwEncapsulationException(__FILE__, __LINE__); - } - - Container::size_type position = b.size(); - resize(position + sz); - memcpy(&b[position], &v[0], sz); - } - - const Ice::EncodingVersion& getWriteEncoding() const - { - return _currentWriteEncaps ? _currentWriteEncaps->encoding : _encoding; - } - - const Ice::EncodingVersion& 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. - // - Ice::Int sz; - read(sz); - if(sz < 6) - { - throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); - } - if(i - sizeof(Ice::Int) + sz > b.end()) - { - throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); - } - _currentReadEncaps->sz = sz; - - read(_currentReadEncaps->encoding); - checkSupportedEncoding(_currentReadEncaps->encoding); // Make sure the encoding is supported - - return _currentReadEncaps->encoding; - } - - void endReadEncaps() - { - assert(_currentReadEncaps); - - if(_currentReadEncaps->encoding != Ice::Encoding_1_0) - { - skipOpts(); - if(i != b.begin() + _currentReadEncaps->start + _currentReadEncaps->sz) - { - throwEncapsulationException(__FILE__, __LINE__); - } - } - else if(i != b.begin() + _currentReadEncaps->start + _currentReadEncaps->sz) - { - if(i + 1 != b.begin() + _currentReadEncaps->start + _currentReadEncaps->sz) - { - throwEncapsulationException(__FILE__, __LINE__); - } - - // - // Ice version < 3.3 had a bug where user exceptions with - // class members could be encoded with a trailing byte - // when dispatched with AMD. So we tolerate an extra byte - // in the encapsulation. - // - ++i; - } - - ReadEncaps* oldEncaps = _currentReadEncaps; - _currentReadEncaps = _currentReadEncaps->previous; - if(oldEncaps == &_preAllocatedReadEncaps) - { - oldEncaps->reset(); - } - else - { - delete oldEncaps; - } - } - Ice::EncodingVersion skipEmptyEncaps() - { - Ice::Int sz; - read(sz); - if(sz != static_cast<Ice::Int>(sizeof(Ice::Int)) + 2) - { - throwEncapsulationException(__FILE__, __LINE__); - } - - if(i + 2 > b.end()) - { - throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); - } - - Ice::EncodingVersion encoding; - read(encoding); - return encoding; - } - void endReadEncapsChecked(); // Used by public stream API. - Ice::EncodingVersion readEncaps(const Ice::Byte*& v, Ice::Int& sz) - { - Ice::EncodingVersion encoding; - v = i; - read(sz); - if(sz < 6) - { - throwEncapsulationException(__FILE__, __LINE__); - } - if(i - sizeof(Ice::Int) + sz > b.end()) - { - throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); - } - - read(encoding); - i += sz - sizeof(Ice::Int) - 2; - return encoding; - } - - const Ice::EncodingVersion& getReadEncoding() const - { - return _currentReadEncaps ? _currentReadEncaps->encoding : _encoding; - } - - Ice::Int getReadEncapsSize(); - Ice::EncodingVersion skipEncaps(); - - void startWriteSlice(const std::string& typeId, int compactId, bool last) - { - assert(_currentWriteEncaps && _currentWriteEncaps->encoder); - _currentWriteEncaps->encoder->startSlice(typeId, compactId, last); - } - void endWriteSlice() - { - assert(_currentWriteEncaps && _currentWriteEncaps->encoder); - _currentWriteEncaps->encoder->endSlice(); - } - - std::string startReadSlice() - { - assert(_currentReadEncaps && _currentReadEncaps->decoder); - return _currentReadEncaps->decoder->startSlice(); - } - void endReadSlice() - { - assert(_currentReadEncaps && _currentReadEncaps->decoder); - _currentReadEncaps->decoder->endSlice(); - } - void skipSlice() - { - assert(_currentReadEncaps && _currentReadEncaps->decoder); - _currentReadEncaps->decoder->skipSlice(); - } - - void readPendingObjects(); - void writePendingObjects(); - - void writeSize(Ice::Int v) // Inlined for performance reasons. - { - assert(v >= 0); - if(v > 254) - { - write(Ice::Byte(255)); - write(v); - } - else - { - write(static_cast<Ice::Byte>(v)); - } - } - void rewriteSize(Ice::Int v, Container::iterator dest) - { - assert(v >= 0); - if(v > 254) - { - *dest++ = Ice::Byte(255); - write(v, dest); - } - else - { - *dest = static_cast<Ice::Byte>(v); - } - } - Ice::Int readSize() // Inlined for performance reasons. - { - Ice::Byte byte; - read(byte); - unsigned char val = static_cast<unsigned char>(byte); - if(val == 255) - { - Ice::Int v; - read(v); - if(v < 0) - { - throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); - } - return v; - } - else - { - return static_cast<Ice::Int>(static_cast<unsigned char>(byte)); - } - } - - Ice::Int readAndCheckSeqSize(int); - - size_type startSize() - { - size_type position = b.size(); - write(Ice::Int(0)); - return position; - } - - void endSize(size_type position) - { - rewrite(static_cast<Ice::Int>(b.size() - position) - 4, position); - } - - void writeBlob(const std::vector<Ice::Byte>&); - void readBlob(std::vector<Ice::Byte>&, Ice::Int); - - void writeBlob(const Ice::Byte* v, Container::size_type sz) - { - if(sz > 0) - { - Container::size_type position = b.size(); - resize(position + sz); - memcpy(&b[position], &v[0], sz); - } - } - - void readBlob(const Ice::Byte*& v, Container::size_type sz) - { - if(sz > 0) - { - v = i; - if(static_cast<Container::size_type>(b.end() - i) < sz) - { - throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); - } - i += sz; - } - else - { - v = i; - } - } - - template<typename T> void write(const T& v) - { - Ice::StreamHelper<T, Ice::StreamableTraits<T>::helper>::write(this, v); - } - template<typename T> void read(T& v) - { - Ice::StreamHelper<T, Ice::StreamableTraits<T>::helper>::read(this, v); - } - - template<typename T> void write(Ice::Int tag, const IceUtil::Optional<T>& v) - { - if(!v) - { - return; // Optional not set - } - - if(writeOpt(tag, Ice::StreamOptionalHelper<T, - Ice::StreamableTraits<T>::helper, - Ice::StreamableTraits<T>::fixedLength>::optionalFormat)) - { - Ice::StreamOptionalHelper<T, - Ice::StreamableTraits<T>::helper, - Ice::StreamableTraits<T>::fixedLength>::write(this, *v); - } - } - template<typename T> void read(Ice::Int tag, IceUtil::Optional<T>& v) - { - if(readOpt(tag, Ice::StreamOptionalHelper<T, - Ice::StreamableTraits<T>::helper, - Ice::StreamableTraits<T>::fixedLength>::optionalFormat)) - { - v.__setIsSet(); - Ice::StreamOptionalHelper<T, - Ice::StreamableTraits<T>::helper, - Ice::StreamableTraits<T>::fixedLength>::read(this, *v); - } - else - { - v = IceUtil::None; - } - } - - // - // Template functions for sequences and custom sequences - // - template<typename T> void write(const std::vector<T>& v) - { - if(v.empty()) - { - writeSize(0); - } - else - { - write(&v[0], &v[0] + v.size()); - } - } - template<typename T> void write(const T* begin, const T* end) - { - writeSize(static_cast<Ice::Int>(end - begin)); - for(const T* p = begin; p != end; ++p) - { - write(*p); - } - } - - // Read/write type and tag for optionals - bool writeOpt(Ice::Int tag, Ice::OptionalFormat format) - { - assert(_currentWriteEncaps); - if(_currentWriteEncaps->encoder) - { - return _currentWriteEncaps->encoder->writeOpt(tag, format); - } - else - { - return writeOptImpl(tag, format); - } - } - bool readOpt(Ice::Int tag, Ice::OptionalFormat expectedFormat) - { - assert(_currentReadEncaps); - if(_currentReadEncaps->decoder) - { - return _currentReadEncaps->decoder->readOpt(tag, expectedFormat); - } - else - { - return readOptImpl(tag, expectedFormat); - } - } - - // Byte - void write(Ice::Byte v) - { - b.push_back(v); - } - void write(const Ice::Byte*, const Ice::Byte*); - void read(Ice::Byte& v) - { - if(i >= b.end()) - { - throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); - } - v = *i++; - } - void read(std::vector<Ice::Byte>&); - void read(std::pair<const Ice::Byte*, const Ice::Byte*>&); - - // This method is useful for generic stream helpers - void read(std::pair<const Ice::Byte*, const Ice::Byte*>& p, ::IceUtil::ScopedArray<Ice::Byte>& result) - { - result.reset(); - read(p); - } - - // Bool - void write(bool v) - { - b.push_back(static_cast<Ice::Byte>(v)); - } - void write(const std::vector<bool>&); - void write(const bool*, const bool*); - void read(bool& v) - { - if(i >= b.end()) - { - throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); - } - v = (0 != *i++); - } - void read(std::vector<bool>&); - void read(std::pair<const bool*, const bool*>&, ::IceUtil::ScopedArray<bool>&); - - // Short - void write(Ice::Short); - void write(const Ice::Short*, const Ice::Short*); - void read(Ice::Short&); - void read(std::vector<Ice::Short>&); - void read(std::pair<const Ice::Short*, const Ice::Short*>&, ::IceUtil::ScopedArray<Ice::Short>&); - - // Int - void write(Ice::Int v) // Inlined for performance reasons. - { - Container::size_type position = b.size(); - resize(position + sizeof(Ice::Int)); - write(v, &b[position]); - } - void write(Ice::Int v, Container::iterator dest) - { -#ifdef ICE_BIG_ENDIAN - const Ice::Byte* src = reinterpret_cast<const Ice::Byte*>(&v) + sizeof(Ice::Int) - 1; - *dest++ = *src--; - *dest++ = *src--; - *dest++ = *src--; - *dest = *src; -#else - const Ice::Byte* src = reinterpret_cast<const Ice::Byte*>(&v); - *dest++ = *src++; - *dest++ = *src++; - *dest++ = *src++; - *dest = *src; -#endif - } - - void read(Ice::Int& v) // Inlined for performance reasons. - { - if(b.end() - i < static_cast<int>(sizeof(Ice::Int))) - { - throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); - } - const Ice::Byte* src = &(*i); - i += sizeof(Ice::Int); -#ifdef ICE_BIG_ENDIAN - Ice::Byte* dest = reinterpret_cast<Ice::Byte*>(&v) + sizeof(Ice::Int) - 1; - *dest-- = *src++; - *dest-- = *src++; - *dest-- = *src++; - *dest = *src; -#else - Ice::Byte* dest = reinterpret_cast<Ice::Byte*>(&v); - *dest++ = *src++; - *dest++ = *src++; - *dest++ = *src++; - *dest = *src; -#endif - } - - void write(const Ice::Int*, const Ice::Int*); - void read(std::vector<Ice::Int>&); - void read(std::pair<const Ice::Int*, const Ice::Int*>&, ::IceUtil::ScopedArray<Ice::Int>&); - - // Long - -#ifdef ICE_CPP11_MAPPING - void write(long long int); -#else - void write(Ice::Long); -#endif - - void write(const Ice::Long*, const Ice::Long*); - void read(Ice::Long&); - void read(std::vector<Ice::Long>&); - void read(std::pair<const Ice::Long*, const Ice::Long*>&, ::IceUtil::ScopedArray<Ice::Long>&); - - // Float - void write(Ice::Float); - void write(const Ice::Float*, const Ice::Float*); - void read(Ice::Float&); - void read(std::vector<Ice::Float>&); - void read(std::pair<const Ice::Float*, const Ice::Float*>&, ::IceUtil::ScopedArray<Ice::Float>&); - - // Double - void write(Ice::Double); - void write(const Ice::Double*, const Ice::Double*); - void read(Ice::Double&); - void read(std::vector<Ice::Double>&); - void read(std::pair<const Ice::Double*, const Ice::Double*>&, ::IceUtil::ScopedArray<Ice::Double>&); - - // String - void write(const std::string& v, bool convert = true) - { - Ice::Int sz = static_cast<Ice::Int>(v.size()); - if(convert && sz > 0 && _stringConverter != 0) - { - writeConverted(v.data(), static_cast<size_t>(sz)); - } - else - { - writeSize(sz); - if(sz > 0) - { - Container::size_type position = b.size(); - resize(position + sz); - memcpy(&b[position], v.data(), sz); - } - } - } - - // for custom strings - void write(const char* vdata, size_t vsize, bool convert = true) - { - Ice::Int sz = static_cast<Ice::Int>(vsize); - if(convert && sz > 0 && _stringConverter != 0) - { - writeConverted(vdata, vsize); - } - else - { - writeSize(sz); - if(sz > 0) - { - Container::size_type position = b.size(); - resize(position + sz); - memcpy(&b[position], vdata, vsize); - } - } - } - - // Null-terminated C string - void write(const char* vdata, bool convert = true) - { - write(vdata, strlen(vdata), convert); - } - - void write(const std::string*, const std::string*, bool = true); - - void read(std::string& v, bool convert = true) - { - Ice::Int sz = readSize(); - if(sz > 0) - { - if(b.end() - i < sz) - { - throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); - } - if(convert && _stringConverter != 0) - { - readConverted(v, sz); - } - else - { - std::string(reinterpret_cast<const char*>(&*i), reinterpret_cast<const char*>(&*i) + sz).swap(v); - } - i += sz; - } - else - { - v.clear(); - } - } - - // For custom strings, convert = false - void read(const char*& vdata, size_t& vsize) - { - Ice::Int sz = readSize(); - if(sz > 0) - { - if(b.end() - i < sz) - { - throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); - } - - vdata = reinterpret_cast<const char*>(&*i); - vsize = static_cast<size_t>(sz); - i += sz; - } - else - { - vdata = 0; - vsize = 0; - } - } - - // For custom strings, convert = true - void read(const char*& vdata, size_t& vsize, std::string& holder) - { - if(_stringConverter == 0) - { - holder.clear(); - read(vdata, vsize); - } - else - { - Ice::Int sz = readSize(); - if(sz > 0) - { - if(b.end() - i < sz) - { - throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); - } - - readConverted(holder, sz); - vdata = holder.data(); - vsize = holder.size(); - } - else - { - holder.clear(); - vdata = 0; - vsize = 0; - } - } - } - - void read(std::vector<std::string>&, bool = true); - - void write(const std::wstring& v); - void write(const std::wstring*, const std::wstring*); - void read(std::wstring&); - void read(std::vector<std::wstring>&); - - // Proxy -#ifdef ICE_CPP11_MAPPING - void writeProxy(const Ice::ObjectPrxPtr&); - - template<typename T, typename ::std::enable_if<::std::is_base_of<::Ice::ObjectPrx, T>::value>::type* = nullptr> - void write(const ::std::shared_ptr<T>& v) - { - writeProxy(::std::static_pointer_cast<::Ice::ObjectPrx>(v)); - } - - ::std::shared_ptr<::Ice::ObjectPrx> readProxy(); - - template<typename T, typename ::std::enable_if<::std::is_base_of<::Ice::ObjectPrx, T>::value>::type* = nullptr> - void read(::std::shared_ptr<T>& v) - { - ::std::shared_ptr<::Ice::ObjectPrx> proxy(readProxy()); - if(!proxy) - { - v = 0; - } - else - { - v = ::IceInternal::createProxy<T>(); - v->__copyFrom(proxy); - } - } -#else - void write(const Ice::ObjectPrx&); - template<typename T> void write(const IceInternal::ProxyHandle<T>& v) - { - write(Ice::ObjectPrx(upCast(v.get()))); - } - void read(Ice::ObjectPrx&); - template<typename T> void read(IceInternal::ProxyHandle<T>& v) - { - __read(this, v); // Generated __read method, necessary for forward declarations. - } -#endif - - // Class -#ifdef ICE_CPP11_MAPPING // C++11 mapping - template<typename T, typename ::std::enable_if<::std::is_base_of<::Ice::Value, T>::value>::type* = nullptr> - void write(const ::std::shared_ptr<T>& v) - { - initWriteEncaps(); - _currentWriteEncaps->encoder->write(v); - } - - template<typename T, typename ::std::enable_if<::std::is_base_of<::Ice::Value, T>::value>::type* = nullptr> - void read(::std::shared_ptr<T>& v) - { - read(&patchHandle<T>, &v); - } -#else // C++98 mapping - void write(const Ice::ObjectPtr& v) - { - initWriteEncaps(); - _currentWriteEncaps->encoder->write(v); - } - template<typename T> void write(const IceInternal::Handle<T>& v) - { - write(Ice::ObjectPtr(upCast(v.get()))); - } - - template<typename T> void read(IceInternal::Handle<T>& v) - { - read(&patchHandle<T>, &v); - } -#endif - - void read(PatchFunc patchFunc, void* patchAddr) - { - initReadEncaps(); - _currentReadEncaps->decoder->read(patchFunc, patchAddr); - } - - // Enum - Ice::Int readEnum(Ice::Int); - void writeEnum(Ice::Int, Ice::Int); - - // Exception - void writeException(const Ice::UserException&); - void throwException(const UserExceptionFactoryPtr& = 0); - - void sliceObjects(bool); - - // Read/write/skip optionals - bool readOptImpl(Ice::Int, Ice::OptionalFormat); - bool writeOptImpl(Ice::Int, Ice::OptionalFormat); - void skipOpt(Ice::OptionalFormat); - void skipOpts(); - - // Skip bytes from the stream - void skip(size_type size) - { - if(i + size > b.end()) - { - throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); - } - i += size; - } - void skipSize() - { - Ice::Byte bt; - read(bt); - if(static_cast<unsigned char>(bt) == 255) - { - skip(4); - } - } - - size_type pos() - { - return i - b.begin(); - } - - void rewrite(Ice::Int value, size_type p) - { - write(value, b.begin() + p); - } - -private: - - // - // String - // - void writeConverted(const char*, size_t); - void readConverted(std::string&, Ice::Int); - - // - // I can't throw these exception from inline functions from within - // this file, because I cannot include the header with the - // exceptions. Doing so would screw up the whole include file - // ordering. - // - void throwUnmarshalOutOfBoundsException(const char*, int); - void throwEncapsulationException(const char*, int); - - // - // Optimization. The instance may not be deleted while a - // stack-allocated BasicStream still holds it. - // - Instance* _instance; - - // - // The public stream API needs to attach data to a stream. - // - void* _closure; - - class ReadEncaps; - class WriteEncaps; - enum SliceType { NoSlice, ObjectSlice, ExceptionSlice }; - - typedef std::vector<Ice::ValuePtr> ObjectList; - - class ICE_API EncapsDecoder : private ::IceUtil::noncopyable - { - public: - - virtual ~EncapsDecoder() { } - - virtual void read(PatchFunc, void*) = 0; - virtual void throwException(const UserExceptionFactoryPtr&) = 0; - - virtual void startInstance(SliceType) = 0; - virtual Ice::SlicedDataPtr endInstance(bool) = 0; - virtual const std::string& startSlice() = 0; - virtual void endSlice() = 0; - virtual void skipSlice() = 0; - - virtual bool readOpt(Ice::Int, Ice::OptionalFormat) - { - return false; - } - - virtual void readPendingObjects() - { - } - - protected: - - EncapsDecoder(BasicStream* stream, ReadEncaps* encaps, bool sliceObjects, const ValueFactoryManagerPtr& f) : - _stream(stream), _encaps(encaps), _sliceObjects(sliceObjects), _servantFactoryManager(f), _typeIdIndex(0) - { - } - - std::string readTypeId(bool); - Ice::ValuePtr newInstance(const std::string&); - - void addPatchEntry(Ice::Int, PatchFunc, void*); - void unmarshal(Ice::Int, const Ice::ValuePtr&); - - typedef std::map<Ice::Int, Ice::ValuePtr> IndexToPtrMap; - typedef std::map<Ice::Int, std::string> TypeIdReadMap; - - struct PatchEntry - { - PatchFunc patchFunc; - void* patchAddr; - }; - typedef std::vector<PatchEntry> PatchList; - typedef std::map<Ice::Int, PatchList> PatchMap; - - BasicStream* _stream; - ReadEncaps* _encaps; - const bool _sliceObjects; - ValueFactoryManagerPtr _servantFactoryManager; - - // Encapsulation attributes for object un-marshalling - PatchMap _patchMap; - - private: - - // Encapsulation attributes for object un-marshalling - IndexToPtrMap _unmarshaledMap; - TypeIdReadMap _typeIdMap; - Ice::Int _typeIdIndex; - ObjectList _objectList; - }; - - class ICE_API EncapsDecoder10 : public EncapsDecoder - { - public: - - EncapsDecoder10(BasicStream* stream, ReadEncaps* encaps, bool sliceObjects, const ValueFactoryManagerPtr& f) : - EncapsDecoder(stream, encaps, sliceObjects, f), _sliceType(NoSlice) - { - } - - virtual void read(PatchFunc, void*); - virtual void throwException(const UserExceptionFactoryPtr&); - - virtual void startInstance(SliceType); - virtual Ice::SlicedDataPtr endInstance(bool); - virtual const std::string& startSlice(); - virtual void endSlice(); - virtual void skipSlice(); - - virtual void readPendingObjects(); - - private: - - void readInstance(); - - // Instance attributes - SliceType _sliceType; - bool _skipFirstSlice; - - // Slice attributes - Ice::Int _sliceSize; - std::string _typeId; - }; - - class ICE_API EncapsDecoder11 : public EncapsDecoder - { - public: - - EncapsDecoder11(BasicStream* stream, ReadEncaps* encaps, bool sliceObjects, const ValueFactoryManagerPtr& f) : - EncapsDecoder(stream, encaps, sliceObjects, f), _preAllocatedInstanceData(0), _current(0), _objectIdIndex(1) - { - } - - virtual void read(PatchFunc, void*); - virtual void throwException(const UserExceptionFactoryPtr&); - - virtual void startInstance(SliceType); - virtual Ice::SlicedDataPtr endInstance(bool); - virtual const std::string& startSlice(); - virtual void endSlice(); - virtual void skipSlice(); - - virtual bool readOpt(Ice::Int, Ice::OptionalFormat); - - private: - - Ice::Int readInstance(Ice::Int, PatchFunc, void*); - Ice::SlicedDataPtr readSlicedData(); - - struct IndirectPatchEntry - { - Ice::Int index; - PatchFunc patchFunc; - void* patchAddr; - }; - typedef std::vector<IndirectPatchEntry> IndirectPatchList; - - typedef std::vector<Ice::Int> IndexList; - typedef std::vector<IndexList> IndexListList; - - struct InstanceData - { - InstanceData(InstanceData* p) : previous(p), next(0) - { - if(previous) - { - previous->next = this; - } - } - - ~InstanceData() - { - if(next) - { - delete next; - } - } - - // Instance attributes - SliceType sliceType; - bool skipFirstSlice; - Ice::SliceInfoSeq slices; // Preserved slices. - IndexListList indirectionTables; - - // Slice attributes - Ice::Byte sliceFlags; - Ice::Int sliceSize; - std::string typeId; - int compactId; - IndirectPatchList indirectPatchList; - - InstanceData* previous; - InstanceData* next; - }; - InstanceData _preAllocatedInstanceData; - InstanceData* _current; - - void push(SliceType sliceType) - { - if(!_current) - { - _current = &_preAllocatedInstanceData; - } - else - { - _current = _current->next ? _current->next : new InstanceData(_current); - } - _current->sliceType = sliceType; - _current->skipFirstSlice = false; - } - - Ice::Int _objectIdIndex; // The ID of the next object to un-marshal. - }; - - class ICE_API EncapsEncoder : private ::IceUtil::noncopyable - { - public: - - virtual ~EncapsEncoder() { } - - virtual void write(const Ice::ValuePtr&) = 0; - virtual void write(const Ice::UserException&) = 0; - - virtual void startInstance(SliceType, const Ice::SlicedDataPtr&) = 0; - virtual void endInstance() = 0; - virtual void startSlice(const std::string&, int, bool) = 0; - virtual void endSlice() = 0; - - virtual bool writeOpt(Ice::Int, Ice::OptionalFormat) - { - return false; - } - - virtual void writePendingObjects() - { - } - - protected: - - EncapsEncoder(BasicStream* stream, WriteEncaps* encaps) : _stream(stream), _encaps(encaps), _typeIdIndex(0) - { - } - - Ice::Int registerTypeId(const std::string&); - - BasicStream* _stream; - WriteEncaps* _encaps; - - typedef std::map<Ice::ValuePtr, Ice::Int> PtrToIndexMap; - typedef std::map<std::string, Ice::Int> TypeIdWriteMap; - - // Encapsulation attributes for object marshalling. - PtrToIndexMap _marshaledMap; - - private: - - // Encapsulation attributes for object marshalling. - TypeIdWriteMap _typeIdMap; - Ice::Int _typeIdIndex; - }; - - class ICE_API EncapsEncoder10 : public EncapsEncoder - { - public: - - EncapsEncoder10(BasicStream* stream, WriteEncaps* encaps) : - EncapsEncoder(stream, encaps), _sliceType(NoSlice), _objectIdIndex(0) - { - } - - virtual void write(const Ice::ValuePtr&); - virtual void write(const Ice::UserException&); - - virtual void startInstance(SliceType, const Ice::SlicedDataPtr&); - virtual void endInstance(); - virtual void startSlice(const std::string&, int, bool); - virtual void endSlice(); - - virtual void writePendingObjects(); - - private: - - Ice::Int registerObject(const Ice::ValuePtr&); - - // Instance attributes - SliceType _sliceType; - - // Slice attributes - Container::size_type _writeSlice; // Position of the slice data members - - // Encapsulation attributes for object marshalling. - Ice::Int _objectIdIndex; - PtrToIndexMap _toBeMarshaledMap; - }; - - class ICE_API EncapsEncoder11 : public EncapsEncoder - { - public: - - EncapsEncoder11(BasicStream* stream, WriteEncaps* encaps) : - EncapsEncoder(stream, encaps), _preAllocatedInstanceData(0), _current(0), _objectIdIndex(1) - { - } - - virtual void write(const Ice::ValuePtr&); - virtual void write(const Ice::UserException&); - - virtual void startInstance(SliceType, const Ice::SlicedDataPtr&); - virtual void endInstance(); - virtual void startSlice(const std::string&, int, bool); - virtual void endSlice(); - - virtual bool writeOpt(Ice::Int, Ice::OptionalFormat); - - private: - - void writeSlicedData(const Ice::SlicedDataPtr&); - void writeInstance(const Ice::ValuePtr&); - - struct InstanceData - { - InstanceData(InstanceData* p) : previous(p), next(0) - { - if(previous) - { - previous->next = this; - } - } - - ~InstanceData() - { - if(next) - { - delete next; - } - } - - // Instance attributes - SliceType sliceType; - bool firstSlice; - - // Slice attributes - Ice::Byte sliceFlags; - Container::size_type writeSlice; // Position of the slice data members - Container::size_type sliceFlagsPos; // Position of the slice flags - PtrToIndexMap indirectionMap; - ObjectList indirectionTable; - - InstanceData* previous; - InstanceData* next; - }; - InstanceData _preAllocatedInstanceData; - InstanceData* _current; - - Ice::Int _objectIdIndex; // The ID of the next object to marhsal - }; - - class ReadEncaps : private ::IceUtil::noncopyable - { - public: - - ReadEncaps() : start(0), decoder(0), previous(0) - { - // Inlined for performance reasons. - } - ~ReadEncaps() - { - // Inlined for performance reasons. - delete decoder; - } - void reset() - { - // Inlined for performance reasons. - delete decoder; - decoder = 0; - - previous = 0; - } - - Container::size_type start; - Ice::Int sz; - Ice::EncodingVersion encoding; - - EncapsDecoder* decoder; - - ReadEncaps* previous; - }; - - class WriteEncaps : private ::IceUtil::noncopyable - { - - public: - - WriteEncaps() : format(Ice::DefaultFormat), encoder(0), previous(0) - { - // Inlined for performance reasons. - } - ~WriteEncaps() - { - // Inlined for performance reasons. - delete encoder; - } - void reset() - { - // Inlined for performance reasons. - delete encoder; - encoder = 0; - - previous = 0; - } - - Container::size_type start; - Ice::EncodingVersion encoding; - Ice::FormatType format; - - EncapsEncoder* encoder; - - WriteEncaps* previous; - }; - - // - // The encoding version to use when there's no encapsulation to - // read from or write to. This is for example used to read message - // headers or when the user is using the streaming API with no - // encapsulation. - // - Ice::EncodingVersion _encoding; - - ReadEncaps* _currentReadEncaps; - WriteEncaps* _currentWriteEncaps; - - void initReadEncaps(); - void initWriteEncaps(); - - ReadEncaps _preAllocatedReadEncaps; - WriteEncaps _preAllocatedWriteEncaps; - - bool _sliceObjects; - - const IceUtil::StringConverterPtr _stringConverter; - const IceUtil::WstringConverterPtr _wstringConverter; - - int _startSeq; - int _minSeqSize; -}; - -} // End namespace IceInternal - -#endif diff --git a/cpp/include/Ice/Buffer.h b/cpp/include/Ice/Buffer.h index 86091b15258..56966089c06 100644 --- a/cpp/include/Ice/Buffer.h +++ b/cpp/include/Ice/Buffer.h @@ -21,6 +21,8 @@ public: Buffer() : i(b.begin()) { } Buffer(const Ice::Byte* beg, const Ice::Byte* end) : b(beg, end), i(b.begin()) { } + Buffer(const std::vector<Ice::Byte>& v) : b(v), i(b.begin()) { } + Buffer(Buffer& o, bool adopt) : b(o.b, adopt), i(b.begin()) { } virtual ~Buffer() { } void swapBuffer(Buffer&); @@ -43,6 +45,8 @@ public: Container(); Container(const_iterator, const_iterator); + Container(const std::vector<value_type>&); + Container(Container&, bool); ~Container(); diff --git a/cpp/include/Ice/Exception.h b/cpp/include/Ice/Exception.h index 63780ae93b3..349e9ef5d78 100644 --- a/cpp/include/Ice/Exception.h +++ b/cpp/include/Ice/Exception.h @@ -16,13 +16,10 @@ #include <Ice/Handle.h> #include <Ice/ObjectF.h> #include <Ice/ValueF.h> -#include <Ice/StreamF.h> namespace IceInternal { -class BasicStream; - namespace Ex { @@ -37,6 +34,9 @@ ICE_API void throwMarshalException(const char*, int, const std::string&); namespace Ice { +class OutputStream; +class InputStream; + typedef IceUtil::Exception Exception; class ICE_API LocalException : public IceUtil::Exception @@ -69,21 +69,15 @@ public: #endif virtual void ice_throw() const = 0; - virtual void __write(::IceInternal::BasicStream*) const; - virtual void __read(::IceInternal::BasicStream*); - - virtual void __write(const OutputStreamPtr&) const; - virtual void __read(const InputStreamPtr&); + virtual void __write(::Ice::OutputStream*) const; + virtual void __read(::Ice::InputStream*); virtual bool __usesClasses() const; protected: - virtual void __writeImpl(::IceInternal::BasicStream*) const = 0; - virtual void __readImpl(::IceInternal::BasicStream*) = 0; - - virtual void __writeImpl(const OutputStreamPtr&) const; - virtual void __readImpl(const InputStreamPtr&); + virtual void __writeImpl(::Ice::OutputStream*) const = 0; + virtual void __readImpl(::Ice::InputStream*) = 0; }; typedef ::IceInternal::Handle<UserException> UserExceptionPtr; diff --git a/cpp/include/Ice/FactoryTable.h b/cpp/include/Ice/FactoryTable.h index 8b6c8d1ad2a..03362685c43 100644 --- a/cpp/include/Ice/FactoryTable.h +++ b/cpp/include/Ice/FactoryTable.h @@ -14,7 +14,6 @@ #include <Ice/UserExceptionFactory.h> #include <Ice/ValueFactory.h> - namespace Ice { @@ -35,8 +34,8 @@ class ICE_API FactoryTable : private IceUtil::noncopyable { public: - void addExceptionFactory(const ::std::string&, const IceInternal::UserExceptionFactoryPtr&); - IceInternal::UserExceptionFactoryPtr getExceptionFactory(const ::std::string&) const; + void addExceptionFactory(const ::std::string&, const Ice::UserExceptionFactoryPtr&); + Ice::UserExceptionFactoryPtr getExceptionFactory(const ::std::string&) const; void removeExceptionFactory(const ::std::string&); #ifdef ICE_CPP11_MAPPING @@ -55,7 +54,7 @@ private: IceUtil::Mutex _m; - typedef ::std::pair<IceInternal::UserExceptionFactoryPtr, int> EFPair; + typedef ::std::pair<Ice::UserExceptionFactoryPtr, int> EFPair; typedef ::std::map< ::std::string, EFPair> EFTable; EFTable _eft; diff --git a/cpp/include/Ice/Ice.h b/cpp/include/Ice/Ice.h index 84b30cba8f1..765004c06f6 100644 --- a/cpp/include/Ice/Ice.h +++ b/cpp/include/Ice/Ice.h @@ -37,7 +37,6 @@ #include <Ice/Connection.h> #include <Ice/ConnectionAsync.h> #include <Ice/Functional.h> -#include <Ice/Stream.h> #include <Ice/ImplicitContext.h> #include <Ice/Locator.h> #include <Ice/Router.h> diff --git a/cpp/include/Ice/Incoming.h b/cpp/include/Ice/Incoming.h index b0b26542c83..d95fb113731 100644 --- a/cpp/include/Ice/Incoming.h +++ b/cpp/include/Ice/Incoming.h @@ -14,7 +14,8 @@ #include <Ice/ConnectionIF.h> #include <Ice/ServantLocatorF.h> #include <Ice/ServantManagerF.h> -#include <Ice/BasicStream.h> +#include <Ice/OutputStream.h> +#include <Ice/InputStream.h> #include <Ice/Object.h> #include <Ice/Current.h> #include <Ice/IncomingAsyncF.h> @@ -32,7 +33,7 @@ public: void __adopt(IncomingBase&); - BasicStream* __startWriteParams(Ice::FormatType); + Ice::OutputStream* __startWriteParams(Ice::FormatType); void __endWriteParams(bool); void __writeEmptyParams(); void __writeParamEncaps(const Ice::Byte*, Ice::Int, bool); @@ -64,7 +65,7 @@ protected: bool _response; Ice::Byte _compress; - BasicStream _os; + Ice::OutputStream _os; // // Optimization. The request handler may not be deleted while a @@ -97,34 +98,34 @@ public: return _inParamPos != 0; } - void invoke(const ServantManagerPtr&, BasicStream*); + void invoke(const ServantManagerPtr&, Ice::InputStream*); // Inlined for speed optimization. - BasicStream* startReadParams() + Ice::InputStream* startReadParams() { // // Remember the encoding used by the input parameters, we'll // encode the response parameters with the same encoding. // - _current.encoding = _is->startReadEncaps(); + _current.encoding = _is->startEncapsulation(); return _is; } void endReadParams() const { - _is->endReadEncaps(); + _is->endEncapsulation(); } void readEmptyParams() { - _current.encoding = _is->skipEmptyEncaps(); + _current.encoding = _is->skipEmptyEncapsulation(); } void readParamEncaps(const Ice::Byte*& v, Ice::Int& sz) { - _current.encoding = _is->readEncaps(v, sz); + _current.encoding = _is->readEncapsulation(v, sz); } private: - BasicStream* _is; + Ice::InputStream* _is; IncomingAsyncPtr _cb; Ice::Byte* _inParamPos; diff --git a/cpp/include/Ice/Initialize.h b/cpp/include/Ice/Initialize.h index 8a892877555..6b060f07106 100644 --- a/cpp/include/Ice/Initialize.h +++ b/cpp/include/Ice/Initialize.h @@ -15,7 +15,6 @@ #include <Ice/PropertiesF.h> #include <Ice/InstanceF.h> #include <Ice/LoggerF.h> -#include <Ice/StreamF.h> #include <Ice/InstrumentationF.h> #include <Ice/Dispatcher.h> #include <Ice/FactoryTable.h> @@ -99,6 +98,7 @@ struct InitializationData CompactIdResolverPtr compactIdResolver; BatchRequestInterceptorPtr batchRequestInterceptor; #endif + ValueFactoryManagerPtr valueFactoryManager; }; ICE_API CommunicatorPtr initialize(int&, char*[], const InitializationData& = InitializationData(), @@ -110,32 +110,12 @@ ICE_API CommunicatorPtr initialize(Ice::StringSeq&, const InitializationData& = ICE_API CommunicatorPtr initialize(const InitializationData& = InitializationData(), Int = ICE_INT_VERSION); -ICE_API InputStreamPtr createInputStream(const CommunicatorPtr&, const ::std::vector< Byte >&); -ICE_API InputStreamPtr createInputStream(const CommunicatorPtr&, const ::std::vector< Byte >&, - const EncodingVersion&); -ICE_API InputStreamPtr wrapInputStream(const CommunicatorPtr&, const ::std::vector< Byte >&); -ICE_API InputStreamPtr wrapInputStream(const CommunicatorPtr&, const ::std::vector< Byte >&, const EncodingVersion&); -ICE_API InputStreamPtr createInputStream(const CommunicatorPtr&, - const ::std::pair< const Ice::Byte*, const Ice::Byte*>&); -ICE_API InputStreamPtr createInputStream(const CommunicatorPtr&, - const ::std::pair< const Ice::Byte*, const Ice::Byte*>&, - const EncodingVersion&); -ICE_API InputStreamPtr wrapInputStream(const CommunicatorPtr&, - const ::std::pair< const Ice::Byte*, const Ice::Byte*>&); -ICE_API InputStreamPtr wrapInputStream(const CommunicatorPtr&, - const ::std::pair< const Ice::Byte*, const Ice::Byte*>&, - const EncodingVersion&); - -ICE_API OutputStreamPtr createOutputStream(const CommunicatorPtr&); -ICE_API OutputStreamPtr createOutputStream(const CommunicatorPtr&, const EncodingVersion&); - ICE_API LoggerPtr getProcessLogger(); ICE_API void setProcessLogger(const LoggerPtr&); typedef Ice::Plugin* (*PluginFactory)(const ::Ice::CommunicatorPtr&, const std::string&, const ::Ice::StringSeq&); ICE_API void registerPluginFactory(const std::string&, PluginFactory, bool); - // // RAII helper class // diff --git a/cpp/include/Ice/InputStream.h b/cpp/include/Ice/InputStream.h new file mode 100644 index 00000000000..0e1aea08587 --- /dev/null +++ b/cpp/include/Ice/InputStream.h @@ -0,0 +1,944 @@ +// ********************************************************************** +// +// 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. +// +// ********************************************************************** + +#ifndef ICE_INPUT_STREAM_H +#define ICE_INPUT_STREAM_H + +#include <IceUtil/StringConverter.h> +#include <Ice/CommunicatorF.h> +#include <Ice/InstanceF.h> +#include <Ice/Object.h> +#include <Ice/ValueF.h> +#include <Ice/ProxyF.h> +#include <Ice/LoggerF.h> +#include <Ice/ValueFactory.h> +#include <Ice/Buffer.h> +#include <Ice/Protocol.h> +#include <Ice/SlicedDataF.h> +#include <Ice/UserExceptionFactory.h> +#include <Ice/StreamHelpers.h> +#include <Ice/FactoryTable.h> +#include <Ice/Traits.h> + +namespace Ice +{ + +class UserException; + +template<typename T> inline void +patchHandle(void* addr, const ValuePtr& v) +{ +#ifdef ICE_CPP11_MAPPING + ::std::shared_ptr<T>* handle = static_cast<::std::shared_ptr<T>*>(addr); + *handle = ::std::dynamic_pointer_cast<T>(v); + if(v && !(*handle)) + { + IceInternal::Ex::throwUOE(T::ice_staticId(), v); + } +#else + IceInternal::Handle<T>* p = static_cast<IceInternal::Handle<T>*>(addr); + __patch(*p, v); // Generated __patch method, necessary for forward declarations. +#endif +} + +class ICE_API InputStream : public IceInternal::Buffer +{ +public: + + typedef size_t size_type; + typedef void (*PatchFunc)(void*, const ValuePtr&); + + // + // These constructors use the latest encoding version. Without a communicator, the stream + // will not be able to unmarshal a proxy. For other unmarshaling tasks, you can provide + // Helpers for objects that are normally provided by a communicator. + // + InputStream(); + InputStream(const std::vector<Byte>&); + InputStream(const std::pair<const Byte*, const Byte*>&); + InputStream(IceInternal::Buffer&, bool = false); + + // + // These constructors use the communicator's default encoding version. + // + InputStream(const CommunicatorPtr&); + InputStream(const CommunicatorPtr&, const std::vector<Byte>&); + InputStream(const CommunicatorPtr&, const std::pair<const Byte*, const Byte*>&); + InputStream(const CommunicatorPtr&, IceInternal::Buffer&, bool = false); + + // + // These constructors use the given encoding version. Without a communicator, the stream + // will not be able to unmarshal a proxy. For other unmarshaling tasks, you can provide + // Helpers for objects that are normally provided by a communicator. + // + InputStream(const EncodingVersion&); + InputStream(const EncodingVersion&, const std::vector<Byte>&); + InputStream(const EncodingVersion&, const std::pair<const Byte*, const Byte*>&); + InputStream(const EncodingVersion&, IceInternal::Buffer&, bool = false); + + // + // These constructors use the given communicator and encoding version. + // + InputStream(const CommunicatorPtr&, const EncodingVersion&); + InputStream(const CommunicatorPtr&, const EncodingVersion&, const std::vector<Byte>&); + InputStream(const CommunicatorPtr&, const EncodingVersion&, const std::pair<const Byte*, const Byte*>&); + InputStream(const CommunicatorPtr&, const EncodingVersion&, IceInternal::Buffer&, bool = false); + + ~InputStream() + { + // Inlined for performance reasons. + + if(_currentEncaps != &_preAllocatedEncaps) + { + clear(); // Not inlined. + } + } + + // + // Use initialize() if you originally constructed the stream without a communicator. + // + void initialize(const CommunicatorPtr&); + void initialize(const CommunicatorPtr&, const EncodingVersion&); + + void clear(); + + // + // Must return Instance*, because we don't hold an InstancePtr for + // optimization reasons (see comments below). + // + IceInternal::Instance* instance() const { return _instance; } // Inlined for performance reasons. + + void setStringConverters(const IceUtil::StringConverterPtr&, const IceUtil::WstringConverterPtr&); + + void setValueFactoryManager(const ValueFactoryManagerPtr&); + + void setLogger(const LoggerPtr&); + +#ifdef ICE_CPP11_MAPPING + void setCompactIdResolver(std::function<std::string (int)>); +#else + void setCompactIdResolver(const CompactIdResolverPtr&); +#endif + +#ifndef ICE_CPP11_MAPPING + void setCollectObjects(bool); +#endif + + void setSliceObjects(bool); + + void setTraceSlicing(bool); + + void* getClosure() const; + void* setClosure(void*); + + void swap(InputStream&); + + void resetEncapsulation(); + + void resize(Container::size_type sz) + { + b.resize(sz); + i = b.end(); + } + + void startObject() + { + assert(_currentEncaps && _currentEncaps->decoder); + _currentEncaps->decoder->startInstance(ObjectSlice); + } + SlicedDataPtr endObject(bool preserve) + { + assert(_currentEncaps && _currentEncaps->decoder); + return _currentEncaps->decoder->endInstance(preserve); + } + + void startException() + { + assert(_currentEncaps && _currentEncaps->decoder); + _currentEncaps->decoder->startInstance(ExceptionSlice); + } + SlicedDataPtr endException(bool preserve) + { + assert(_currentEncaps && _currentEncaps->decoder); + return _currentEncaps->decoder->endInstance(preserve); + } + + const EncodingVersion& startEncapsulation() + { + Encaps* oldEncaps = _currentEncaps; + if(!oldEncaps) // First allocated encaps? + { + _currentEncaps = &_preAllocatedEncaps; + } + else + { + _currentEncaps = new Encaps(); + _currentEncaps->previous = oldEncaps; + } + _currentEncaps->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 < 6) + { + throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + if(i - sizeof(Int) + sz > b.end()) + { + throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + _currentEncaps->sz = sz; + + read(_currentEncaps->encoding); + IceInternal::checkSupportedEncoding(_currentEncaps->encoding); // Make sure the encoding is supported + + return _currentEncaps->encoding; + } + + void endEncapsulation() + { + assert(_currentEncaps); + + if(_currentEncaps->encoding != Encoding_1_0) + { + skipOpts(); + if(i != b.begin() + _currentEncaps->start + _currentEncaps->sz) + { + throwEncapsulationException(__FILE__, __LINE__); + } + } + else if(i != b.begin() + _currentEncaps->start + _currentEncaps->sz) + { + if(i + 1 != b.begin() + _currentEncaps->start + _currentEncaps->sz) + { + throwEncapsulationException(__FILE__, __LINE__); + } + + // + // Ice version < 3.3 had a bug where user exceptions with + // class members could be encoded with a trailing byte + // when dispatched with AMD. So we tolerate an extra byte + // in the encapsulation. + // + ++i; + } + + Encaps* oldEncaps = _currentEncaps; + _currentEncaps = _currentEncaps->previous; + if(oldEncaps == &_preAllocatedEncaps) + { + oldEncaps->reset(); + } + else + { + delete oldEncaps; + } + } + + EncodingVersion skipEmptyEncapsulation() + { + Int sz; + read(sz); + if(sz != static_cast<Int>(sizeof(Int)) + 2) + { + throwEncapsulationException(__FILE__, __LINE__); + } + + if(i + 2 > b.end()) + { + throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + + EncodingVersion encoding; + read(encoding); + return encoding; + } + + EncodingVersion readEncapsulation(const Byte*& v, Int& sz) + { + EncodingVersion encoding; + v = i; + read(sz); + if(sz < 6) + { + throwEncapsulationException(__FILE__, __LINE__); + } + if(i - sizeof(Int) + sz > b.end()) + { + throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + + read(encoding); + i += sz - sizeof(Int) - 2; + return encoding; + } + + const EncodingVersion& getEncoding() const + { + return _currentEncaps ? _currentEncaps->encoding : _encoding; + } + + Int getEncapsSize(); + EncodingVersion skipEncapsulation(); + + std::string startSlice() + { + assert(_currentEncaps && _currentEncaps->decoder); + return _currentEncaps->decoder->startSlice(); + } + void endSlice() + { + assert(_currentEncaps && _currentEncaps->decoder); + _currentEncaps->decoder->endSlice(); + } + void skipSlice() + { + assert(_currentEncaps && _currentEncaps->decoder); + _currentEncaps->decoder->skipSlice(); + } + + void readPendingObjects(); + + Int readSize() // Inlined for performance reasons. + { + Byte byte; + read(byte); + unsigned char val = static_cast<unsigned char>(byte); + if(val == 255) + { + Int v; + read(v); + if(v < 0) + { + throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + return v; + } + else + { + return static_cast<Int>(static_cast<unsigned char>(byte)); + } + } + + Int readAndCheckSeqSize(int); + + void readBlob(std::vector<Byte>&, Int); + + void readBlob(const Byte*& v, Container::size_type sz) + { + if(sz > 0) + { + v = i; + if(static_cast<Container::size_type>(b.end() - i) < sz) + { + throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + i += sz; + } + else + { + v = i; + } + } + + template<typename T> void read(T& v) + { + StreamHelper<T, StreamableTraits<T>::helper>::read(this, v); + } + + template<typename T> void read(Int tag, IceUtil::Optional<T>& v) + { + if(readOpt(tag, StreamOptionalHelper<T, + StreamableTraits<T>::helper, + StreamableTraits<T>::fixedLength>::optionalFormat)) + { + v.__setIsSet(); + StreamOptionalHelper<T, + StreamableTraits<T>::helper, + StreamableTraits<T>::fixedLength>::read(this, *v); + } + else + { + v = IceUtil::None; + } + } + + // Read type and tag for optionals + bool readOpt(Int tag, OptionalFormat expectedFormat) + { + assert(_currentEncaps); + if(_currentEncaps->decoder) + { + return _currentEncaps->decoder->readOpt(tag, expectedFormat); + } + else + { + return readOptImpl(tag, expectedFormat); + } + } + + // Byte + void read(Byte& v) + { + if(i >= b.end()) + { + throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + v = *i++; + } + void read(std::vector<Byte>&); + void read(std::pair<const Byte*, const Byte*>&); + + // This method is useful for generic stream helpers + void read(std::pair<const Byte*, const Byte*>& p, ::IceUtil::ScopedArray<Byte>& result) + { + result.reset(); + read(p); + } + + // Bool + void read(bool& v) + { + if(i >= b.end()) + { + throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + v = (0 != *i++); + } + void read(std::vector<bool>&); + void read(std::pair<const bool*, const bool*>&, ::IceUtil::ScopedArray<bool>&); + + // Short + void read(Short&); + void read(std::vector<Short>&); + void read(std::pair<const Short*, const Short*>&, ::IceUtil::ScopedArray<Short>&); + + // Int + void read(Int& v) // Inlined for performance reasons. + { + if(b.end() - i < static_cast<int>(sizeof(Int))) + { + throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + const Byte* src = &(*i); + i += sizeof(Int); +#ifdef ICE_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 read(std::vector<Int>&); + void read(std::pair<const Int*, const Int*>&, ::IceUtil::ScopedArray<Int>&); + + // Long + + void read(Long&); + void read(std::vector<Long>&); + void read(std::pair<const Long*, const Long*>&, ::IceUtil::ScopedArray<Long>&); + + // Float + void read(Float&); + void read(std::vector<Float>&); + void read(std::pair<const Float*, const Float*>&, ::IceUtil::ScopedArray<Float>&); + + // Double + void read(Double&); + void read(std::vector<Double>&); + void read(std::pair<const Double*, const Double*>&, ::IceUtil::ScopedArray<Double>&); + + // String + void read(std::string& v, bool convert = true) + { + Int sz = readSize(); + if(sz > 0) + { + if(b.end() - i < sz) + { + throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + if(convert && _stringConverter) + { + readConverted(v, sz); + } + else + { + std::string(reinterpret_cast<const char*>(&*i), reinterpret_cast<const char*>(&*i) + sz).swap(v); + } + i += sz; + } + else + { + v.clear(); + } + } + + // For custom strings, convert = false + void read(const char*& vdata, size_t& vsize) + { + Int sz = readSize(); + if(sz > 0) + { + if(b.end() - i < sz) + { + throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + + vdata = reinterpret_cast<const char*>(&*i); + vsize = static_cast<size_t>(sz); + i += sz; + } + else + { + vdata = 0; + vsize = 0; + } + } + + // For custom strings, convert = true + void read(const char*& vdata, size_t& vsize, std::string& holder) + { + if(!_stringConverter) + { + holder.clear(); + read(vdata, vsize); + } + else + { + Int sz = readSize(); + if(sz > 0) + { + if(b.end() - i < sz) + { + throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + + readConverted(holder, sz); + vdata = holder.data(); + vsize = holder.size(); + } + else + { + holder.clear(); + vdata = 0; + vsize = 0; + } + } + } + + void read(std::vector<std::string>&, bool = true); + + void read(std::wstring&); + void read(std::vector<std::wstring>&); + + // Proxy +#ifdef ICE_CPP11_MAPPING + std::shared_ptr<ObjectPrx> readProxy(); + + template<typename T, typename ::std::enable_if<::std::is_base_of<ObjectPrx, T>::value>::type* = nullptr> + void read(::std::shared_ptr<T>& v) + { + ::std::shared_ptr<ObjectPrx> proxy(readProxy()); + if(!proxy) + { + v = 0; + } + else + { + v = ::IceInternal::createProxy<T>(); + v->__copyFrom(proxy); + } + } +#else + void read(ObjectPrx&); + template<typename T> void read(IceInternal::ProxyHandle<T>& v) + { + __read(this, v); // Generated __read method, necessary for forward declarations. + } +#endif + + // Class +#ifdef ICE_CPP11_MAPPING // C++11 mapping + template<typename T, typename ::std::enable_if<::std::is_base_of<Value, T>::value>::type* = nullptr> + void read(::std::shared_ptr<T>& v) + { + read(&patchHandle<T>, &v); + } +#else // C++98 mapping + template<typename T> void read(IceInternal::Handle<T>& v) + { + read(&patchHandle<T>, &v); + } +#endif + + void read(PatchFunc patchFunc, void* patchAddr) + { + initEncaps(); + _currentEncaps->decoder->read(patchFunc, patchAddr); + } + + // Enum + Int readEnum(Int); + + // Exception + void throwException(const Ice::UserExceptionFactoryPtr& = 0); + + // Read/write/skip optionals + bool readOptImpl(Int, OptionalFormat); + void skipOpt(OptionalFormat); + void skipOpts(); + + // Skip bytes from the stream + void skip(size_type size) + { + if(i + size > b.end()) + { + throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); + } + i += size; + } + void skipSize() + { + Byte bt; + read(bt); + if(static_cast<unsigned char>(bt) == 255) + { + skip(4); + } + } + + size_type pos() + { + return i - b.begin(); + } + + InputStream(IceInternal::Instance*, const EncodingVersion&); + InputStream(IceInternal::Instance*, const EncodingVersion&, IceInternal::Buffer&, bool = false); + + void initialize(IceInternal::Instance*, const EncodingVersion&); + +private: + + void initialize(const EncodingVersion&); + + // + // String + // + void readConverted(std::string&, Int); + + // + // We can't throw these exception from inline functions from within + // this file, because we cannot include the header with the + // exceptions. Doing so would screw up the whole include file + // ordering. + // + void throwUnmarshalOutOfBoundsException(const char*, int); + void throwEncapsulationException(const char*, int); + + std::string resolveCompactId(int) const; + + void postUnmarshal(const ValuePtr&) const; + + class Encaps; + enum SliceType { NoSlice, ObjectSlice, ExceptionSlice }; + + void traceSkipSlice(const std::string&, SliceType) const; + + ValueFactoryManagerPtr valueFactoryManager() const; + + LoggerPtr logger() const; + +#ifdef ICE_CPP11_MAPPING + std::function<std::string (int)> compactIdResolver() const; +#else + CompactIdResolverPtr compactIdResolver() const; +#endif + + // + // Optimization. The instance may not be deleted while a + // stack-allocated stream still holds it. + // + IceInternal::Instance* _instance; + + typedef std::vector<ValuePtr> ObjectList; + + class ICE_API EncapsDecoder : private ::IceUtil::noncopyable + { + public: + + virtual ~EncapsDecoder() { } + + virtual void read(PatchFunc, void*) = 0; + virtual void throwException(const Ice::UserExceptionFactoryPtr&) = 0; + + virtual void startInstance(SliceType) = 0; + virtual SlicedDataPtr endInstance(bool) = 0; + virtual const std::string& startSlice() = 0; + virtual void endSlice() = 0; + virtual void skipSlice() = 0; + + virtual bool readOpt(Int, OptionalFormat) + { + return false; + } + + virtual void readPendingObjects() + { + } + + protected: + + EncapsDecoder(InputStream* stream, Encaps* encaps, bool sliceObjects, const Ice::ValueFactoryManagerPtr& f) : + _stream(stream), _encaps(encaps), _sliceObjects(sliceObjects), _valueFactoryManager(f), _typeIdIndex(0) + { + } + + std::string readTypeId(bool); + ValuePtr newInstance(const std::string&); + + void addPatchEntry(Int, PatchFunc, void*); + void unmarshal(Int, const ValuePtr&); + + typedef std::map<Int, ValuePtr> IndexToPtrMap; + typedef std::map<Int, std::string> TypeIdMap; + + struct PatchEntry + { + PatchFunc patchFunc; + void* patchAddr; + }; + typedef std::vector<PatchEntry> PatchList; + typedef std::map<Int, PatchList> PatchMap; + + InputStream* _stream; + Encaps* _encaps; + const bool _sliceObjects; + Ice::ValueFactoryManagerPtr _valueFactoryManager; + + // Encapsulation attributes for object un-marshalling + PatchMap _patchMap; + + private: + + // Encapsulation attributes for object un-marshalling + IndexToPtrMap _unmarshaledMap; + TypeIdMap _typeIdMap; + Int _typeIdIndex; + ObjectList _objectList; + }; + + class ICE_API EncapsDecoder10 : public EncapsDecoder + { + public: + + EncapsDecoder10(InputStream* stream, Encaps* encaps, bool sliceObjects, const Ice::ValueFactoryManagerPtr& f) : + EncapsDecoder(stream, encaps, sliceObjects, f), _sliceType(NoSlice) + { + } + + virtual void read(PatchFunc, void*); + virtual void throwException(const Ice::UserExceptionFactoryPtr&); + + virtual void startInstance(SliceType); + virtual SlicedDataPtr endInstance(bool); + virtual const std::string& startSlice(); + virtual void endSlice(); + virtual void skipSlice(); + + virtual void readPendingObjects(); + + private: + + void readInstance(); + + // Instance attributes + SliceType _sliceType; + bool _skipFirstSlice; + + // Slice attributes + Int _sliceSize; + std::string _typeId; + }; + + class ICE_API EncapsDecoder11 : public EncapsDecoder + { + public: + + EncapsDecoder11(InputStream* stream, Encaps* encaps, bool sliceObjects, const Ice::ValueFactoryManagerPtr& f) : + EncapsDecoder(stream, encaps, sliceObjects, f), _preAllocatedInstanceData(0), _current(0), _objectIdIndex(1) + { + } + + virtual void read(PatchFunc, void*); + virtual void throwException(const Ice::UserExceptionFactoryPtr&); + + virtual void startInstance(SliceType); + virtual SlicedDataPtr endInstance(bool); + virtual const std::string& startSlice(); + virtual void endSlice(); + virtual void skipSlice(); + + virtual bool readOpt(Int, OptionalFormat); + + private: + + Int readInstance(Int, PatchFunc, void*); + SlicedDataPtr readSlicedData(); + + struct IndirectPatchEntry + { + Int index; + PatchFunc patchFunc; + void* patchAddr; + }; + typedef std::vector<IndirectPatchEntry> IndirectPatchList; + + typedef std::vector<Int> IndexList; + typedef std::vector<IndexList> IndexListList; + + struct InstanceData + { + InstanceData(InstanceData* p) : previous(p), next(0) + { + if(previous) + { + previous->next = this; + } + } + + ~InstanceData() + { + if(next) + { + delete next; + } + } + + // Instance attributes + SliceType sliceType; + bool skipFirstSlice; + SliceInfoSeq slices; // Preserved slices. + IndexListList indirectionTables; + + // Slice attributes + Byte sliceFlags; + Int sliceSize; + std::string typeId; + int compactId; + IndirectPatchList indirectPatchList; + + InstanceData* previous; + InstanceData* next; + }; + InstanceData _preAllocatedInstanceData; + InstanceData* _current; + + void push(SliceType sliceType) + { + if(!_current) + { + _current = &_preAllocatedInstanceData; + } + else + { + _current = _current->next ? _current->next : new InstanceData(_current); + } + _current->sliceType = sliceType; + _current->skipFirstSlice = false; + } + + Int _objectIdIndex; // The ID of the next object to un-marshal. + }; + + class Encaps : private ::IceUtil::noncopyable + { + public: + + Encaps() : start(0), decoder(0), previous(0) + { + // Inlined for performance reasons. + } + ~Encaps() + { + // Inlined for performance reasons. + delete decoder; + } + void reset() + { + // Inlined for performance reasons. + delete decoder; + decoder = 0; + + previous = 0; + } + + Container::size_type start; + Int sz; + EncodingVersion encoding; + + EncapsDecoder* decoder; + + Encaps* previous; + }; + + // + // The encoding version to use when there's no encapsulation to + // read from. This is for example used to read message headers. + // + EncodingVersion _encoding; + + Encaps* _currentEncaps; + + void initEncaps(); + + Encaps _preAllocatedEncaps; + +#ifndef ICE_CPP11_MAPPING + bool _collectObjects; +#endif + + bool _traceSlicing; + + void* _closure; + + bool _sliceObjects; + + int _startSeq; + int _minSeqSize; + + IceUtil::StringConverterPtr _stringConverter; + IceUtil::WstringConverterPtr _wstringConverter; + ValueFactoryManagerPtr _valueFactoryManager; + LoggerPtr _logger; +#ifdef ICE_CPP11_MAPPING + std::function<std::string (int)> _compactIdResolver; +#else + CompactIdResolverPtr _compactIdResolver; +#endif +}; + +} // End namespace Ice + +#endif diff --git a/cpp/include/Ice/InterfaceByValue.h b/cpp/include/Ice/InterfaceByValue.h index c2be72d3eb9..c32227a14d4 100644 --- a/cpp/include/Ice/InterfaceByValue.h +++ b/cpp/include/Ice/InterfaceByValue.h @@ -11,7 +11,8 @@ #define ICE_INTERFACE_BY_VALUE_H #include <Ice/Value.h> -#include <Ice/BasicStream.h> +#include <Ice/OutputStream.h> +#include <Ice/InputStream.h> #ifdef ICE_CPP11_MAPPING @@ -24,17 +25,17 @@ class InterfaceByValue : public Ice::ValueHelper<Ice::InterfaceByValue<T>, Ice:: public: virtual void - __writeImpl(::IceInternal::BasicStream* __os) const + __writeImpl(::Ice::OutputStream* __os) const { - __os->startWriteSlice(T::ice_staticId(), -1, true); - __os->endWriteSlice(); + __os->startSlice(T::ice_staticId(), -1, true); + __os->endSlice(); } virtual void - __readImpl(::IceInternal::BasicStream* __is) + __readImpl(::Ice::InputStream* __is) { - __is->startReadSlice(); - __is->endReadSlice(); + __is->startSlice(); + __is->endSlice(); } virtual const std::string& ice_id() const diff --git a/cpp/include/Ice/LocalObject.h b/cpp/include/Ice/LocalObject.h index 1fbbdf153f1..bd5a3278a6e 100644 --- a/cpp/include/Ice/LocalObject.h +++ b/cpp/include/Ice/LocalObject.h @@ -13,13 +13,6 @@ #include <IceUtil/Shared.h> #include <Ice/LocalObjectF.h> -namespace IceInternal -{ - -class BasicStream; - -} - namespace Ice { diff --git a/cpp/include/Ice/Object.h b/cpp/include/Ice/Object.h index 9dcaab32f2c..b057d6bfa16 100644 --- a/cpp/include/Ice/Object.h +++ b/cpp/include/Ice/Object.h @@ -16,14 +16,20 @@ #include <Ice/ProxyF.h> #include <Ice/IncomingAsyncF.h> #include <Ice/Current.h> -#include <Ice/StreamF.h> #include <Ice/Format.h> +namespace Ice +{ + +class OutputStream; +class InpputStream; + +} + namespace IceInternal { class Incoming; -class BasicStream; class Direct; class GCVisitor; @@ -116,11 +122,8 @@ public: virtual Int ice_operationAttributes(const std::string&) const; - virtual void __write(IceInternal::BasicStream*) const; - virtual void __read(IceInternal::BasicStream*); - - virtual void __write(const OutputStreamPtr&) const; - virtual void __read(const InputStreamPtr&); + virtual void __write(Ice::OutputStream*) const; + virtual void __read(Ice::InputStream*); virtual bool __gcVisit(IceInternal::GCVisitor&) { return false; }; virtual void ice_collectable(bool) { }; @@ -144,11 +147,8 @@ protected: protected: - virtual void __writeImpl(IceInternal::BasicStream*) const {} - virtual void __readImpl(IceInternal::BasicStream*) {} - - virtual void __writeImpl(const OutputStreamPtr&) const; - virtual void __readImpl(const InputStreamPtr&); + virtual void __writeImpl(Ice::OutputStream*) const {} + virtual void __readImpl(Ice::InputStream*) {} static void __checkMode(OperationMode, OperationMode); }; @@ -209,9 +209,6 @@ public: virtual DispatchStatus __dispatch(IceInternal::Incoming&, const Current&); }; -ICE_API void ice_writeObject(const OutputStreamPtr&, const ValuePtr&); -ICE_API void ice_readObject(const InputStreamPtr&, ValuePtr&); - } #endif diff --git a/cpp/include/Ice/Outgoing.h b/cpp/include/Ice/Outgoing.h index e44c1660a4e..b86819cd8d7 100644 --- a/cpp/include/Ice/Outgoing.h +++ b/cpp/include/Ice/Outgoing.h @@ -18,7 +18,8 @@ #include <Ice/InstanceF.h> #include <Ice/ConnectionIF.h> #include <Ice/ReferenceF.h> -#include <Ice/BasicStream.h> +#include <Ice/OutputStream.h> +#include <Ice/InputStream.h> #include <Ice/Current.h> #include <Ice/ObserverHelper.h> #include <Ice/ObjectAdapterF.h> @@ -43,10 +44,10 @@ public: virtual void sent() = 0; virtual void completed(const Ice::Exception&) = 0; - virtual void completed(BasicStream&) = 0; + virtual void completed(Ice::InputStream&) = 0; virtual void retryException(const Ice::Exception&) = 0; - BasicStream* os() { return &_os; } + Ice::OutputStream* os() { return &_os; } void attachRemoteObserver(const Ice::ConnectionInfoPtr& c, const Ice::EndpointPtr& endpt, Ice::Int requestId) { @@ -64,7 +65,7 @@ protected: OutgoingBase(Instance*); - BasicStream _os; + Ice::OutputStream _os; #ifdef ICE_CPP11_MAPPING std::exception_ptr _exception; #else @@ -89,7 +90,7 @@ public: virtual void sent(); virtual void completed(const Ice::Exception&); - virtual void completed(BasicStream&); + virtual void completed(Ice::InputStream&); virtual void retryException(const Ice::Exception&); protected: @@ -130,49 +131,49 @@ public: bool invoke(); // Returns true if ok, false if user exception. void abort(const Ice::LocalException&); - virtual void completed(BasicStream&); + virtual void completed(Ice::InputStream&); // Inlined for speed optimization. - BasicStream* startReadParams() + Ice::InputStream* startReadParams() { - _is.startReadEncaps(); + _is.startEncapsulation(); return &_is; } void endReadParams() { - _is.endReadEncaps(); + _is.endEncapsulation(); } void readEmptyParams() { - _is.skipEmptyEncaps(); + _is.skipEmptyEncapsulation(); } void readParamEncaps(const Ice::Byte*& encaps, Ice::Int& sz) { - _is.readEncaps(encaps, sz); + _is.readEncapsulation(encaps, sz); } - BasicStream* startWriteParams(Ice::FormatType format) + Ice::OutputStream* startWriteParams(Ice::FormatType format) { - _os.startWriteEncaps(_encoding, format); + _os.startEncapsulation(_encoding, format); return &_os; } void endWriteParams() { - _os.endWriteEncaps(); + _os.endEncapsulation(); } void writeEmptyParams() { - _os.writeEmptyEncaps(_encoding); + _os.writeEmptyEncapsulation(_encoding); } void writeParamEncaps(const Ice::Byte* encaps, Ice::Int size) { if(size == 0) { - _os.writeEmptyEncaps(_encoding); + _os.writeEmptyEncapsulation(_encoding); } else { - _os.writeEncaps(encaps, size); + _os.writeEncapsulation(encaps, size); } } @@ -186,7 +187,7 @@ public: private: Ice::EncodingVersion _encoding; - BasicStream _is; + Ice::InputStream _is; const std::string& _operation; }; @@ -216,7 +217,7 @@ public: virtual void sent(); virtual void completed(const Ice::Exception&); - virtual void completed(BasicStream&); + virtual void completed(Ice::InputStream&); virtual void retryException(const Ice::Exception&); private: diff --git a/cpp/include/Ice/OutgoingAsync.h b/cpp/include/Ice/OutgoingAsync.h index 61d962a0c7d..afcfc1d7fcc 100644 --- a/cpp/include/Ice/OutgoingAsync.h +++ b/cpp/include/Ice/OutgoingAsync.h @@ -16,6 +16,7 @@ #include <Ice/CommunicatorF.h> #include <Ice/ConnectionIF.h> #include <Ice/ObjectAdapterF.h> +#include <Ice/OutputStream.h> #include <exception> @@ -57,12 +58,12 @@ public: _childObserver.attach(getObserver().getCollocatedObserver(adapter, requestId, size)); } - BasicStream* getOs() + Ice::OutputStream* getOs() { return &_os; } - virtual BasicStream* getIs(); + virtual Ice::InputStream* getIs(); protected: @@ -77,7 +78,7 @@ protected: ObserverHelperT<Ice::Instrumentation::ChildInvocationObserver> _childObserver; - BasicStream _os; + Ice::OutputStream _os; }; // @@ -156,32 +157,32 @@ public: void invoke(); - BasicStream* startWriteParams(Ice::FormatType format) + Ice::OutputStream* startWriteParams(Ice::FormatType format) { - _os.startWriteEncaps(_encoding, format); + _os.startEncapsulation(_encoding, format); return &_os; } void endWriteParams() { - _os.endWriteEncaps(); + _os.endEncapsulation(); } void writeEmptyParams() { - _os.writeEmptyEncaps(_encoding); + _os.writeEmptyEncapsulation(_encoding); } void writeParamEncaps(const ::Ice::Byte* encaps, ::Ice::Int size) { if(size == 0) { - _os.writeEmptyEncaps(_encoding); + _os.writeEmptyEncapsulation(_encoding); } else { - _os.writeEncaps(encaps, size); + _os.writeEncapsulation(encaps, size); } } - virtual BasicStream* getIs() + virtual Ice::InputStream* getIs() { return &_is; } @@ -316,7 +317,7 @@ public: const std::shared_ptr<Ice::ObjectPrx>&, Ice::OperationMode, Ice::FormatType, - std::function<void (::IceInternal::BasicStream*)>, + std::function<void (::Ice::OutputStream*)>, std::function<void ()>, std::function<void (::std::exception_ptr)>, std::function<void (bool)>, @@ -338,7 +339,7 @@ public: TwowayClosureCallback(const std::string&, const std::shared_ptr<Ice::ObjectPrx>&, bool, - std::function<void (::IceInternal::BasicStream*)>, + std::function<void (::Ice::InputStream*)>, std::function<void (const ::Ice::UserException&)>, std::function<void (::std::exception_ptr)>, std::function<void (bool)>); @@ -357,9 +358,9 @@ public: const std::shared_ptr<Ice::ObjectPrx>&, Ice::OperationMode, Ice::FormatType, - std::function<void (::IceInternal::BasicStream*)>, + std::function<void (::Ice::OutputStream*)>, bool, - std::function<void (::IceInternal::BasicStream*)>, + std::function<void (::Ice::InputStream*)>, std::function<void (const ::Ice::UserException&)>, std::function<void (::std::exception_ptr)>, std::function<void (bool)>, @@ -370,7 +371,7 @@ private: const std::string& __name; std::shared_ptr<Ice::ObjectPrx> __proxy; bool __readEmptyParams; - std::function<void (::IceInternal::BasicStream*)> __read; + std::function<void (::Ice::InputStream*)> __read; std::function<void (const ::Ice::UserException&)> __userException; std::function<void (::std::exception_ptr)> __exception; std::function<void (bool)> __sent; diff --git a/cpp/include/Ice/OutputStream.h b/cpp/include/Ice/OutputStream.h new file mode 100644 index 00000000000..74594f1dc25 --- /dev/null +++ b/cpp/include/Ice/OutputStream.h @@ -0,0 +1,715 @@ +// ********************************************************************** +// +// 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. +// +// ********************************************************************** + +#ifndef ICE_OUTPUT_STREAM_H +#define ICE_OUTPUT_STREAM_H + +#include <IceUtil/StringConverter.h> +#include <Ice/CommunicatorF.h> +#include <Ice/InstanceF.h> +#include <Ice/Object.h> +#include <Ice/ValueF.h> +#include <Ice/ProxyF.h> +#include <Ice/Buffer.h> +#include <Ice/Protocol.h> +#include <Ice/SlicedDataF.h> +#include <Ice/StreamHelpers.h> +#include <Ice/Traits.h> + +namespace Ice +{ + +class UserException; + +class ICE_API OutputStream : public IceInternal::Buffer +{ +public: + + typedef size_t size_type; + + // + // Constructing an OutputStream without providing a communicator means the stream will + // use the default encoding version, the default format for class encoding, and will not + // use string converters. You can supply a communicator later by calling initialize(). + // + OutputStream(); + + // + // This constructor uses the communicator's default encoding version. + // + OutputStream(const CommunicatorPtr&); + + // + // This constructor uses the given communicator and encoding version. + // + OutputStream(const CommunicatorPtr&, const EncodingVersion&); + + ~OutputStream() + { + // Inlined for performance reasons. + + if(_currentEncaps != &_preAllocatedEncaps) + { + clear(); // Not inlined. + } + } + + // + // Initializes the stream to use the communicator's default encoding version, class + // encoding format, and string converters. + // + void initialize(const CommunicatorPtr&); + + // + // Initializes the stream to use the given encoding version and the communicator's + // default class encoding format and string converters. + // + void initialize(const CommunicatorPtr&, const EncodingVersion&); + + void clear(); + + // + // Must return Instance*, because we don't hold an InstancePtr for + // optimization reasons (see comments below). + // + IceInternal::Instance* instance() const { return _instance; } // Inlined for performance reasons. + + void setStringConverters(const IceUtil::StringConverterPtr&, const IceUtil::WstringConverterPtr&); + + void setFormat(FormatType); + + void* getClosure() const; + void* setClosure(void*); + + void swap(OutputStream&); + void resetEncapsulation(); + + void resize(Container::size_type sz) + { + b.resize(sz); + i = b.end(); + } + + void startObject(const SlicedDataPtr& data) + { + assert(_currentEncaps && _currentEncaps->encoder); + _currentEncaps->encoder->startInstance(ObjectSlice, data); + } + void endObject() + { + assert(_currentEncaps && _currentEncaps->encoder); + _currentEncaps->encoder->endInstance(); + } + + void startException(const SlicedDataPtr& data) + { + assert(_currentEncaps && _currentEncaps->encoder); + _currentEncaps->encoder->startInstance(ExceptionSlice, data); + } + void endException() + { + assert(_currentEncaps && _currentEncaps->encoder); + _currentEncaps->encoder->endInstance(); + } + + void startEncapsulation(); + + void startEncapsulation(const EncodingVersion& encoding, FormatType format) + { + IceInternal::checkSupportedEncoding(encoding); + + Encaps* oldEncaps = _currentEncaps; + if(!oldEncaps) // First allocated encaps? + { + _currentEncaps = &_preAllocatedEncaps; + } + else + { + _currentEncaps = new Encaps(); + _currentEncaps->previous = oldEncaps; + } + _currentEncaps->format = format; + _currentEncaps->encoding = encoding; + _currentEncaps->start = b.size(); + + write(Int(0)); // Placeholder for the encapsulation length. + write(_currentEncaps->encoding); + } + void endEncapsulation() + { + assert(_currentEncaps); + + // Size includes size and version. + const Int sz = static_cast<Int>(b.size() - _currentEncaps->start); + write(sz, &(*(b.begin() + _currentEncaps->start))); + + Encaps* oldEncaps = _currentEncaps; + _currentEncaps = _currentEncaps->previous; + if(oldEncaps == &_preAllocatedEncaps) + { + oldEncaps->reset(); + } + else + { + delete oldEncaps; + } + } + + void writeEmptyEncapsulation(const EncodingVersion& encoding) + { + IceInternal::checkSupportedEncoding(encoding); + write(Int(6)); // Size + write(encoding); + } + void writeEncapsulation(const Byte* v, Int sz) + { + if(sz < 6) + { + throwEncapsulationException(__FILE__, __LINE__); + } + + Container::size_type position = b.size(); + resize(position + sz); + memcpy(&b[position], &v[0], sz); + } + + const EncodingVersion& getEncoding() const + { + return _currentEncaps ? _currentEncaps->encoding : _encoding; + } + + void startSlice(const std::string& typeId, int compactId, bool last) + { + assert(_currentEncaps && _currentEncaps->encoder); + _currentEncaps->encoder->startSlice(typeId, compactId, last); + } + void endSlice() + { + assert(_currentEncaps && _currentEncaps->encoder); + _currentEncaps->encoder->endSlice(); + } + + void writePendingObjects(); + + void writeSize(Int v) // Inlined for performance reasons. + { + assert(v >= 0); + if(v > 254) + { + write(Byte(255)); + write(v); + } + else + { + write(static_cast<Byte>(v)); + } + } + void rewriteSize(Int v, Container::iterator dest) + { + assert(v >= 0); + if(v > 254) + { + *dest++ = Byte(255); + write(v, dest); + } + else + { + *dest = static_cast<Byte>(v); + } + } + + size_type startSize() + { + size_type position = b.size(); + write(Int(0)); + return position; + } + + void endSize(size_type position) + { + rewrite(static_cast<Int>(b.size() - position) - 4, position); + } + + void writeBlob(const std::vector<Byte>&); + + void writeBlob(const Byte* v, Container::size_type sz) + { + if(sz > 0) + { + Container::size_type position = b.size(); + resize(position + sz); + memcpy(&b[position], &v[0], sz); + } + } + + template<typename T> void write(const T& v) + { + StreamHelper<T, StreamableTraits<T>::helper>::write(this, v); + } + + template<typename T> void write(Int tag, const IceUtil::Optional<T>& v) + { + if(!v) + { + return; // Optional not set + } + + if(writeOpt(tag, StreamOptionalHelper<T, + StreamableTraits<T>::helper, + StreamableTraits<T>::fixedLength>::optionalFormat)) + { + StreamOptionalHelper<T, + StreamableTraits<T>::helper, + StreamableTraits<T>::fixedLength>::write(this, *v); + } + } + + // + // Template functions for sequences and custom sequences + // + template<typename T> void write(const std::vector<T>& v) + { + if(v.empty()) + { + writeSize(0); + } + else + { + write(&v[0], &v[0] + v.size()); + } + } + template<typename T> void write(const T* begin, const T* end) + { + writeSize(static_cast<Int>(end - begin)); + for(const T* p = begin; p != end; ++p) + { + write(*p); + } + } + + // Write type and tag for optionals + bool writeOpt(Int tag, OptionalFormat format) + { + assert(_currentEncaps); + if(_currentEncaps->encoder) + { + return _currentEncaps->encoder->writeOpt(tag, format); + } + else + { + return writeOptImpl(tag, format); + } + } + + // Byte + void write(Byte v) + { + b.push_back(v); + } + void write(const Byte*, const Byte*); + + // Bool + void write(bool v) + { + b.push_back(static_cast<Byte>(v)); + } + void write(const std::vector<bool>&); + void write(const bool*, const bool*); + + // Short + void write(Short); + void write(const Short*, const Short*); + + // Int + void write(Int v) // Inlined for performance reasons. + { + Container::size_type position = b.size(); + resize(position + sizeof(Int)); + write(v, &b[position]); + } + void write(Int v, Container::iterator dest) + { +#ifdef ICE_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 write(const Int*, const Int*); + + // Long + +#ifdef ICE_CPP11_MAPPING + void write(long long int); +#else + void write(Long); +#endif + + void write(const Long*, const Long*); + + // Float + void write(Float); + void write(const Float*, const Float*); + + // Double + void write(Double); + void write(const Double*, const Double*); + + // String + void write(const std::string& v, bool convert = true) + { + Int sz = static_cast<Int>(v.size()); + if(convert && sz > 0 && _stringConverter != 0) + { + writeConverted(v.data(), static_cast<size_t>(sz)); + } + else + { + writeSize(sz); + if(sz > 0) + { + Container::size_type position = b.size(); + resize(position + sz); + memcpy(&b[position], v.data(), sz); + } + } + } + + // for custom strings + void write(const char* vdata, size_t vsize, bool convert = true) + { + Int sz = static_cast<Int>(vsize); + if(convert && sz > 0 && _stringConverter != 0) + { + writeConverted(vdata, vsize); + } + else + { + writeSize(sz); + if(sz > 0) + { + Container::size_type position = b.size(); + resize(position + sz); + memcpy(&b[position], vdata, vsize); + } + } + } + + // Null-terminated C string + void write(const char* vdata, bool convert = true) + { + write(vdata, strlen(vdata), convert); + } + + void write(const std::string*, const std::string*, bool = true); + + void write(const std::wstring& v); + void write(const std::wstring*, const std::wstring*); + + // Proxy +#ifdef ICE_CPP11_MAPPING + void writeProxy(const ObjectPrxPtr&); + + template<typename T, typename ::std::enable_if<::std::is_base_of<ObjectPrx, T>::value>::type* = nullptr> + void write(const ::std::shared_ptr<T>& v) + { + writeProxy(::std::static_pointer_cast<ObjectPrx>(v)); + } +#else + void write(const ObjectPrx&); + template<typename T> void write(const IceInternal::ProxyHandle<T>& v) + { + write(ObjectPrx(upCast(v.get()))); + } +#endif + + // Class +#ifdef ICE_CPP11_MAPPING // C++11 mapping + template<typename T, typename ::std::enable_if<::std::is_base_of<Value, T>::value>::type* = nullptr> + void write(const ::std::shared_ptr<T>& v) + { + initEncaps(); + _currentEncaps->encoder->write(v); + } +#else // C++98 mapping + void write(const ObjectPtr& v) + { + initEncaps(); + _currentEncaps->encoder->write(v); + } + template<typename T> void write(const IceInternal::Handle<T>& v) + { + write(ObjectPtr(upCast(v.get()))); + } +#endif + + // Enum + void writeEnum(Int, Int); + + // Exception + void writeException(const UserException&); + + // Optionals + bool writeOptImpl(Int, OptionalFormat); + + size_type pos() + { + return i - b.begin(); + } + + void rewrite(Int value, size_type p) + { + write(value, b.begin() + p); + } + + OutputStream(IceInternal::Instance*, const EncodingVersion&); + + void initialize(IceInternal::Instance*, const EncodingVersion&); + + void finished(std::vector<Byte>&); + virtual std::pair<const Byte*, const Byte*> finished(); + +private: + + // + // String + // + void writeConverted(const char*, size_t); + + // + // We can't throw this exception from inline functions from within + // this file, because we cannot include the header with the + // exceptions. Doing so would screw up the whole include file + // ordering. + // + void throwEncapsulationException(const char*, int); + + // + // Optimization. The instance may not be deleted while a + // stack-allocated stream still holds it. + // + IceInternal::Instance* _instance; + + // + // The public stream API needs to attach data to a stream. + // + void* _closure; + + class Encaps; + enum SliceType { NoSlice, ObjectSlice, ExceptionSlice }; + + typedef std::vector<ValuePtr> ObjectList; + + class ICE_API EncapsEncoder : private ::IceUtil::noncopyable + { + public: + + virtual ~EncapsEncoder() { } + + virtual void write(const ValuePtr&) = 0; + virtual void write(const UserException&) = 0; + + virtual void startInstance(SliceType, const SlicedDataPtr&) = 0; + virtual void endInstance() = 0; + virtual void startSlice(const std::string&, int, bool) = 0; + virtual void endSlice() = 0; + + virtual bool writeOpt(Int, OptionalFormat) + { + return false; + } + + virtual void writePendingObjects() + { + } + + protected: + + EncapsEncoder(OutputStream* stream, Encaps* encaps) : _stream(stream), _encaps(encaps), _typeIdIndex(0) + { + } + + Int registerTypeId(const std::string&); + + OutputStream* _stream; + Encaps* _encaps; + + typedef std::map<ValuePtr, Int> PtrToIndexMap; + typedef std::map<std::string, Int> TypeIdMap; + + // Encapsulation attributes for object marshalling. + PtrToIndexMap _marshaledMap; + + private: + + // Encapsulation attributes for object marshalling. + TypeIdMap _typeIdMap; + Int _typeIdIndex; + }; + + class ICE_API EncapsEncoder10 : public EncapsEncoder + { + public: + + EncapsEncoder10(OutputStream* stream, Encaps* encaps) : + EncapsEncoder(stream, encaps), _sliceType(NoSlice), _objectIdIndex(0) + { + } + + virtual void write(const ValuePtr&); + virtual void write(const UserException&); + + virtual void startInstance(SliceType, const SlicedDataPtr&); + virtual void endInstance(); + virtual void startSlice(const std::string&, int, bool); + virtual void endSlice(); + + virtual void writePendingObjects(); + + private: + + Int registerObject(const ValuePtr&); + + // Instance attributes + SliceType _sliceType; + + // Slice attributes + Container::size_type _writeSlice; // Position of the slice data members + + // Encapsulation attributes for object marshalling. + Int _objectIdIndex; + PtrToIndexMap _toBeMarshaledMap; + }; + + class ICE_API EncapsEncoder11 : public EncapsEncoder + { + public: + + EncapsEncoder11(OutputStream* stream, Encaps* encaps) : + EncapsEncoder(stream, encaps), _preAllocatedInstanceData(0), _current(0), _objectIdIndex(1) + { + } + + virtual void write(const ValuePtr&); + virtual void write(const UserException&); + + virtual void startInstance(SliceType, const SlicedDataPtr&); + virtual void endInstance(); + virtual void startSlice(const std::string&, int, bool); + virtual void endSlice(); + + virtual bool writeOpt(Int, OptionalFormat); + + private: + + void writeSlicedData(const SlicedDataPtr&); + void writeInstance(const ValuePtr&); + + struct InstanceData + { + InstanceData(InstanceData* p) : previous(p), next(0) + { + if(previous) + { + previous->next = this; + } + } + + ~InstanceData() + { + if(next) + { + delete next; + } + } + + // Instance attributes + SliceType sliceType; + bool firstSlice; + + // Slice attributes + Byte sliceFlags; + Container::size_type writeSlice; // Position of the slice data members + Container::size_type sliceFlagsPos; // Position of the slice flags + PtrToIndexMap indirectionMap; + ObjectList indirectionTable; + + InstanceData* previous; + InstanceData* next; + }; + InstanceData _preAllocatedInstanceData; + InstanceData* _current; + + Int _objectIdIndex; // The ID of the next object to marhsal + }; + + class Encaps : private ::IceUtil::noncopyable + { + + public: + + Encaps() : format(DefaultFormat), encoder(0), previous(0) + { + // Inlined for performance reasons. + } + ~Encaps() + { + // Inlined for performance reasons. + delete encoder; + } + void reset() + { + // Inlined for performance reasons. + delete encoder; + encoder = 0; + + previous = 0; + } + + Container::size_type start; + EncodingVersion encoding; + FormatType format; + + EncapsEncoder* encoder; + + Encaps* previous; + }; + + // + // The encoding version to use when there's no encapsulation to + // read from or write to. This is for example used to read message + // headers or when the user is using the streaming API with no + // encapsulation. + // + EncodingVersion _encoding; + + FormatType _format; + + Encaps* _currentEncaps; + + void initEncaps(); + + Encaps _preAllocatedEncaps; + + IceUtil::StringConverterPtr _stringConverter; + IceUtil::WstringConverterPtr _wstringConverter; +}; + +} // End namespace Ice + +#endif diff --git a/cpp/include/Ice/Protocol.h b/cpp/include/Ice/Protocol.h index 6cb5274f197..a3b56e701cf 100644 --- a/cpp/include/Ice/Protocol.h +++ b/cpp/include/Ice/Protocol.h @@ -72,9 +72,6 @@ enum ProtocolSupport EnableBoth }; -// Forward declaration -class BasicStream; - ICE_API void stringToMajorMinor(const ::std::string&, Ice::Byte&, Ice::Byte&); template<typename T> std::string @@ -104,6 +101,16 @@ ICE_API void throwUnsupportedProtocolException(const char*, int, const Ice::Prot ICE_API void throwUnsupportedEncodingException(const char*, int, const Ice::EncodingVersion&, const Ice::EncodingVersion&); +const ::Ice::Byte OPTIONAL_END_MARKER = 0xFF; + +const ::Ice::Byte FLAG_HAS_TYPE_ID_STRING = (1<<0); +const ::Ice::Byte FLAG_HAS_TYPE_ID_INDEX = (1<<1); +const ::Ice::Byte FLAG_HAS_TYPE_ID_COMPACT = (1<<0) | (1<<1); +const ::Ice::Byte FLAG_HAS_OPTIONAL_MEMBERS = (1<<2); +const ::Ice::Byte FLAG_HAS_INDIRECTION_TABLE = (1<<3); +const ::Ice::Byte FLAG_HAS_SLICE_SIZE = (1<<4); +const ::Ice::Byte FLAG_IS_LAST_SLICE = (1<<5); + } namespace Ice diff --git a/cpp/include/Ice/Proxy.h b/cpp/include/Ice/Proxy.h index 07acb25e477..d9fce7f54df 100644 --- a/cpp/include/Ice/Proxy.h +++ b/cpp/include/Ice/Proxy.h @@ -26,7 +26,6 @@ //#include <Ice/RouterF.h> // Can't include RouterF.h here, otherwise we have cyclic includes //#include <Ice/LocatorF.h> // Can't include RouterF.h here, otherwise we have cyclic includes #include <Ice/Current.h> -#include <Ice/StreamF.h> #include <Ice/CommunicatorF.h> #include <Ice/ObserverHelper.h> #include <Ice/LocalException.h> @@ -66,10 +65,7 @@ class LocatorPrx; typedef ::std::shared_ptr<::Ice::LocatorPrx> LocatorPrxPtr; class LocalException; -} - -namespace Ice -{ +class OutputStream; class ICE_API ObjectPrx : public ::std::enable_shared_from_this<ObjectPrx> { @@ -500,6 +496,8 @@ public: int __hash() const; + void __write(OutputStream&) const; + protected: virtual ::std::shared_ptr<ObjectPrx> __newInstance() const; @@ -783,9 +781,7 @@ typedef ::IceInternal::ProxyHandle< ::IceProxy::Ice::Locator> LocatorPrx; typedef LocatorPrx LocatorPrxPtr; class LocalException; - -ICE_API void ice_writeObjectPrx(const ::Ice::OutputStreamPtr&, const ObjectPrx&); -ICE_API void ice_readObjectPrx(const ::Ice::InputStreamPtr&, ObjectPrx&); +class OutputStream; class Callback_Object_ice_isA_Base : public virtual ::IceInternal::CallbackBase { }; typedef ::IceUtil::Handle< Callback_Object_ice_isA_Base> Callback_Object_ice_isAPtr; @@ -1225,6 +1221,8 @@ public: ::IceInternal::RequestHandlerPtr __setRequestHandler(const ::IceInternal::RequestHandlerPtr&); void __updateRequestHandler(const ::IceInternal::RequestHandlerPtr&, const ::IceInternal::RequestHandlerPtr&); + void __write(::Ice::OutputStream&) const; + protected: virtual Object* __newInstance() const; diff --git a/cpp/include/Ice/SlicedData.h b/cpp/include/Ice/SlicedData.h index 83ef02bce94..4d2a444e1f9 100644 --- a/cpp/include/Ice/SlicedData.h +++ b/cpp/include/Ice/SlicedData.h @@ -96,8 +96,8 @@ public: virtual void __gcVisitMembers(IceInternal::GCVisitor&); #endif - virtual void __write(::IceInternal::BasicStream*) const; - virtual void __read(::IceInternal::BasicStream*); + virtual void __write(::Ice::OutputStream*) const; + virtual void __read(::Ice::InputStream*); private: diff --git a/cpp/include/Ice/Stream.h b/cpp/include/Ice/Stream.h deleted file mode 100644 index aa500040445..00000000000 --- a/cpp/include/Ice/Stream.h +++ /dev/null @@ -1,485 +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. -// -// ********************************************************************** - -#ifndef ICE_STREAM_H -#define ICE_STREAM_H - -#include <Ice/StreamF.h> -#include <Ice/CommunicatorF.h> -#include <Ice/Object.h> -#include <Ice/Exception.h> -#include <Ice/Proxy.h> -#include <Ice/SlicedDataF.h> -#include <IceUtil/Shared.h> -#include <Ice/StreamHelpers.h> - -namespace Ice -{ - -class ICE_API ReadObjectCallback : public ::IceUtil::Shared -{ -public: - - virtual void invoke(const ValuePtr&) = 0; -}; -typedef IceUtil::Handle<ReadObjectCallback> ReadObjectCallbackPtr; - -template<typename T> -class ReadObjectCallbackI : public ReadObjectCallback -{ - -public: - - ReadObjectCallbackI(ICE_INTERNAL_HANDLE<T>& v) : - _v(v) - { - } - - virtual void invoke(const ValuePtr& p) - { -#ifdef ICE_CPP11_MAPPING - _v = ::std::dynamic_pointer_cast<T>(p); -#else - _v = ::IceInternal::Handle<T>::dynamicCast(p); -#endif - if(p && !_v) - { - IceInternal::Ex::throwUOE(T::ice_staticId(), p); - } - } - -private: - - ICE_INTERNAL_HANDLE<T>& _v; -}; - -class ICE_API UserExceptionReader : public UserException -{ -public: - - UserExceptionReader(const CommunicatorPtr&); - ~UserExceptionReader() throw(); - - virtual void read(const InputStreamPtr&) const = 0; - virtual bool usesClasses() const = 0; - - virtual ::std::string ice_id() const = 0; -#ifndef ICE_CPP11_MAPPING - ICE_DEPRECATED_API("ice_name() is deprecated, use ice_id() instead.") - virtual ::std::string ice_name() const = 0; -#endif - virtual UserException* ice_clone() const = 0; - virtual void ice_throw() const = 0; - - virtual void __write(IceInternal::BasicStream*) const; - virtual void __read(IceInternal::BasicStream*); - - virtual bool __usesClasses() const; - - using UserException::__read; - using UserException::__write; - -protected: - - virtual void __writeImpl(::IceInternal::BasicStream*) const; - virtual void __readImpl(::IceInternal::BasicStream*); - - using UserException::__writeImpl; - using UserException::__readImpl; - - const CommunicatorPtr _communicator; -}; - -class ICE_API UserExceptionReaderFactory : public IceUtil::Shared -{ -public: - - virtual void createAndThrow(const std::string&) const = 0; -}; -typedef ::IceUtil::Handle<UserExceptionReaderFactory> UserExceptionReaderFactoryPtr; - -class ICE_API InputStream : public ::IceUtil::Shared -{ -public: - - typedef size_t size_type; - - virtual CommunicatorPtr communicator() const = 0; - - virtual void sliceObjects(bool) = 0; - - virtual Int readSize() = 0; - virtual Int readAndCheckSeqSize(int) = 0; - - virtual ObjectPrxPtr readProxy() = 0; -#ifndef ICE_CPP11_MAPPING - template<typename T> void read(IceInternal::ProxyHandle<T>& v) -#else - template<typename T, typename ::std::enable_if<IsProxy<T>::value>::type* = nullptr> - void read(::std::shared_ptr<T>& v) -#endif - { - ObjectPrxPtr proxy = readProxy(); - if(!proxy) - { - v = 0; - } - else - { - v = ICE_MAKE_SHARED(T); - v->__copyFrom(proxy); - } - } - - virtual void readObject(const ReadObjectCallbackPtr&) = 0; -#ifndef ICE_CPP11_MAPPING - template<typename T> void read(IceInternal::Handle<T>& v) -#else - template<typename T, typename ::std::enable_if<IsValue<T>::value>::type* = nullptr> - void read(::std::shared_ptr<T>& v) -#endif - { - readObject(new ReadObjectCallbackI<T>(v)); - } - - virtual Int readEnum(Int maxValue) - { - if(getEncoding() == 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(); - } - } - - virtual void throwException() = 0; - virtual void throwException(const UserExceptionReaderFactoryPtr&) = 0; - - virtual void startObject() = 0; - virtual SlicedDataPtr endObject(bool) = 0; - - virtual void startException() = 0; - virtual SlicedDataPtr endException(bool) = 0; - - virtual std::string startSlice() = 0; - virtual void endSlice() = 0; - virtual void skipSlice() = 0; - - virtual EncodingVersion startEncapsulation() = 0; - virtual void endEncapsulation() = 0; - virtual EncodingVersion skipEncapsulation() = 0; - - virtual EncodingVersion getEncoding() const = 0; - - virtual void readPendingObjects() = 0; - - virtual size_type pos() = 0; - virtual void rewind() = 0; - - virtual void skip(Int) = 0; - virtual void skipSize() = 0; - - virtual void read(bool&) = 0; - virtual void read(Byte&) = 0; - virtual void read(Short&) = 0; - virtual void read(Int&) = 0; - virtual void read(Long&) = 0; - virtual void read(Float&) = 0; - virtual void read(Double&) = 0; - virtual void read(::std::string&, bool = true) = 0; - virtual void read(const char*&, size_t&) = 0; - virtual void read(const char*&, size_t&, std::string&) = 0; - virtual void read(::std::vector< ::std::string>&, bool) = 0; // Overload required for additional bool argument. - virtual void read(::std::wstring&) = 0; - - // - // std::vector<bool> is a special C++ type, so we give it its own read function - // - virtual void read(::std::vector<bool>&) = 0; - - virtual void read(::std::pair<const bool*, const bool*>&, ::IceUtil::ScopedArray<bool>&) = 0; - virtual void read(::std::pair<const Byte*, const Byte*>&) = 0; - virtual void read(::std::pair<const Short*, const Short*>&, ::IceUtil::ScopedArray<Short>&) = 0; - virtual void read(::std::pair<const Int*, const Int*>&, ::IceUtil::ScopedArray<Int>&) = 0; - virtual void read(::std::pair<const Long*, const Long*>&, ::IceUtil::ScopedArray<Long>&) = 0; - virtual void read(::std::pair<const Float*, const Float*>&, ::IceUtil::ScopedArray<Float>&) = 0; - virtual void read(::std::pair<const Double*, const Double*>&, ::IceUtil::ScopedArray<Double>&) = 0; - - // This method is useful for generic stream helpers - void read(::std::pair<const Byte*, const Byte*>& p, ::IceUtil::ScopedArray<Byte>& result) - { - result.reset(); - read(p); - } - - virtual bool readOptional(Int, OptionalFormat) = 0; - - template<typename T> inline void read(T& v) - { - StreamHelper<T, StreamableTraits<T>::helper>::read(this, v); - } - - template<typename T> inline void read(Int tag, IceUtil::Optional<T>& v) - { - if(readOptional(tag, StreamOptionalHelper<T, - StreamableTraits<T>::helper, - StreamableTraits<T>::fixedLength>::optionalFormat)) - { - v.__setIsSet(); - StreamOptionalHelper<T, StreamableTraits<T>::helper, StreamableTraits<T>::fixedLength>::read(this, *v); - } - else - { - v = IceUtil::None; - } - } - - virtual void closure(void*) = 0; - virtual void* closure() const = 0; -}; - -class ICE_API OutputStream : public ::IceUtil::Shared -{ -public: - - typedef size_t size_type; - - virtual CommunicatorPtr communicator() const = 0; - - virtual void writeSize(Int) = 0; - - virtual void writeProxy(const ObjectPrxPtr&) = 0; -#ifndef ICE_CPP11_MAPPING - template<typename T> void write(const IceInternal::ProxyHandle<T>& v) - { - writeProxy(ObjectPrx(v.get())); - } -#else - template<typename T, typename ::std::enable_if<IsProxy<T>::value>::type* = nullptr> - void write(const ::std::shared_ptr<T>& v) - { - writeProxy(::std::dynamic_pointer_cast<ObjectPrx>(v)); - } -#endif - - virtual void writeObject(const ValuePtr&) = 0; -#ifndef ICE_CPP11_MAPPING - template<typename T> void write(const IceInternal::Handle<T>& v) - { - writeObject(ObjectPtr(v.get())); - } -#else - template<typename T, typename ::std::enable_if<IsValue<T>::value>::type* = nullptr> - void write(const ::std::shared_ptr<T>& v) - { - writeObject(::std::dynamic_pointer_cast<Value>(v)); - } -#endif - - virtual void writeEnum(Int v, Int maxValue) - { - if(getEncoding() == 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); - } - } - - virtual void writeException(const UserException&) = 0; - - virtual void startObject(const SlicedDataPtr&) = 0; - virtual void endObject() = 0; - - virtual void startException(const SlicedDataPtr&) = 0; - virtual void endException() = 0; - - virtual void startSlice(const ::std::string&, int, bool) = 0; - virtual void endSlice() = 0; - - virtual void startEncapsulation(const EncodingVersion&, FormatType) = 0; - virtual void startEncapsulation() = 0; - virtual void endEncapsulation() = 0; - - virtual EncodingVersion getEncoding() const = 0; - - virtual void writePendingObjects() = 0; - - virtual void finished(::std::vector<Byte>&) = 0; - virtual std::pair<const Byte*, const Byte*> finished() = 0; - - virtual size_type pos() = 0; - virtual void rewrite(Int, size_type) = 0; - - virtual void reset(bool) = 0; - - virtual void write(bool) = 0; - virtual void write(Byte) = 0; - virtual void write(Short) = 0; - virtual void write(Int) = 0; - virtual void write(Long) = 0; - virtual void write(Float) = 0; - virtual void write(Double) = 0; - virtual void write(const ::std::string&, bool = true) = 0; - virtual void write(const char*, size_t, bool = true) = 0; - virtual void write(const ::std::vector< ::std::string>&, bool) = 0; // Overload required for bool argument. - virtual void write(const char*, bool = true) = 0; - virtual void write(const ::std::wstring&) = 0; - - // - // std::vector<bool> is a special C++ type, so we give it its own write function - // - virtual void write(const ::std::vector<bool>&) = 0; - - virtual void write(const bool*, const bool*) = 0; - virtual void write(const Byte*, const Byte*) = 0; - virtual void write(const Short*, const Short*) = 0; - virtual void write(const Int*, const Int*) = 0; - virtual void write(const Long*, const Long*) = 0; - virtual void write(const Float*, const Float*) = 0; - virtual void write(const Double*, const Double*) = 0; - - virtual bool writeOptional(Int, OptionalFormat) = 0; - - virtual size_type startSize() = 0; - virtual void endSize(size_type pos) = 0; - - template<typename T> inline void write(const T& v) - { - StreamHelper<T, StreamableTraits<T>::helper>::write(this, v); - } - - template<typename T> inline void write(Int tag, const IceUtil::Optional<T>& v) - { - if(v) - { - writeOptional(tag, StreamOptionalHelper<T, - StreamableTraits<T>::helper, - StreamableTraits<T>::fixedLength>::optionalFormat); - StreamOptionalHelper<T, StreamableTraits<T>::helper, StreamableTraits<T>::fixedLength>::write(this, *v); - } - } - - // - // Template functions for sequences and custom sequences - // - template<typename T> void write(const T* begin, const T* end) - { - writeSize(static_cast<Int>(end - begin)); - for(const T* p = begin; p != end; ++p) - { - write(*p); - } - } -}; - -class ICE_API ObjectReader : public Object -{ -public: - - virtual void read(const InputStreamPtr&) = 0; - -private: - - virtual void __write(::IceInternal::BasicStream*) const; - virtual void __read(::IceInternal::BasicStream*); - - virtual void __write(const OutputStreamPtr&) const; - virtual void __read(const InputStreamPtr&); -}; -typedef ::IceInternal::Handle<ObjectReader> ObjectReaderPtr; - -class ICE_API ObjectWriter : public Object -{ -public: - - virtual void write(const OutputStreamPtr&) const = 0; - -private: - - virtual void __write(::IceInternal::BasicStream*) const; - virtual void __read(::IceInternal::BasicStream*); - - virtual void __write(const OutputStreamPtr&) const; - virtual void __read(const InputStreamPtr&); -}; -typedef ::IceInternal::Handle<ObjectWriter> ObjectWriterPtr; - -class ICE_API UserExceptionWriter : public UserException -{ -public: - - UserExceptionWriter(const CommunicatorPtr&); - ~UserExceptionWriter() throw(); - - virtual void write(const OutputStreamPtr&) const = 0; - virtual bool usesClasses() const = 0; - - virtual ::std::string ice_id() const = 0; -#ifndef ICE_CPP11_MAPPING - ICE_DEPRECATED_API("ice_name() is deprecated, use ice_id() instead.") - virtual ::std::string ice_name() const = 0; -#endif - virtual UserException* ice_clone() const = 0; - virtual void ice_throw() const = 0; - - virtual void __write(IceInternal::BasicStream*) const; - virtual void __read(IceInternal::BasicStream*); - - virtual bool __usesClasses() const; - - using UserException::__read; - using UserException::__write; - -protected: - - virtual void __writeImpl(::IceInternal::BasicStream*) const; - virtual void __readImpl(::IceInternal::BasicStream*); - - using UserException::__writeImpl; - using UserException::__readImpl; - - const CommunicatorPtr _communicator; -}; - -} - -#endif diff --git a/cpp/include/Ice/StreamF.h b/cpp/include/Ice/StreamF.h deleted file mode 100644 index f7f17eb27e2..00000000000 --- a/cpp/include/Ice/StreamF.h +++ /dev/null @@ -1,30 +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. -// -// ********************************************************************** - -#ifndef ICE_STREAM_F_H -#define ICE_STREAM_F_H - -#include <IceUtil/Shared.h> - -#include <Ice/Handle.h> - -namespace Ice -{ - -class InputStream; -ICE_API IceUtil::Shared* upCast(::Ice::InputStream*); -typedef IceInternal::Handle< InputStream > InputStreamPtr; - -class OutputStream; -ICE_API IceUtil::Shared* upCast(::Ice::OutputStream*); -typedef IceInternal::Handle< OutputStream > OutputStreamPtr; - -} - -#endif diff --git a/cpp/include/Ice/UserExceptionFactory.h b/cpp/include/Ice/UserExceptionFactory.h index 4a1085fd15d..23c8aba5999 100644 --- a/cpp/include/Ice/UserExceptionFactory.h +++ b/cpp/include/Ice/UserExceptionFactory.h @@ -14,7 +14,7 @@ #include <IceUtil/Handle.h> #include <Ice/Config.h> -namespace IceInternal +namespace Ice { class ICE_API UserExceptionFactory : public IceUtil::Shared @@ -24,11 +24,15 @@ public: virtual void createAndThrow(const ::std::string&) = 0; virtual ~UserExceptionFactory() {} }; - typedef ::IceUtil::Handle<UserExceptionFactory> UserExceptionFactoryPtr; +} + +namespace IceInternal +{ + template<class E> -class DefaultUserExceptionFactory : public UserExceptionFactory +class DefaultUserExceptionFactory : public Ice::UserExceptionFactory { public: diff --git a/cpp/include/Ice/Value.h b/cpp/include/Ice/Value.h index 3a242168229..d348b0e01e5 100644 --- a/cpp/include/Ice/Value.h +++ b/cpp/include/Ice/Value.h @@ -13,18 +13,13 @@ #ifdef ICE_CPP11_MAPPING // C++11 mapping #include <Ice/ValueF.h> -#include <Ice/StreamF.h> - -namespace IceInternal -{ - -class BasicStream; - -} namespace Ice { +class OutputStream; +class InputStream; + class ICE_API Value { public: @@ -34,8 +29,8 @@ public: virtual void ice_preMarshal(); virtual void ice_postUnmarshal(); - virtual void __write(IceInternal::BasicStream*) const; - virtual void __read(IceInternal::BasicStream*); + virtual void __write(Ice::OutputStream*) const; + virtual void __read(Ice::InputStream*); virtual const std::string& ice_id() const; static const std::string& ice_staticId(); @@ -46,8 +41,8 @@ protected: virtual std::shared_ptr<Value> cloneImpl() const = 0; - virtual void __writeImpl(IceInternal::BasicStream*) const {} - virtual void __readImpl(IceInternal::BasicStream*) {} + virtual void __writeImpl(Ice::OutputStream*) const {} + virtual void __readImpl(Ice::InputStream*) {} }; template<typename T, typename Base> class ValueHelper : public Base @@ -76,9 +71,6 @@ protected: } }; -ICE_API void ice_writeObject(const OutputStreamPtr&, const std::shared_ptr<Value>&); -ICE_API void ice_readObject(const InputStreamPtr&, std::shared_ptr<Value>&); - } #endif // C++11 mapping end diff --git a/cpp/include/Ice/ValueFactoryManagerF.h b/cpp/include/Ice/ValueFactoryManagerF.h deleted file mode 100644 index 0cbd46da420..00000000000 --- a/cpp/include/Ice/ValueFactoryManagerF.h +++ /dev/null @@ -1,26 +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. -// -// ********************************************************************** - -#ifndef ICE_VALUE_FACTORY_MANAGER_F_H -#define ICE_VALUE_FACTORY_MANAGER_F_H - -#include <IceUtil/Shared.h> - -#include <Ice/Handle.h> - -namespace IceInternal -{ - -class ValueFactoryManager; -IceUtil::Shared* upCast(ValueFactoryManager*); -typedef Handle<ValueFactoryManager> ValueFactoryManagerPtr; - -} - -#endif |