// TextLineParser.cpp: implementation of the CTextLineParser class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
//#include "TextLineParserTest.h"
#include "TextLineParser.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CTextLineParser::CTextLineParser()
{
	m_pFormat = NULL;
	m_nFormatSize = 0;
}

CTextLineParser::~CTextLineParser()
{

}

void CTextLineParser::SetFormat(TLP_FORMAT* pFormat, int nFormatSize, char cDelimiter)
{
	ASSERT(AfxIsValidAddress(pFormat, nFormatSize));

	m_pFormat = pFormat;
	m_nFormatSize = nFormatSize;
	m_cDelimiter = cDelimiter;
}

#ifdef _DEBUG

BOOL CTextLineParser::CheckStruct(void* pStruct)
{
	int nStructSize = 0;
	int dbgi;
	for(dbgi = 0; dbgi < m_nFormatSize; dbgi++)
	{
		switch (m_pFormat[dbgi])
		{
			case TLP_INT:
				nStructSize += sizeof(int);
				break;
			case TLP_ZSTR:
				nStructSize += sizeof(char*);
				break;
			case TLP_DOUBLE:
				nStructSize += sizeof(double);
				break;
			default:
				ASSERT(FALSE);
				break;
		}
	}
	return AfxIsValidAddress(pStruct, nStructSize);
}

#endif

bool CTextLineParser::ParseTextLine(char** pszText, void* pStruct)
{
	ASSERT(CheckStruct(pStruct));
	ASSERT(AfxIsValidString(*pszText));
	ASSERT(m_pFormat && m_nFormatSize);

	BYTE* pStructField = (BYTE*)pStruct;
	char* p = *pszText;
	int nParam = 0;
	bool bRet;

	while (*p != '\0')
	{
		if((*p == '\r' && *(p + 1) == '\n') ||
		   (*p == '@'  && *(p + 1) == '@'))
		{
			if (nParam == m_nFormatSize - 1)
			{
				*p = '\0';
				SetParam(nParam, pStructField, *pszText);
				bRet = true;
			}
			else
				bRet = false;	// Skip empty line or bad formated line
			
			*pszText = p + 2;		
			return bRet;
		}
		else if (*p == m_cDelimiter)
		{
			*p = '\0';
			SetParam(nParam, pStructField, *pszText);

			*pszText = ++p;
			nParam++;
		}	
		else
			p++;
	}
	
	if (nParam == m_nFormatSize - 1)
	{
		SetParam(nParam, pStructField, *pszText);
		bRet = true;
	}
	else
		bRet = false;
		
	*pszText = NULL;
	return bRet;
}

void CTextLineParser::SetParam(int nParam, BYTE*& pStructField, char* p)
{	
	ASSERT(nParam < m_nFormatSize);

	switch (m_pFormat[nParam])
	{
		case TLP_INT:
			*((int*)pStructField) = atoi(p);
			pStructField += sizeof(int);
			break;
		case TLP_ZSTR:
			*((char**)pStructField) = p;
			pStructField += sizeof(char*);
			break;
		case TLP_DOUBLE:
			*((double*)pStructField) = atof(p);
			pStructField += sizeof(double);
			break;
		default:
			ASSERT(FALSE);
			break;
	}
}