123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332 |
- using System;
- using System.Globalization;
- using System.Text;
- using System.IO;
- namespace Wayne.FDCPOSInterface
- {
- public class SignedFuellingInfo
- {
- /// <summary>
- /// A class that calculates a CRC32 value from various sources.
- /// </summary>
- public class Crc32
- {
- #region Fields
- private UInt32[] table;
- private UInt32 initialValue;
- private UInt32 crc;
- private UInt32 length;
- private byte[] tempBuffer;
- #endregion
- #region Construction
- /// <summary>
- /// Constructor.
- /// Initializes the CRC to 0xFFFFFFFF.
- /// </summary>
- public Crc32()
- : this(0xffffffff)
- {
- }
- /// <summary>
- /// Constructor.
- /// </summary>
- /// <param name="initialValue">The initial value of the CRC.</param>
- public Crc32(UInt32 initialValue)
- {
- this.initialValue = initialValue;
- UInt32 poly = 0xedb88320;
- table = new UInt32[256];
- UInt32 temp = 0;
- for (UInt32 i = 0; i < table.Length; i++)
- {
- temp = i;
- for (UInt32 j = 8; j > 0; j--)
- {
- if ((temp & 1) == 1)
- temp = (UInt32)((temp >> 1) ^ poly);
- else
- temp >>= 1;
- }
- table[i] = temp;
- }
- Reset();
- }
- #endregion
- #region Properties
- /// <summary>
- /// The CRC32 value.
- /// </summary>
- public UInt32 Value
- {
- get { return ~crc; }
- }
- /// <summary>
- /// The total length of the data.
- /// </summary>
- public UInt32 Length
- {
- get { return length; }
- }
- #endregion
- #region Methods
- /// <summary>
- /// Resets the CRC32 value.
- /// </summary>
- public void Reset()
- {
- crc = initialValue;
- length = 0;
- }
- /// <summary>
- /// Appends a byte array to the CRC32 value.
- /// </summary>
- /// <param name="bytes">The bytes to append.</param>
- public void Append(byte[] bytes)
- {
- Append(bytes, 0, bytes.Length);
- }
- /// <summary>
- /// Appends a byte array to the CRC32 value.
- /// </summary>
- /// <param name="bytes">The bytes to append.</param>
- /// <param name="offset">The offset of the array of where to start.</param>
- /// <param name="length">The number of bytes to read from the array.</param>
- public void Append(byte[] bytes, int offset, int length)
- {
- this.length += (UInt32)length;
- for (int i = offset; i < length; i++)
- {
- byte index = (byte)(((crc) & 0xff) ^ bytes[i]);
- crc = (UInt32)((crc >> 8) ^ table[index]);
- }
- }
- /// <summary>
- /// Appends a text string to the CRC32 value.
- /// </summary>
- /// <param name="text">The text to append.</param>
- public void Append(string text)
- {
- if (!string.IsNullOrEmpty(text))
- Append(Encoding.Unicode.GetBytes(text));
- }
- /// <summary>
- /// Appends the content of a file to the CRC32 value.
- /// </summary>
- /// <param name="filename">The filename of the file to append.</param>
- public void AppendFile(string filename)
- {
- AppendFile(filename, 16384);
- }
- /// <summary>
- /// Appends the content of a file to the CRC32 value.
- /// </summary>
- /// <param name="filename">The filename of the file to append.</param>
- /// <param name="bufferSize">The size of the read-buffer to use.</param>
- public void AppendFile(string filename, int bufferSize)
- {
- try
- {
- if ((tempBuffer == null) || (bufferSize != tempBuffer.Length))
- tempBuffer = new byte[bufferSize];
- using (FileStream fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read))
- {
- using (BinaryReader binaryReader = new BinaryReader(fileStream))
- {
- int usedBufferSize;
- do
- {
- usedBufferSize = binaryReader.Read(tempBuffer, 0, bufferSize);
- if (usedBufferSize > 0)
- Append(tempBuffer, 0, usedBufferSize);
- }
- while (usedBufferSize == bufferSize);
- }
- }
- }
- catch { }
- }
- #endregion
- }
- public class Data
- {
- public DateTime DateTime { get; set; }
- public int PumpNumber { get; set; }
- public string ProductName { get; set; }
- public decimal TotalAmount { get; set; }
- public decimal Volume { get; set; }
- public decimal Price { get; set; }
- public string CurrencySymbol { get; set; }
- public bool CurrencySymbolAfterValue { get; set; }
- public bool SpaceBetweenCurrencySymbolAndValue { get; set; }
- public string VolumeUnit { get; set; }
- public int ControllerModuleCrc { get; set; }
- public int PrinterWidth { get; set; }
- }
- private const string Iv = "@BEPQRV]";
- private readonly Crc32 crc32 = new Crc32((uint)(
- ((Iv[6] - Iv[0]) * (Iv[7] - Iv[0]) + (Iv[2] - Iv[0])) * 1024 * 1024 +
- ((Iv[3] - Iv[0]) * (Iv[5] - Iv[0]) + (Iv[1] - Iv[0])) * 1024 +
- ((Iv[6] - Iv[0]) * (Iv[7] - Iv[0]) + (Iv[4] - Iv[0]))));
- private const string SignChar = "^";
- private const string BadSignReplaceChar = " ";
- private const string SignError = "\r\n^*PUMP INFO SIGN ERROR*^\r\n";
- public string EncodeReceiptText(Data data)
- {
- StringBuilder result = new StringBuilder();
- NumberFormatInfo numberFormatInfo = new NumberFormatInfo
- {
- NumberDecimalDigits = 2,
- NumberDecimalSeparator = ","
- };
- if (data.PrinterWidth < 30)
- {
- // Design for 24 chars
- // ===================
- string preText = data.PrinterWidth > 24 ? new string(' ', data.PrinterWidth - 24) : string.Empty;
- //^ #12 [20100503085824] ^45697A3C
- result.Append(preText + GetSignedString(string.Concat(SignChar, " #", data.PumpNumber.ToString().PadRight(3),
- "[", data.DateTime.ToString("yyyyMMddHHmmss"), "] ", SignChar)));
- //^ Blyfri 95 ^2C5BD546
- result.Append(preText + GetSignedString(string.Concat(SignChar, " ", data.ProductName.PadRight(21), SignChar)));
- //^ 563,74 DKK ^65B9F8A3
- result.Append(preText + GetSignedString(string.Concat(SignChar, GetCurrencyString(numberFormatInfo, data).PadLeft(21), " ", SignChar)));
- //^ 54,52 L ^98C35479
- result.Append(preText + GetSignedString(string.Concat(SignChar, data.Volume.ToString(numberFormatInfo).PadLeft(10), " ", data.VolumeUnit.PadRight(11), SignChar)));
- //^ @ 10,34 DKK/L ^465D9872
- result.Append(preText + GetSignedString(string.Concat(SignChar, string.Concat("@ ", data.Price.ToString(numberFormatInfo)).PadLeft(10), " ", string.Concat(data.CurrencySymbol, "/", data.VolumeUnit).PadRight(11), SignChar)));
- //^ CS A8F0EC90:######## ^6A9C8FC4)
- result.Append(preText + GetSignedString(string.Concat(SignChar, " CS ", data.ControllerModuleCrc.ToString("X8"), " ######## ", SignChar)));
- }
- else
- {
- // Design for 30 chars
- // ===================
- string preText = data.PrinterWidth > 30 ? new string(' ', data.PrinterWidth - 30) : string.Empty;
- //123456789012345678901234567890
- //^ #12 [20100503085824] ^4A7692AE
- result.Append(preText + GetSignedString(string.Concat(SignChar, " #", data.PumpNumber.ToString().PadRight(3),
- "[", data.DateTime.ToString("yyyyMMddHHmmss"), "] ", SignChar)));
- //123456789012345678901234567890
- //^ Unlead 95 563,74 SEK ^3CE18720
- result.Append(preText + GetSignedString(string.Concat(SignChar, " ", data.ProductName.PadRight(14), GetCurrencyString(numberFormatInfo, data).PadLeft(12), " ", SignChar)));
- //123456789012345678901234567890
- //^ 54,52 L @ 10,34 SEK/L ^0A1B0FB2
- result.Append(preText + GetSignedString(string.Concat(SignChar, " ", string.Concat(data.Volume.ToString(numberFormatInfo), " ", data.VolumeUnit,
- " @ ", data.Price.ToString(numberFormatInfo), " ", data.CurrencySymbol, "/", data.VolumeUnit).PadRight(27), SignChar)));
- //123456789012345678901234567890
- //^ C/S A8F0EC90:######## ^05198FB7
- result.Append(preText + GetSignedString(string.Concat(SignChar, " C/S ", data.ControllerModuleCrc.ToString("X8"), " ######## ", SignChar)));
- }
- return result.ToString();
- }
- public string DecodeReceiptText(string text, int printerModuleCrc)
- {
- bool hasError = false;
- int offset = 0;
- int startCharIndex, endCharIndex;
- do
- {
- startCharIndex = text.IndexOf(SignChar, offset);
- if (startCharIndex > -1)
- {
- endCharIndex = text.IndexOf(SignChar, startCharIndex + 1);
- if (endCharIndex == -1)
- {
- text = text.Replace(SignChar, BadSignReplaceChar);
- hasError = true;
- }
- else
- {
- if (text.Length <= endCharIndex + 8)
- {
- text = text.Remove(startCharIndex, 1).Insert(startCharIndex, BadSignReplaceChar).Remove(endCharIndex, 1).Insert(endCharIndex, BadSignReplaceChar);
- hasError = true;
- }
- else
- {
- string crcString = text.Substring(endCharIndex + 1, 8);
- string signedText = text.Substring(startCharIndex, endCharIndex - startCharIndex + 1);
- if (!crcString.Equals(GetStringSignValue(signedText), StringComparison.InvariantCultureIgnoreCase))
- {
- text = text.Remove(startCharIndex, 1).Insert(startCharIndex, BadSignReplaceChar).Remove(endCharIndex, 1).Insert(endCharIndex, BadSignReplaceChar);
- hasError = true;
- }
- int printerModuleCrcIndex = signedText.IndexOf("########");
- if (printerModuleCrcIndex > -1)
- text = text.Remove(startCharIndex + printerModuleCrcIndex, 8).Insert(startCharIndex + printerModuleCrcIndex, printerModuleCrc.ToString("X8"));
- text = text.Remove(endCharIndex + 1, 8);
- }
- offset = endCharIndex + 1;
- }
- }
- else
- endCharIndex = -1;
- }
- while ((startCharIndex > -1) && (endCharIndex > -1));
- if (hasError)
- return text + SignError;
- return text;
- }
- private static string GetCurrencyString(IFormatProvider numberFormatInfo, Data data)
- {
- if (data.CurrencySymbolAfterValue)
- return string.Concat(data.TotalAmount.ToString(numberFormatInfo), data.SpaceBetweenCurrencySymbolAndValue ? " " : string.Empty, data.CurrencySymbol);
- return string.Concat(data.CurrencySymbol, data.SpaceBetweenCurrencySymbolAndValue ? " " : string.Empty, data.TotalAmount.ToString(numberFormatInfo));
- }
- private string GetSignedString(string text)
- {
- return string.Concat(text, GetStringSignValue(text));
- }
- private string GetStringSignValue(string text)
- {
- crc32.Reset();
- crc32.Append(text);
- return crc32.Value.ToString("X8");
- }
- }
- }
|