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(); try { var str = new List(); 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(); 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(); 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(); } } }