/***************************************************************************
                          kmessbuffer.cpp -  description
                             -------------------
    begin                : Sat July 2 2005
    copyright            : (C) 2003 by Mike K. Bennett
                           (C) 2005 by Diederik van der Boor
    email                : mkb137b@hotmail.com
                           vdboor --at-- codingdomain.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "kmessbuffer.h"

#include <string.h>  // for memcpy

#include <kdebug.h>


// Constructor
KMessBuffer::KMessBuffer( unsigned int sz )
  : QByteArray( sz )
{
}

// Destructor
KMessBuffer::~KMessBuffer()
{
}


// Add data
void KMessBuffer::add( char *data, unsigned int dataSize )
{
  // Get old data
  int         oldSize   = size();
  const char *oldBuffer = this->data();

  // Make room for new data
  int   newSize   = oldSize + dataSize;
  char *newBuffer = new char[ newSize ];

  // Copy the bytes
  memcpy(newBuffer,           oldBuffer, oldSize);  // Copy old
  memcpy(newBuffer + oldSize, data,      dataSize); // Copy new

  // Assign to this object
  assign( newBuffer, newSize );  // does the deletion automatically
}


// Retrieve data
QByteArray KMessBuffer::left( unsigned int blockSize ) const
{
  if ( size() < blockSize )
  {
    // FIXME: en ifdef
    kdDebug() << "Buffer size " << size() << " < asked size " << blockSize << "!" << endl;
    return QByteArray();
  }

  char *leftPart = new char[ blockSize ];
  memcpy(leftPart, data(), blockSize);

  QByteArray qbaWrapper;
  qbaWrapper.assign(leftPart, blockSize);  // does the deletion automatically

  return qbaWrapper;
}


// Remove read data
void KMessBuffer::remove( unsigned blockSize )
{
  if ( size() < blockSize )
  {
    kdDebug() << "KMessBuffer - WARNING - size " << size() << " < asked size " << blockSize << "!" << endl;
    return;
  }

  uint  newSize   = size() - blockSize;
  char *newBuffer = new char[ newSize ];
  memcpy(newBuffer, data() + blockSize, newSize);

  // Assign new buffer
  assign( newBuffer, newSize );  // does the deletion automatically
}


// Find a newline character
int KMessBuffer::findNewline() const
{
  int   index = -1;
  char *data  = this->data();

  // Avoid the "index 0 out of range" errors
  if(size() == 0)
  {
    return -1;
  }

  // Keep searching until a \r is followed by a \n
  do
  {
    // Find the next \r
    index = find('\r', index + 1);
    if(index == -1)
    {
      return -1;
    }
  }
  while(data[index + 1] != '\n');

  return index;
}


// Return the length of the buffer
int KMessBuffer::length() const
{
  return size();
}

