398 lines
16 KiB
C#
398 lines
16 KiB
C#
/*********************************************************************************************************************/
|
|
/*!@file txtFileHandler.cs
|
|
* @brief Handle for Texas Instruments-txt files.
|
|
*
|
|
*====================================================================================================================\n
|
|
* @copyright
|
|
*
|
|
* ___________________________________________________________________________________________________________________\n
|
|
* Copyright (c) 2016 SENSUS, GmbH.\n
|
|
* All Rights Reserved.\n
|
|
* \n
|
|
* Confidential property of\n
|
|
* SENSUS GmbH,\n
|
|
* Meineckestr. 10, 30880 LAATZEN, GERMANY\n
|
|
* \n
|
|
* Design by\n
|
|
* Hard- und Softwareentwicklung Thomas Wiedebusch,\n
|
|
* Ostermarsch 17c, 31191 ALGERMISSEN/UMMELN, GERMANY\n
|
|
* \n
|
|
*====================================================================================================================\n
|
|
* @intro
|
|
*
|
|
*____________________________________________________________________________________________________________________\n
|
|
* Functions:\n
|
|
* Reading txt files,\n
|
|
* Replacing bytes with CRC.\n
|
|
*
|
|
*====================================================================================================================\n
|
|
* @version
|
|
*
|
|
*____________________________________________________________________________________________________________________\n
|
|
* V1.00 25-Feb-2016..27-Feb-2016 by Thomas Wiedebusch\n
|
|
* - Initial.
|
|
*
|
|
*
|
|
*====================================================================================================================\n
|
|
*/
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.IO;
|
|
|
|
namespace CRC_CCITT
|
|
{
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
/*!@brief txtFileHandler class.
|
|
* @author Thomas Wiedebusch
|
|
* @date 25-Feb-2016
|
|
*
|
|
*/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
class txtFileHandler_t
|
|
{
|
|
//class variables
|
|
String inputFile_str; //file name
|
|
String outputFile_str; //file name
|
|
String fileLine_str; //one line of the file
|
|
crcGenrator_memSetFn_t MemSetFn_vdp; //set data to address of working memory
|
|
crcGenrator_memGetFn_t MemGetFn_u8p; //get data from working memory
|
|
|
|
UInt32 crcFileLineBaseAddress_u32 = 0; //CRC file line address reminder set during input file processing
|
|
UInt32 crcFileLine_u32 = 0; //CRC address line in file reminder set during input file processing
|
|
bool crcFileLineFound_bol = false; //CRC address in file found reminder
|
|
UInt32 memAddressCtr_u32 = 0; //CRC memory address counter
|
|
bool placeCrcToFile_bol; //CRC output to file is required
|
|
UInt32 crcAddress_u32; //CRC address given as parameter at startup
|
|
|
|
//txt file markers
|
|
const Char addressMarker_cchr = '@'; //base address marker
|
|
const Char endOfFileMarker_cchr = 'q'; //end of file marker
|
|
const Byte maxDataOfFileLine_cu8 = 16; //maximum data at one file line
|
|
const Byte fileLineDataCellIncrement_cu8 = 3; //3 digits increment for one data byte e.g. A5_
|
|
|
|
//calculations
|
|
UInt32 fileLineCtr_u32 = 0; //actual accessed file line
|
|
bool memoryAddressSetup_bol = false; //initial memory address has been set
|
|
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
/*!@brief Constructor for txt file handler class:\n
|
|
* -initializes file,\n
|
|
* -this constructor will only be called if the input file has been found,\n
|
|
* -sets delegates to memory set and get function being able to dispatch read data.\n
|
|
* @author Thomas Wiedebusch
|
|
* @date 25-Feb-2016
|
|
* @param[in] inputFileIn_str file name for input file
|
|
* @param[in] outputFileIn_str file name for output file, can be identical with input file
|
|
* @param[in] MemSetInFn_vdp set function to dispatch data to memory
|
|
* @param[in] MemGetInFn_vdp get function to read data from memory
|
|
*
|
|
*/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
public txtFileHandler_t(String inputFileIn_str, String outputFileIn_str, crcGenrator_memSetFn_t MemSetInFn_vdp,
|
|
crcGenrator_memGetFn_t MemGetInFn_u8p, UInt32 crcAddressIn_u32, bool placeCrcToFileIn_bol)
|
|
{
|
|
inputFile_str = inputFileIn_str;
|
|
outputFile_str = outputFileIn_str;
|
|
MemSetFn_vdp = MemSetInFn_vdp;
|
|
MemGetFn_u8p = MemGetInFn_u8p;
|
|
placeCrcToFile_bol = placeCrcToFileIn_bol;
|
|
crcAddress_u32 = crcAddressIn_u32;
|
|
}
|
|
/**/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
/*!@brief Read file and dispatch the data to the CRC generator:\n
|
|
* -reads every line and checks format.
|
|
* @author Thomas Wiedebusch
|
|
* @date 25-Feb-2016
|
|
* @return file format valid
|
|
*
|
|
*/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
public bool ValidateInputFile_bol()
|
|
{
|
|
bool returnValue_bol = false;
|
|
fileLineCtr_u32 = 0;
|
|
|
|
try
|
|
{
|
|
//check if file exits
|
|
if (File.Exists(inputFile_str))
|
|
{
|
|
//opens file for read
|
|
StreamReader inputFile_st = new StreamReader(inputFile_str);
|
|
|
|
//read single line until file end or validation failed
|
|
do
|
|
{
|
|
fileLine_str = inputFile_st.ReadLine();
|
|
|
|
//decode the file line
|
|
returnValue_bol = ProcessInputFileLine_bol();
|
|
|
|
//change file line counter after check and line counter reminder for the records
|
|
fileLineCtr_u32++;
|
|
} while (returnValue_bol && !inputFile_st.EndOfStream);
|
|
//release file
|
|
inputFile_st.Close();
|
|
}
|
|
}//try
|
|
catch
|
|
{
|
|
}
|
|
return returnValue_bol;
|
|
}
|
|
/**/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
/*!@brief Extract the information given by the read line from file:\n
|
|
* -builds base address from '@' input,\n
|
|
* -extracts bytes and dispatches these to CRC generator memory,\n
|
|
* -searches for CRC address and reminds file line for this,\n
|
|
* -validates file with file end marker 'q'.
|
|
* @author Thomas Wiedebusch
|
|
* @date 25-Feb-2016..26-Feb-2016
|
|
* @return txt file valid
|
|
*
|
|
*/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
bool ProcessInputFileLine_bol()
|
|
{
|
|
bool returnValue_bol = false;
|
|
|
|
try
|
|
{
|
|
//read first byte of line
|
|
Char lineStart_chr = fileLine_str[0];
|
|
switch (lineStart_chr)
|
|
{
|
|
case addressMarker_cchr:
|
|
//extract new base address
|
|
String mem_str = fileLine_str.Substring(1, fileLine_str.Length - 1);
|
|
memAddressCtr_u32 = UInt32.Parse( mem_str, System.Globalization.NumberStyles.HexNumber);
|
|
|
|
//check memory address range
|
|
if( crcGenerator_t.maxMemBytes_cu32 > memAddressCtr_u32)
|
|
{
|
|
memoryAddressSetup_bol = true;
|
|
returnValue_bol = true;
|
|
}
|
|
break;
|
|
case endOfFileMarker_cchr:
|
|
//if end of file marker read on first line then the file is invalid
|
|
if (0 != fileLineCtr_u32)
|
|
{
|
|
returnValue_bol = true;
|
|
}
|
|
break;
|
|
default:
|
|
//if data read on first line then the file is invalid
|
|
if ((0 != fileLineCtr_u32) && (memoryAddressSetup_bol))
|
|
{
|
|
Byte data_u8;
|
|
Byte fileLineDataCtr_u8 = 0;
|
|
String data_str;
|
|
//remind the base address of this file line to save it for CRC replacement
|
|
UInt32 fileLineBaseAddress_u32 = memAddressCtr_u32;
|
|
//search file line
|
|
for (Byte ctr_u8 = 0; ctr_u8 < maxDataOfFileLine_cu8; ctr_u8++)
|
|
{
|
|
//inner loop limitation to actual file line length
|
|
while (fileLine_str.Length > fileLineDataCtr_u8)
|
|
{
|
|
//remind file line for CRC output
|
|
if (crcAddress_u32 == memAddressCtr_u32)
|
|
{
|
|
//remind the file entry
|
|
crcFileLine_u32 = fileLineCtr_u32;
|
|
//remind the base address for the file line for CRC replacement
|
|
crcFileLineBaseAddress_u32 = fileLineBaseAddress_u32;
|
|
//mark that entry has been found
|
|
crcFileLineFound_bol = true;
|
|
}
|
|
//extract data
|
|
data_str = fileLine_str.Substring(fileLineDataCtr_u8, fileLineDataCellIncrement_cu8);
|
|
data_u8 = Byte.Parse(data_str, System.Globalization.NumberStyles.HexNumber);
|
|
//dispatch data to CRC generator
|
|
MemSetFn_vdp(memAddressCtr_u32, data_u8);
|
|
memAddressCtr_u32++;
|
|
fileLineDataCtr_u8 += fileLineDataCellIncrement_cu8;
|
|
}//file line length
|
|
}//data counter
|
|
returnValue_bol = true;
|
|
}
|
|
break;
|
|
}//switch
|
|
}//try
|
|
catch
|
|
{
|
|
}
|
|
return returnValue_bol;
|
|
}
|
|
/**/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
/*!@brief Read input file and store it to output file:\n
|
|
* -reads every line, format has been checked,\n
|
|
* -replaces CRC if required.
|
|
* @author Thomas Wiedebusch
|
|
* @date 25-Feb-2016..26-Feb-2016
|
|
* @param[in] crcResult_u16 result of CRC calculation
|
|
*
|
|
*/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
public void CreateOutputFile_vd(UInt16 crcResult_u16)
|
|
{
|
|
//the file line counter will be used to reference the input of already detected records
|
|
fileLineCtr_u32 = 0;
|
|
|
|
try
|
|
{
|
|
//check if file exits
|
|
if (File.Exists(inputFile_str))
|
|
{
|
|
//opens file for read
|
|
StreamReader inputFile_st = new StreamReader(inputFile_str);
|
|
if (File.Exists(outputFile_str))
|
|
{
|
|
//erase it
|
|
File.Delete(outputFile_str);
|
|
}
|
|
|
|
//open it for write access
|
|
StreamWriter outputFile_st = new StreamWriter(outputFile_str, true);
|
|
|
|
//read single line until and output it to the output file
|
|
do
|
|
{
|
|
//read one line of the input file
|
|
fileLine_str = inputFile_st.ReadLine();
|
|
|
|
//output of CRC to file is required
|
|
if (placeCrcToFile_bol)
|
|
{
|
|
//if CRC address is not in file generate a new address with CRC only at the beginning
|
|
if (!crcFileLineFound_bol)
|
|
{
|
|
//build a new file entry for CRC which is not inside the file address range
|
|
BuildAndWriteNewCrc_vd(crcResult_u16, outputFile_st);
|
|
//remove CRC to file request
|
|
placeCrcToFile_bol = false;
|
|
}
|
|
//search for file entry to replace CRC
|
|
else if (crcFileLine_u32 == fileLineCtr_u32)
|
|
{
|
|
//the base address for this file line has been set in advance during file scan
|
|
ReplaceCrcData_vd(crcResult_u16);
|
|
//remove CRC to file request
|
|
placeCrcToFile_bol = false;
|
|
}
|
|
}//output of CRC to file is required
|
|
|
|
//write all lines to output file
|
|
outputFile_st.WriteLine(fileLine_str);
|
|
|
|
//change file line of input file
|
|
fileLineCtr_u32++;
|
|
} while (!inputFile_st.EndOfStream);
|
|
|
|
//release files
|
|
inputFile_st.Close();
|
|
outputFile_st.Close();
|
|
|
|
//if the output file is equal to the input file, erase input file and rename temporary output file
|
|
if (crcProgram_t.fileUndefined_cstr == outputFile_str)
|
|
{
|
|
File.Delete(inputFile_str);
|
|
if (File.Exists(outputFile_str))
|
|
{
|
|
//rename output to input file name, output file will be deleted
|
|
File.Move(outputFile_str, inputFile_str);
|
|
}
|
|
|
|
}
|
|
}//input file exists
|
|
}//try
|
|
catch
|
|
{
|
|
}
|
|
}
|
|
/**/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
/*!@brief Replaces the CRC data if CRC address is inside the file address range:\n
|
|
* -search for CRC address,\n
|
|
* -replace CRC data in fileLine_str.
|
|
* @author Thomas Wiedebusch
|
|
* @date 26-Feb-2016..27-Feb-2016
|
|
* @param[in] crcResult_u16 result of CRC calculation
|
|
*
|
|
*/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
void ReplaceCrcData_vd(UInt16 crcResult_u16)
|
|
{
|
|
//build the CRC sub string for replacement
|
|
Byte dataLsb_u8 = (Byte)(crcResult_u16 & 0x00FF);
|
|
Byte dataMsb_u8 = (Byte)((crcResult_u16 >> 8) & 0x00FF);
|
|
String crcSubStringOutput_str = dataLsb_u8.ToString("X2") + " " + dataMsb_u8.ToString("X2") + " ";
|
|
|
|
//search for address entry in file
|
|
memAddressCtr_u32 = crcFileLineBaseAddress_u32;
|
|
UInt32 beforeCrcAddress_u32 = crcFileLineBaseAddress_u32;
|
|
Byte ctr_u8 = 0;
|
|
while (memAddressCtr_u32 < crcAddress_u32)
|
|
{
|
|
ctr_u8 += fileLineDataCellIncrement_cu8;
|
|
memAddressCtr_u32++;
|
|
}
|
|
|
|
//extract string before CRC address from fileLine_str
|
|
String beforeCrcAddress_str = "";
|
|
if (beforeCrcAddress_u32 < crcAddress_u32)
|
|
{
|
|
beforeCrcAddress_str = fileLine_str.Substring(0, ctr_u8);
|
|
}
|
|
|
|
//extract string after CRC address from fileLine_str
|
|
String afterCrcAddress_str = "";
|
|
if (fileLine_str.Length > ctr_u8 + 2 * fileLineDataCellIncrement_cu8)
|
|
{
|
|
afterCrcAddress_str = fileLine_str.Substring(ctr_u8 + 2 * fileLineDataCellIncrement_cu8,
|
|
fileLine_str.Length - (ctr_u8 + 2 * fileLineDataCellIncrement_cu8));
|
|
}
|
|
|
|
//replace fileLine_str with substring at ctr position
|
|
fileLine_str = beforeCrcAddress_str + crcSubStringOutput_str + afterCrcAddress_str;
|
|
}
|
|
/**/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
/*!@brief Builds and writes a new CRC entry if CRC address is outside the file address range:\n
|
|
* -assemble and write CRC address,\n
|
|
* -assemble and write CRC data.
|
|
* @author Thomas Wiedebusch
|
|
* @date 26-Feb-2016
|
|
* @param[in] crcResult_u16 result of CRC calculation
|
|
* @param[in] outputFile_st output file stream object
|
|
*
|
|
*/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
void BuildAndWriteNewCrc_vd(UInt16 crcResult_u16, StreamWriter outputFile_st)
|
|
{
|
|
//build the NEW address for CRC
|
|
String crcOutput_str = addressMarker_cchr.ToString();
|
|
crcOutput_str += crcAddress_u32.ToString("X");
|
|
//write address to file
|
|
outputFile_st.WriteLine(crcOutput_str);
|
|
|
|
//build the CRC file line (line contains CRC only)
|
|
Byte dataLsb_u8, dataMsb_u8;
|
|
dataLsb_u8 = (Byte)(crcResult_u16 & 0x00FF);
|
|
dataMsb_u8 = (Byte)((crcResult_u16 >> 8) & 0x00FF);
|
|
crcOutput_str = dataLsb_u8.ToString("X2") + " " + dataMsb_u8.ToString("X2");
|
|
//write CRC data to file
|
|
outputFile_st.WriteLine(crcOutput_str);
|
|
}
|
|
/**/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
}//class txtFileHandler
|
|
}//namespace CRC_CCITT
|
|
/*=====================================END OF FILE===================================================================*/ |