ASCU_ALL/DataClient/ByteConverter.cs
2021-07-07 16:36:28 +05:00

120 lines
3.7 KiB
C#

using DataClient.Struct;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Text.RegularExpressions;
using NLog;
namespace DataClient
{
public static class ByteConverter
{
private static Logger log = LogManager.GetCurrentClassLogger();
public static TechCycle[] BytesToTechcycles(byte[] arr)
{
var res = new List<TechCycle>();
try
{
var str = new List<byte>();
for (var i = 0; i < arr.Length; i++)
if (arr[i] == 0x0a)
{
res.Add(BytesToTechcycle(str.ToArray()));
str.Clear();
}
else
str.Add(arr[i]);
} catch { throw; }
return res.ToArray();
}
public static TechCycle BytesToTechcycle(byte[] arr)
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
var enc = Encoding.GetEncoding(866);
var exc = new ArgumentException("Wrong structure in byte array.");
var flag = 0;
var str = new List<byte>();
var res = new TechCycle();
try
{
for (var i = 0; i < arr.Length; i++)
if (arr[i] == 0x09)
switch (flag)
{
case 0:
var idxStr = enc.GetString(str.ToArray());
if (idxStr == "00") res.Operation = TechCycle.Oper.end_cycle_manual;
else if (int.TryParse(idxStr, out int idx)) res.index = (sbyte?)idx;
str.Clear();
flag++;
break;
case 1:
var timestr = enc.GetString(str.ToArray());
var rgx = new Regex(@"^([0-1]\d{1}|[2][0-3]):([0-5]\d{1}):([0-5]\d{1})$");
if (!rgx.IsMatch(timestr)) throw exc;
str.Clear();
flag++;
break;
default: throw exc;
}
else str.Add(arr[i]);
if (flag != 2) throw exc;
var unixTimeStr = enc.GetString(str.ToArray());
if (!int.TryParse(unixTimeStr, out int unixTime)) throw exc;
res.start = (new DateTime(1970, 1, 1, 0, 0, 0, 0)).AddSeconds(unixTime).ToLocalTime();
return res;
}
catch { throw; }
}
public static (DateTime date, byte?[] bytes)[] BytesToTimeLine(byte[] arr, DateTime date)
{
var res = new List<(DateTime date, byte?[] bytes)>();
var matrix = new List<byte?>();
var currdate = new DateTime(date.Year, date.Month, date.Day, 0, 0, 0);
var cursor = 0;
var halfseconds = 0;
try
{
while (cursor < arr.Length)
{
switch (arr[cursor])
{
case 0xfb:
halfseconds = BitConverter.ToInt32(arr, ++cursor);
cursor += 4;
break;
case 0xfc:
for (var i = 0; i < matrix.Count; i++) matrix[i] = null;
res.Add((currdate.AddSeconds(++halfseconds / 2D), matrix.ToArray()));
halfseconds = BitConverter.ToInt32(arr, ++cursor);
cursor += 4;
break;
case 0xfe:
halfseconds += BitConverter.ToInt16(arr, ++cursor);
cursor += 2;
break;
case 0xff:
res.Add((currdate.AddSeconds(halfseconds / 2D), matrix.ToArray()));
cursor++;
halfseconds++;
break;
default:
while (matrix.Count < arr[cursor]) matrix.Add(null);
matrix[arr[cursor]] = arr[cursor + 1];
cursor += 2;
break;
}
}
}
catch(Exception e)
{
log.Warn(e, "Error in structure AD file.");
return res.ToArray();
}
return res.ToArray();
}
}
}