
#include "SD_Card.h"
#include "DPC_Timeout.h"
#include "string.h"
#include "stdlib.h"
#include "stdio.h"
#include "rtc.h"

volatile ff_search_struct FileSearchStruct;

void SD_Card_Var_Init(SD_CARD_Global_Struct* SD_Struct){

	HTTP_DATA_Struct* HTTP_DATA;
	HTTP_DATA=&SD_Struct->CSV_DATA;

	SD_Struct->DATA0 = &SD_Struct->DATA0_ch[0];

	SD_Struct->Header = "serial_number;"
				"started_at;"
				"ended_at;"
				"status_indication;"
				"energy_sum;"
				"battery_level_at_start;"
				"battery_level_at_end;"
				"battery_voltage_at_start;"
				"battery_voltage_at_end;"
				"battery_temperature_at_end;"
				"latitude;"
				"longitude;"
				"maximum_load_current;"
				"maximum_charge_current;"
				"internal_resistance;"
				"is_moderated;"
				"event_time;"
				"battery_condition_id\r";


	SD_Struct->FileName = &SD_Struct->Filename_ch[0];
	SD_Struct->Path = &SD_Struct->Path_ch[0];



	HTTP_DATA->Serial_Number				 = &HTTP_DATA->Serial_Number_var[0];
	HTTP_DATA->Battery_Condition_ID			 = &HTTP_DATA->Battery_Condition_ID_var[0];
	HTTP_DATA->Event_time					 = &HTTP_DATA->Event_time_var[0];
	HTTP_DATA->Started_At_Time 				 = &HTTP_DATA->Started_At_Time_var[0];
	HTTP_DATA->Ended_At_Time				 = &HTTP_DATA->Ended_At_Time_var[0];
	HTTP_DATA->Status_Indication			 = &HTTP_DATA->Status_Indication_var[0];
	HTTP_DATA->Energy_Sum					 = &HTTP_DATA->Energy_Sum_var[0];
	HTTP_DATA->Battery_Level_At_Start		 = &HTTP_DATA->Battery_Level_At_Start_var[0];
	HTTP_DATA->Battery_Level_At_End			 = &HTTP_DATA->Battery_Level_At_End_var[0];
	HTTP_DATA->Battery_Voltage_At_Start 	 = &HTTP_DATA->Battery_Voltage_At_Start_var[0];
	HTTP_DATA->Battery_Voltage_At_End		 = &HTTP_DATA->Battery_Voltage_At_End_var[0];
	HTTP_DATA->Battery_Temperature_At_End	 = &HTTP_DATA->Battery_Temperature_At_End_var[0];
	HTTP_DATA->Latitude						 = &HTTP_DATA->Latitude_var[0];
	HTTP_DATA->Longitude					 = &HTTP_DATA->Longitude_var[0];
	HTTP_DATA->Maximum_Load_Current			 = &HTTP_DATA->Maximum_Load_Current_var[0];
	HTTP_DATA->Maximum_Charge_Current		 = &HTTP_DATA->Maximum_Charge_Current_var[0];
	HTTP_DATA->Internal_Resistance			 = &HTTP_DATA->Internal_Resistance_var[0];
	HTTP_DATA->Moderated					 = &HTTP_DATA->Moderated_var[0];
	HTTP_DATA->Current_time					 = &HTTP_DATA->Current_time_var[0];

}

uint8_t SD_Received_LOOKFOR(char* answ, char* LOOKFOR){
	uint8_t result=0;
	char *istr='\0';
	istr=strstr(answ, LOOKFOR);
	if (istr=='\0')
	{
		result=0; //nothing found
	}
	else
	{
		result=1; //found
	}
	return result;
}

SD_Card_states SD_Set_Command(SD_CARD_Global_Struct* SD_Struct, SD_Op_Commands CMD, uint32_t Timeout){

	if (SD_Struct->SD_State_to_return == SD_READY){
		//Battery_Data_to_String_Converter(Sim_Struct);
		SD_Struct->SD_Active_Command = CMD;
		SD_Struct->SD_State_to_return = SD_BUSY;
		DPC_TO_Set(TO_SD_Card,Timeout);
		//CSV_Data_Compilation(SD_Struct);
		return SD_COMMAND_SET;
	}
	else return SD_COMMAND_NOT_SET;
}


