#include "SCR.h"
#include <string.h>
 
char g_chEndSections=0;
 
void fn_v_Bin_Read( SCR_tdst_File_Description   *_File, int _Length, void *_Dest )
{
	char *pch=(char *)_Dest;
 
	_File->lChangeInPos+=_Length;
 
	if( _Length <= _File->p_stHandle->iCnt )
	{
		memcpy( _Dest, (void *)_File->p_stHandle->p_cCurrent, _Length );
		_File->p_stHandle->iCnt-=_Length;
		_File->p_stHandle->p_cCurrent+=_Length;
	}
	else
	{   
		memcpy( _Dest, (void *)_File->p_stHandle->p_cCurrent, _File->p_stHandle->iCnt );
		pch+=_File->p_stHandle->iCnt;
		_Length-=_File->p_stHandle->iCnt;
		while( _Length )
		{
			(_File)->p_stHandle->iCnt = SCR_M_fread((_File)->p_stHandle->p_cBase, 1, SCR_CV_ui_Cfg_SizeBufferFile, _File);
			if(((_File)->p_stHandle->iCnt == 0) || ((_File)->p_stHandle->iCnt == -1))
			{
				(_File)->p_stHandle->iCnt = 0;
				*pch = EOF;
				break;
			}
			else
			{
				(_File)->p_stHandle->p_cCurrent = (_File)->p_stHandle->p_cBase;
				if( _Length <= _File->p_stHandle->iCnt )
				{
					memcpy( (void *)pch, (void *)_File->p_stHandle->p_cCurrent, _Length );
					_File->p_stHandle->iCnt-=_Length;
					_File->p_stHandle->p_cCurrent+=_Length;
					_Length=0;
				}
				else
				{
					memcpy( (void *)pch, (void *)_File->p_stHandle->p_cCurrent, _File->p_stHandle->iCnt );
					pch+=_File->p_stHandle->iCnt;
					_Length-=_File->p_stHandle->iCnt;
				}
			}
		}
	}
}
 
void fn_v_Bin_Skip( SCR_tdst_File_Description   *_File, int _Length )
{
	_File->lChangeInPos+=_Length;
 
	if( _Length <= _File->p_stHandle->iCnt )
	{
		_File->p_stHandle->iCnt-=_Length;
		_File->p_stHandle->p_cCurrent+=_Length;
	}
	else
	{   
		_Length-=_File->p_stHandle->iCnt;
		while( _Length )
		{
			(_File)->p_stHandle->iCnt = SCR_M_fread((_File)->p_stHandle->p_cBase, 1, SCR_CV_ui_Cfg_SizeBufferFile, _File);
			if(((_File)->p_stHandle->iCnt == 0) || ((_File)->p_stHandle->iCnt == -1))
			{
				(_File)->p_stHandle->iCnt = 0;
				break;
			}
			else
			{
				(_File)->p_stHandle->p_cCurrent = (_File)->p_stHandle->p_cBase;
				if( _Length <= _File->p_stHandle->iCnt )
				{
					_File->p_stHandle->iCnt-=_Length;
					_File->p_stHandle->p_cCurrent+=_Length;
					_Length=0;
				}
				else
				{
					_Length-=_File->p_stHandle->iCnt;
				}
			}
		}
	}
}
 
 
 
 
char SCR_fn_ch_Bin_GetCHAR( SCR_tdst_File_Description   *_File )
{
	char ch;
	fn_v_Bin_Read(_File, sizeof( char ), (void*)&ch);
	return ch;
}
 
short SCR_fn_s_Bin_GetSHORT( SCR_tdst_File_Description   *_File )
{
	short s;
	fn_v_Bin_Read(_File, sizeof( short ), (void*)&s);
	return s;
}
 
long SCR_fn_l_Bin_GetLONG( SCR_tdst_File_Description   *_File )
{
	long l;
	fn_v_Bin_Read(_File, sizeof( long ), (void*)&l);
	return l;
}
 
unsigned char SCR_fn_uch_Bin_GetUCHAR( SCR_tdst_File_Description   *_File )
{
	unsigned char ch;
	fn_v_Bin_Read(_File, sizeof( unsigned char ), (void*)&ch);
	return ch;
}
 
unsigned short SCR_fn_us_Bin_GetUSHORT( SCR_tdst_File_Description   *_File )
{
	unsigned short s;
	fn_v_Bin_Read(_File, sizeof( unsigned short ), (void*)&s);
	return s;
}
 
