/*-------------------------------------------------------------------------
 * drawElements Memory Pool Library
 * --------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Memory pool management.
 *//*--------------------------------------------------------------------*/

#include "dePoolStringBuilder.h"

#include <string.h>
#include <stdarg.h>
#include <stdio.h>

typedef struct StringBlock_s
{
	const char*				str;
	struct StringBlock_s*	next;
} StringBlock;

struct dePoolStringBuilder_s
{
	deMemPool*		pool;
	int				length;
	StringBlock*	blockListHead;
	StringBlock*	blockListTail;
};

dePoolStringBuilder* dePoolStringBuilder_create (deMemPool* pool)
{
	dePoolStringBuilder* builder = DE_POOL_NEW(pool, dePoolStringBuilder);
	if (!builder)
		return DE_NULL;

	builder->pool			= pool;
	builder->length			= 0;
	builder->blockListHead	= DE_NULL;
	builder->blockListTail	= DE_NULL;

	return builder;
}

deBool dePoolStringBuilder_appendString (dePoolStringBuilder* builder, const char* str)
{
	StringBlock*	block		= DE_POOL_NEW(builder->pool, StringBlock);
	size_t			len			= strlen(str);
	char*			blockStr	= (char*)deMemPool_alloc(builder->pool, len + 1);

	if (!block || !blockStr)
		return DE_FALSE;

	/* Initialize block. */
	{
		char*		d	= blockStr;
		const char*	s	= str;
		while (*s)
			*d++ = *s++;
		*d = 0;

		block->str	= blockStr;
		block->next	= DE_NULL;
	}

	/* Add block to list. */
	if (builder->blockListTail)
		builder->blockListTail->next = block;
	else
		builder->blockListHead = block;

	builder->blockListTail = block;

	builder->length += (int)len;

	return DE_TRUE;
}

deBool dePoolStringBuilder_appendFormat (dePoolStringBuilder* builder, const char* format, ...)
{
	char	buf[512];
	va_list	args;
	deBool	ok;

	va_start(args, format);
	vsnprintf(buf, DE_LENGTH_OF_ARRAY(buf), format, args);
	ok = dePoolStringBuilder_appendString(builder, buf);
	va_end(args);

	return ok;
}

/* \todo [2009-09-05 petri] Other appends? printf style? */

int dePoolStringBuilder_getLength (dePoolStringBuilder* builder)
{
	return builder->length;
}

char* dePoolStringBuilder_dupToString (dePoolStringBuilder* builder)
{
	return dePoolStringBuilder_dupToPool(builder, builder->pool);
}

char* dePoolStringBuilder_dupToPool (dePoolStringBuilder* builder, deMemPool* pool)
{
	char* resultStr = (char*)deMemPool_alloc(pool, (size_t)builder->length + 1);

	if (resultStr)
	{
		StringBlock*	block	= builder->blockListHead;
		char*			dstPtr	= resultStr;

		while (block)
		{
			const char* p = block->str;
			while (*p)
				*dstPtr++ = *p++;
			block = block->next;
		}

		*dstPtr++ = 0;

		DE_ASSERT((int)strlen(resultStr) == builder->length);
	}

	return resultStr;
}
