#include <v_lib.h>
#include "estring.h"

V_LOCAL estr_p
estring_alloc(u32_t min_string_len)
{
	estr_p str;
	u32_t minlen, cksize;
	/* reserve space for trailing zero */
	minlen = sizeof(estr_t) + min_string_len + 1;
	NOT_LESS_POWER_TWO(cksize,minlen,u32_t);
	str = (estr_p)memAlloc(cksize);
	str->data = (char*)(str + 1);
	str->datalen = cksize - sizeof(estr_t);
	return str;
}

V_LOCAL estr_p
estring_realloc(estr_p str,u32_t min_string_len)
{
	u32_t minlen, cksize;
	if(str->datalen > min_string_len)
		return str;
	minlen = sizeof(estr_t) + min_string_len + 1;
	NOT_LESS_POWER_TWO(cksize,minlen,u32_t);
	str = (estr_p)memRealloc(str,cksize);
	str->data = (char*)(str + 1);
	str->datalen = cksize - sizeof(estr_t);
	/* the 'str->data' still points to the original contents */
	return str;
}

estr_p	V_GLOBAL
esNewString(char *strz)
{
	u32_t len;
	estr_p ret;
	if(!strz)
		return NULL;
	len = strlen(strz);
	ret = estring_alloc(len);
	ret->len = len;
	memCopy(ret->data,strz,len + 1);
	return ret;
}

estr_p	V_GLOBAL
esAssignString(estr_p str,char *strz)
{
	u32_t len;
	if(!str)
		return esNewString(strz);
	if(!strz)
	{
		memFree(str);
		return NULL;
	}
	len = strlen(strz);
	str = estring_realloc(str,len);
	memCopy(str->data,strz,len + 1);
	return str;
}

estr_p	V_GLOBAL
esCatenateString(estr_p str1,estr_p str2)
{
	if(!str1)
		return esDuplicateString(str2);
	if(!str2)
		return str1;
	str1 = estring_realloc(str1,str1->len + str2->len);
	strcat(str1->data,str2->data);
	return str1;
}

estr_p	V_GLOBAL
esCatenateStringZ(estr_p str1,char *strz)
{
	if(!str1)
		return esNewString(strz);
	if(!strz)
		return str1;
	str1 = estring_realloc(str1,str1->len + strlen(strz));
	strcat(str1->data,strz);
	return str1;
}

/*
 * Conversions: with default format
 */

estr_p	V_GLOBAL
esRealToString(vec_t val)
{
	char buf[256];
	sprintf(buf,"%g",val);
	return esNewString(buf);
}

estr_p	V_GLOBAL
esIntToString(int val)
{
	char buf[64];
	sprintf(buf,"%i",val);
	return esNewString(buf);
}

/*
 * Conversions: with format
 */

estr_p	V_GLOBAL
esRealToStringEx(char *fmt,vec_t val)
{
	char buf[256];
	if(!fmt)
		return esRealToString(val);
	sprintf(buf,fmt,val);
	return esNewString(buf);
}

estr_p	V_GLOBAL
esIntToStringEx(char *fmt,int val)
{
	char buf[64];
	if(!fmt)
		return esIntToString(val);
	sprintf(buf,fmt,val);
	return esNewString(buf);
}