unsigned long SCR_fn_ul_Bin_GetULONG( SCR_tdst_File_Description   *_File )
{
	unsigned long l;
	fn_v_Bin_Read(_File, sizeof( unsigned long ), (void*)&l);
	return l;
}
 
 
float SCR_fn_f_Bin_GetFLOAT( SCR_tdst_File_Description   *_File )
{
	float f;
	fn_v_Bin_Read(_File, sizeof( float ), (void*)&f);
	return f;
}
 
double SCR_fn_d_Bin_GetDOUBLE( SCR_tdst_File_Description   *_File )
{
	double d;
	fn_v_Bin_Read(_File, sizeof( double ), (void*)&d);
	return d;
}
 
 
char * SCR_fn_sz_Bin_GetSTRING( SCR_tdst_File_Description   *_File )
{
	short s=SCR_fn_s_Bin_GetSHORT( _File );
	char *sz;
	SCR_M_Mem_Alloc(char, sz, s+1);
	fn_v_Bin_Read( _File, s, (void *)sz );
	sz[s]=0;
	return sz;
}
 
int SCR_fn_sz_Bin_GetSTRING2Buffer( SCR_tdst_File_Description   *_File, char *sz )
{
	short s=SCR_fn_s_Bin_GetSHORT( _File );
	fn_v_Bin_Read( _File, s, (void *)sz );
	sz[s]=0;
	return s;
}
 
 
void * SCR_fn_p_Bin_GetARRAY( SCR_tdst_File_Description   *_File, short sIze )
{
	short s=SCR_fn_s_Bin_GetSHORT( _File );
	char *sz;
	SCR_M_Mem_Alloc(char, sz, s*sIze);
	fn_v_Bin_Read( _File, s*sIze, (void *)sz );
	return (void *)sz;
 
}
 
void SCR_fn_sz_Bin_GetREFERENCE2Buffer( SCR_tdst_File_Description   *_File, char* sz )
{
	unsigned short usVal, usLast, usIsIndex;
	int i=0;
	do{
	  usVal=SCR_fn_us_Bin_GetUSHORT( _File );
	  usLast=usVal&0x4000;
	  usIsIndex=usVal&0x8000;
	  usVal&=0x3FFF;
	  if( usIsIndex )
      {
		  strcpy( sz+i, _File->p_stRefs->a_szRefName[usVal] );
		  i+=strlen( _File->p_stRefs->a_szRefName[usVal] );
	  }
	  else
	  {
		  fn_v_Bin_Read( _File, usVal, sz+i );
		  i+=usVal;
	  }
	} while ( !usLast );
 
	sz[i]=0;
}
 
 
static char buffer[200];
 
char *SCR_fn_sz_Bin_GetREFERENCE( SCR_tdst_File_Description   *_File )
{
	unsigned short usVal, usLast, usIsIndex;
	int i=0;
	char *retVal;
	do{
	  usVal=SCR_fn_us_Bin_GetUSHORT( _File );
	  usLast=usVal&0x4000;
	  usIsIndex=usVal&0x8000;
	  usVal&=0x3FFF;
	  if( usIsIndex )
      {
		  strcpy( buffer+i, _File->p_stRefs->a_szRefName[usVal] );
		  i+=strlen( _File->p_stRefs->a_szRefName[usVal] );
	  }
	  else
	  {
		  fn_v_Bin_Read( _File, usVal, buffer+i );
		  i+=usVal;
	  }
	} while ( !usLast );
 
	buffer[i]=0;
	SCR_M_Mem_Alloc(char, retVal, i);
	strcpy( retVal, buffer );
	return retVal;
}
 
void SCR_fn_v_Bin_BeginSection( SCR_tdst_File_Description   *_p_stFile )
{
	unsigned short us;
	us=SCR_fn_us_Bin_GetUSHORT( _p_stFile );
	if( us==0xFFFF )
	{
		_p_stFile->lToEndSection=SCR_fn_l_Bin_GetLONG( _p_stFile )+6;
		_p_stFile->lChangeInPos=6;
	}
	else
	{
		_p_stFile->lToEndSection=(long)us+2;
		_p_stFile->lChangeInPos=2;
	}
}
 
short fn_s_Bin_SectionName( SCR_tdst_File_Description   *_File, char * _p_szAction, char * _p_szId )
{
	char *pch;
	short s=SCR_fn_sz_Bin_GetSTRING2Buffer( _File, _p_szAction );
	pch=strchr( _p_szAction, ':' );
	if( pch )
	{
		strcpy( _p_szId, pch+1 );
		*pch=0;
	}
	else _p_szId[0]=0;
	return s+2;
}
 
