/***************************************************************************

    supportware
    Copyright (C) 2001-2008 by c.holzheuer
    c.holzheuer@sourceworx.org

    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 <ddiobuffer.h>
#include <iostream>
#include <stdexcept>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <ddiommap.h>
#include <string.h>


using namespace std;


/**
	Den einlese-pointer weiterziehen
*/

int ddiobufferhandler::move_input( int bytes )
{
	int newend = _input_offset + bytes;
	if( newend > _size )
		return 0;
 _input_offset = newend;
 // FRAGWÜRDIG
 _data[_input_offset] = 0; //??
 return _input_offset;
}


/**
	Den auslese-pointer weiterziehen
*/

int ddiobufferhandler::move_output( int bytes )
{
 	int newend = _output_offset + bytes;
 	if( newend > _size || newend > _input_offset )
 		return 0;
	_output_offset = newend;
	return _output_offset;
}



/**
	@return the current part of the buffer as string.
 ( valid input data which is not yet written )
*/

ddstring ddiobufferhandler::to_string() const
{
	return ddstring( (char*) (_data + _output_offset), _input_offset );
}

/***************************************************************************

    supportware
    Copyright (C) 2001-2008 by c.holzheuer
    c.holzheuer@sourceworx.org

    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.

***************************************************************************/


/**
 	Default constructor
*/

ddiobuffer::ddiobuffer()
: _origsize( 0 )
{

}





/**
	Destructor.
*/

ddiobuffer::~ddiobuffer()
{
	if( _data )
		::free( _data );
}


/**
	Init this buffer.
	@param size: the number of bytes to allocate.
*/

void ddiobuffer::init_buffer( int size )
{
	_data  = 0;
	if( size <= 0 || _origsize != 0 )
		throw runtime_error( " init_buffer( int size ): Zero size or init_buffer called twice" );
	
	_size = _origsize = size;	
	_data = (char*) ::malloc( _size );//new char[thesize+1];    
	reset();
}


/**
	Buffer via realloc vergrößern.
*/

int ddiobuffer::grow_buffer( int bytes )
{	
	// FIX! Fehler behandeln!!!
	_size = (_size+bytes) > (_size+DDBUFFERBODYGROW) ? (_size+bytes) : (_size+DDBUFFERBODYGROW);
	
	_data = (char*) ::realloc( _data, _size );
	// FIX! Der buffer muss irgendwie aufgeräumt werden! 
 	if( _data == 0 )
		log_fatal( "ddiobuffer::grow: out of memory:"+ddstrutil::from_int(_size) ); 
	return max_input(); 
}


/**
	Buffer via realloc auf die Default-Größe schrumpfen.
*/

void ddiobuffer::shrink_buffer()
{
	// nur verkleinern, wenn nötig
	if( _size == _origsize ) 
		return; 
	
	_size = _origsize;
	_data = (char*) ::realloc( _data, _origsize );	// FIX! Der buffer muss irgendwie aufgeräumt werden! 
 	if( _data == 0 )
		log_fatal( "ddiobuffer::shrink: out of memory:"+ddstrutil::from_int(_size) ); 

	
}


/**
 	Daten in den Buffer schreiben
*/
	
void ddiobuffer::append ( const char* src, int bytes )
{
	if( !bytes )
		return;		
	
	if( bytes>=max_input() )
		grow_buffer( bytes+1 );	
	::memcpy( input(), src, bytes );
	_input_offset += bytes;
}






