// Common, group Parsing
// Copyright Alexander Liss

#include <string.h>
#include "strtokens.h"


		// StrTokens


int StrTokens::parse(const char * str)
{
	int g=0;
	g=data.set(str);
	if(g) return 1;
	return parse();
}

int StrTokens::parse(const char * d,int s)
{
	int g=0;
	g=data.set(d,s);
	if(g) return 1;
	return parse();
}

int StrTokens::translate_parse(const char * str,const char *from,char to)
{
	int g=0;
	g=data.set(str);
	if(g) return 1;
	g=translate_char(data.data,from,to);
	if(g) return 2;
	return parse();
}

int StrTokens::shrink_parse(const char * str,const char *from,char to,bool drop_ends)
{
	int g=0;
	g=data.set(str);
	if(g) return 1;
	g=shrink_char(data.data,from,to,drop_ends);
	if(g) return 2;
	return parse();
}

int StrTokens::get_next(StrBuffer& dest)
{
	int g=0;

	if(current >= data.data+data.data_size)
		return 1;

	g=dest.set(current);

	if(g) return 2;

	move_next();

	return 0;
}

int StrTokens::move_next()
{

	if(current >= data.data+data.data_size-1)
		return 1;

	while(*current!=0 && current != data.data+data.data_size-1) 
		++current;

	//step over delimiter
	++current;


	if(current >= data.data+data.data_size)
		return 2;

	//++current;

	return 0;
}

int StrTokens::parse()
{

	int g=0;

	start_pointer=current=data.data;

	for(int i=0;i<delimiters.data_size;++i)
	{
		g=translate_char(data.data,delimiters.data[i],0);
		if(g) return 1;
	}

	token_number=0;
	if(start_pointer) token_number=1;
	while(!move_next()) ++token_number;

	current=start_pointer;
	
	return 0;
}


		// GLOBAL FUNCTIONS 


int translate_char(char * data_string,char from,char to)
{
	if( ! data_string) return 1;

	if(from==to) return 0;

	int size=strlen(data_string);

	for(int i=0;i<size;++i)
	{
		if(data_string[i]==from)
			data_string[i]=to;
	}

	return 0;
}

int translate_char(char * data_string,const char *from,char to)
{
	if( ! data_string || ! from ) return 1;


	int g=0, 
		size=strlen(from);

	for(int i=0;i<size;++i)
	{
		g=translate_char(data_string,from[i],to);
		if(g) return 2;
	}

	return 0;
}


int shrink_char(char * data_string,const char *from,char to,bool drop_ends)
{
	StrBuffer buf(data_string);

	int g=translate_char(buf.data,from,to);

	if( g) return 1;

	int j=0;
	for(int i=0;i<buf.data_size;i++)
	{
		if(	buf.data[i]!=to ||
			j!=0 && data_string[j-1]!=to ||
			j==0 && ! drop_ends )
		{
			data_string[j]=buf.data[i];	
			++j;
		}

	}

	if(drop_ends && j>1 && data_string[j-1] == to)
		--j;

	// clear tail
	for(;j<buf.data_size;++j)
		data_string[j]=0;

	return 0;
}


int drop_char(char * data_string,const char *drop_list)
{
	StrBuffer buf(data_string);
	char to=drop_list[0];

	int g=translate_char(buf.data,drop_list,to);

	if(g) return 1;

	int j=0;
	for(int i=0;i<buf.data_size;i++)
	{
		if(buf.data[i]!=to)
		{
			data_string[j]=buf.data[i];	
			++j;
		}
	}

	// clear tail
	for(;j<buf.data_size;++j)
		data_string[j]=0;

	return 0;
}



int translate_char(StrBuffer& b,char from,char to)
{
	if(translate_char(b.data,from,to))
		return 1;
	b.data_size=strlen(b.data);
	return 0;
}

int translate_char(StrBuffer& b,const char *from,char to)
{
	if(translate_char(b.data,from,to))
		return 1;
	b.data_size=strlen(b.data);
	return 0;
}

int shrink_char(StrBuffer& b,const char *from,char to,bool drop_ends)
{
	if(shrink_char(b.data,from,to,drop_ends))
		return 1;
	b.data_size=strlen(b.data);
	return 0;
}

int drop_char(StrBuffer& b,const char *drop_list)
{
	if(drop_char(b.data,drop_list))
		return 1;
	b.data_size=strlen(b.data);
	return 0;
}