void SD_Card_Processing(SD_CARD_Global_Struct* SD_Struct){

	SD_Stages* Active_Stage;
	SD_Op_Commands* CMD;
	Time_Struct rtc_time;
	char Filename_ch[20];
	char* Filename = &Filename_ch[0];
	char Path_ch[100];
	char* Path=&Path_ch[0];

	FileSearchStruct.filename=&FileSearchStruct.filename_ch[0];
	FileSearchStruct.fullpath=&FileSearchStruct.fullpath_ch[0];

	strcpy(Path,"");
	strcpy(Filename,"");


	CMD = &SD_Struct->SD_Active_Command;
	Active_Stage = &SD_Struct->SD_Stages_list;

	SD_Struct->SD_CARD_ChipDetect = HAL_GPIO_ReadPin(SD_CD_GPIO_Port, SD_CD_Pin);

	if (DPC_TO_Check(TO_SD_Card)==TO_OUT_TOOK){
		if (*Active_Stage != SD_IDLE) {
			SD_Struct->SD_Stages_list = SD_UMOUNT;
		}
	}

	switch (*Active_Stage){

	case SD_IDLE:

		if (SD_Struct->Mount_Flag){
			if (*CMD == SD_OP_WRITE_STATUS){
				CSV_Status_Data_Compilation(SD_Struct);
				*Active_Stage = SD_OPEN_DIR;
			}
			else if (*CMD == SD_OP_WRITE_PARAM){
				CSV_Param_Data_Compilation(SD_Struct);
				*Active_Stage = SD_OPEN_DIR;
			}
			else if(*CMD == SD_OP_WRITE_HEADER){
				*Active_Stage = SD_OPEN_DIR;
			}
			else if (*CMD == SD_OP_DELETEOLD){
				RTC_Get_Values(&rtc_time);
				if (rtc_time.year>20){
					*Active_Stage = SD_DELETE_OLD_FILES;
				}
				else *Active_Stage = SD_IDLE;
			}
		}

		if (*CMD == SD_OP_MOUNT){
			*Active_Stage = SD_MOUNT;
		}
		else if (*CMD == SD_OP_UMOUNT){
			*Active_Stage = SD_UMOUNT;
		}


		break;
	case SD_MOUNT:

		fres = f_mount(&FatFs, "", 1); //1=mount now
		if (fres != FR_OK) {
			SD_Struct->Fat_result=fres;
		}
		else if(fres==FR_OK){
			SD_Struct->Mount_Flag = 1;
			*Active_Stage =  SD_CHECK_FREE_SPACE;
		}
		break;
	case SD_CHECK_FREE_SPACE:
		fres = f_getfree("", &free_clusters, &getFreeFs);
		if (fres == FR_OK) {
			total_sectors = (getFreeFs->n_fatent - 2) * getFreeFs->csize;
			free_sectors = free_clusters * getFreeFs->csize;

			#if _MAX_SS != _MIN_SS
				free_space=free_sectors*getFreeFs->ssize;
			#else
				free_space = free_sectors * 512;
			#endif

			if (free_space < __MIN_FREE_SPACE_REQUIRED){
				*Active_Stage =  SD_DELETE_OLD_FILES;
			}
			else {
				SD_Struct->Mount_Flag = 1;
				*Active_Stage =  SD_IDLE;
			}
		}
		break;
	case SD_DELETE_OLD_FILES:
		FileSearchStruct.Oldest_FN_Month=99;
		FileSearchStruct.Oldest_FN_Year=99;
		FileSearchStruct.Oldest_FN_Value=0;
		Search_for_Oldest(&FileSearchStruct, Path, SD_Struct->Battery_Serial);

		strcat(FileSearchStruct.fullpath,"/");
		strcat(FileSearchStruct.fullpath,FileSearchStruct.filename);
		if (FileSearchStruct.isDir==1){
			fres = delete_node(FileSearchStruct.fullpath, sizeof(FileSearchStruct.fullpath_ch), &flinf);
		}
		else{
			fres=f_unlink(FileSearchStruct.fullpath);
		}
		if (fres==FR_OK){
			*Active_Stage =  SD_CHECK_FREE_SPACE;
		}
		else *Active_Stage =  SD_CHECK_FREE_SPACE;
		break;
	case SD_OPEN_DIR:

		//strcpy(Path,"/");
		//itoa(SD_Struct->Battery_Serial,Path+1,sizeof(SD_Struct->Battery_Serial)+6);
		SD_Update_Path(SD_Struct);

		fres = f_opendir(&dir, SD_Struct->Path);
		if (fres == FR_OK) {
			*Active_Stage =  SD_OPEN_FILE;
		}
		else if (fres == FR_NO_PATH){
			fres = f_mkdir(SD_Struct->Path);
			*Active_Stage =  SD_OPEN_DIR;
		}
		else *Active_Stage =  SD_OPEN_DIR;

		break;
	case SD_OPEN_FILE:
		strcat(SD_Struct->Path,"/");
		strcat(SD_Struct->Path,SD_Struct->FileName);
		if (f_open(&fil, SD_Struct->Path, FA_READ | FA_WRITE | FA_OPEN_ALWAYS )==FR_OK){
			if (fil.fsize==0){
				*Active_Stage = SD_WRITE_HEADER;
			}
			else {
				*Active_Stage =  SD_READ;
			}

		}
		//fres = f_open(&fil, "1221.csv" /* SD_Struct->FileName*/, FA_READ | FA_WRITE | FA_OPEN_ALWAYS | FA_CREATE_ALWAYS);

		break;
	case SD_READ:
		fres = f_read(&fil, &readbuff[0], strlen(SD_Struct->Header), &nRead);
		//f_gets(&readbuff[0], sizeof(SD_Struct->Header),&fil);
		//if (fres == FR_OK){
			if(SD_Received_LOOKFOR(&readbuff[0], SD_Struct->Header)){
				*Active_Stage =  SD_WRITE;
			}
			else *Active_Stage =  SD_WRITE_HEADER;
		//}
		break;
	case SD_WRITE_HEADER:
			f_puts(SD_Struct->Header, &fil);
			*Active_Stage =  SD_WRITE;
		break;
	case SD_WRITE:
		fres = f_lseek(&fil, f_size(&fil));
		fres = f_write(&fil, SD_Struct->DATA0, strlen(SD_Struct->DATA0), &BytesWr);
		//f_puts(SD_Struct->DATA0, &fil);
		*Active_Stage =  SD_CLOSE;
		break;

	case SD_CLOSE:
		if(f_close(&fil) == FR_OK){
			if (f_closedir(&dir)==FR_OK){
				*Active_Stage =  SD_IDLE;
			}
		}
		break;

	case SD_UMOUNT:
		if(f_mount(NULL, "", 1) == FR_OK){
			*Active_Stage =  SD_IDLE;
			SD_Struct->Mount_Flag = 0;
		}
		break;
	}

	if (*Active_Stage == SD_IDLE) {
		SD_Struct->SD_Active_Command = SD_OP_DONOTHING;
		SD_Struct->SD_State_to_return = SD_READY;

	}
	else SD_Struct->SD_State_to_return = SD_BUSY;
}

