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();
}
}
}