using Edge.Core.Parser.BinaryParser.Util; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace HengShan_Pump_TQC_IFSF.MessageEntity { public enum DatabaseType { COMMUNICATION_SERVICE_DATABASE, CALCULATOR_DATABASE, /// /// DB_Ad = FP_ID (21H-24H) /// FUELLING_POINT_DATABASE, /// /// DB_Ad = FP_ID (21H-24H) + LN_ID (11H-18H) /// LOGICAL_NOZZLE_DATABASE, /// /// DB_Ad = FP_ID (21H-24H) + TR_DAT (21H) + TR_Seq_Nb (0001-9999) /// FUELLING_TRANSACTION_DATABASE, ERROR_CODE_DATABASE, Unknown, } /// /// DB_Ad_Lg(1 byte) + DB_Ad(1-8 byte) + [Data_Id(1 byte) + Data_Lg(1 or 3) + Data_El] /// public class DatabaseDataParser { private List output = new List(); private byte[] databaseId; private List> dataIds = new List>(); public static DatabaseDataParser New() { return new DatabaseDataParser(); } private DatabaseType DetermineDatabaseType(byte[] databaseId) { if (databaseId.Length == 1) { if (databaseId[0] == 0) return DatabaseType.COMMUNICATION_SERVICE_DATABASE; if (databaseId[0] == 1) return DatabaseType.CALCULATOR_DATABASE; if (databaseId[0] >= 0x21 && databaseId[0] <= 0x24) return DatabaseType.FUELLING_POINT_DATABASE; } else if (databaseId.Length == 2) { if (databaseId[0] >= 0x21 && databaseId[0] <= 0x24 && databaseId[1] >= 0x11 && databaseId[1] <= 0x18) return DatabaseType.LOGICAL_NOZZLE_DATABASE; } else if (databaseId.Length == 3) { if (databaseId[0] >= 0x21 && databaseId[0] <= 0x24 && databaseId[1] == 0x41 && databaseId[2] >= 0x01 && databaseId[2] <= 0x40) return DatabaseType.ERROR_CODE_DATABASE; } else if (databaseId.Length == 4) { if (databaseId[0] >= 0x21 && databaseId[0] <= 0x24 && databaseId[1] == 0x21 && databaseId[2] >= 0x00 && databaseId[2] <= 0x99 && databaseId[3] >= 0x00 && databaseId[3] <= 0x99) return DatabaseType.FUELLING_TRANSACTION_DATABASE; } return DatabaseType.Unknown; } public DatabaseDataParser AssignDatabaseId(byte[] databaseId) { this.databaseId = databaseId; var databaseLen = databaseId.Length.GetBinBytes(1); this.output.AddRange(databaseLen); this.output.AddRange(databaseId); return this; } public DatabaseType DatabaseType => this.DetermineDatabaseType(this.databaseId); /// /// dataId:dataElement /// if data len is 0, then dataElement is a 0 length byte array. /// public IEnumerable> DataIds => this.dataIds; public byte[] DatabaseId => this.databaseId; /// /// /// /// /// leave it to null if the dataIdLen and dataIdElement are omit from msg. /// or leave a 0 length array then the dataIdLen and dataIdElement will be combined as single byte 0x00 /// public DatabaseDataParser AddDataId(byte dataId, byte[] dataElement) { this.dataIds.Add(new System.Tuple(dataId, dataElement)); this.output.Add(dataId); if (dataElement == null) { } else { if (dataElement.Length > 254) { //var exceed = (dataElement.Length - 254).GetBinBytes(2); this.output.Add(0xFF); this.output.AddRange(dataElement.Length.GetBinBytes(2)); this.output.AddRange(dataElement); } else if (dataElement.Length == 0) { this.output.Add(0x00); } else { this.output.AddRange(dataElement.Length.GetBinBytes(1)); this.output.AddRange(dataElement); } } return this; } /// /// deserialize /// /// should follow: DB_Ad_Lg(1 byte) + DB_Ad(1-8 byte) + [Data_Id(1 byte) + Data_Lg(1 or 3) + Data_El] /// public DatabaseDataParser Convert(byte[] rawData) { var databaseIdLen = rawData.Take(1).ToInt32(); this.databaseId = rawData.Skip(1).Take(databaseIdLen).ToArray(); var dataIdsPart = rawData.Skip(1 + databaseIdLen); int previousDataIdFullLen = 0; while (true) { if (previousDataIdFullLen >= dataIdsPart.Count()) break; var dataId = dataIdsPart.Skip(previousDataIdFullLen).Take(1).FirstOrDefault(); var dataElementLenByteCounts = 1; var dataElementLen = 0; var dataElementLenFirstByte = dataIdsPart.Skip(previousDataIdFullLen + 1).Take(1).ToInt32(); if (dataElementLenFirstByte > 254) { dataElementLen = dataIdsPart.Skip(previousDataIdFullLen + 2).Take(2).ToInt32(); dataElementLenByteCounts = 3; } else dataElementLen = dataIdsPart.Skip(previousDataIdFullLen + 1).Take(1).ToInt32(); this.dataIds.Add(new System.Tuple( dataId, dataIdsPart.Skip(previousDataIdFullLen + 1 + dataElementLenByteCounts).Take(dataElementLen).ToArray())); previousDataIdFullLen += 1 + dataElementLenByteCounts + dataElementLen; if (previousDataIdFullLen == dataIdsPart.Count()) break; } return this; } /// /// serialize /// /// DB_Ad_Lg(1 byte) + DB_Ad(1-8 byte) + [Data_Id(1 byte) + Data_Lg(1 or 3) + Data_El] public byte[] Convert() { return this.output.ToArray(); } } }