void SD_Update_Path(SD_CARD_Global_Struct* source){
	uint64_t Raw;
	char* part1="/";
	char* stringptr=&source->Raw_var[0];

	Raw=source->Battery_Serial;

	itoa(Raw,stringptr,sizeof(Raw)+2);
	strcpy(source->Path,part1);
	strcat(source->Path,stringptr);
	//strcat(source->Path,part1);

}

void Search_for_Oldest(volatile ff_search_struct* sourceStruct,char* Path, uint64_t ActualSerial){

	uint32_t Raw;
	uint64_t Raw64;

	char Path2_ch[100];
	char* Path2=&Path2_ch[0];

	char Filename_ch[20];
	char* Filename = &Filename_ch[0];


//	Oldest_FN_Year = 99;
//	Oldest_FN_Month = 99;
//	Oldest_FN_Value = 0;

	fres = f_opendir(&dir,Path);
	if (fres == FR_OK) {

		//i = strlen(Path);
		for (;;) {
			fres = f_readdir(&dir, &flinf);                   /* Read a directory item */
			if (fres != FR_OK || flinf.fname[0] == 0) break;  /* Break on error or end of dir */
			if (flinf.fname[0] == '.') continue;             /* Ignore dot entry */

			#if _USE_LFN
			Filename = *flinf.lfname ? fno.lfname : fno.fname;
			#else
			Filename = flinf.fname;
			#endif

			if ((flinf.fattrib & AM_DIR) && !(flinf.fattrib & AM_SYS) && !(flinf.fattrib & AM_HID) ){
				Raw64=atol(Filename);
				if (Raw64 != ActualSerial){
					strcpy(sourceStruct->fullpath,Path);
					strcpy(sourceStruct->filename,Filename);
					sourceStruct->isDir=1;
					break;
				}
				else {
					strcpy(Path2,Path);
					strcat(Path2,"/");
					strcat(Path2,Filename);
					Search_for_Oldest(sourceStruct,Path2,ActualSerial);
				}
//				if (sourceStruct->value!=0){
//					sourceStruct->Lastfound_FN_Month=(uint8_t)(sourceStruct->value/100);
//					Raw=sourceStruct->Lastfound_FN_Month*100;
//					sourceStruct->Lastfound_FN_Year=(uint8_t)(sourceStruct->value-Raw);
//				}
			}
			else if ( !(flinf.fattrib & AM_DIR) && !(flinf.fattrib & AM_SYS) && !(flinf.fattrib & AM_HID) ) {
				sourceStruct->isDir=0;
				sourceStruct->value = Filename_to_Value(Filename);
				if (sourceStruct->value!=0){
					sourceStruct->Lastfound_FN_Month=(uint8_t)(sourceStruct->value/100);
					Raw=sourceStruct->Lastfound_FN_Month*100;
					sourceStruct->Lastfound_FN_Year=(uint8_t)(sourceStruct->value-Raw);


//					if (Lastfound_FN_Month<=Oldest_FN_Month && Lastfound_FN_Year<=Oldest_FN_Year){
//						Oldest_FN_Year  = Lastfound_FN_Year;
//						Oldest_FN_Month = Lastfound_FN_Month;
//						Oldest_FN_Value = FN_Value;
//					}
				}
			}

			if (sourceStruct->Lastfound_FN_Month!=0 || sourceStruct->Lastfound_FN_Year!=0){
				if (sourceStruct->Lastfound_FN_Month<=sourceStruct->Oldest_FN_Month && sourceStruct->Lastfound_FN_Year<=sourceStruct->Oldest_FN_Year){
					sourceStruct->Oldest_FN_Year  = sourceStruct->Lastfound_FN_Year;
					sourceStruct->Oldest_FN_Month = sourceStruct->Lastfound_FN_Month;
					//sourceStruct->Oldest_FN_Value = sourceStruct->value;
					strcpy(sourceStruct->fullpath,Path);
					strcpy(sourceStruct->filename,Filename);
				}
			}

//	            if (flinf.fattrib & AM_DIR) {                    /* It is a directory */
//	                //res = scan_files(path);
//	                //if (res != FR_OK) break;
//	                //path[i] = 0;
//	            } else {                                       /* It is a file. */
//
//	                //printf("%s/%s\n", path, fn);
//	            }
		}

//		if (Oldest_FN_Value!=0){
//			Configure_Path_to_delete(Path, Oldest_FN_Value);
//		}
		//fres = f_unlink()
	}
}

