diff options
author | Benoit Foucher <benoit@zeroc.com> | 2013-01-23 14:36:10 +0100 |
---|---|---|
committer | Benoit Foucher <benoit@zeroc.com> | 2013-01-23 14:36:10 +0100 |
commit | 66bf1a7f2d0d46281ebf3d62caab6b9158eaa8a0 (patch) | |
tree | bd6aca447179f8d2e586c12cb961d683552504be | |
parent | Minor code style fixes (diff) | |
download | ice-66bf1a7f2d0d46281ebf3d62caab6b9158eaa8a0.tar.bz2 ice-66bf1a7f2d0d46281ebf3d62caab6b9158eaa8a0.tar.xz ice-66bf1a7f2d0d46281ebf3d62caab6b9158eaa8a0.zip |
Fix for ICE-4841 - added no copy option when creating input stream
29 files changed, 327 insertions, 129 deletions
diff --git a/cpp/include/Ice/BasicStream.h b/cpp/include/Ice/BasicStream.h index b5036a79528..a2717687e77 100644 --- a/cpp/include/Ice/BasicStream.h +++ b/cpp/include/Ice/BasicStream.h @@ -55,6 +55,7 @@ public: typedef void (*PatchFunc)(void*, const Ice::ObjectPtr&); BasicStream(Instance*, const Ice::EncodingVersion&, bool = false); + BasicStream(Instance*, const Ice::EncodingVersion&, const Ice::Byte*, const Ice::Byte*); ~BasicStream() { // Inlined for performance reasons. diff --git a/cpp/include/Ice/Buffer.h b/cpp/include/Ice/Buffer.h index 7801cd33b2c..c3b522f97f3 100644 --- a/cpp/include/Ice/Buffer.h +++ b/cpp/include/Ice/Buffer.h @@ -20,6 +20,7 @@ class ICE_API Buffer : private IceUtil::noncopyable public: Buffer(size_t maxCapacity) : b(maxCapacity), i(b.begin()) { } + Buffer(const Ice::Byte* beg, const Ice::Byte* end) : b(beg, end), i(b.begin()) { } virtual ~Buffer() { } void swapBuffer(Buffer&); @@ -41,6 +42,7 @@ public: typedef size_t size_type; Container(size_type maxCapacity); + Container(const_iterator, const_iterator); ~Container(); @@ -80,6 +82,8 @@ public: void resize(size_type n) // Inlined for performance reasons. { + assert(!_buf || _capacity > 0); + if(n == 0) { clear(); @@ -93,6 +97,8 @@ public: void reset() { + assert(!_buf || _capacity > 0); + if(_size > 0 && _size * 2 < _capacity) { // diff --git a/cpp/include/Ice/Initialize.h b/cpp/include/Ice/Initialize.h index 004bd4277b6..753ac5dddb2 100644 --- a/cpp/include/Ice/Initialize.h +++ b/cpp/include/Ice/Initialize.h @@ -108,11 +108,19 @@ ICE_API CommunicatorPtr initialize(const InitializationData& = InitializationDat 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 createInputStream(const CommunicatorPtr&, const ::std::vector< Byte >&, bool); +ICE_API InputStreamPtr createInputStream(const CommunicatorPtr&, const ::std::vector< Byte >&, + const EncodingVersion&, bool); 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 createInputStream(const CommunicatorPtr&, + const ::std::pair< const Ice::Byte*, const Ice::Byte*>&, bool); +ICE_API InputStreamPtr createInputStream(const CommunicatorPtr&, + const ::std::pair< const Ice::Byte*, const Ice::Byte*>&, + const EncodingVersion&, bool); ICE_API OutputStreamPtr createOutputStream(const CommunicatorPtr&); ICE_API OutputStreamPtr createOutputStream(const CommunicatorPtr&, const EncodingVersion&); diff --git a/cpp/src/Freeze/ObjectStore.cpp b/cpp/src/Freeze/ObjectStore.cpp index 44a9fb2b02f..bf4f3b0545d 100644 --- a/cpp/src/Freeze/ObjectStore.cpp +++ b/cpp/src/Freeze/ObjectStore.cpp @@ -346,10 +346,7 @@ Freeze::ObjectStoreBase::unmarshal(Identity& ident, const EncodingVersion& encoding) { IceInternal::InstancePtr instance = IceInternal::getInstance(communicator); - IceInternal::BasicStream stream(instance.get(), encoding, true); - stream.b.resize(bytes.size()); - memcpy(&stream.b[0], &bytes[0], bytes.size()); - stream.i = stream.b.begin(); + IceInternal::BasicStream stream(instance.get(), encoding, &bytes[0], &bytes[0] + bytes.size()); stream.read(ident); } @@ -385,11 +382,8 @@ Freeze::ObjectStoreBase::unmarshal(ObjectRecord& v, bool keepStats) { IceInternal::InstancePtr instance = IceInternal::getInstance(communicator); - IceInternal::BasicStream stream(instance.get(), encoding, true); + IceInternal::BasicStream stream(instance.get(), encoding, &bytes[0], &bytes[0] + bytes.size()); stream.sliceObjects(false); - stream.b.resize(bytes.size()); - memcpy(&stream.b[0], &bytes[0], bytes.size()); - stream.i = stream.b.begin(); stream.startReadEncaps(); if(keepStats) diff --git a/cpp/src/FreezeScript/DumpDescriptors.cpp b/cpp/src/FreezeScript/DumpDescriptors.cpp index 4b61939857f..4661cc5a9fb 100644 --- a/cpp/src/FreezeScript/DumpDescriptors.cpp +++ b/cpp/src/FreezeScript/DumpDescriptors.cpp @@ -1269,12 +1269,12 @@ FreezeScript::RecordDescriptor::execute(const SymbolTablePtr& /*sym*/, ExecuteIn Ice::ByteSeq keyBytes; keyBytes.resize(dbKey.get_size()); memcpy(&keyBytes[0], dbKey.get_data(), dbKey.get_size()); - Ice::InputStreamPtr inKey = Ice::createInputStream(info->communicator, keyBytes); + Ice::InputStreamPtr inKey = Ice::createInputStream(info->communicator, keyBytes, false); Ice::ByteSeq valueBytes; valueBytes.resize(dbValue.get_size()); memcpy(&valueBytes[0], dbValue.get_data(), dbValue.get_size()); - Ice::InputStreamPtr inValue = Ice::createInputStream(info->communicator, valueBytes); + Ice::InputStreamPtr inValue = Ice::createInputStream(info->communicator, valueBytes, false); inValue->startEncapsulation(); // diff --git a/cpp/src/FreezeScript/Transformer.cpp b/cpp/src/FreezeScript/Transformer.cpp index 5048e82cffc..c10c13e37a9 100644 --- a/cpp/src/FreezeScript/Transformer.cpp +++ b/cpp/src/FreezeScript/Transformer.cpp @@ -1960,8 +1960,8 @@ FreezeScript::RecordDescriptor::transformRecord(const Ice::ByteSeq& inKeyBytes, Ice::ByteSeq& outKeyBytes, Ice::ByteSeq& outValueBytes) { - Ice::InputStreamPtr inKey = Ice::createInputStream(_info->communicator, inKeyBytes); - Ice::InputStreamPtr inValue = Ice::createInputStream(_info->communicator, inValueBytes); + Ice::InputStreamPtr inKey = Ice::createInputStream(_info->communicator, inKeyBytes, false); + Ice::InputStreamPtr inValue = Ice::createInputStream(_info->communicator, inValueBytes, false); inValue->startEncapsulation(); Ice::OutputStreamPtr outKey = Ice::createOutputStream(_info->communicator); diff --git a/cpp/src/Ice/BasicStream.cpp b/cpp/src/Ice/BasicStream.cpp index 46f6e440241..e30462bdbb7 100644 --- a/cpp/src/Ice/BasicStream.cpp +++ b/cpp/src/Ice/BasicStream.cpp @@ -112,6 +112,30 @@ IceInternal::BasicStream::BasicStream(Instance* instance, const EncodingVersion& _preAllocatedWriteEncaps.encoding = encoding; } +IceInternal::BasicStream::BasicStream(Instance* instance, const EncodingVersion& encoding, const Byte* begin, + const Byte* end) : + IceInternal::Buffer(begin, end), + _instance(instance), + _closure(0), + _encoding(encoding), + _currentReadEncaps(0), + _currentWriteEncaps(0), + _sliceObjects(true), + _messageSizeMax(_instance->messageSizeMax()), // Cached for efficiency. + _unlimited(false), + _stringConverter(instance->initializationData().stringConverter), + _wstringConverter(instance->initializationData().wstringConverter), + _startSeq(-1), + _sizePos(-1) +{ + // + // Initialize the encoding members of our pre-allocated encapsulations, in case + // this stream is used without an explicit encapsulation. + // + _preAllocatedReadEncaps.encoding = encoding; + _preAllocatedWriteEncaps.encoding = encoding; +} + void IceInternal::BasicStream::clear() { diff --git a/cpp/src/Ice/Buffer.cpp b/cpp/src/Ice/Buffer.cpp index bed4c088b92..ec1fdf6730a 100644 --- a/cpp/src/Ice/Buffer.cpp +++ b/cpp/src/Ice/Buffer.cpp @@ -30,14 +30,28 @@ IceInternal::Buffer::Container::Container(size_type maxCapacity) : { } +IceInternal::Buffer::Container::Container(const_iterator beg, const_iterator end) : + _buf(const_cast<iterator>(beg)), + _size(end - beg), + _capacity(0), + _maxCapacity(0), + _shrinkCounter(0) +{ +} + IceInternal::Buffer::Container::~Container() { - ::free(_buf); + if(_buf && _capacity > 0) + { + ::free(_buf); + } } void IceInternal::Buffer::Container::swap(Container& other) { + assert(!_buf || _capacity > 0); + std::swap(_buf, other._buf); std::swap(_size, other._size); @@ -48,6 +62,8 @@ IceInternal::Buffer::Container::swap(Container& other) void IceInternal::Buffer::Container::clear() { + assert(!_buf || _capacity > 0); + free(_buf); _buf = 0; _size = 0; @@ -57,6 +73,8 @@ IceInternal::Buffer::Container::clear() void IceInternal::Buffer::Container::reserve(size_type n) { + assert(!_buf || _capacity > 0); + size_type c = _capacity; if(n > _capacity) { diff --git a/cpp/src/Ice/Initialize.cpp b/cpp/src/Ice/Initialize.cpp index 30a3a4a1672..60adb309571 100644 --- a/cpp/src/Ice/Initialize.cpp +++ b/cpp/src/Ice/Initialize.cpp @@ -39,6 +39,24 @@ extern IceUtil::Handle<IceInternal::GC> theCollector; } +namespace +{ + +pair<const Byte*, const Byte*> +makePair(const vector<Byte>& v) +{ + if(v.empty()) + { + return pair<const Byte*, const Byte*>(0, 0); + } + else + { + return pair<const Byte*, const Byte*>(&v[0], &v[0] + v.size()); + } +} + +} + void Ice::collectGarbage() { @@ -253,26 +271,53 @@ Ice::initialize(const InitializationData& initData, Int version) InputStreamPtr Ice::createInputStream(const CommunicatorPtr& communicator, const vector<Byte>& bytes) { - return new InputStreamI(communicator, bytes); + return createInputStream(communicator, makePair(bytes)); } InputStreamPtr Ice::createInputStream(const CommunicatorPtr& communicator, const vector<Byte>& bytes, const EncodingVersion& v) { - return new InputStreamI(communicator, bytes, v); + return createInputStream(communicator, makePair(bytes), v); +} + +InputStreamPtr +Ice::createInputStream(const CommunicatorPtr& communicator, const vector<Byte>& bytes, bool copyBytes) +{ + return createInputStream(communicator, makePair(bytes), copyBytes); +} + +InputStreamPtr +Ice::createInputStream(const CommunicatorPtr& communicator, const vector<Byte>& bytes, const EncodingVersion& v, + bool copyBytes) +{ + return createInputStream(communicator, makePair(bytes), v, copyBytes); } InputStreamPtr Ice::createInputStream(const CommunicatorPtr& communicator, const pair<const Ice::Byte*, const Ice::Byte*>& bytes) { - return new InputStreamI(communicator, bytes); + return createInputStream(communicator, bytes, true); } InputStreamPtr Ice::createInputStream(const CommunicatorPtr& communicator, const pair<const Ice::Byte*, const Ice::Byte*>& bytes, const EncodingVersion& v) { - return new InputStreamI(communicator, bytes, v); + return createInputStream(communicator, bytes, v, true); +} + +InputStreamPtr +Ice::createInputStream(const CommunicatorPtr& communicator, const pair<const Ice::Byte*, const Ice::Byte*>& bytes, + bool copyBytes) +{ + return new InputStreamI(communicator, bytes, copyBytes); +} + +InputStreamPtr +Ice::createInputStream(const CommunicatorPtr& communicator, const pair<const Ice::Byte*, const Ice::Byte*>& bytes, + const EncodingVersion& v, bool copyBytes) +{ + return new InputStreamI(communicator, bytes, v, copyBytes); } OutputStreamPtr diff --git a/cpp/src/Ice/StreamI.cpp b/cpp/src/Ice/StreamI.cpp index 5df5ec83b38..d204bba06bb 100644 --- a/cpp/src/Ice/StreamI.cpp +++ b/cpp/src/Ice/StreamI.cpp @@ -83,49 +83,21 @@ UserExceptionReader::__read(BasicStream* is) // // InputStreamI // -InputStreamI::InputStreamI(const CommunicatorPtr& communicator, const vector<Byte>& data) : +InputStreamI::InputStreamI(const CommunicatorPtr& communicator, const pair<const Byte*, const Byte*>& data, + bool copyData) : _communicator(communicator), _closure(0) { Instance* instance = getInstance(communicator).get(); - _is = new BasicStream(instance, instance->defaultsAndOverrides()->defaultEncoding, true); - _is->closure(this); - _is->writeBlob(data); - _is->i = _is->b.begin(); -} - -InputStreamI::InputStreamI(const CommunicatorPtr& communicator, const vector<Byte>& data, const EncodingVersion& v) : - _communicator(communicator), - _closure(0) -{ - Instance* instance = getInstance(communicator).get(); - _is = new BasicStream(instance, v, true); - _is->closure(this); - _is->writeBlob(data); - _is->i = _is->b.begin(); -} - -InputStreamI::InputStreamI(const CommunicatorPtr& communicator, const pair<const Byte*, const Byte*>& data) : - _communicator(communicator), - _closure(0) -{ - Instance* instance = getInstance(communicator).get(); - _is = new BasicStream(instance, instance->defaultsAndOverrides()->defaultEncoding, true); - _is->closure(this); - _is->writeBlob(data.first, data.second - data.first); - _is->i = _is->b.begin(); + initialize(instance, data, instance->defaultsAndOverrides()->defaultEncoding, copyData); } InputStreamI::InputStreamI(const CommunicatorPtr& communicator, const pair<const Byte*, const Byte*>& data, - const EncodingVersion& v) : + const EncodingVersion& v, bool copyData) : _communicator(communicator), _closure(0) { - Instance* instance = getInstance(communicator).get(); - _is = new BasicStream(instance, v, true); - _is->closure(this); - _is->writeBlob(data.first, data.second - data.first); - _is->i = _is->b.begin(); + initialize(getInstance(communicator).get(), data, v, copyData); } InputStreamI::~InputStreamI() @@ -415,6 +387,23 @@ InputStreamI::closure() const return _closure; } +void +InputStreamI::initialize(Instance* instance, const pair<const Byte*, const Byte*>& buf, const EncodingVersion& v, + bool copyData) +{ + if(copyData) + { + _is = new BasicStream(instance, v, true); + _is->writeBlob(buf.first, buf.second - buf.first); + _is->i = _is->b.begin(); + } + else + { + _is = new BasicStream(instance, v, buf.first, buf.second); + } + _is->closure(this); +} + // // OutputStreamI // diff --git a/cpp/src/Ice/StreamI.h b/cpp/src/Ice/StreamI.h index da1f33cf7e4..f1490faddc2 100644 --- a/cpp/src/Ice/StreamI.h +++ b/cpp/src/Ice/StreamI.h @@ -30,10 +30,8 @@ class InputStreamI : public InputStream { public: - InputStreamI(const CommunicatorPtr&, const std::vector<Byte>&); - InputStreamI(const CommunicatorPtr&, const std::vector<Byte>&, const EncodingVersion&); - InputStreamI(const CommunicatorPtr&, const std::pair<const Byte*, const Byte*>&); - InputStreamI(const CommunicatorPtr&, const std::pair<const Byte*, const Byte*>&, const EncodingVersion&); + InputStreamI(const CommunicatorPtr&, const std::pair<const Byte*, const Byte*>&, bool); + InputStreamI(const CommunicatorPtr&, const std::pair<const Byte*, const Byte*>&, const EncodingVersion&, bool); virtual ~InputStreamI(); virtual CommunicatorPtr communicator() const; @@ -102,6 +100,8 @@ public: private: + void initialize(IceInternal::Instance*, const std::pair<const Byte*, const Byte*>&, const EncodingVersion&, bool); + const CommunicatorPtr _communicator; IceInternal::BasicStream* _is; std::vector< ReadObjectCallbackPtr > _callbacks; diff --git a/cpp/src/slice2freeze/Main.cpp b/cpp/src/slice2freeze/Main.cpp index a42d692297c..d16c8213653 100644 --- a/cpp/src/slice2freeze/Main.cpp +++ b/cpp/src/slice2freeze/Main.cpp @@ -360,14 +360,11 @@ writeCodecC(const TypePtr& type, const StringList& metaData, const string& name, << "const Ice::EncodingVersion& encoding)"; C << sb; C << nl << "IceInternal::InstancePtr instance = IceInternal::getInstance(communicator);"; - C << nl << "IceInternal::BasicStream stream(instance.get(), encoding, true);"; + C << nl << "IceInternal::BasicStream stream(instance.get(), encoding, &bytes[0], &bytes[0] + bytes.size());"; if(type->usesClasses()) { C << nl << "stream.sliceObjects(false);"; } - C << nl << "stream.b.resize(bytes.size());"; - C << nl << "::memcpy(&stream.b[0], &bytes[0], bytes.size());"; - C << nl << "stream.i = stream.b.begin();"; if(encaps) { C << nl << "stream.startReadEncaps();"; @@ -754,11 +751,9 @@ writeDictWithIndicesC(const string& name, const string& absolute, const Dict& di else { C << nl << "IceInternal::InstancePtr __instance = IceInternal::getInstance(__communicator);"; - C << nl << "IceInternal::BasicStream __stream(__instance.get(), __encoding, true);"; + C << nl << "IceInternal::BasicStream __stream(__instance.get(), __encoding, "; + C << "&__bytes[0], &__bytes[0] + __bytes.size());"; - C << nl << "__stream.b.resize(__bytes.size());"; - C << nl << "::memcpy(&__stream.b[0], &__bytes[0], __bytes.size());"; - C << nl << "__stream.i = __stream.b.begin();"; writeMarshalUnmarshalCode(C, indexTypes[i].type, false, 0, "__index", false, indexTypes[i].metaData, 0, "__stream", false); } diff --git a/cpp/src/slice2freezej/Main.cpp b/cpp/src/slice2freezej/Main.cpp index 183d262b92e..49c0514a2ae 100644 --- a/cpp/src/slice2freezej/Main.cpp +++ b/cpp/src/slice2freezej/Main.cpp @@ -930,16 +930,11 @@ FreezeGenerator::generate(UnitPtr& u, const Dict& dict) << "(byte[] b, Ice.Communicator communicator, Ice.EncodingVersion encoding)"; out << sb; out << nl << "IceInternal.BasicStream __is = " - << "new IceInternal.BasicStream(IceInternal.Util.getInstance(communicator), encoding, true, false);"; + << "new IceInternal.BasicStream(IceInternal.Util.getInstance(communicator), encoding, b);"; if(type->usesClasses()) { out << nl << "__is.sliceObjects(false);"; } - out << nl << "__is.resize(b.length, true);"; - out << nl << "IceInternal.Buffer __buf = __is.getBuffer();"; - out << nl << "__buf.b.position(0);"; - out << nl << "__buf.b.put(b);"; - out << nl << "__buf.b.position(0);"; if(encaps) { out << nl << "__is.startReadEncaps();"; @@ -1101,12 +1096,7 @@ FreezeGenerator::generate(UnitPtr& u, const Dict& dict) else { out << nl << "IceInternal.BasicStream __is = " - << "new IceInternal.BasicStream(IceInternal.Util.getInstance(communicator), encoding, true, false);"; - out << nl << "__is.resize(bytes.length, true);"; - out << nl << "IceInternal.Buffer buf = __is.getBuffer();"; - out << nl << "buf.b.position(0);"; - out << nl << "buf.b.put(bytes);"; - out << nl << "buf.b.position(0);"; + << "new IceInternal.BasicStream(IceInternal.Util.getInstance(communicator), encoding, bytes);"; int iter = 0; list<string> metaData; diff --git a/cpp/test/Ice/stream/Client.cpp b/cpp/test/Ice/stream/Client.cpp index a0d9ccb3dc4..6d581bc6c6b 100644 --- a/cpp/test/Ice/stream/Client.cpp +++ b/cpp/test/Ice/stream/Client.cpp @@ -183,6 +183,12 @@ run(int, char**, const Ice::CommunicatorPtr& communicator) in->read(v); test(v); in->endEncapsulation(); + + in = Ice::createInputStream(communicator, data, false); + in->startEncapsulation(); + in->read(v); + test(v); + in->endEncapsulation(); } { diff --git a/cs/src/Ice/BasicStream.cs b/cs/src/Ice/BasicStream.cs index 8235229ea0a..58f10d6c87e 100644 --- a/cs/src/Ice/BasicStream.cs +++ b/cs/src/Ice/BasicStream.cs @@ -104,17 +104,24 @@ namespace IceInternal public BasicStream(Instance instance, Ice.EncodingVersion encoding) { initialize(instance, encoding, false); + _buf = new Buffer(instance.messageSizeMax()); } public BasicStream(Instance instance, Ice.EncodingVersion encoding, bool unlimited) { initialize(instance, encoding, unlimited); + _buf = new Buffer(instance.messageSizeMax()); + } + + public BasicStream(Instance instance, Ice.EncodingVersion encoding, byte[] data) + { + initialize(instance, encoding, false); + _buf = new Buffer(data); } private void initialize(Instance instance, Ice.EncodingVersion encoding, bool unlimited) { instance_ = instance; - _buf = new Buffer(instance_.messageSizeMax()); _closure = null; _encoding = encoding; diff --git a/cs/src/Ice/Buffer.cs b/cs/src/Ice/Buffer.cs index 5917742008f..3b6295da859 100644 --- a/cs/src/Ice/Buffer.cs +++ b/cs/src/Ice/Buffer.cs @@ -25,6 +25,15 @@ namespace IceInternal _maxCapacity = maxCapacity; } + public Buffer(byte[] data) + { + b = ByteBuffer.wrap(data); + b.order(ByteBuffer.ByteOrder.LITTLE_ENDIAN); + _size = data.Length; + _capacity = 0; + _maxCapacity = 0; + } + public int size() { return _size; @@ -59,6 +68,8 @@ namespace IceInternal public void resize(int n, bool reading) { + Debug.Assert(b == _emptyBuffer || _capacity > 0); + if(n == 0) { clear(); diff --git a/cs/src/Ice/ByteBuffer.cs b/cs/src/Ice/ByteBuffer.cs index 5fb80ecbbde..a3a5737190a 100644 --- a/cs/src/Ice/ByteBuffer.cs +++ b/cs/src/Ice/ByteBuffer.cs @@ -53,6 +53,17 @@ namespace IceInternal return ret; } + public static ByteBuffer wrap(byte[] bytes) + { + ByteBuffer ret = new ByteBuffer(); + ret._position = 0; + ret._limit = bytes.Length; + ret._capacity = bytes.Length; + ret._bytes = bytes; + ret._valBytes = new ValBytes(); + return ret; + } + public int position() { return _position; diff --git a/cs/src/Ice/StreamI.cs b/cs/src/Ice/StreamI.cs index c5c5e757efb..3b92a924769 100644 --- a/cs/src/Ice/StreamI.cs +++ b/cs/src/Ice/StreamI.cs @@ -11,30 +11,35 @@ namespace Ice { public class InputStreamI : InputStream { - public InputStreamI(Communicator communicator, byte[] data) + public InputStreamI(Communicator communicator, byte[] data, bool copyData) { _communicator = communicator; IceInternal.Instance instance = IceInternal.Util.getInstance(communicator); - _is = new IceInternal.BasicStream(instance, instance.defaultsAndOverrides().defaultEncoding, true); - initialize(data); + initialize(instance, data, instance.defaultsAndOverrides().defaultEncoding, copyData); } - public InputStreamI(Communicator communicator, byte[] data, EncodingVersion v) + public InputStreamI(Communicator communicator, byte[] data, EncodingVersion v, bool copyData) { _communicator = communicator; - IceInternal.Instance instance = IceInternal.Util.getInstance(communicator); - _is = new IceInternal.BasicStream(instance, v, true); - initialize(data); + initialize(IceInternal.Util.getInstance(communicator), data, v, copyData); } - private void initialize(byte[] data) + private void initialize(IceInternal.Instance instance, byte[] data, EncodingVersion v, bool copyData) { + if(copyData) + { + _is = new IceInternal.BasicStream(instance, v, true); + _is.resize(data.Length, true); + IceInternal.Buffer buf = _is.getBuffer(); + buf.b.position(0); + buf.b.put(data); + buf.b.position(0); + } + else + { + _is = new IceInternal.BasicStream(instance, v, data); + } _is.closure(this); - _is.resize(data.Length, true); - IceInternal.Buffer buf = _is.getBuffer(); - buf.b.position(0); - buf.b.put(data); - buf.b.position(0); } public Communicator communicator() diff --git a/cs/src/Ice/Util.cs b/cs/src/Ice/Util.cs index 9a4dd3f1684..eb88832610d 100644 --- a/cs/src/Ice/Util.cs +++ b/cs/src/Ice/Util.cs @@ -445,7 +445,7 @@ namespace Ice /// <returns>The input stream.</returns> public static InputStream createInputStream(Communicator communicator, byte[] bytes) { - return new InputStreamI(communicator, bytes); + return createInputStream(communicator, bytes, true); } /// <summary> @@ -458,7 +458,35 @@ namespace Ice /// <returns>The input stream.</returns> public static InputStream createInputStream(Communicator communicator, byte[] bytes, EncodingVersion v) { - return new InputStreamI(communicator, bytes, v); + return createInputStream(communicator, bytes, v, true); + } + + /// <summary> + /// Creates an input stream for dynamic invocation and dispatch. The stream uses + /// the communicator's default encoding version. + /// </summary> + /// <param name="communicator">The communicator for the stream.</param> + /// <param name="bytes">An encoded request or reply.</param> + /// <param name="copyBytes">True if the given bytes should be copied, false otherwise.</param> + /// <returns>The input stream.</returns> + public static InputStream createInputStream(Communicator communicator, byte[] bytes, bool copyBytes) + { + return new InputStreamI(communicator, bytes, copyBytes); + } + + /// <summary> + /// Creates an input stream for dynamic invocation and dispatch. The stream uses + /// the given encoding version. + /// </summary> + /// <param name="communicator">The communicator for the stream.</param> + /// <param name="bytes">An encoded request or reply.</param> + /// <param name="v">The desired encoding version.</param> + /// <param name="copyBytes">True if the given bytes should be copied, false otherwise.</param> + /// <returns>The input stream.</returns> + public static InputStream createInputStream(Communicator communicator, byte[] bytes, EncodingVersion v, + bool copyBytes) + { + return new InputStreamI(communicator, bytes, v, copyBytes); } /// <summary> diff --git a/cs/test/Ice/stream/AllTests.cs b/cs/test/Ice/stream/AllTests.cs index e8375a61f61..0d35bc427f0 100644 --- a/cs/test/Ice/stream/AllTests.cs +++ b/cs/test/Ice/stream/AllTests.cs @@ -207,6 +207,12 @@ public class AllTests : TestCommon.TestApp test(@in.readBool()); @in.endEncapsulation(); @in.destroy(); + + @in = Ice.Util.createInputStream(communicator, data, false); + @in.startEncapsulation(); + test(@in.readBool()); + @in.endEncapsulation(); + @in.destroy(); } { diff --git a/java/src/Freeze/ObjectStore.java b/java/src/Freeze/ObjectStore.java index 82ccc40ac55..17c6c35f836 100644 --- a/java/src/Freeze/ObjectStore.java +++ b/java/src/Freeze/ObjectStore.java @@ -310,13 +310,8 @@ class ObjectStore implements IceUtil.Store static Ice.Identity unmarshalKey(byte[] b, Ice.Communicator communicator, Ice.EncodingVersion encoding) { - IceInternal.BasicStream is = - new IceInternal.BasicStream(IceInternal.Util.getInstance(communicator), encoding, true, false); - is.resize(b.length, true); - IceInternal.Buffer buf = is.getBuffer(); - buf.b.position(0); - buf.b.put(b); - buf.b.position(0); + IceInternal.BasicStream is = + new IceInternal.BasicStream(IceInternal.Util.getInstance(communicator), encoding, b); Ice.Identity key = new Ice.Identity(); key.__read(is); return key; @@ -349,13 +344,8 @@ class ObjectStore implements IceUtil.Store unmarshalValue(byte[] b, Ice.Communicator communicator, Ice.EncodingVersion encoding, boolean keepStats) { IceInternal.BasicStream is = - new IceInternal.BasicStream(IceInternal.Util.getInstance(communicator), encoding, true, false); + new IceInternal.BasicStream(IceInternal.Util.getInstance(communicator), encoding, b); is.sliceObjects(false); - is.resize(b.length, true); - IceInternal.Buffer buf = is.getBuffer(); - buf.b.position(0); - buf.b.put(b); - buf.b.position(0); ObjectRecord rec = new ObjectRecord(); is.startReadEncaps(); if(keepStats) diff --git a/java/src/Ice/InputStreamI.java b/java/src/Ice/InputStreamI.java index 68676199847..2fd21254f57 100644 --- a/java/src/Ice/InputStreamI.java +++ b/java/src/Ice/InputStreamI.java @@ -12,32 +12,37 @@ package Ice; public class InputStreamI implements InputStream { public - InputStreamI(Communicator communicator, byte[] data) + InputStreamI(Communicator communicator, byte[] data, boolean copyData) { _communicator = communicator; IceInternal.Instance instance = IceInternal.Util.getInstance(communicator); - _is = new IceInternal.BasicStream(instance, instance.defaultsAndOverrides().defaultEncoding, true, false); - initialize(data); + initialize(instance, data, instance.defaultsAndOverrides().defaultEncoding, copyData); } public - InputStreamI(Communicator communicator, byte[] data, EncodingVersion v) + InputStreamI(Communicator communicator, byte[] data, EncodingVersion v, boolean copyData) { _communicator = communicator; - IceInternal.Instance instance = IceInternal.Util.getInstance(communicator); - _is = new IceInternal.BasicStream(instance, v, true, false); - initialize(data); + initialize(IceInternal.Util.getInstance(communicator), data, v, copyData); } private void - initialize(byte[] data) + initialize(IceInternal.Instance instance, byte[] data, EncodingVersion v, boolean copyData) { + if(copyData) + { + _is = new IceInternal.BasicStream(instance, v, true, false); + _is.resize(data.length, true); + IceInternal.Buffer buf = _is.getBuffer(); + buf.b.position(0); + buf.b.put(data); + buf.b.position(0); + } + else + { + _is = new IceInternal.BasicStream(instance, v, data); + } _is.closure(this); - _is.resize(data.length, true); - IceInternal.Buffer buf = _is.getBuffer(); - buf.b.position(0); - buf.b.put(data); - buf.b.position(0); } public Communicator diff --git a/java/src/Ice/Util.java b/java/src/Ice/Util.java index 328aee186fa..049d82f0e7f 100644 --- a/java/src/Ice/Util.java +++ b/java/src/Ice/Util.java @@ -440,7 +440,7 @@ public final class Util public static InputStream createInputStream(Communicator communicator, byte[] bytes) { - return new InputStreamI(communicator, bytes); + return createInputStream(communicator, bytes, true); } /** @@ -455,7 +455,40 @@ public final class Util public static InputStream createInputStream(Communicator communicator, byte[] bytes, EncodingVersion v) { - return new InputStreamI(communicator, bytes, v); + return createInputStream(communicator, bytes, v, true); + } + + /** + * Creates an input stream for dynamic invocation and dispatch. The stream uses + * the communicator's default encoding version. + * + * @param communicator The communicator for the stream. + * @param bytes An encoded request or reply. + * @param copyBytes True if the given bytes should be copied, + * false otherwise. + * @return The input stream. + **/ + public static InputStream + createInputStream(Communicator communicator, byte[] bytes, boolean copyBytes) + { + return new InputStreamI(communicator, bytes, copyBytes); + } + + /** + * Creates an input stream for dynamic invocation and dispatch. The stream uses + * the given encoding version. + * + * @param communicator The communicator for the stream. + * @param bytes An encoded request or reply. + * @param v The desired encoding version. + * @param copyBytes True if the given bytes should be copied, + * false otherwise. + * @return The input stream. + **/ + public static InputStream + createInputStream(Communicator communicator, byte[] bytes, EncodingVersion v, boolean copyBytes) + { + return new InputStreamI(communicator, bytes, v, copyBytes); } /** diff --git a/java/src/IceInternal/BasicStream.java b/java/src/IceInternal/BasicStream.java index c8e9f819605..f3d4966b6e8 100644 --- a/java/src/IceInternal/BasicStream.java +++ b/java/src/IceInternal/BasicStream.java @@ -20,20 +20,27 @@ public class BasicStream public BasicStream(Instance instance, Ice.EncodingVersion encoding, boolean unlimited) { - initialize(instance, encoding, unlimited, instance.cacheMessageBuffers() > 1); + this(instance, encoding, unlimited, instance.cacheMessageBuffers() > 1); } public BasicStream(Instance instance, Ice.EncodingVersion encoding, boolean unlimited, boolean direct) { - initialize(instance, encoding, unlimited, direct); + initialize(instance, encoding, unlimited); + _buf = new Buffer(_instance.messageSizeMax(), direct); + } + + public + BasicStream(Instance instance, Ice.EncodingVersion encoding, byte[] data) + { + initialize(instance, encoding, true); + _buf = new Buffer(data); } private void - initialize(Instance instance, Ice.EncodingVersion encoding, boolean unlimited, boolean direct) + initialize(Instance instance, Ice.EncodingVersion encoding, boolean unlimited) { _instance = instance; - _buf = new Buffer(_instance.messageSizeMax(), direct); _closure = null; _encoding = encoding; diff --git a/java/src/IceInternal/Buffer.java b/java/src/IceInternal/Buffer.java index 3f880586719..e2182243785 100644 --- a/java/src/IceInternal/Buffer.java +++ b/java/src/IceInternal/Buffer.java @@ -25,6 +25,17 @@ public class Buffer _direct = direct; } + public + Buffer(byte[] data) + { + b = java.nio.ByteBuffer.wrap(data); + b.order(java.nio.ByteOrder.LITTLE_ENDIAN); + _size = data.length; + _capacity = 0; + _maxCapacity = 0; + _direct = false; + } + public int size() { @@ -64,6 +75,8 @@ public class Buffer public void resize(int n, boolean reading) { + assert(b == _emptyBuffer || _capacity > 0); + if(n == 0) { clear(); diff --git a/java/test/Ice/stream/Client.java b/java/test/Ice/stream/Client.java index 9c26e5503e6..1c43cc75435 100644 --- a/java/test/Ice/stream/Client.java +++ b/java/test/Ice/stream/Client.java @@ -179,6 +179,12 @@ public class Client extends test.Util.Application test(in.readBool()); in.endEncapsulation(); in.destroy(); + + in = Ice.Util.createInputStream(comm, data, false); + in.startEncapsulation(); + test(in.readBool()); + in.endEncapsulation(); + in.destroy(); } { diff --git a/php/src/IcePHP/Operation.cpp b/php/src/IcePHP/Operation.cpp index 4dee27a4ae2..bfeaeff4075 100644 --- a/php/src/IcePHP/Operation.cpp +++ b/php/src/IcePHP/Operation.cpp @@ -560,7 +560,7 @@ void IcePHP::TypedInvocation::unmarshalResults(int argc, zval** args, zval* ret, const pair<const Ice::Byte*, const Ice::Byte*>& bytes TSRMLS_DC) { - Ice::InputStreamPtr is = Ice::createInputStream(_communicator->getCommunicator(), bytes); + Ice::InputStreamPtr is = Ice::createInputStream(_communicator->getCommunicator(), bytes, false); // // Store a pointer to a local SlicedDataUtil object as the stream's closure. @@ -667,7 +667,7 @@ IcePHP::TypedInvocation::unmarshalResults(int argc, zval** args, zval* ret, zval* IcePHP::TypedInvocation::unmarshalException(const pair<const Ice::Byte*, const Ice::Byte*>& bytes TSRMLS_DC) { - Ice::InputStreamPtr is = Ice::createInputStream(_communicator->getCommunicator(), bytes); + Ice::InputStreamPtr is = Ice::createInputStream(_communicator->getCommunicator(), bytes, false); // // Store a pointer to a local SlicedDataUtil object as the stream's closure. diff --git a/py/modules/IcePy/Operation.cpp b/py/modules/IcePy/Operation.cpp index ea9bffcc263..b575cce2626 100644 --- a/py/modules/IcePy/Operation.cpp +++ b/py/modules/IcePy/Operation.cpp @@ -1602,7 +1602,7 @@ IcePy::TypedInvocation::unmarshalResults(const pair<const Ice::Byte*, const Ice: PyObjectHandle results = PyTuple_New(numResults); if(results.get() && numResults > 0) { - Ice::InputStreamPtr is = Ice::createInputStream(_communicator, bytes); + Ice::InputStreamPtr is = Ice::createInputStream(_communicator, bytes, false); // // Store a pointer to a local SlicedDataUtil object as the stream's closure. @@ -1676,7 +1676,7 @@ IcePy::TypedInvocation::unmarshalResults(const pair<const Ice::Byte*, const Ice: PyObject* IcePy::TypedInvocation::unmarshalException(const pair<const Ice::Byte*, const Ice::Byte*>& bytes) { - Ice::InputStreamPtr is = Ice::createInputStream(_communicator, bytes); + Ice::InputStreamPtr is = Ice::createInputStream(_communicator, bytes, false); // // Store a pointer to a local SlicedDataUtil object as the stream's closure. @@ -3227,7 +3227,7 @@ IcePy::TypedUpcall::dispatch(PyObject* servant, const pair<const Ice::Byte*, con if(!_op->inParams.empty()) { - Ice::InputStreamPtr is = Ice::createInputStream(_communicator, inBytes); + Ice::InputStreamPtr is = Ice::createInputStream(_communicator, inBytes, false); // // Store a pointer to a local SlicedDataUtil object as the stream's closure. diff --git a/rb/src/IceRuby/Operation.cpp b/rb/src/IceRuby/Operation.cpp index 62ee8290442..a6871da2f5e 100644 --- a/rb/src/IceRuby/Operation.cpp +++ b/rb/src/IceRuby/Operation.cpp @@ -495,7 +495,7 @@ IceRuby::OperationI::unmarshalResults(const vector<Ice::Byte>& bytes, const Ice: // Unmarshal the results. If there is more than one value to be returned, then return them // in a tuple of the form (result, outParam1, ...). Otherwise just return the value. // - Ice::InputStreamPtr is = Ice::createInputStream(communicator, bytes); + Ice::InputStreamPtr is = Ice::createInputStream(communicator, bytes, false); // // Store a pointer to a local SlicedDataUtil object as the stream's closure. @@ -564,7 +564,7 @@ IceRuby::OperationI::unmarshalResults(const vector<Ice::Byte>& bytes, const Ice: VALUE IceRuby::OperationI::unmarshalException(const vector<Ice::Byte>& bytes, const Ice::CommunicatorPtr& communicator) { - Ice::InputStreamPtr is = Ice::createInputStream(communicator, bytes); + Ice::InputStreamPtr is = Ice::createInputStream(communicator, bytes, false); // // Store a pointer to a local SlicedDataUtil object as the stream's closure. |