/**
***  IPDial - Buffer.c
***
***  This file implements dynamically growing buffers.
***
***
***  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.
***
***  This program is distributed in the hope that it will be useful,
***  but WITHOUT ANY WARRANTY; without even the implied warranty of
***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
***  GNU General Public License for more details.
***
***  You should have received a copy of the GNU General Public License
***  along with this program; if not, write to the Free Software
***  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
***
***  Authors: Jochen Wiedmann <wiedmann@neckar-alb.de>
***           Stefan Gybas <cab@studbox.uni-stuttgart.de>
**/




/**
***  Include files
**/
#ifndef IPDIAL_H
#include "IPDial.h"
#endif
#include <ctype.h>


#ifndef MAX
#define MAX(a,b) (((a)>(b))?(a):(b))
#endif





/**
***  Type definitions
**/
typedef struct
{ STRPTR buf;
  ULONG size;
  ULONG filled;
} Buffer;





/*** BufferCreate() function
***
***  Creates a new buffer.
**/
APTR BufferCreate(VOID)

{ Buffer *buf;

  if ((buf = malloc(sizeof(*buf))))
  { if ((buf->buf = malloc(2048)))
    { buf->size = 2048;
      BufferClear(buf);
    }
    else
    { free(buf);
      buf = NULL;
    }
  }
  return(buf);
}





/*** BufferClear() function
***
***  This function clears a buffer.
**/
VOID BufferClear(APTR buf)

{ ((Buffer *) buf)->filled = 0;
  ((Buffer *) buf)->buf[0] = '\0';
}





/**
***  This function adds the given number of bytes to a buffer.
**/
VOID BufferExtend(APTR buffer, const UBYTE* addbuffer, ULONG addsize)

{ Buffer *buf = buffer;
  ULONG newfilled = buf->filled + addsize;
  extern ULONG EchoMode;

  /**
  ***  Allocate a new buffer, if needed.
  **/
  if (newfilled+1 > buf->size)
  { buf->size = MAX(newfilled+1, buf->size)*2;

    if (!(buf->buf = realloc(buf->buf, buf->size)))
    { PrintError(0, "not enough memory");
    }
  }

  /**
  ***  We are now guaranteed, that the buffer is big enough.
  ***  Copy data and ensure, that we get a valid C string.
  **/
  memcpy(buf->buf + buf->filled, addbuffer, addsize);
  buf->filled += addsize;
  buf->buf[buf->filled] = '\0';
}





/*** BufferCheck() function
***
***  Checks, if a buffer contains one of the given strings.
***  If this is the case, the strings number (beginning with
***  0) will be returned, -1 otherwise.
**/
LONG BufferCheck(APTR buffer, STRPTR *args)

{ Buffer *buf = buffer;
  LONG i;

  if (buf->filled)
  { for (i = 0;  *args;  ++i, ++args)
    { if (strstr((char *) buf->buf, (char *)  *args))
      { return(i);
      }
    }
  }
  return(-1);
}





/*** BufferBuffer() function
***
***  Returns the string associated to a buffer.
**/
STRPTR BufferBuffer(APTR buf)

{ return(((Buffer *) buf)->buf);
}