void Battery_Data_to_CSV_Converter(SD_CARD_Global_Struct* Sd_Struct, HTTP_DATA_Struct* DST){
	Battery_Data_Struct* Bat_data;
	HTTP_DATA_Struct CSV_Data_DST;
	CSV_Data_DST = *DST;

	char* Raw = &Sd_Struct->Raw_var[0];
	int Size;
	Bat_data = &Sd_Struct->BATTERY_DATA;


	itoa(Bat_data->Serial,Raw,sizeof(Bat_data->Serial)+2);
	strcpy(Sd_Struct->CSV_DATA.Serial_Number, Raw);

	itoa(Bat_data->Battery_cond_ID,Raw,10);
	strcpy(Sd_Struct->CSV_DATA.Battery_Condition_ID, Raw);

	SIM800_Time_To_String(&Bat_data->Event_time,CSV_Data_DST.Event_time);
	SIM800_Time_To_String(&Bat_data->Started_At_Time,CSV_Data_DST.Started_At_Time);
	SIM800_Time_To_String(&Bat_data->Ended_At_Time,CSV_Data_DST.Ended_At_Time);

	itoa(Bat_data->Status_Indication,Raw,10);
	strcpy(CSV_Data_DST.Status_Indication, Raw);

	itoa(Bat_data->Energy_Sum,Raw,10);
	strcpy(CSV_Data_DST.Energy_Sum, Raw);

	itoa(Bat_data->Battery_Level_At_Start,Raw,10);
	strcpy(CSV_Data_DST.Battery_Level_At_Start, Raw);

	itoa(Bat_data->Battery_Level_At_End,Raw,10);
	strcpy(CSV_Data_DST.Battery_Level_At_End, Raw);

	sprintf(Raw, "%f", Bat_data->Battery_Voltage_At_Start);
	//ftoa(Bat_data->Battery_Voltage_At_Start,Raw,sizeof(Bat_data->Battery_Voltage_At_Start));
	strcpy(CSV_Data_DST.Battery_Voltage_At_Start, Raw);

	sprintf(Raw, "%f", Bat_data->Battery_Voltage_At_End);
	//ftoa(Bat_data->Battery_Voltage_At_End,Raw,sizeof(Bat_data->Battery_Voltage_At_End));
	strcpy(CSV_Data_DST.Battery_Voltage_At_End, Raw);

	itoa(Bat_data->Battery_Temperature_At_End,Raw,10);
	strcpy(CSV_Data_DST.Battery_Temperature_At_End, Raw);

	itoa(Bat_data->Maximum_Load_Current,Raw,10);
	strcpy(CSV_Data_DST.Maximum_Load_Current, Raw);

	itoa(Bat_data->Maximum_Charge_Current,Raw,10);
	strcpy(CSV_Data_DST.Maximum_Charge_Current, Raw);

	sprintf(Raw, "%f", Bat_data->Internal_Resistance);
	//ftoa(Bat_data->Internal_Resistance,Raw,sizeof(Bat_data->Internal_Resistance));
	strcpy(CSV_Data_DST.Internal_Resistance, Raw);

	if (Bat_data->Moderated){
		strcpy(CSV_Data_DST.Moderated,"true");
	}
	else strcpy(CSV_Data_DST.Moderated,"false");

	//memcpy(DST,&CSV_Data_DST, sizeof(CSV_Data_DST));

	memset(Raw,0,100);
}

