- Updated Detail class to include JsonSourceGenerationOptions and JsonSerializable attributes for source generation. - Modified ProcessData class to utilize source generation context for Description deserialization. - Renamed RowSourceGenerationContext to QS408MRowSourceGenerationContext for clarity. - Updated Run class to use QS408MRunSourceGenerationContext for serialization. - Enhanced Description class with source generation attributes. - Refactored FileRead class to use source generation context for Description deserialization. - Added new methods in ProcessDataStandardFormat for JSON element array extraction. - Introduced new PDSF file handler classes: Body, Constant, FileRead, Footer, Header, Row, Run, and Site. - Implemented logic for parsing and handling PDSF data structures. - Added unit tests for PDSF processing to ensure functionality.
190 lines
6.6 KiB
C#
190 lines
6.6 KiB
C#
using Adaptation.Shared;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
using System.Text.Json.Serialization;
|
|
|
|
namespace Adaptation.FileHandlers.pdsf;
|
|
|
|
#nullable enable
|
|
|
|
internal class Run
|
|
{
|
|
|
|
public Header Header { get; }
|
|
public ReadOnlyCollection<Site> Sites { get; }
|
|
public Body Body { get; }
|
|
public Footer Footer { get; }
|
|
|
|
public Run(Header header, ReadOnlyCollection<Site> sites, Body body, Footer footer)
|
|
{
|
|
Header = header;
|
|
Sites = sites;
|
|
Body = body;
|
|
Footer = footer;
|
|
}
|
|
|
|
internal static string GetBefore(string text, int[] i, string search)
|
|
{
|
|
string str;
|
|
string str1;
|
|
int num = text.IndexOf(search, i[0]);
|
|
if (num <= -1)
|
|
{
|
|
str = text.Substring(i[0]);
|
|
i[0] = text.Length;
|
|
str1 = str.Trim();
|
|
}
|
|
else
|
|
{
|
|
str = text.Substring(i[0], num - i[0]);
|
|
i[0] = num + search.Length;
|
|
str1 = str.Trim();
|
|
}
|
|
return str1;
|
|
}
|
|
|
|
internal static string GetToEOL(string text, int[] i)
|
|
{
|
|
string result;
|
|
if (text.IndexOf("\n", i[0]) > -1)
|
|
result = GetBefore(text, i, "\n");
|
|
else
|
|
result = GetBefore(text, i, Environment.NewLine);
|
|
return result;
|
|
}
|
|
|
|
internal static int ScanPast(string text, int[] i, string search)
|
|
{
|
|
int result;
|
|
int num = text.IndexOf(search, i[0]);
|
|
if (num <= -1)
|
|
result = text.Length;
|
|
else
|
|
result = num + search.Length;
|
|
return result;
|
|
}
|
|
|
|
private static void WriteJson(Logistics logistics, List<FileInfo> fileInfoCollection, Run result)
|
|
{
|
|
FileInfo fileInfo = new($"{logistics.ReportFullPath}.run.json");
|
|
string json = JsonSerializer.Serialize(result, RunSourceGenerationContext.Default.Run);
|
|
File.WriteAllText(fileInfo.FullName, json);
|
|
File.SetLastWriteTime(fileInfo.FullName, logistics.DateTimeFromSequence);
|
|
fileInfoCollection.Add(fileInfo);
|
|
}
|
|
|
|
private static ReadOnlyCollection<string> GetLines(Logistics logistics, JsonElement[]? jsonElements)
|
|
{
|
|
List<string> results = new();
|
|
int columns = 0;
|
|
StringBuilder stringBuilder = new();
|
|
results.Add($"\"Count\",{jsonElements?.Length}");
|
|
results.Add($"\"{nameof(logistics.Sequence)}\",\"{logistics.Sequence}\"");
|
|
results.Add($"\"{nameof(logistics.MesEntity)}\",\"{logistics.MesEntity}\"");
|
|
string dateTimeFromSequence = logistics.DateTimeFromSequence.ToString("MM/dd/yyyy hh:mm:ss tt");
|
|
for (int i = 0; i < jsonElements?.Length;)
|
|
{
|
|
_ = stringBuilder.Append('"').Append(nameof(logistics.DateTimeFromSequence)).Append('"').Append(',');
|
|
foreach (JsonProperty jsonProperty in jsonElements[0].EnumerateObject())
|
|
{
|
|
columns += 1;
|
|
_ = stringBuilder.Append('"').Append(jsonProperty.Name).Append('"').Append(',');
|
|
}
|
|
break;
|
|
}
|
|
if (jsonElements?.Length != 0)
|
|
_ = stringBuilder.Remove(stringBuilder.Length - 1, 1);
|
|
results.Add(stringBuilder.ToString());
|
|
for (int i = 0; i < jsonElements?.Length; i++)
|
|
{
|
|
_ = stringBuilder.Clear();
|
|
_ = stringBuilder.Append('"').Append(dateTimeFromSequence).Append('"').Append(',');
|
|
foreach (JsonProperty jsonProperty in jsonElements[i].EnumerateObject())
|
|
{
|
|
if (jsonProperty.Value.ValueKind == JsonValueKind.Object)
|
|
_ = stringBuilder.Append(',');
|
|
else if (jsonProperty.Value.ValueKind != JsonValueKind.String)
|
|
_ = stringBuilder.Append(jsonProperty.Value).Append(',');
|
|
else
|
|
_ = stringBuilder.Append('"').Append(jsonProperty.Value).Append('"').Append(',');
|
|
}
|
|
_ = stringBuilder.Remove(stringBuilder.Length - 1, 1);
|
|
results.Add(stringBuilder.ToString());
|
|
}
|
|
return results.AsReadOnly();
|
|
}
|
|
|
|
private static void WriteCommaSeparatedValues(Logistics logistics, Run run)
|
|
{
|
|
List<Row> results = new();
|
|
Row row;
|
|
for (int i = 0; i < run.Sites.Count; i++)
|
|
{
|
|
row = new(run, i);
|
|
results.Add(row);
|
|
}
|
|
string json = JsonSerializer.Serialize(results);
|
|
JsonElement[]? jsonElements = JsonSerializer.Deserialize<JsonElement[]>(json);
|
|
ReadOnlyCollection<string> lines = GetLines(logistics, jsonElements);
|
|
File.WriteAllText($"{logistics.ReportFullPath}.csv", string.Join(Environment.NewLine, lines));
|
|
}
|
|
|
|
private static string GetText(ProcessDataStandardFormat processDataStandardFormat)
|
|
{
|
|
string result;
|
|
List<string> results = new();
|
|
int skipColumns = processDataStandardFormat.Columns.Count - 1;
|
|
foreach (string line in processDataStandardFormat.Body)
|
|
results.Add(string.Join("\t", line.Split('\t').Skip(skipColumns)));
|
|
result = string.Join(Environment.NewLine, results);
|
|
return result;
|
|
}
|
|
|
|
internal static Run? Get(Logistics logistics, ProcessDataStandardFormat processDataStandardFormat, List<FileInfo> fileInfoCollection, Header lastHeader)
|
|
{
|
|
Run? result;
|
|
Constant constant = new();
|
|
int[] i = new int[] { 0 };
|
|
string text = GetText(processDataStandardFormat);
|
|
Header? header = Header.Get(constant, lastHeader, text, i);
|
|
if (header is null)
|
|
result = null;
|
|
else
|
|
{
|
|
ReadOnlyCollection<Site> sites = Site.Get(text, i);
|
|
if (sites.Count == 0)
|
|
result = null;
|
|
else
|
|
{
|
|
Body? body = Body.Get(constant, text, i);
|
|
if (body is null)
|
|
result = null;
|
|
else
|
|
{
|
|
Footer? footer = Footer.Get(constant, text, i);
|
|
if (footer is null)
|
|
result = null;
|
|
else
|
|
{
|
|
result = new(header, sites, body, footer);
|
|
WriteJson(logistics, fileInfoCollection, result);
|
|
WriteCommaSeparatedValues(logistics, result);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
}
|
|
|
|
[JsonSourceGenerationOptions(WriteIndented = true)]
|
|
[JsonSerializable(typeof(Run))]
|
|
internal partial class RunSourceGenerationContext : JsonSerializerContext
|
|
{
|
|
} |