/******************************************************************************
*
*               Module   : Buffer
*               Fichier  : Buffer.c
*               Auteur   : J. DUCLOY
*               Date     : Juillet 93
*               $Id: Buffer.c,v 1.3 2005/06/22 14:53:33 parmentf Exp $
*******************************************************************************
*
* Copyleft INIST, LORIA, UL
* 
******************************************************************************/

#include "Buffer.h"
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include "Except.h"

Buffer *BufferBuffer=NULL; 

int BufferInit()
{
  BufferBuffer=BufferCreate(16,16);
  return 1;
}


Buffer * BufferCreate (int sizeP, int incrementP)
{
    Buffer *newBuf;

    if ((newBuf = (Buffer *)malloc(sizeof(Buffer))))
      {

	if(( newBuf->buf    = (char *)malloc(sizeP)))
	  {
	    newBuf->buf[0] = '\0';
	    newBuf->size   = sizeP;
	    newBuf->incr   = incrementP;
	    newBuf->length = 0;
	  }
	else
	  {
	    ExceptSetError("Buffer","MA", "memory allocation failed","","",2);
	    free(newBuf);
	    newBuf=NULL;
	  }
      }
    else
      {
	ExceptSetError("Buffer","MA", "memory allocation failed","","",2);
	newBuf=NULL;
      }

    return (newBuf);
}

Buffer *BufferFromString(char *s1)
{
  Buffer *b1;
  int l1;
  if (!s1)return BufferCreate(16,16);
  l1=strlen(s1)+1;
  if (l1<16)
    {
      if (!(b1=BufferCreate(16,16)))return NULL;
    }
  else if (!(b1=BufferCreate(l1,l1)))return NULL;
  BufferStrcpy(b1,s1);
  return b1;
}

/* principale fonction de lecture de bloc  */

char* BufferFgetsUpTo(Buffer *b, FILE *s, int c) /* char c;  */
{
     int c1; /* char c1; */

   /* on initialise sur le premier caractere ou on renvoie NULL */

   if( (c1=getc(s))!=EOF)
      {
	if (c==c1)
	  {
	    b->length=0;
	    b->buf[0]='\0';
	    return (b->buf);
	  }
	b->length=1;
	b->buf[0]=c1;
      }
   else return(NULL);
    while ((c1=getc(s))!=EOF)
        {
           if (c==c1) {BufferEndString(b);return (b->buf);}
           else BufferCatChar(b,c1);
        }
     BufferEndString(b);
     return (b->buf);
}

char* BufferFgetsUpToEOF(Buffer *b, FILE *s)
{
  int c; /* char c; */
  while ((c=getc(s))!=EOF)
    {
      BufferCatChar(b,c);
    }
  BufferEndString(b);
  return (b->buf);
}

char* BufferFgetsUpToTest(Buffer *b, FILE *s, int c) /* char c;  */
{
     int c1; /* char c1; */

   /* on initialise sur le premier caractere ou on renvoie NULL */

   if( (c1=getc(s))!=EOF)
      {
	if (c==c1)
	  {
	    b->length=0;
	    b->buf[0]='\0';
	    return (b->buf);
	  }
	b->length=1;
	b->buf[0]=c1;
      }
   else return(NULL);
    while ((c1=getc(s))!=EOF)
        {
           if (c==c1) {BufferEndString(b);return (b->buf);}
           else BufferCatChar(b,c1);
        }
     BufferEndString(b);
     return NULL;
}

char* BufferStrcat(Buffer *b, char *s)
{
  char c;
  if(s)
    {
      while((c=*s++))
	{
	  BufferCatChar(b,c);
	};
      BufferEndString(b);
    }
  return (b->buf);
}

char* BufferStrncat(Buffer *b, char *s, int n)
{
  char c;
  int i;
  i=0;
  if(s)
    {
      while((c=*s++))
	{
	  if(i>=n)break;
	  i++;
	  BufferCatChar(b,c);
	};
      BufferEndString(b);
    }
  return (b->buf);
}

char* BufferStrcpy(Buffer *b, char *s)
{
  int len;
  len=strlen(s);
  if(len>=b->size)
    {
      free(b->buf);
      b->size=len+1;
      if(!(b->buf=malloc(b->size)))
	 {
	   ExceptSetError("Buffer","MA", "memory allocation failed in BufferStrcpy","","",2);
	   return NULL;
	 }
    }
  strcpy(b->buf,s);
  b->length=len;
  return (b->buf);
}

char* BufferStrncpy(Buffer *b, char *s, int n1)
{
  if(n1<1)return NULL;
  if(n1>=b->size)
    {
      free(b->buf);
      b->size=n1+1;
      if(!(b->buf=malloc(b->size)))
	{
	  ExceptSetError("Buffer","MA", "memory allocation failed in BufferStrncpy","","",2);
	  return NULL;
	}
    }
  strncpy(b->buf,s,n1);
  b->length=n1;
  b->buf[n1]=0;
  return (b->buf);
}

void BufferFree(Buffer *b1)
{
  free(b1->buf);
  free(b1);
}

char *BufferReset(Buffer *b1)
{
  b1->buf[0]='\0';
  b1->length=0;
  return b1->buf;
}