uint64_t Filename_to_Value(char* FN){
	Time_Struct rtc_time;
	uint32_t Raw;
	uint32_t FN_month;
	char* istr="/0";
	//char* test1_ptr=&test1[0];


	istr=strstr(FN,".CSV");
	if (istr=='\0')
	{
		Raw=0; //nothing found
	}
	else
	{
		Raw=atoi(istr-4); //found
	}
	return Raw;
}

uint8_t Configure_Path_to_delete(char* path, uint32_t Value){
	char service[10];
	char* csv=".CSV";
	char* service_ptr=&service[0];

	itoa(Value,service_ptr,sizeof(Value)+6);
	strcat(path,service_ptr);
	strcat(path,csv);
}

void CSV_Status_Data_Compilation(SD_CARD_Global_Struct* Sd_Struct){

	char* Delimeter=";";
	char* EndOfString = "\r";

	strcpy(Sd_Struct->DATA0,Sd_Struct->CSV_DATA.Serial_Number);
	strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,"");
	strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,"");
	strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,"");
	strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,"");
	strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,"");
	strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,"");
	strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,"");
	strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,"");
	strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,"");
	strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,"");
	strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,"");
	strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,"");
	strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,"");
	strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,"");
	strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,"");
	strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,Sd_Struct->CSV_DATA.Event_time);
	strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,Sd_Struct->CSV_DATA.Battery_Condition_ID);
	//strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,EndOfString);
}

void CSV_Param_Data_Compilation(SD_CARD_Global_Struct* Sd_Struct){

	char* Delimeter=";";
	char* EndOfString = "\n";

	strcpy(Sd_Struct->DATA0,Sd_Struct->CSV_DATA.Serial_Number);
	strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,Sd_Struct->CSV_DATA.Started_At_Time);
	strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,Sd_Struct->CSV_DATA.Ended_At_Time);
	strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,Sd_Struct->CSV_DATA.Status_Indication);
	strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,Sd_Struct->CSV_DATA.Energy_Sum);
	strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,Sd_Struct->CSV_DATA.Battery_Level_At_Start);
	strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,Sd_Struct->CSV_DATA.Battery_Level_At_End);
	strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,Sd_Struct->CSV_DATA.Battery_Voltage_At_Start);
	strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,Sd_Struct->CSV_DATA.Battery_Voltage_At_End);
	strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,Sd_Struct->CSV_DATA.Battery_Temperature_At_End);
	strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,Sd_Struct->CSV_DATA.Latitude);
	strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,Sd_Struct->CSV_DATA.Longitude);
	strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,Sd_Struct->CSV_DATA.Maximum_Load_Current);
	strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,Sd_Struct->CSV_DATA.Maximum_Charge_Current);
	strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,Sd_Struct->CSV_DATA.Internal_Resistance);
	strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,Sd_Struct->CSV_DATA.Moderated);
	strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,"");
	strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,"");
	//strcat(Sd_Struct->DATA0,Delimeter);
	strcat(Sd_Struct->DATA0,EndOfString);
}
