/******************************** -*- C -*- ****************************
 *
 *	String Functions
 *
 *	$Revision: 1.7.5$
 *	$Date: 2000/05/28 16:56:52$
 *	$Author: pb$
 *
 ***********************************************************************/

/***********************************************************************
 *
 * Copyright 1988-92, 1994-95, 1999, 2000 Free Software Foundation, Inc.
 * Written by Steve Byrne.
 *
 * This file is part of GNU Smalltalk.
 *
 * GNU Smalltalk 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, or (at your option) any later 
 * version.
 * 
 * GNU Smalltalk 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
 * GNU Smalltalk; see the file COPYING.  If not, write to the Free Software
 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
 *
 ***********************************************************************/


#include <stdio.h>
#include "gst.h"
#include "alloc.h"
#include "obstack.h"
#include "str.h"
#if STDC_HEADERS
#include <stdlib.h>
#include <string.h>
#endif /* STDC_HEADERS */

#define	STRING_BASE_SIZE	128

static char	*bufBase = nil;
static long	curLen = 0;
static long	maxBufLen = 0;

/*
 *	char *curStrBuf()
 *
 * Description
 *
 *	Returns the currently accumulated string, as a C string, and resets
 *	the pointer to start with a new string.  The string returned is unique.
 *
 * Outputs
 *
 *	Pointer to NUL terminated C string that is the accumulated string.
 */
char *
curStrBuf()
{
  char *result;

  result = (char *) xmalloc(curLen + 1);
  result[curLen] = '\0';
  return (copyBuffer(result));
}

/*
 *	char *obstack_curStrBuf(h)
 *
 * Description
 *
 *	Returns the currently accumulated string, as a C string, and resets
 *	the pointer to start with a new string.  The string returned is unique
 *	and is allocated in the given obstack
 *
 * Inputs
 *
 *	h	Obstack in which the string is to be allocated
 *
 * Outputs
 *
 *	Pointer to NUL terminated C string that is the accumulated string.
 */
char *
obstack_curStrBuf(h)
     struct obstack	*h;
{
  char *result;

  result = (char *) obstack_alloc(h, curLen + 1);
  result[curLen] = '\0';
  return (copyBuffer(result));
}

/*
 *	void addStrBufChar(c)
 *
 * Description
 *
 *	Adds a character "c" to the string being accumulated.  The character can
 *	be any valid ASCII character.
 *
 * Inputs
 *
 *	c     : the character to add to the string.
 *
 */
void
addStrBufChar(c)
     char	c;
{
  if (curLen >= maxBufLen) {
    if (maxBufLen) {
      maxBufLen += (maxBufLen / 2);
      bufBase = (char *)xrealloc(bufBase, maxBufLen);
    } else {
      maxBufLen = STRING_BASE_SIZE;
      bufBase = (char *)xmalloc(maxBufLen);
    }
  }

  bufBase[curLen++] = c;
}

/*
 *	void addBufPointer(ptr)
 *
 * Description
 *
 *	Adds a pointer "ptr" to the buffer being built.
 *
 * Inputs
 *
 *	ptr     : the pointer to be appended.
 *
 */
void
addBufPointer(ptr)
     voidPtr ptr;
{
  if (curLen > maxBufLen - SIZEOF_CHAR_P) {
    if (maxBufLen) {
      maxBufLen += (maxBufLen / 2) + SIZEOF_CHAR_P;
      bufBase = (char *)xrealloc(bufBase, maxBufLen);
    } else {
      maxBufLen = STRING_BASE_SIZE;
      bufBase = (char *)xmalloc(maxBufLen);
    }
  }

  *((voidPtr *) (bufBase + curLen)) = ptr;
  curLen += SIZEOF_CHAR_P;
}

/*
 *	char *copyBuffer(where)
 *
 * Description
 *
 *	Returns the currently accumulated buffer, and resets the pointer
 *	to start with a new string.
 *
 * Inputs
 *
 *	where:	Pointer to the area to where the buffer must be moved
 *
 * Outputs
 *
 *	where is returned
 */
voidPtr
copyBuffer(where)
     voidPtr where;
{
  memcpy(where, bufBase, curLen);
  curLen = 0;

  return (where);
}

/*
 *	char *resetBuffer()
 *
 * Description
 *
 *	Resets the pointer to start with a new string.
 */
void
resetBuffer()
{
  curLen = 0;
}

/*
 *	long bufferSize()
 *
 * Description
 *
 *	Answer the current size of the buffer
 *
 * Outputs
 *
 *	where is returned
 */
long
bufferSize()
{
  return (curLen);
}