char *BufferSave(Buffer *b1)
{
  char *str1;
  if (b1)
    {
      if((str1=malloc(b1->length+1)))
	{
	  strcpy(str1,b1->buf);
	  return str1;
	}
      else
	{
	  ExceptSetError("Buffer","MA", "memory allocation failed in BufferSave","","",2);
	  return NULL;
	}
    }
  return NULL;
}

/* undeleted parmentf 20/11/2002 
   I don't remember why this function has been deleted.
   It must be because no other .c used it in whole DILIB.
*/
/* del parmentf 11/10/2002 */
char *BufferStrRepl(Buffer *b1, char *s1, char *s2)
{
  static Buffer *intBuf=NULL;
  char *pt;
  char *pt1;

  if(!intBuf)intBuf=BufferCreate(b1->size, b1->incr);
  if ((pt=strstr(BufferString(b1),s1)))
    {
      pt1=BufferString(b1);
      BufferReset(intBuf);
      do
	{
	  BufferStrncat(intBuf,pt1,pt-pt1);
	  BufferStrcat (intBuf,s2);
	  pt1=pt+strlen(s1);
	}
      while ((pt=strstr(pt1,s1)));
      BufferStrcat (intBuf,pt1);
      BufferStrcpy(b1,BufferString(intBuf));
    }
  return BufferString(b1);
  
}

char *BufferIncrement(Buffer *b1)
{
   b1->size+=b1->incr;
   if(!(b1->buf=realloc(b1->buf, b1->size)))
     {
       ExceptSetError("Buffer","MA", "memory allocation failed (realloc)","","",2);
       return NULL;
     }
   return b1->buf;
}

char *BufferCharCat(Buffer *b1, unsigned char c1)
{
  static char *bCar=NULL;
  if (!bCar)
    {
      bCar=malloc(2);
      bCar[1]='\0';
    }
  bCar[0]=c1;
  BufferStrcat(b1, bCar);
  return BufferString(b1);
}

Buffer *BufferClone(Buffer *b1)
{
  Buffer *b2;
  b2=BufferCreate(b1->size,b1->incr);
  BufferCopy(b2,b1);
  return b2;
}

Buffer *BufferPrivate=NULL;

char *BufferGetSubString(char *s1, int o1, int l1)
{
  int l2;

  l2=strlen(s1);
  if (o1>=l2)return ("");
  if ((o1+l1)>=l2)return (s1+o1);
  if (!BufferPrivate)BufferPrivate=BufferCreate(l1+1, l1);
  BufferStrncpy(BufferPrivate,s1+o1,l1);
  return BufferString(BufferPrivate);
}

char *BufferGetIntString(char *s1)
{

  char c;
  char *s2;
  s2=s1;
  while((c=*s2++))
    {
      if (isdigit((int)c))continue;
      else
	{
	  if (!BufferPrivate)BufferPrivate=BufferCreate(10, 10);
	  BufferStrncpy(BufferPrivate,s1,s2-s1);
	  return BufferString(BufferPrivate);
	}
    }
  return s1;
}

char *BufferIntCat(Buffer *b1, int i1)
{
  static char *intBuf=NULL;
  if (!intBuf)intBuf=malloc(20);
  sprintf(intBuf, "%d", i1);
  BufferStrcat(b1, intBuf);
  return BufferString(b1);
}

char *BufferIntCpy(Buffer *b1, int i1)
{
  static char *intBuf=NULL;
  if (!intBuf)intBuf=malloc(20);
  sprintf(intBuf, "%d", i1);
  BufferStrcpy(b1, intBuf);
  return BufferString(b1);
}

char *BufferDoubleCat(Buffer *b1, double d1, char *format)
{
  static char *intBuf=NULL;
  if (!intBuf)intBuf=malloc(20);
  if (format)
    {
      sprintf(intBuf, format, d1);
    }
  else
    {
      if(d1>999999) sprintf(intBuf, "%e", d1);
      else if (d1>9999)  sprintf(intBuf, "%.3f", d1);
      else if (d1>99)  sprintf(intBuf, "%.5f", d1);
      else if (d1>1)  sprintf(intBuf, "%.7f", d1);
      else sprintf(intBuf, "%e", d1);
    }
  BufferStrcat(b1, intBuf);
  return BufferString(b1);
}

char *BufferTextCleanCat(Buffer *b, int mode, char *str)
{
  int c;
  int flagSep;
  while ((c=*str++))
    {
      switch(c)
	{
	case ' ':
	  if ((flagSep==1)&&(mode=='s')) break;
	  flagSep=1;
	  BufferCharCat(b, c);
	  break;
	case '\n':
	  if ((flagSep==1)&&(mode=='s')) break;
	  flagSep=1;
	  if (mode=='s') BufferStrcat(b, " ");
	  else BufferStrcat(b, "&#xA;");
	  break;
	case '\t':
	  if ((flagSep==1)&&(mode=='s')) break;
	  flagSep=1;
	  if (mode=='s') BufferStrcat(b, " ");
	  else BufferStrcat(b, "&#x09;");
	  break;
	default:
	  flagSep=0;
	  BufferCharCat(b, c);
	  break;
	}
    }
}
