/// <summary> /// Represents one entry from a Header Array (HAR) file. /// </summary> /// <param name="header"> /// The four character identifier for this <see cref="HeaderArray{TValue}"/>. /// </param> /// <param name="coefficient"> /// The coefficient related to the <see cref="HeaderArray{TValue}"/> /// </param> /// <param name="description"> /// The long name description of the <see cref="HeaderArray{TValue}"/>. /// </param> /// <param name="type"> /// The type of element stored in the array. /// </param> /// <param name="dimensions"> /// The dimensions of the array. /// </param> /// <param name="entries"> /// The data in the array. /// </param> public HeaderArray([NotNull] string header, [NotNull] string coefficient, [CanBeNull] string description, HeaderArrayType type, [NotNull] IEnumerable <int> dimensions, [NotNull] IImmutableSequenceDictionary <string, TValue> entries) { if (header is null) { throw new ArgumentNullException(nameof(header)); } if (coefficient is null) { throw new ArgumentNullException(nameof(coefficient)); } if (dimensions is null) { throw new ArgumentNullException(nameof(dimensions)); } if (entries is null) { throw new ArgumentNullException(nameof(entries)); } Header = header; Coefficient = coefficient; Description = description ?? string.Empty; Type = type; Dimensions = dimensions as IImmutableList <int> ?? dimensions.ToImmutableArray(); _entries = entries; }
/// <summary> /// Reads the metadata entry and returns a long-name description, whether or not the full matrix is stored, the data type, and the dimensions. /// </summary> /// <param name="reader"> /// The reader from which the metadata is returned. /// </param> /// <returns> /// A long-name description, a sparse indicator, the data type, the dimensions, and the count of values. /// </returns> private static (string Description, HeaderArrayStorage Storage, HeaderArrayType Type, int[] Dimensions, int Count) GetMetadata([NotNull] BinaryReader reader) { byte[] descriptionBuffer = InitializeArray(reader); HeaderArrayType type = (HeaderArrayType)BitConverter.ToInt16(descriptionBuffer, default(short)); HeaderArrayStorage storage = (HeaderArrayStorage)BitConverter.ToInt32(descriptionBuffer, sizeof(short)); string description = Encoding.ASCII.GetString(descriptionBuffer, sizeof(short) + sizeof(int), 70).Trim('\u0000', '\u0002', '\u0020'); int[] dimensions = new int[BitConverter.ToInt32(descriptionBuffer, sizeof(short) + sizeof(int) + 70)]; int count = 1; for (int i = 0; i < dimensions.Length; i++) { dimensions[i] = BitConverter.ToInt32(descriptionBuffer, sizeof(short) + sizeof(int) + 70 + sizeof(int) + i * sizeof(int)); count *= dimensions[i]; } if (type == HeaderArrayType.C1) { // 1C is actually a vector of character vectors. // So just take the first dimension. count = dimensions[0]; } return(description, storage, type, dimensions, count); }
/// <summary> /// Reads the JSON representation of the object. /// </summary> /// <param name="reader"> /// The <see cref="JsonReader"/> to read from. /// </param> /// <param name="objectType"> /// Type of the object. /// </param> /// <param name="existingValue"> /// The existing value of object being read. /// </param> /// <param name="serializer"> /// The calling serializer. /// </param> /// <returns> /// The object value. /// </returns> public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { JObject jObject = JObject.Load(reader); HeaderArrayType type = Map[jObject["Type"].Value <string>()]; switch (type) { case HeaderArrayType.RE: case HeaderArrayType.R2: { return(Create <float>(jObject, type)); } case HeaderArrayType.I2: { return(Create <int>(jObject, type)); } case HeaderArrayType.C1: { return(Create <string>(jObject, type)); } default: { throw new DataValidationException(nameof(HeaderArrayType), Map, type); } } }
private static IHeaderArray Create <TValue>(JObject jObject, HeaderArrayType type) where TValue : IEquatable <TValue> { IEnumerable <KeyValuePair <string, IImmutableList <string> > > sets = ParseSets(jObject["Sets"]); IEnumerable <KeyValuePair <KeySequence <string>, TValue> > entries = ParseEntries(jObject["Entries"]); IImmutableSequenceDictionary <string, TValue> sequenceDictionary = new ImmutableSequenceDictionary <string, TValue>(sets, entries); return (new HeaderArray <TValue>( jObject["Header"].Value <string>(), jObject["Coefficient"].Value <string>(), jObject["Description"].Value <string>(), type, jObject["Dimensions"].Values <int>().ToImmutableArray(), sequenceDictionary)); IEnumerable <KeyValuePair <KeySequence <string>, TValue> > ParseEntries(JToken jsonEntries) { return (JsonConvert.DeserializeObject <IDictionary <string, TValue> >(jsonEntries.ToString()) .Select( x => new KeyValuePair <KeySequence <string>, TValue>( KeySequence <string> .Parse(x.Key), x.Value))); } IEnumerable <KeyValuePair <string, IImmutableList <string> > > ParseSets(JToken jsonSets) { return (jsonSets.Values <JToken>() .Select( x => new KeyValuePair <string, IImmutableList <string> >( x.Value <string>("Key"), x.Value <JArray>("Value") .Values <string>() .ToImmutableArray()))); } }
/// <summary> /// Creates an <see cref="IHeaderArray{TValue}"/> from one entry from a Header Array (HAR) file. /// </summary> /// <param name="header"> /// The four character identifier for this <see cref="HeaderArray{TValue}"/>. /// </param> /// <param name="coefficient"> /// The coefficient related to the <see cref="HeaderArray{TValue}"/> /// </param> /// <param name="description"> /// The long name description of the <see cref="HeaderArray{TValue}"/>. /// </param> /// <param name="type"> /// The type of element stored in the array. /// </param> /// <param name="dimensions"> /// The dimensions of the array. /// </param> /// <param name="entries"> /// The data in the array. /// </param> public static IHeaderArray <TValue> Create([NotNull] string header, [NotNull] string coefficient, [CanBeNull] string description, HeaderArrayType type, [NotNull] IEnumerable <int> dimensions, [NotNull] IEnumerable <TValue> entries) { if (header is null) { throw new ArgumentNullException(nameof(header)); } if (coefficient is null) { throw new ArgumentNullException(nameof(coefficient)); } if (dimensions is null) { throw new ArgumentNullException(nameof(dimensions)); } if (entries is null) { throw new ArgumentNullException(nameof(entries)); } return(new HeaderArray <TValue>(header, coefficient, description, type, dimensions, ImmutableSequenceDictionary <string, TValue> .Create(entries))); }