diff options
author | Mark Spruiell <mes@zeroc.com> | 2016-03-09 16:00:39 -0800 |
---|---|---|
committer | Mark Spruiell <mes@zeroc.com> | 2016-03-09 16:00:39 -0800 |
commit | 15063818726cf3d474d77d9d5586b36a10a3d453 (patch) | |
tree | 35912f8e447722fdbc5f46a8a1500361a9327642 /cpp/src | |
parent | fixing leak in Outgoing (diff) | |
download | ice-15063818726cf3d474d77d9d5586b36a10a3d453.tar.bz2 ice-15063818726cf3d474d77d9d5586b36a10a3d453.tar.xz ice-15063818726cf3d474d77d9d5586b36a10a3d453.zip |
ICE-6852 - allow OutputStream to marshal to user-supplied buffer
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/Ice/Buffer.cpp | 47 | ||||
-rw-r--r-- | cpp/src/Ice/OutputStream.cpp | 10 | ||||
-rw-r--r-- | cpp/src/IceDB/IceDB.h | 18 |
3 files changed, 52 insertions, 23 deletions
diff --git a/cpp/src/Ice/Buffer.cpp b/cpp/src/Ice/Buffer.cpp index fe6c5490f78..33cbaeabc34 100644 --- a/cpp/src/Ice/Buffer.cpp +++ b/cpp/src/Ice/Buffer.cpp @@ -25,31 +25,36 @@ IceInternal::Buffer::Container::Container() : _buf(0), _size(0), _capacity(0), - _shrinkCounter(0) + _shrinkCounter(0), + _owned(true) { } IceInternal::Buffer::Container::Container(const_iterator beg, const_iterator end) : _buf(const_cast<iterator>(beg)), _size(end - beg), - _capacity(0), - _shrinkCounter(0) + _capacity(end - beg), + _shrinkCounter(0), + _owned(false) { } IceInternal::Buffer::Container::Container(const vector<value_type>& v) : - _capacity(0), _shrinkCounter(0) { if(v.empty()) { _buf = 0; _size = 0; + _capacity = 0; + _owned = true; } else { _buf = const_cast<value_type*>(&v[0]); _size = v.size(); + _capacity = _size; + _owned = false; } } @@ -61,24 +66,27 @@ IceInternal::Buffer::Container::Container(Container& other, bool adopt) _size = other._size; _capacity = other._capacity; _shrinkCounter = other._shrinkCounter; + _owned = other._owned; other._buf = 0; other._size = 0; other._capacity = 0; other._shrinkCounter = 0; + other._owned = true; } else { _buf = other._buf; _size = other._size; - _capacity = 0; + _capacity = other._capacity; _shrinkCounter = 0; + _owned = false; } } IceInternal::Buffer::Container::~Container() { - if(_buf && _capacity > 0) + if(_buf && _owned) { ::free(_buf); } @@ -91,25 +99,27 @@ IceInternal::Buffer::Container::swap(Container& other) std::swap(_size, other._size); std::swap(_capacity, other._capacity); std::swap(_shrinkCounter, other._shrinkCounter); + std::swap(_owned, other._owned); } void IceInternal::Buffer::Container::clear() { - if(_buf && _capacity > 0) + if(_buf && _owned) { - free(_buf); + ::free(_buf); } + _buf = 0; _size = 0; _capacity = 0; + _shrinkCounter = 0; + _owned = true; } void IceInternal::Buffer::Container::reserve(size_type n) { - assert(!_buf || _capacity > 0); - size_type c = _capacity; if(n > _capacity) { @@ -125,11 +135,26 @@ IceInternal::Buffer::Container::reserve(size_type n) return; } - pointer p = reinterpret_cast<pointer>(::realloc(_buf, _capacity)); + pointer p; + if(_owned) + { + p = reinterpret_cast<pointer>(::realloc(_buf, _capacity)); + } + else + { + p = reinterpret_cast<pointer>(::malloc(_capacity)); + if(p) + { + ::memcpy(p, _buf, _size); + _owned = true; + } + } + if(!p) { _capacity = c; // Restore the previous capacity. throw std::bad_alloc(); } + _buf = p; } diff --git a/cpp/src/Ice/OutputStream.cpp b/cpp/src/Ice/OutputStream.cpp index 05c800a6e10..c9b4ca0a5de 100644 --- a/cpp/src/Ice/OutputStream.cpp +++ b/cpp/src/Ice/OutputStream.cpp @@ -95,6 +95,16 @@ Ice::OutputStream::OutputStream(const CommunicatorPtr& communicator, const Encod initialize(communicator, encoding); } +Ice::OutputStream::OutputStream(const CommunicatorPtr& communicator, const EncodingVersion& encoding, + const pair<const Byte*, const Byte*>& buf) : + Buffer(buf.first, buf.second), + _closure(0), + _currentEncaps(0) +{ + initialize(communicator, encoding); + b.reset(); +} + Ice::OutputStream::OutputStream(Instance* instance, const EncodingVersion& encoding) : _closure(0), _currentEncaps(0) diff --git a/cpp/src/IceDB/IceDB.h b/cpp/src/IceDB/IceDB.h index af9bd2206c0..d905f2bab22 100644 --- a/cpp/src/IceDB/IceDB.h +++ b/cpp/src/IceDB/IceDB.h @@ -515,19 +515,13 @@ struct Codec<T, IceContext, Ice::OutputStream> static bool write(const T& t, MDB_val& val, const IceContext& ctx) { - Ice::OutputStream stream(ctx.communicator, ctx.encoding); + const size_t limit = val.mv_size; + std::pair<Ice::Byte*, Ice::Byte*> p(reinterpret_cast<Ice::Byte*>(val.mv_data), + reinterpret_cast<Ice::Byte*>(val.mv_data) + limit); + Ice::OutputStream stream(ctx.communicator, ctx.encoding, p); stream.write(t); - if(stream.b.size() > val.mv_size) - { - val.mv_size = stream.b.size(); - return false; - } - else - { - val.mv_size = stream.b.size(); - memcpy(val.mv_data, &stream.b[0], stream.b.size()); - return true; - } + val.mv_size = stream.b.size(); + return stream.b.size() > limit ? false : true; } }; |