void fn_v_Bin_Line(
    SCR_tdst_File_Description   *_p_stFile,
    char                        *_p_szKeyword1,
    char                        *_p_szKeyword2,
    char                        *_p_szKeyword3,
    char                        *_p_szKeyword4,
    SCR_tde_Cxt_ParseType       *_p_eParseType,
    unsigned int                *_p_uiNbRead
)
{
	char sTag;
 
	*_p_uiNbRead=0;
 
	if( _p_stFile->lCountEndSections==-1 )
	{
		*_p_uiNbRead=_p_stFile->lToEndSection;
		_p_stFile->lCountEndSections=0;
	}
	if( _p_stFile->lCountEndSections>0 )
	{
		*_p_eParseType=SCR_EPT_Cxt_EndSection;
		*_p_uiNbRead=_p_stFile->lToEndSection;
		_p_stFile->lToEndSection=0;
		_p_stFile->lCountEndSections--;
		return;
	}
 
	sTag=SCR_fn_ch_Bin_GetCHAR( _p_stFile ); /* get type tag */
 
	if( sTag>0 )
	{
		*_p_eParseType=SCR_EPT_Cxt_Entry;
		_p_szKeyword1[0]=sTag;
		*_p_uiNbRead+=1;
		return;
	}
 
	switch( sTag )
	{
	case TAG_BEGINSECTION:
	  /* Get section name (action + id) */
	  *_p_uiNbRead+=fn_s_Bin_SectionName(_p_stFile, _p_szKeyword1, _p_szKeyword2);
	  *_p_eParseType = SCR_EPT_Cxt_BeginSection;
	  break;
	
	case TAG_EOF:
	case TAG_COMMENT:
	  *_p_eParseType = SCR_EPT_Cxt_None;
	  break;
		
	default:   /* it is a directive then... */
	  /**_p_eParseType = SCR_EPT_Cxt_None;*/
	  _p_szKeyword4[0]=sTag;
	  *_p_eParseType = SCR_EPT_Cxt_Directive;
	  break;
	}
 
	*_p_uiNbRead+=1;
 
	return;
}
 
 
long fn_l_Bin_ToEndSection( SCR_tdst_Cxt_Description *p_stContext )
{
	long l,l1;
	char ch;
	unsigned short us=SCR_fn_us_Bin_GetUSHORT( &p_stContext->p_stOpenFile->stFile );
	if( us!=0xFFFF )
	{
		l=us-1;
		l1=us+2;
	}
	else
	{
		l=SCR_fn_l_Bin_GetLONG( &p_stContext->p_stOpenFile->stFile )-1;
		l1=l+7;
	}
	fn_v_Bin_Skip( &p_stContext->p_stOpenFile->stFile, l );
	ch=SCR_fn_ch_Bin_GetCHAR( &p_stContext->p_stOpenFile->stFile );
	if( ch<=0 )
		p_stContext->p_stOpenFile->stFile.lCountEndSections=-ch+1;
	return l1;
}
 
 
void SCR_fn_v_Bin_EndSection( SCR_tdst_File_Description   *_p_stFile )
{
	char ch;
 
	ch=SCR_fn_ch_Bin_GetCHAR( _p_stFile );
	if( ch<=0 )
		_p_stFile->lCountEndSections=-ch+1;
	else
		_p_stFile->lCountEndSections=-1;
}
 
 
 
SCR_tdst_Cxt_Values *SCR_fnp_st_Bin_GetREFERENCE( char *szName )
{
	SCR_tdst_Cxt_Description *cxt=fnp_st_Cxt_Compute(0);
	SCR_tdst_File_Description *_file=&cxt->p_stOpenFile->stFile;
	long lPosition=cxt->stPosition.lAfterSeekInFile;
	long lToEndSection, lChangeInPos;
	SCR_tdst_Cxt_Values *p_stVal;
	int _iRes;
	lChangeInPos=_file->lChangeInPos;
	lToEndSection=_file->lToEndSection;
	if( cxt->p_stOpenFile->stParsingInfos.stPosition.lAfterSeekInFile<lPosition+lToEndSection )
	{
		fn_v_Bin_Skip( _file, lToEndSection-lChangeInPos-1 );
		SCR_fn_v_Bin_EndSection( _file );
		cxt->p_stOpenFile->stParsingInfos.stPosition.lAfterSeekInFile=lPosition+lToEndSection;
	}
	_file->lChangeInPos=_file->lToEndSection=0;
	p_stVal = SCR_fnp_st_RdL0_AnalyseSection(szName, SCR_CDF_uw_Anl_Normal);
	cxt->stPosition.lAfterSeekInFile=lPosition;
    _file->lChangeInPos=lChangeInPos;
	_file->lToEndSection=lToEndSection;
	SCR_M_fseek(_file, lPosition+lChangeInPos, SEEK_SET, _iRes);
	return p_stVal;
}
 
