/******************************************************************************
 *
 * Copyright (c) 1999	TOSHIYUKI ARAI. ALL RIGHTS RESERVED. 
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer.
 *  
 * 2. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *
 *	StringTokenizer.cpp
 *
 *****************************************************************************/

// SOL++2000
// 1999.09.23 Modified hasMoreToken method.

#include <sol\StringTokenizer.h>


StringTokenizer::StringTokenizer()
{
	num = 0;
	separator[num++] = ' ';
	separator[num++] = '\t';
	separator[num++] = ',';
	string = null;
}



StringTokenizer::StringTokenizer(const char* string)
{
	num = 0;
	separator[num++] = ' ';
	separator[num++] = '\t';
	separator[num++] = ',';
	this -> string = string;
}


StringTokenizer::StringTokenizer(String& buffer) 
{
	num = 0;
	separator[num++] = ' ';
	separator[num++] = '\t';
	separator[num++] = ',';
	this -> string = (char*)buffer;
}


StringTokenizer::StringTokenizer(StringBuffer& buffer) 
{
	num = 0;
	separator[num++] = ' ';
	separator[num++] = '\t';
	separator[num++] = ',';
	this -> string = (char*)buffer.getBuffer();
}

int StringTokenizer::addSeparator(char x)
{
	int rc = False;
	if(num < 5) {
		separator[num++] = x;
		rc = True;
	}
	return rc;
}


boolean StringTokenizer::hasMoreToken()
{
	boolean rc = false;
	// 1999.09.23 Added *string != Zero
	if (string != null && *string != Zero) {
		rc = true;
	}
	return rc;
}

void StringTokenizer::clearSeparator()
{
	num = 0;
}


int StringTokenizer::isSeparator(char x)
{
	int rc = False;
	for(int i = 0; i< num; i++) {
		if(separator[i] == x) {
			rc = True;
			break;
		}
	}
	return rc;
}


const char* StringTokenizer::getToken(String& token)
{
	if (string != null) {
		StringBuffer buffer;
		string = getToken(buffer);
		token = buffer.getBuffer();
	}
	return string;
}


const char* StringTokenizer::getToken(StringBuffer& buffer)
{
	int flag = 0;
	const char* line = string;
	
	if(line == null || *line == Zero) {
		return null;
	}

	while(*line !=Zero && isSeparator(*line) == True) {		
		line++;
	}

	while(*line != Zero) {
		if(*line == '"' && *(line+1) == '"') {
			line += 2;
			break;
		}
		if(*line == '"') {
			line++;  
			flag++;
		}
		if(isSeparator(*line) == True && flag == 2) {
			break;
		}
		if(isSeparator(*line) == True && flag == 0) {
			break;
		}
		buffer.append(*line++);
	}
	return line;
}


const char* StringTokenizer::getToken(char* token, int size)
{
	if (string != null) {
		string = getToken(string, token, size);
	}
	return string;
}

const char* StringTokenizer::getToken(const char* line, char* first, int size)
{
	int flag = 0;

	if(*line == Zero) return NULL;

	while(*line !=Zero && isSeparator(*line) == True) {		
		line++;
	}

	int len = 1;
	while(*line != Zero) {
		if(*line == '"' && *(line+1) == '"') {
			line += 2;
			break;
		}
		if(*line == '"') {
			line++;  
			flag++;
		}
		if(isSeparator(*line) == True && flag == 2) {
			break;
		}
		if(isSeparator(*line) == True && flag == 0) {
			break;
		}
	
		if(len < size) {
			*first++ = *line++;
			len++;
		}
		else {
			break;
		}
	}
	*first = Zero;
	return line;
}


const char* StringTokenizer::getInteger(const char* line, int* value)
{
	char word[10];

	const char* ptr = getToken(line, word, sizeof(word));
	*value = atoi(word);
	return ptr; 
}


int StringTokenizer::hexStringToInt(const char* str)
{
  	int n;
	if(*str++ =='0' && *str++ == 'x') {
		sscanf(str, "%x", &n);
		return n;
	}
	return 0;
}

