lang/c/msgpack: C++ binding: safer memory managent

git-svn-id: file:///Users/frsyuki/project/msgpack-git/svn/x@68 5a5092ae-2292-43ba-b2d5-dcab9c1a2731
This commit is contained in:
frsyuki 2009-02-15 09:09:58 +00:00
parent 9923cf4daf
commit b790df530a
4 changed files with 102 additions and 24 deletions

View file

@ -178,12 +178,13 @@ private:
};
unpacker::unpacker(zone& z) :
m_ctx(new context(&z)),
unpacker::unpacker() :
m_buffer(NULL),
m_used(0),
m_free(0),
m_off(0)
m_off(0),
m_zone(new zone()),
m_ctx(new context(&*m_zone))
{ }
@ -201,14 +202,14 @@ void unpacker::expand_buffer(size_t len)
else { next_size = UNPACKER_INITIAL_BUFFER_SIZE; }
while(next_size < len + m_used) { next_size *= 2; }
m_buffer = m_ctx->user()->realloc(m_buffer, next_size);
m_buffer = m_zone->realloc(m_buffer, next_size);
m_free = next_size - m_used;
} else {
size_t next_size = UNPACKER_INITIAL_BUFFER_SIZE;
while(next_size < len + m_used - m_off) { next_size *= 2; }
char* tmp = m_ctx->user()->malloc(next_size);
char* tmp = m_zone->malloc(next_size);
memcpy(tmp, m_buffer+m_off, m_used-m_off);
m_buffer = tmp;
@ -226,20 +227,49 @@ bool unpacker::execute()
} else if(ret == 0) {
return false;
} else {
expand_buffer(0);
return true;
}
}
zone* unpacker::release_zone()
{
zone* n = new zone();
std::auto_ptr<zone> old(m_zone.release());
m_zone.reset(n);
//std::auto_ptr<zone> old(new zone());
//m_zone.swap(old);
// move all bytes in m_buffer to new buffer from the new zone
if(m_used <= m_off) {
m_buffer = NULL;
m_used = 0;
m_free = 0;
m_off = 0;
} else {
try {
expand_buffer(0);
} catch (...) {
// m_zone.swap(old);
zone* tmp = old.release();
old.reset(m_zone.release());
m_zone.reset(tmp);
throw;
}
}
m_ctx->user(&*m_zone);
return old.release();
}
object unpacker::data()
{
return m_ctx->data();
}
void unpacker::reset(zone& z)
void unpacker::reset()
{
if(m_off != 0) { expand_buffer(0); }
m_ctx->reset(&z);
if(m_off != 0) { std::auto_ptr<zone> old(release_zone()); }
m_ctx->reset();
}