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/Ice/Buffer.cpp | |
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/Ice/Buffer.cpp')
-rw-r--r-- | cpp/src/Ice/Buffer.cpp | 47 |
1 files changed, 36 insertions, 11 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; } |