571 lines
23 KiB
C#
571 lines
23 KiB
C#
/*********************************************************************************************************************/
|
|
/*!@file crcProgram.cs
|
|
* @brief Main file for CRC_CCITT.
|
|
*
|
|
*====================================================================================================================\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
|
|
* crcProgram:\n
|
|
* - Initial CRC16 calculation for polynomial 0x1021,\n
|
|
* inputs: -file_in name of s19 | txt file,\n
|
|
* [-file_out name of s19 | txt file],\n
|
|
* -start_address1=0..0xFFFFFE\n
|
|
* -end_address1=0..0xFFFFFF | -length1=0..0xFFFFFF\n
|
|
* [-start_address2=0..0xFFFFFE]\n
|
|
* [-end_address2=0..0xFFFFFF | -length2=0..0xFFFFFE]\n
|
|
* [-crc_address=0..0xFFFFFF]\n
|
|
* [-seed=0..0xFFFF]\n
|
|
* [-order=MMSB_FIRST|LSB_FIRST]\n
|
|
*
|
|
*====================================================================================================================\n
|
|
* @version
|
|
*
|
|
*____________________________________________________________________________________________________________________\n
|
|
* V1.00 19-Feb-2016..26.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
|
|
{
|
|
class crcProgram_t
|
|
{
|
|
//class variables
|
|
public const String fileUndefined_cstr = "undefined";
|
|
const UInt16 searchIgnoreBytesOfString_cu16 = 3;
|
|
static String inputFile_strs = fileUndefined_cstr;
|
|
static String outputFile_strs = fileUndefined_cstr;
|
|
static UInt32 crcAddress_u32s = 0;
|
|
static UInt32 startAddress1_u32s = 0;
|
|
static UInt32 endAddress1_u32s = 0;
|
|
static UInt32 length1_u32s = 0;
|
|
//optional input parameters
|
|
static UInt32 startAddress2_u32s = 0; //second address range undefined
|
|
static UInt32 endAddress2_u32s = 0; //second address range undefined
|
|
static UInt32 length2_u32s = 0; //second address range undefined
|
|
static UInt16 seed_u16s = 0xFFFF; //default value
|
|
static bool wordAccess_bols = false; //default BYTE access
|
|
static bool lsbFirst_bols = false; //default MSB first
|
|
//internal variables
|
|
static UInt16 crcResult_u16s = 0;
|
|
static bool crcAddressDefined_bols = false; //assume missing arguments
|
|
static Byte argsNumber_u8s = 0;
|
|
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
/*!@brief Main program.
|
|
* @author Thomas Wiedebusch
|
|
* @date 19-Feb-2016..25-Feb-2016
|
|
* @param[in] args_st
|
|
* @return exit code
|
|
*
|
|
*/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
static void Main(string[] args_str)
|
|
{
|
|
try
|
|
{
|
|
//required input parameters
|
|
argsNumber_u8s = (Byte)args_str.GetLength(0);
|
|
//check number of command line args and start of syntax for command line parameter input"-"
|
|
if ((argsNumber_u8s > 2) && ("-" == args_str[0].Substring(0, 1)))
|
|
{
|
|
//extract information given by command line input
|
|
ParseCommandLineArguments_vds(args_str);
|
|
|
|
//check and init input parameters
|
|
CheckAndLimitInput_vds();
|
|
|
|
}//check number of command line parameters and string "-" as start for parameter input
|
|
}//try
|
|
catch
|
|
{
|
|
}
|
|
//set the address ranges for output to console, therefore the arguments have to be extracted
|
|
BuildAddressRanges_vds();
|
|
|
|
//initial messages for input display to user after address build
|
|
DisplayStartMsg_vds();
|
|
|
|
//check for sufficient number of input parameters and defined file to process
|
|
if(((endAddress1_u32s > 0) && (length1_u32s > 0)) && (String.Compare(inputFile_strs, fileUndefined_cstr) != 0))
|
|
{
|
|
//check for physically file existence
|
|
if (File.Exists( inputFile_strs))
|
|
{
|
|
//confirm the file has been file found
|
|
DisplayFileInformationMsg_vds();
|
|
|
|
//start the file and CRC processing
|
|
if (Process_bols())
|
|
{
|
|
//output crc result to console
|
|
DisplayResultMsg_vds();
|
|
}
|
|
else
|
|
{
|
|
//file has unknown format
|
|
DispalyUnknownFileFormatErrorMsg_vd();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//input file can't be found, don't start processing
|
|
DisplayInFileNotFoundErrorMsg_vds();
|
|
}
|
|
}
|
|
else//if parameters are missing or help request
|
|
{
|
|
DisplayMissedParamErrorMsg_vds();
|
|
}//argumentsSufficient_bols
|
|
}//Main
|
|
/**/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
/*!@brief Process file and CRC.
|
|
* @author Thomas Wiedebusch
|
|
* @date 21-Feb-2016..25-Feb-2016
|
|
* @return files valid
|
|
*
|
|
*/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
static bool Process_bols()
|
|
{
|
|
bool returnValue_bol = false;
|
|
//initialize CRC generator
|
|
crcGenerator_t crcGenerator_cl = new crcGenerator_t(startAddress1_u32s, length1_u32s,
|
|
startAddress2_u32s, length2_u32s, seed_u16s, wordAccess_bols, lsbFirst_bols);
|
|
|
|
crcGenrator_memSetFn_t MemSetFn_vdp = crcGenerator_cl.MemSetFn_vdp();
|
|
crcGenrator_memGetFn_t MemGetFn_u8p = crcGenerator_cl.MemGetFn_u8p();
|
|
|
|
//initialize s19 file handler
|
|
s19FileHandler_t s19FileHandler_cl = new s19FileHandler_t(inputFile_strs, outputFile_strs, MemSetFn_vdp,
|
|
MemGetFn_u8p, crcAddress_u32s, crcAddressDefined_bols);
|
|
|
|
//initialize txt file handler
|
|
txtFileHandler_t txtFileHandler_cl = new txtFileHandler_t(inputFile_strs, outputFile_strs, MemSetFn_vdp,
|
|
MemGetFn_u8p, crcAddress_u32s, crcAddressDefined_bols);
|
|
|
|
//read file, extract and copy to memory, returns false on corrupted record
|
|
if (s19FileHandler_cl.ValidateInputFile_bol())
|
|
{
|
|
returnValue_bol = true;
|
|
|
|
//process crc
|
|
crcResult_u16s = crcGenerator_cl.CrcCalculate_u16();
|
|
|
|
//create the output file
|
|
s19FileHandler_cl.CreateOutputFile_vd(crcResult_u16s);
|
|
}
|
|
//read file, extract and copy to memory, returns false on corrupted record
|
|
else if (txtFileHandler_cl.ValidateInputFile_bol())
|
|
{
|
|
returnValue_bol = true;
|
|
|
|
//process crc
|
|
crcResult_u16s = crcGenerator_cl.CrcCalculate_u16();
|
|
|
|
//create the output file
|
|
txtFileHandler_cl.CreateOutputFile_vd(crcResult_u16s);
|
|
}
|
|
return returnValue_bol;
|
|
}
|
|
/**/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
/*!@brief Safety module to avoid wrong input ranges:\n
|
|
* Takes input range from crcGenerator_t class.
|
|
* @author Thomas Wiedebusch
|
|
* @date 21-Feb-2016
|
|
*
|
|
*/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
static void CheckAndLimitInput_vds()
|
|
{
|
|
//get the defined input range for addresses from crcGenerator class
|
|
UInt32 maxAddress_u32 = crcGenerator_t.maxMemBytes_cu32;
|
|
|
|
if (startAddress1_u32s > maxAddress_u32)
|
|
{
|
|
startAddress1_u32s = maxAddress_u32;
|
|
}
|
|
if (startAddress2_u32s > maxAddress_u32)
|
|
{
|
|
startAddress2_u32s = maxAddress_u32;
|
|
}
|
|
if (endAddress1_u32s > maxAddress_u32)
|
|
{
|
|
endAddress1_u32s = maxAddress_u32;
|
|
}
|
|
if (endAddress2_u32s > maxAddress_u32)
|
|
{
|
|
endAddress2_u32s = maxAddress_u32;
|
|
}
|
|
if (length1_u32s + startAddress1_u32s > maxAddress_u32)
|
|
{
|
|
length1_u32s = maxAddress_u32 - startAddress1_u32s;
|
|
}
|
|
if (length2_u32s + startAddress2_u32s > maxAddress_u32)
|
|
{
|
|
length2_u32s = maxAddress_u32 - startAddress2_u32s;
|
|
}
|
|
if (crcAddress_u32s > maxAddress_u32)
|
|
{
|
|
crcAddress_u32s = maxAddress_u32;
|
|
}
|
|
}
|
|
/**/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
/*!@brief Build address ranges out of end addresses or lengths.
|
|
* @author Thomas Wiedebusch
|
|
* @date 21-Feb-2016..23-Feb-2016
|
|
*
|
|
*/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
static void BuildAddressRanges_vds()
|
|
{
|
|
//check for start and end address
|
|
if (endAddress1_u32s < startAddress1_u32s)
|
|
{
|
|
endAddress1_u32s = startAddress1_u32s;
|
|
}
|
|
|
|
//check first address range
|
|
if( length1_u32s > 0)
|
|
{
|
|
endAddress1_u32s = startAddress1_u32s + length1_u32s;
|
|
}
|
|
else
|
|
{
|
|
length1_u32s = endAddress1_u32s - startAddress1_u32s;
|
|
}//first address range is defined
|
|
|
|
//check for start and end address
|
|
if (endAddress2_u32s < startAddress2_u32s)
|
|
{
|
|
endAddress2_u32s = startAddress2_u32s;
|
|
}
|
|
//check second address range
|
|
if (length2_u32s > 0)
|
|
{
|
|
endAddress2_u32s = startAddress2_u32s + length2_u32s;
|
|
}
|
|
else
|
|
{
|
|
length2_u32s = endAddress2_u32s - startAddress2_u32s;
|
|
}//second address range is defined
|
|
}
|
|
/**/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
/*!@brief Parse command line arguments:\n
|
|
* -extracts the path and file information,\n
|
|
* -extracts and assigns the variables.
|
|
* @author Thomas Wiedebusch
|
|
* @date 19-Feb-2016..23-Feb-2016
|
|
* @param[in] args_st command line arguments
|
|
*
|
|
*/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
static void ParseCommandLineArguments_vds(String[] args_str)
|
|
{
|
|
//assign numerical values to the variables or strings to strings
|
|
for (Byte ctr_u8 = 0; ctr_u8 < argsNumber_u8s; ctr_u8++)
|
|
{
|
|
try
|
|
{
|
|
//read args string
|
|
String argsString_str = args_str[ctr_u8];
|
|
|
|
//search for "="
|
|
UInt16 stringCtr_u16 = 0;
|
|
UInt16 stringLength_u16 = (UInt16)argsString_str.Length;
|
|
//avoid access on string size below size of ignored bytes, may be possible on additional wrong space
|
|
if (stringLength_u16 > searchIgnoreBytesOfString_cu16)
|
|
{
|
|
//remove at least the 3 digits to avoid search overrun
|
|
stringLength_u16 -= searchIgnoreBytesOfString_cu16;
|
|
while ((stringCtr_u16 != argsString_str.IndexOf("=", stringCtr_u16))
|
|
&& (stringCtr_u16 < stringLength_u16))
|
|
{
|
|
stringCtr_u16++;
|
|
}
|
|
//extract compare string
|
|
String compareString_str = argsString_str.Substring(1, stringCtr_u16 - 1);
|
|
String textString_str;
|
|
//deliver and convert string to variable
|
|
switch (compareString_str)
|
|
{
|
|
case "file_in":
|
|
//extract text and remove the "=" before the text
|
|
inputFile_strs = argsString_str.Substring(stringCtr_u16 + 1,
|
|
argsString_str.Length - stringCtr_u16 - 1);
|
|
break;
|
|
case "file_out":
|
|
//extract text and remove the "=" before the text
|
|
outputFile_strs = argsString_str.Substring(stringCtr_u16 + 1,
|
|
argsString_str.Length - stringCtr_u16 - 1);
|
|
break;
|
|
case "crc_address":
|
|
crcAddressDefined_bols = true;
|
|
crcAddress_u32s = ExtractUint32HexNumberFromString_u32s(argsString_str, stringCtr_u16);
|
|
;
|
|
break;
|
|
case "start_address1":
|
|
startAddress1_u32s = ExtractUint32HexNumberFromString_u32s(argsString_str, stringCtr_u16);
|
|
break;
|
|
case "end_address1":
|
|
endAddress1_u32s = ExtractUint32HexNumberFromString_u32s(argsString_str, stringCtr_u16);
|
|
break;
|
|
case "length1":
|
|
length1_u32s = ExtractUint32HexNumberFromString_u32s(argsString_str, stringCtr_u16);
|
|
break;
|
|
case "start_address2":
|
|
startAddress2_u32s = ExtractUint32HexNumberFromString_u32s(argsString_str, stringCtr_u16);
|
|
break;
|
|
case "end_address2":
|
|
endAddress2_u32s = ExtractUint32HexNumberFromString_u32s(argsString_str, stringCtr_u16);
|
|
break;
|
|
case "length2":
|
|
length2_u32s = ExtractUint32HexNumberFromString_u32s(argsString_str, stringCtr_u16);
|
|
break;
|
|
case "seed":
|
|
seed_u16s = (UInt16)ExtractUint32HexNumberFromString_u32s(argsString_str, stringCtr_u16);
|
|
break;
|
|
case "order":
|
|
//extract text and remove the "=" before the text
|
|
textString_str = argsString_str.Substring(stringCtr_u16 + 1,
|
|
argsString_str.Length - stringCtr_u16 - 1);
|
|
if (0 == String.Compare(textString_str, "LSB_FIRST"))
|
|
{
|
|
lsbFirst_bols = true;
|
|
}
|
|
break;
|
|
case "size":
|
|
//extract text and remove the "=" before the text
|
|
textString_str = argsString_str.Substring(stringCtr_u16 + 1,
|
|
argsString_str.Length - stringCtr_u16 - 1);
|
|
if (0 == String.Compare(textString_str, "WORD"))
|
|
{
|
|
wordAccess_bols = true;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}//switch
|
|
}//string length minimum
|
|
}//try
|
|
catch
|
|
{
|
|
}
|
|
}//all arguments access
|
|
}
|
|
/**/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
/*!@brief Converts input string of hex number to uint32.
|
|
* @author Thomas Wiedebusch
|
|
* @date 19-Feb-2016..23-Feb-2016
|
|
* @param[in] argsString_st input string
|
|
* @param[in] stringCtr_u16 string counter at last parameter identifier "="
|
|
* @return number_u32 extracted uint32
|
|
*
|
|
*/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
static UInt32 ExtractUint32HexNumberFromString_u32s(String argsString_str, UInt16 stringCtr_u16)
|
|
{
|
|
UInt32 number_u32 = 0;
|
|
|
|
try
|
|
{
|
|
//extract variable and remove the "=0x" before the hexadecimal number
|
|
String variableString_str = argsString_str.Substring(stringCtr_u16 + searchIgnoreBytesOfString_cu16,
|
|
argsString_str.Length - stringCtr_u16 - searchIgnoreBytesOfString_cu16);
|
|
number_u32 = UInt32.Parse(variableString_str, System.Globalization.NumberStyles.HexNumber);
|
|
}//try
|
|
catch
|
|
{
|
|
}
|
|
|
|
return number_u32;
|
|
}
|
|
/**/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
/*!@brief Display start message.
|
|
* @author Thomas Wiedebusch
|
|
* @date 19-Feb-2016..25-Feb-2016
|
|
*
|
|
*/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
static void DisplayStartMsg_vds()
|
|
{
|
|
//output program information
|
|
Console.WriteLine("================================================================================");
|
|
Console.WriteLine(" CRC_CCITT (CRC16 Polynomial 0x1021) Builder!");
|
|
Console.WriteLine(" File input formats are Motorola-s19 and TI-txt files");
|
|
Console.WriteLine("");
|
|
Console.WriteLine(" Version V1.00");
|
|
Console.WriteLine("");
|
|
Console.WriteLine(" Copyright (c) 2016 SENSUS GmbH, Laatzen, Germany");
|
|
Console.WriteLine(" All rights reserved");
|
|
Console.WriteLine(" Written by Thomas Wiedebusch");
|
|
Console.WriteLine("================================================================================");
|
|
|
|
//Scanned address and size information
|
|
Console.WriteLine("Start address1: 0x{0:X}", startAddress1_u32s);
|
|
Console.WriteLine("Length1: 0x{0:X}", length1_u32s);
|
|
Console.WriteLine("End address1: 0x{0:X}", endAddress1_u32s);
|
|
if ((startAddress2_u32s > 0) && (length2_u32s > 0))
|
|
{
|
|
Console.WriteLine("Start address2: 0x{0:X}", startAddress2_u32s);
|
|
Console.WriteLine("Length2: 0x{0:X}", length2_u32s);
|
|
Console.WriteLine("End address2: 0x{0:X}", endAddress2_u32s);
|
|
}
|
|
|
|
//output seed value
|
|
Console.WriteLine("Seed: 0x{0:X4}", seed_u16s);
|
|
|
|
//check data format
|
|
if (wordAccess_bols)
|
|
{
|
|
Console.WriteLine("Access format: WORD");
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine("Access format: BYTE");
|
|
}
|
|
|
|
//check access order
|
|
if (lsbFirst_bols)
|
|
{
|
|
Console.WriteLine("Access order: LSB_FIRST");
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine("Access order: MSB_FIRST");
|
|
}
|
|
Console.WriteLine("");
|
|
}
|
|
/**/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
/*!@brief Display insufficient parameter error message.
|
|
* @author Thomas Wiedebusch
|
|
* @date 19-Feb-2016..25-Feb-2016
|
|
*
|
|
*/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
static void DisplayMissedParamErrorMsg_vds()
|
|
{
|
|
Console.WriteLine("================================================================================");
|
|
Console.WriteLine("PARAMETERS ARE MISSED OR WRONG FORMAT, CRC CALCULATION CAN'T BE EXECUTED!");
|
|
Console.WriteLine("================================================================================");
|
|
Console.WriteLine("");
|
|
Console.WriteLine("Required parameters for CRC16 calculation (order independent):");
|
|
Console.WriteLine("-file_in=file_name is the name of the input file as string, required");
|
|
Console.WriteLine("[-file_out=file_name] is the name of the output file as string, optional");
|
|
Console.WriteLine("[-crc_address=0x0..0xFFFFFF] required for file out, else only console display");
|
|
Console.WriteLine("-start_address1=0x0..0xFFFFFF required");
|
|
Console.WriteLine("-end_address1|length1=0x0..0xFFFFFF required");
|
|
Console.WriteLine("[-start_address2=0x0..0xFFFFFF] optional, default 0x0");
|
|
Console.WriteLine("[-end_address2|length1=0..0xFFFFFF] optional, default 0x0");
|
|
Console.WriteLine("[-seed=0x0..0xFFFF] optional, default 0xFFFF");
|
|
Console.WriteLine("[-size=BYTE|WORD] optional, default BYTE");
|
|
Console.WriteLine("[-order=MSB_FIRST|LSB_FIRST] optional, default MSB_FIRST");
|
|
Console.WriteLine("");
|
|
Console.WriteLine("================================================================================");
|
|
Console.WriteLine("");
|
|
}
|
|
/**/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
/*!@brief Display result message.
|
|
* @author Thomas Wiedebusch
|
|
* @date 19-Feb-2016..25-Feb-2016
|
|
*
|
|
*/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
static void DisplayResultMsg_vds()
|
|
{
|
|
if (crcAddressDefined_bols)
|
|
{
|
|
Console.WriteLine("CRC address: 0x{0:X}", crcAddress_u32s);
|
|
}
|
|
Console.WriteLine("Computed CRC16: 0x{0:X4}", crcResult_u16s);
|
|
Console.WriteLine("");
|
|
}
|
|
/**/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
/*!@brief Display file information message.
|
|
* @author Thomas Wiedebusch
|
|
* @date 21-Feb-2016..24-Feb-2016
|
|
*
|
|
*/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
static void DisplayFileInformationMsg_vds()
|
|
{
|
|
//In/output file information
|
|
Console.WriteLine("Input File: " + inputFile_strs);
|
|
//if the output file is not explicitly defined output file = input file
|
|
if (fileUndefined_cstr == outputFile_strs)
|
|
{
|
|
Console.WriteLine("Output File: " + inputFile_strs);
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine("Output File: " + outputFile_strs);
|
|
}
|
|
Console.WriteLine("");
|
|
}
|
|
/**/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
/*!@brief Display input file not found.
|
|
* @author Thomas Wiedebusch
|
|
* @date 21-Feb-2016
|
|
*
|
|
*/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
static void DisplayInFileNotFoundErrorMsg_vds()
|
|
{
|
|
Console.WriteLine("INPUT FILE \"" + inputFile_strs + "\" NOT FOUND!");
|
|
Console.WriteLine("");
|
|
}
|
|
/**/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
/*!@brief Display file format is unknown.
|
|
* @author Thomas Wiedebusch
|
|
* @date 21-Feb-2016
|
|
*
|
|
*/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
static void DispalyUnknownFileFormatErrorMsg_vd()
|
|
{
|
|
Console.WriteLine("UNEXPECTED FILE FORMAT!");
|
|
Console.WriteLine("Input file is corrupted or not a Motorola-s19 or TI-txt file!");
|
|
Console.WriteLine("");
|
|
}
|
|
/**/
|
|
/*---------------------------------------------------------------------------------------------------------------*/
|
|
}//class crcProgram
|
|
}//namespace CRC_CCITT
|
|
/*=====================================END OF FILE===================================================================*/
|