#include "databuffer.h"

databuffer::databuffer()
{
  totalsize = 0;
}

databuffer::~databuffer()
{
  clear();
}

int databuffer::clear()
{
  for(unsigned int i = 0; i < data.size(); i++)
    delete [] data[i].data;
  data.clear();
  totalsize = 0;
  return 0;
}

int databuffer::append( char *d, int s )
{
  dataseg newseg;
  newseg.data = new char[s];
  newseg.size = s;
  memcpy( newseg.data, d, s );
  data.push_back(newseg);
  totalsize = totalsize + s;
  return 0;
}

int databuffer::append( databuffer &b )
{
  b.consolidate();
  append( b.data[0].data, b.data[0].size );
  return 0;
}

int databuffer::size()
{
  return totalsize;
}

char &databuffer::operator[] (int off)
{
  int start;
  int end;
  start = 0;
  end = 0;
  for(unsigned int i = 0; i < data.size(); i++)
    {
      end = end + data[i].size;
      if(off < end)
        return data[i].data[ off - start ];
      start = end;
    }
  return data[0].data[0];
}

const char &databuffer::operator[] (int off) const
{
  int start;
  int end;
  start = 0;
  end = 0;
  for(unsigned int i = 0; i < data.size(); i++)
    {
      end = end + data[i].size;
      if(off < end)
        return data[i].data[ off - start ];
      start = end;
    }
  return data[0].data[0];
}

int databuffer::consolidate()
{
  char *buffer;
  int start;
  start = 0;
  //nothing to sonsolidate
  if( data.size() < 2 )
    return 0;
    
  buffer  = new char [totalsize];
  for(unsigned int i = 0; i < data.size(); i++)
    {
      memcpy(buffer+start, data[i].data, data[i].size);
      start = start + data[i].size;
      delete [] data[i].data;
    }
  data.clear();
  if(start != totalsize)
    {
      std::cout << "consolidate check failed\n";
      exit(0);
    }
  dataseg newseg;
  newseg.data = buffer;
  newseg.size = totalsize;
  data.push_back(newseg);
  return 0;
}

char * databuffer::getptr()
{
  consolidate();
  return data[0].data;
}
