ASCU_ALL/ApiServer/WorkWithFiles.cs
2024-09-22 04:27:05 +05:00

545 lines
16 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ICSharpCode.SharpZipLib.GZip;
using ICSharpCode.SharpZipLib.Tar;
using System.IO;
using ApiServer.Structures;
using NLog;
namespace ApiServer
{
public static class WorkWithFiles
{
private static Logger log = LogManager.GetCurrentClassLogger();
public static string[] GetFile(string fileName)
{
var vdp = fileName.Substring(9, 2);
var dir_archive = Path.Combine(
Directory.GetCurrentDirectory(),
"data",
"data",
fileName.Substring(0,4),
fileName.Substring(4, 2),
fileName.Substring(6, 2)
);
var tmp = Path.Combine(
Directory.GetCurrentDirectory(),
"temp",
System.Guid.NewGuid().ToString()
);
if (!Directory.Exists(tmp))
Directory.CreateDirectory(tmp);
var flag_exist = false;
var tar_gz = false;
if (File.Exists(Path.Combine(dir_archive, vdp + ".tar.gz")))
{
flag_exist = true;
tar_gz = true;
dir_archive = Path.Combine(dir_archive, vdp + ".tar.gz");
}
if (File.Exists(Path.Combine(dir_archive, vdp + ".tar")))
{
flag_exist = true;
dir_archive = Path.Combine(dir_archive, vdp + ".tar");
}
if (!flag_exist)
return Array.Empty<string>();
if (tar_gz)
ExtractTarGZ(dir_archive, tmp);
else
ExtractTar(dir_archive, tmp);
if (!File.Exists(Path.Combine(tmp, fileName)))
{
Directory.Delete(tmp, true);
return Array.Empty<string>();
}
var result = File.ReadAllLines(Path.Combine(tmp, fileName));
Directory.Delete(tmp, true);
return result;
}
public static byte[] GetFileBytes(string fileName)
{
var vdp = fileName.Substring(9, 2);
var dir_archive = Path.Combine(
Directory.GetCurrentDirectory(),
"data",
"data",
fileName.Substring(0, 4),
fileName.Substring(4, 2),
fileName.Substring(6, 2)
);
var tmp = Path.Combine(
Directory.GetCurrentDirectory(),
"temp",
System.Guid.NewGuid().ToString()
);
log.Info("Path: " + dir_archive);
if (!Directory.Exists(tmp))
Directory.CreateDirectory(tmp);
var flag_exist = false;
var tar_gz = false;
if (File.Exists(Path.Combine(dir_archive, vdp + ".tar.gz")))
{
flag_exist = true;
tar_gz = true;
dir_archive = Path.Combine(dir_archive, vdp + ".tar.gz");
}
if (File.Exists(Path.Combine(dir_archive, vdp + ".tar")))
{
flag_exist = true;
dir_archive = Path.Combine(dir_archive, vdp + ".tar");
}
if (!flag_exist)
return Array.Empty<byte>();
if (tar_gz)
ExtractTarGZ(dir_archive, tmp);
else
ExtractTar(dir_archive, tmp);
if (!File.Exists(Path.Combine(tmp, fileName)))
{
Directory.Delete(tmp, true);
return Array.Empty<byte>();
}
var result = File.ReadAllBytes(Path.Combine(tmp, fileName));
Directory.Delete(tmp, true);
return result;
}
private static void ExtractTarGZ(String gzArchiveName, String destFolder)
{
using (var a = (Stream)File.OpenRead(gzArchiveName))
using (var b = (Stream)new GZipInputStream(a))
using (var c = TarArchive.CreateInputTarArchive(b))
c.ExtractContents(destFolder);
}
private static void ExtractTar(String tarFileName, String destFolder)
{
using (var a = (Stream)File.OpenRead(tarFileName))
using (var b = TarArchive.CreateInputTarArchive(a))
b.ExtractContents(destFolder);
}
public static Protect[] GetProtects(DateTime date, int vdp)
{
var result = new List<Protect>();
var byte_arr = GetFileBytes(
date.Year.ToString("D4") +
date.Month.ToString("D2") +
date.Day.ToString("D2") +
"." +
vdp.ToString("D2") +
"4"
);
for (var i = 0; i < byte_arr.Length; i++)
{
if (i + 3 >= byte_arr.Length)
break;
var unix_date = BitConverter.ToUInt32(byte_arr, i);
i += 4;
var date_time = new DateTime(1970, 1, 1, 0, 0, 0, 0);
date_time = date_time.AddSeconds(unix_date).ToLocalTime();
if (i + 3 >= byte_arr.Length)
break;
var nanosec = BitConverter.ToUInt32(byte_arr, i);
i += 4;
date_time.AddMilliseconds(nanosec / 1000000);
while (byte_arr[i] != 0xff)
{
if (i >= byte_arr.Length)
break;
var index = byte_arr[i];
i++;
if (i >= byte_arr.Length)
break;
var state = byte_arr[i];
i++;
result.Add(
new Protect()
{
Index = index,
start = date_time,
State = state
}
);
}
}
return result.ToArray();
}
public static Discret[] GetDiscrets(DateTime date, int vdp)
{
var desc_struct = Configuration.GetDiscretParams(vdp.ToString("D2"));
var result = new List<Discret>();
var byte_arr = GetFileBytes(
date.Year.ToString("D4") +
date.Month.ToString("D2") +
date.Day.ToString("D2") +
"." +
vdp.ToString("D2") +
"1"
);
var date_bytes_struct = new List<(DateTime dt, byte?[] arr)>();
var curr_date = new DateTime(date.Year, date.Month, date.Day, 0, 0, 0);
var curr_byte_arr = new List<byte?>();
var halfsec = 0D;
var curr_byte = 0;
while (curr_byte < byte_arr.Length)
{
switch (byte_arr[curr_byte])
{
case 0xfb:
curr_byte++;
if (curr_byte + 3 >= byte_arr.Length)
{
curr_byte += 3;
break;
}
halfsec = BitConverter.ToUInt32(byte_arr, curr_byte);
curr_byte += 4;
break;
case 0xfc:
curr_byte_arr = new List<byte?>();
date_bytes_struct.Add((
curr_date.AddSeconds(halfsec / 2),
curr_byte_arr.ToArray()
));
curr_byte++;
if (curr_byte + 3 >= byte_arr.Length)
{
curr_byte += 3;
break;
}
halfsec = BitConverter.ToUInt32(byte_arr, curr_byte);
curr_byte += 4;
break;
case 0xfe:
curr_byte++;
if (curr_byte + 1 >= byte_arr.Length)
{
curr_byte++;
break;
}
halfsec += BitConverter.ToInt16(byte_arr, curr_byte);
curr_byte += 2;
break;
case 0xff:
date_bytes_struct.Add((
curr_date.AddSeconds(halfsec / 2),
curr_byte_arr.ToArray()
));
halfsec++;
curr_byte++;
break;
default:
while (curr_byte_arr.Count <= byte_arr[curr_byte])
curr_byte_arr.Add(null);
curr_byte++;
if (curr_byte >= byte_arr.Length)
break;
curr_byte_arr[byte_arr[curr_byte - 1]] = byte_arr[curr_byte];
curr_byte++;
break;
}
}
foreach (var dm in date_bytes_struct)
{
foreach (var dp in desc_struct)
{
if (dp.Skip)
continue;
byte? state = 0;
for (var i = 0; i < dp.Bits.Length; i++)
{
if (
dm.arr.Length <= dp.Bits[i].ByteIndex ||
!dm.arr[dp.Bits[i].ByteIndex].HasValue
)
{
state = null;
break;
}
var curr_bit = (dm.arr[dp.Bits[i].ByteIndex].Value >> dp.Bits[i].BitIndex) & 1;
state += (byte)(curr_bit * Math.Pow(2, i));
}
var last = result.FindLastIndex(x => x.Index == dp.Index);
if (last != -1 && result[last].State == state)
continue;
result.Add(new Discret()
{
Index = dp.Index,
start = dm.dt,
State = state
});
}
}
return result.ToArray();
}
public static AnalogArr[] GetAnalogs(DateTime date, int vdp)
{
var analog_struct = Configuration.GetAnalogParams(vdp.ToString("D2"));
var result = new List<AnalogArr>();
var byte_arr = GetFileBytes(
date.Year.ToString("D4") +
date.Month.ToString("D2") +
date.Day.ToString("D2") +
"." +
vdp.ToString("D2") +
"1"
);
var date_bytes_struct = new List<(DateTime dt, byte?[] arr)>();
var curr_date = new DateTime(date.Year, date.Month, date.Day, 0, 0, 0);
var curr_byte_arr = new List<byte?>();
var halfsec = 0D;
var curr_byte = 0;
while (curr_byte < byte_arr.Length)
{
switch (byte_arr[curr_byte])
{
case 0xfb:
curr_byte++;
if (curr_byte + 3 >= byte_arr.Length)
{
curr_byte += 3;
break;
}
halfsec = BitConverter.ToUInt32(byte_arr, curr_byte);
curr_byte += 4;
break;
case 0xfc:
curr_byte_arr = new List<byte?>();
date_bytes_struct.Add((
curr_date.AddSeconds(halfsec / 2),
curr_byte_arr.ToArray()
));
curr_byte++;
if (curr_byte + 3 >= byte_arr.Length)
{
curr_byte += 3;
break;
}
halfsec = BitConverter.ToUInt32(byte_arr, curr_byte);
curr_byte += 4;
break;
case 0xfe:
curr_byte++;
if (curr_byte + 1 >= byte_arr.Length)
{
curr_byte++;
break;
}
halfsec += BitConverter.ToInt16(byte_arr, curr_byte);
curr_byte += 2;
break;
case 0xff:
date_bytes_struct.Add((
curr_date.AddSeconds(halfsec / 2),
curr_byte_arr.ToArray()
));
halfsec++;
curr_byte++;
break;
default:
while (curr_byte_arr.Count <= byte_arr[curr_byte])
curr_byte_arr.Add(null);
curr_byte++;
if (curr_byte >= byte_arr.Length)
break;
curr_byte_arr[byte_arr[curr_byte - 1]] = byte_arr[curr_byte];
curr_byte++;
break;
}
}
var sub_res = new Dictionary<int, List<Analog>>();
foreach (var dm in date_bytes_struct)
{
foreach (var dp in analog_struct)
{
if (dp.Skip)
continue;
double? value = 0;
var val_arr = new List<byte>();
for (var i = 0; i < dp.Bytes.Length; i++)
{
if (
dm.arr.Length <= dp.Bytes[i] ||
!dm.arr[dp.Bytes[i]].HasValue
)
{
value = null;
break;
}
val_arr.Add(dm.arr[dp.Bytes[i]].Value);
}
if (val_arr != null)
{
if (val_arr.Count == 1)
value = val_arr[0];
else if (val_arr.Count == 2)
value = BitConverter.ToInt16(val_arr.ToArray(), 0);
else if (val_arr.Count == 4)
value = BitConverter.ToInt32(val_arr.ToArray(), 0);
else if (val_arr.Count == 8)
value = BitConverter.ToInt64(val_arr.ToArray(), 0);
else
for (var i = 0; i < val_arr.Count; i++)
value += (val_arr[i] * Math.Pow(256, i));
}
if (value != null)
{
value = Math.Round(value.Value);
value = value.Value * dp.Mul;
}
if (!sub_res.ContainsKey(dp.Index))
sub_res.Add(dp.Index, new List<Analog>());
if (sub_res[dp.Index].Count != 0 &&
sub_res[dp.Index][sub_res[dp.Index].Count - 1].Value == value)
continue;
sub_res[dp.Index].Add(new Analog()
{
start = dm.dt,
Value = value
});
}
}
foreach (var d in sub_res)
result.Add(new AnalogArr()
{
Index = d.Key,
Analogs = d.Value.ToArray()
});
return result.ToArray();
}
public static DiscretMatrix[] GetDiscretsMatrix(DateTime date, int vdp)
{
log.Info("Load discret struct for vpd " + vdp);
var desc_struct = Configuration.GetDiscretParams(vdp.ToString("D2"));
var result = new List<DiscretMatrix>();
log.Info("Load file " +
date.Year.ToString("D4") +
date.Month.ToString("D2") +
date.Day.ToString("D2") +
"." +
vdp.ToString("D2") +
"1");
var byte_arr = GetFileBytes(
date.Year.ToString("D4") +
date.Month.ToString("D2") +
date.Day.ToString("D2") +
"." +
vdp.ToString("D2") +
"1"
);
var date_bytes_struct = new List<(DateTime dt, byte?[] arr)>();
var curr_date = new DateTime(date.Year, date.Month, date.Day, 0, 0, 0);
var curr_byte_arr = new List<byte?>();
var halfsec = 0D;
var curr_byte = 0;
log.Info("Parse file to structs.");
while (curr_byte < byte_arr.Length)
{
switch (byte_arr[curr_byte])
{
case 0xfb:
curr_byte++;
if (curr_byte + 3 >= byte_arr.Length)
{
curr_byte += 3;
break;
}
halfsec = BitConverter.ToUInt32(byte_arr, curr_byte);
curr_byte += 4;
break;
case 0xfc:
curr_byte_arr = new List<byte?>();
date_bytes_struct.Add((
curr_date.AddSeconds(halfsec / 2),
curr_byte_arr.ToArray()
));
curr_byte++;
if (curr_byte + 3 >= byte_arr.Length)
{
curr_byte += 3;
break;
}
halfsec = BitConverter.ToUInt32(byte_arr, curr_byte);
curr_byte += 4;
break;
case 0xfe:
curr_byte++;
if (curr_byte + 1 >= byte_arr.Length)
{
curr_byte++;
break;
}
halfsec += BitConverter.ToInt16(byte_arr, curr_byte);
curr_byte += 2;
break;
case 0xff:
date_bytes_struct.Add((
curr_date.AddSeconds(halfsec / 2),
curr_byte_arr.ToArray()
));
halfsec++;
curr_byte++;
break;
default:
while (curr_byte_arr.Count <= byte_arr[curr_byte])
curr_byte_arr.Add(null);
curr_byte++;
if (curr_byte >= byte_arr.Length)
break;
curr_byte_arr[byte_arr[curr_byte - 1]] = byte_arr[curr_byte];
curr_byte++;
break;
}
}
var b_matrix = new List<byte?>();
foreach(var d_slice in date_bytes_struct)
{
var sub_res = new DiscretMatrix() { start = d_slice.dt };
foreach (var d_struct in desc_struct)
{
while (b_matrix.Count <= d_struct.Index)
b_matrix.Add(null);
byte? state = 0;
for (var i = 0; i < d_struct.Bits.Length; i++)
{
if (
d_slice.arr.Length <= d_struct.Bits[i].ByteIndex ||
!d_slice.arr[d_struct.Bits[i].ByteIndex].HasValue
)
{
state = null;
break;
}
var curr_bit = (d_slice.arr[d_struct.Bits[i].ByteIndex].Value >> d_struct.Bits[i].BitIndex) & 1;
state += (byte)(curr_bit * Math.Pow(2, i));
}
b_matrix[d_struct.Index] = state;
}
sub_res.M = b_matrix.ToArray();
result.Add(sub_res);
}
return result.ToArray();
}
}
}