/*-------------------------------------------------------------------------
 *
 * stringinfo.c
 *
 * StringInfo provides an indefinitely-extensible string data type.
 * It can be used to buffer either ordinary C strings (null-terminated text)
 * or arbitrary binary data.  All storage is allocated with palloc().
 *
 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *	  $PostgreSQL: pgsql/src/backend/lib/stringinfo.c,v 1.50 2009/01/01 17:23:42 momjian Exp $
 *
 *-------------------------------------------------------------------------
 */
#include "postgres.h"

#include "lib/stringinfo.h"
#include "utils/memutils.h"


/*
 * makeStringInfo
 *
 * Create an empty 'StringInfoData' & return a pointer to it.
 */
StringInfo
makeStringInfo(void)
{
	StringInfo	res;

	res = (StringInfo) palloc(sizeof(StringInfoData));

	initStringInfo(res);

	return res;
}

/*
 * initStringInfo
 *
 * Initialize a StringInfoData struct (with previously undefined contents)
 * to describe an empty string.
 */
void
initStringInfo(StringInfo str)
{
	int			size = 1024;		/* initial default buffer size */

	str->data = (char *) palloc(size);
	str->maxlen = size;
	str->len = 0;
	str->data[0] = '\0';
	str->cursor = 0;
}

/*
 * initStringInfoOfSize
 *
 * Initialize a StringInfoData struct with data buffer of 'size' bytes 
 */
void
initStringInfoOfSize(StringInfo str, int size)
{

	str->data = (char *) palloc(size);
	str->maxlen = size;
	str->len = 0;
	str->data[0] = '\0';
	str->cursor = 0;
}

/*
 * initStringInfoOfString
 *
 * Initialize a StringInfoData struct with c string
 */
void
initStringInfoOfString(StringInfo str, char * buf, int size)
{
	str->data = buf;
	str->maxlen = size;
	str->len = size;
	str->cursor = 0;
}

/*
 * resetStringInfo
 *
 * Reset the StringInfo: the data buffer remains valid, but its
 * previous content, if any, is cleared.
 */
void
resetStringInfo(StringInfo str)
{
	str->data[0] = '\0';
	str->len = 0;
	str->cursor = 0;
}

/*
 * appendStringInfo
 *
 * Format text data under the control of fmt (an sprintf-style format string)
 * and append it to whatever is already in str.  More space is allocated
 * to str if necessary.  This is sort of like a combination of sprintf and
 * strcat.
 */
void
appendStringInfo(StringInfo str, const char *fmt,...)
{
	for (;;)
	{
		va_list		args;
		bool		success;

		/* Try to format the data. */
		va_start(args, fmt);
		success = appendStringInfoVA(str, fmt, args);
		va_end(args);

		if (success)
			break;

		/* Double the buffer size and try again. */
		enlargeStringInfo(str, str->maxlen);
	}
}

/*
 * appendStringInfoVA
 *
 * Attempt to format text data under the control of fmt (an sprintf-style
 * format string) and append it to whatever is already in str.	If successful
 * return true; if not (because there's not enough space), return false
 * without modifying str.  Typically the caller would enlarge str and retry
 * on false return --- see appendStringInfo for standard usage pattern.
 *
 * XXX This API is ugly, but there seems no alternative given the C spec's
 * restrictions on what can portably be done with va_list arguments: you have
 * to redo va_start before you can rescan the argument list, and we can't do
 * that from here.
 */
bool
appendStringInfoVA(StringInfo str, const char *fmt, va_list args)
{
	int			avail,
				nprinted;

	Assert(str != NULL);

	/*
	 * If there's hardly any space, don't bother trying, just fail to make the
	 * caller enlarge the buffer first.
	 */
	avail = str->maxlen - str->len - 1;
	if (avail < 16)
		return false;

	/*
	 * Assert check here is to catch buggy vsnprintf that overruns the
	 * specified buffer length.  Solaris 7 in 64-bit mode is an example of a
	 * platform with such a bug.
	 */
#ifdef USE_ASSERT_CHECKING
	str->data[str->maxlen - 1] = '\0';
#endif

	nprinted = vsnprintf(str->data + str->len, avail, fmt, args);

	Assert(str->data[str->maxlen - 1] == '\0');

	/*
	 * Note: some versions of vsnprintf return the number of chars actually
	 * stored, but at least one returns -1 on failure. Be conservative about
	 * believing whether the print worked.
	 */
	if (nprinted >= 0 && nprinted < avail - 1)
	{
		/* Success.  Note nprinted does not include trailing null. */
		str->len += nprinted;
		return true;
	}

	/* Restore the trailing null so that str is unmodified. */
	str->data[str->len] = '\0';
	return false;
}

/*
 * appendStringInfoString
 *
 * Append a null-terminated string to str.
 * Like appendStringInfo(str, "%s", s) but faster.
 */
void
appendStringInfoString(StringInfo str, const char *s)
{
	appendBinaryStringInfo(str, s, strlen(s));
}