long fn_l_Bin_AnalyseDirective(SCR_tdst_Cxt_Description *_p_stContext)
{
    char    chDirective;
	long l=0;
 
    chDirective = _p_stContext->stBuffers.a_szBufferParams[0];
 
	/*
     *  Test all directives.
     */
	switch( chDirective )
	{
    
    case SCR_CD_w_Cfg_BreakPoint:
	case SCR_CD_w_Cfg_UpdateLog:
	case SCR_CD_w_Cfg_Comments:
	case SCR_CD_w_Cfg_EndComments:
	case SCR_CD_w_Cfg_NotSaveSection:
    case SCR_CD_w_Cfg_EndNotSaveSection:
    	l+=SCR_fn_s_Bin_GetSHORT( &_p_stContext->p_stOpenFile->stFile )+2;
		fn_v_Bin_Skip( &_p_stContext->p_stOpenFile->stFile, l );
		break;
	case SCR_CD_w_Cfg_ForceAnalyse:
    {
    	l+=SCR_fn_s_Bin_GetSHORT( &_p_stContext->p_stOpenFile->stFile )+2;
		fn_v_Bin_Skip( &_p_stContext->p_stOpenFile->stFile, l );
        if(_p_stContext->p_stOpenFile->stParsingInfos.uwDynamicFlags & SCR_CDF_uw_Anl_ForceAnalyse)
        {
            SCR_M_Err_UpdateSyntaxError();
            sprintf(g_st_Err_GlobalError.a_szBufferTmp2, "Directive is \"%s\".", SCR_CD_sz_Cfg_ForceAnalyse );
            SCR_M_Err_RaiseWarning(SCR_EI_Err_UnnecessaryDirective);
        }
        else
            _p_stContext->p_stOpenFile->stParsingInfos.uwDynamicFlags |= SCR_CDF_uw_Anl_ForceAnalyse;
    }
	break;
    case SCR_CD_w_Cfg_EndForceAnalyse:
    {
    	l+=SCR_fn_s_Bin_GetSHORT( &_p_stContext->p_stOpenFile->stFile )+2;
		fn_v_Bin_Skip( &_p_stContext->p_stOpenFile->stFile, l );
        if((_p_stContext->p_stOpenFile->stParsingInfos.uwDynamicFlags & SCR_CDF_uw_Anl_ForceAnalyse) == 0)
        {
            SCR_M_Err_UpdateSyntaxError();
            sprintf(g_st_Err_GlobalError.a_szBufferTmp2, "Directive is \"%s\".", SCR_CD_sz_Cfg_EndForceAnalyse);
            SCR_M_Err_RaiseWarning(SCR_EI_Err_UnnecessaryDirective);
        }
        else
            _p_stContext->p_stOpenFile->stParsingInfos.uwDynamicFlags &= ~SCR_CDF_uw_Anl_ForceAnalyse;
    }
	break;
	case SCR_CD_w_Cfg_SetCurrentFileLong:
	{
		short s1, s2;
    	l+=SCR_fn_s_Bin_GetSHORT( &_p_stContext->p_stOpenFile->stFile )+2;
		s1=SCR_fn_s_Bin_GetSHORT( &_p_stContext->p_stOpenFile->stFile );
		s2=SCR_fn_s_Bin_GetSHORT( &_p_stContext->p_stOpenFile->stFile );
		SCR_M_RdL0_SetFileLong(0, s1, s2 );
    }
	break;
    case SCR_CD_w_Cfg_SetCurrentFileDouble:
    {
		short s;
		double d;
    	l+=SCR_fn_s_Bin_GetSHORT( &_p_stContext->p_stOpenFile->stFile )+2;
		s=SCR_fn_s_Bin_GetSHORT( &_p_stContext->p_stOpenFile->stFile );
		d=SCR_fn_d_Bin_GetDOUBLE( &_p_stContext->p_stOpenFile->stFile );
        SCR_M_RdL0_SetFileDouble(0, s, d);
    }
	break;
	}
	return l;
}
 
 
