// Common, group Buffers
// Copyright Alexander Liss
#include <string.h>
#include "commbuf.h"
// CommBuffer
int CommBuffer::allocate(int size)
{
if(size<=0) allocated=increment;
else
{
allocated=size/increment*increment;
if(allocated<size)
allocated+=increment;
}
data=new unsigned char[allocated];
if(!data)
{
allocated=0;
return 1;
}
memset(data,0,allocated);
return 0;
}
int CommBuffer::copy(const CommBuffer& s)
{
if(!data) return 1;
int g=0;
if(allocated<s.data_size+s.write_offset+1)
g=reallocate(s.data_size+s.write_offset+1);
if(g) return 1;
memcpy(data,s.data,s.data_size+s.write_offset);
data_size=s.data_size;
write_offset=s.write_offset;
encoding=s.encoding;
return 0;
}
CommBuffer::~CommBuffer()
{
if(data) memset(data,0,allocated);
delete []data;
}
int CommBuffer::reallocate(int size)
{
if(size<=0) size=increment;
if(!data)
return allocate(size);
if(size<data_size+write_offset+1) return 1;
int new_size=size/increment*increment;
if(new_size<size)
new_size+=increment;
unsigned char *old_data=data;
int old_allocated=allocated;
data=new unsigned char[new_size];
if(!data)
{
// restore
data=old_data;
return 2;
}
allocated=new_size;
memset(data,0,allocated);
if(old_data)
{
memcpy(data,old_data,data_size+write_offset);
memset(old_data,0,old_allocated);
delete []old_data;
}
return 0;
}
int CommBuffer::set(const unsigned char * from,int size)
{
data_size=0;
if(size<=0 || from==0)
{
if(!data)
allocate(increment);
return 1;
}
if(!data)
allocate(size+1);
if(!data) return 2;
return append(from,size);
}
int CommBuffer::set(int size, char s)
{
data_size=0;
if(size<=0 )
{
if(!data)
allocate(increment);
return 1;
}
if(!data)
allocate(size+1);
if(!data) return 2;
return append(size,s);
}
int CommBuffer::set(const char * str)
{
return set(str,strlen(str));
}
int CommBuffer::append(const unsigned char * from,int size)
{
if(size<=0 || from==0) return 1;
int g=0;
if(data_size+size+1>back_allocated())
g=reallocate(write_offset+data_size+size+1);
if(g) return 2;
memcpy(write_start()+data_size,from,size);
data_size+=size;
write_start()[data_size]=0;
return 0;
}
int CommBuffer::append(int size, char s)
{
if(size<=0) return 1;
int g=0;
if(data_size+size+1>back_allocated())
g=reallocate(write_offset+data_size+size+1);
if(g) return 2;
memset(write_start()+data_size,s,size);
data_size+=size;
write_start()[data_size]=0;
return 0;
}
int CommBuffer::append(const char * str)
{
return append(str,strlen(str));
}
int CommBuffer::prepend(const unsigned char * from,int size)
{
if(size<=0 || from==0) return 1;
if(size>front_allocated())
return 2;
memcpy(write_start()-size,from,size);
write_offset-=size;
data_size+=size;
return 0;
}
int CommBuffer::prepend(int size, char s)
{
if(size<=0) return 1;
if(size>front_allocated())
return 2;
memset(write_start()-size,s,size);
write_offset-=size;
data_size+=size;
return 0;
}
// byte data[n+write_offset] becomes data[write_offset]
int CommBuffer::shift(int n)
{
if(n<0) return 1;
if(n==0) return 0;
if(n>=data_size)
{
memset(write_start(),0,back_allocated());
data_size=0;
return 0;
}
// copy trailing zero
memcpy(write_start(),write_start()+n,data_size-n+1);
data_size-=n;
return 0;
}