/*
 * appendStringInfoChar
 *
 * Append a single byte to str.
 * Like appendStringInfo(str, "%c", ch) but much faster.
 */
void
appendStringInfoChar(StringInfo str, char ch)
{
	/* Make more room if needed */
	if (str->len + 1 >= str->maxlen)
		enlargeStringInfo(str, 1);

	/* OK, append the character */
	str->data[str->len] = ch;
	str->len++;
	str->data[str->len] = '\0';
}

/*
 * appendStringInfoFill
 *
 * Append a single byte, repeated 0 or more times, to str.
 */
void
appendStringInfoFill(StringInfo str, int occurrences, char ch)
{
    /* Length must not overflow. */
    if (str->len + occurrences <= str->len)
        return;

    /* Make more room if needed */
    if (str->len + occurrences >= str->maxlen)
	    enlargeStringInfo(str, occurrences);

    /* Fill specified number of bytes with the character. */
    memset(str->data + str->len, ch, occurrences);
    str->len += occurrences;
    str->data[str->len] = '\0';
}

/*
 * appendBinaryStringInfo
 *
 * Append arbitrary binary data to a StringInfo, allocating more space
 * if necessary.
 */
void
appendBinaryStringInfo(StringInfo str, const void *data, int datalen)
{
	Assert(str != NULL);

	/* Make more room if needed */
	enlargeStringInfo(str, datalen);

	/* OK, append the data */
	memcpy(str->data + str->len, data, datalen);
	str->len += datalen;

	/*
	 * Keep a trailing null in place, even though it's probably useless for
	 * binary data...
	 */
	str->data[str->len] = '\0';
}

/*
 * enlargeStringInfo
 *
 * Make sure there is enough space for 'needed' more bytes
 * ('needed' does not include the terminating null).
 *
 * External callers usually need not concern themselves with this, since
 * all stringinfo.c routines do it automatically.  However, if a caller
 * knows that a StringInfo will eventually become X bytes large, it
 * can save some palloc overhead by enlarging the buffer before starting
 * to store data in it.
 *
 * NB: because we use repalloc() to enlarge the buffer, the string buffer
 * will remain allocated in the same memory context that was current when
 * initStringInfo was called, even if another context is now current.
 * This is the desired and indeed critical behavior!
 */
void
enlargeStringInfo(StringInfo str, int needed)
{
	int			newlen;

	/*
	 * Guard against out-of-range "needed" values.  Without this, we can get
	 * an overflow or infinite loop in the following.
	 */
	if (needed < 0)				/* should not happen */
		elog(ERROR, "invalid string enlargement request size: %d", needed);
	if (((Size) needed) >= (MaxAllocSize - (Size) str->len))
		ereport(ERROR,
				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
				 errmsg("out of memory"),
				 errdetail("Cannot enlarge string buffer containing %d bytes by %d more bytes.",
						   str->len, needed)));

	needed += str->len + 1;		/* total space required now */

	/* Because of the above test, we now have needed <= MaxAllocSize */

	if (needed <= str->maxlen)
		return;					/* got enough space already */

	/*
	 * We don't want to allocate just a little more space with each append;
	 * for efficiency, double the buffer size each time it overflows.
	 * Actually, we might need to more than double it if 'needed' is big...
	 */
	newlen = 2 * str->maxlen;
	while (needed > newlen)
		newlen = 2 * newlen;

	/*
	 * Clamp to MaxAllocSize in case we went past it.  Note we are assuming
	 * here that MaxAllocSize <= INT_MAX/2, else the above loop could
	 * overflow.  We will still have newlen >= needed.
	 */
	if (newlen >= (int) MaxAllocSize)
	{
		/*
		 * Currently we support allocations only up to MaxAllocSize - 1
		 * (see AllocSizeIsValid()).
		 */
		newlen = (int) MaxAllocSize - 1;
	}

	str->data = (char *) repalloc(str->data, newlen);

	str->maxlen = newlen;
}


/*------------------------
 * truncateStringInfo
 * Make sure a StringInfo's string is no longer than 'nchars' characters.
 */
void 
truncateStringInfo(StringInfo str, int nchars)
{
    if (str &&
        str->len > nchars)
    {
        Assert(str->data != NULL && 
               str->len <= str->maxlen);
        str->len = nchars;
        str->data[nchars] = '\0';
    }
}                               /* truncateStringInfo */

/*
 * Replace all occurrences of a string in a StringInfo with a different string.
 */
void
replaceStringInfoString(StringInfo str, char *replace, char *replacement)
{
	char	   *ptr;

	while ((ptr = strstr(str->data, replace)) != NULL)
	{
		char	   *dup = pstrdup(str->data);

		resetStringInfo(str);
		appendBinaryStringInfo(str, dup, ptr - str->data);
		appendStringInfoString(str, replacement);
		appendStringInfoString(str, dup + (ptr - str->data) + strlen(replace));		
		pfree(dup);
	}
}

