summaryrefslogtreecommitdiff
path: root/cpp/src/Ice/Buffer.cpp
diff options
context:
space:
mode:
authorMark Spruiell <mes@zeroc.com>2016-03-09 16:00:39 -0800
committerMark Spruiell <mes@zeroc.com>2016-03-09 16:00:39 -0800
commit15063818726cf3d474d77d9d5586b36a10a3d453 (patch)
tree35912f8e447722fdbc5f46a8a1500361a9327642 /cpp/src/Ice/Buffer.cpp
parentfixing leak in Outgoing (diff)
downloadice-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.cpp47
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;
}