Files
2026-04-17 14:55:32 -04:00

172 lines
6.1 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace IRIGCh10
{
/// <summary>
/// this is the base class for sections in the TMATS document
/// each section is made of a bunch of attributes and values
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class TMATSSection<T> where T : Enum
{
private Dictionary<T, string> _values = new Dictionary<T, string>();
/// <summary>
/// Sets the given tag to a given value
/// </summary>
/// <param name="tag"></param>
/// <param name="value"></param>
public void SetValue(T tag, string value) => _values[tag] = value;
/// <summary>
/// returns given value for a given tag
/// value will be null if value was never set
/// </summary>
/// <param name="tag"></param>
/// <returns></returns>
public string GetValue(T tag) => _values.ContainsKey(tag)?_values[tag]: null;
/// <summary>
/// sets a given tag to a given date, or an empty string if date is null
/// </summary>
/// <param name="tag"></param>
/// <param name="value"></param>
public void SetDate(T tag, DateTime? value)
{
if (null == value)
{
SetValueWithLength(tag, string.Empty);
}
var dt = (DateTime) value;
SetValueWithLength(tag, $"{dt.Month:00}-{dt.Day:00}-{dt.Year:0000}");
}
/// <summary>
/// gets a date for a tag, or null if date isn't set
/// </summary>
/// <param name="tag"></param>
/// <returns></returns>
public DateTime? GetDate(T tag)
{
var value = GetValue(tag);
if( string.IsNullOrWhiteSpace(value) ){ return null; }
if (DateTime.TryParseExact(value, "MM-DD-YYYY", System.Globalization.CultureInfo.InvariantCulture,
System.Globalization.DateTimeStyles.None,
out var dt))
{
return dt;
}
return null;
}
/// <summary>
/// gets a int value for tag, or null if tag was never set
/// </summary>
/// <param name="tag"></param>
/// <returns></returns>
public int? GetIntOrNull(T tag)
{
var val = GetValue(tag);
if( string.IsNullOrWhiteSpace(val)){ return null; }
if (int.TryParse(val, out var iTmp))
{
return iTmp;
}
return null;
}
/// <summary>
/// sets tag value
/// </summary>
/// <param name="tag"></param>
/// <param name="val"></param>
public void SetIntOrNull(T tag, int? val)
{
if (null == val)
{
SetValueWithLength(tag, string.Empty);
}
else
{
SetValueWithLength(tag, ((int) val).ToString());
}
}
/// <summary>
/// originally designed to check the length of values against the max length in spec
/// however no longer checks length as max length is just a suggestion in the spec...
/// </summary>
/// <param name="tag"></param>
/// <param name="value"></param>
public void SetValueWithLength(T tag, string value)
{
var maxLength = MaxLengthDecoder.GetMaxLength(tag);
//apprently maxlength is just a suggestion ...
//if (maxLength < value.Length)
//{
// throw new FormatException($"{tag.ToString()} must be {maxLength} characters or less");
//}
SetValue(tag, value);
}
/// <summary>
/// returns all fields in the section for the tmats document
/// </summary>
/// <returns></returns>
public virtual string Serialize()
{
var tags = Enum.GetValues(typeof(T)).Cast<T>().ToArray();
var sb = new StringBuilder();
foreach (var tag in tags)
{
var s = Serialize(tag);
if( string.IsNullOrWhiteSpace(s)){ continue; }
sb.AppendLine(s);
}
return sb.ToString();
}
/// <summary>
/// some attributes have to be associated with a number, like P-x\N:1 where x is
/// the channel number, this keeps track of the number for all attributes
/// </summary>
private int _number = -1;
private AttributeIdentifiers _attribute = AttributeIdentifiers.GeneralInformation;
/// <summary>
/// serializes just one tag/value to a string
/// </summary>
/// <param name="tag"></param>
/// <returns></returns>
protected string Serialize(T tag)
{
var value = GetValue(tag);
if( string.IsNullOrWhiteSpace(value)){ return null; }
var attrib = DescriptionDecoder.GetDescription(tag);
var attributeIdentifier = DescriptionDecoder.GetDescription(_attribute);
if (_number < 0)
{
return $"{attributeIdentifier}\\{attrib}:{value};";
}
return $"{attributeIdentifier}-{_number}\\{attrib}:{value};";
}
/// <summary>
/// generic constructor for attributes which don't need to be associated with a number,
/// like General Information
/// </summary>
public TMATSSection()
{
}
/// <summary>
/// constructor for attributes that are associated with a specific number, like PCM
/// being associated with a channel number
/// </summary>
/// <param name="attribute"></param>
/// <param name="number"></param>
public TMATSSection(AttributeIdentifiers attribute, int number)
{
_attribute = attribute;
_number = number;
}
}
}