MatFileHandler/MatFileHandler/SubsystemData.cs

144 lines
5.3 KiB
C#

// Copyright 2017-2018 Alexander Luzgarev
using System;
using System.Collections.Generic;
namespace MatFileHandler
{
/// <summary>
/// "Subsystem data" of the .mat file.
/// Subsystem data stores the actual contents
/// of all the "opaque objects" in the file.
/// </summary>
internal class SubsystemData
{
/// <summary>
/// Initializes a new instance of the <see cref="SubsystemData"/> class.
/// Default constructor: initializes everything to null.
/// </summary>
public SubsystemData()
{
ClassInformation = null;
ObjectInformation = null;
Data = null;
}
/// <summary>
/// Initializes a new instance of the <see cref="SubsystemData"/> class.
/// The actual constructor.
/// </summary>
/// <param name="classInformation">Information about the classes.</param>
/// <param name="objectInformation">Information about the objects.</param>
/// <param name="data">Field values.</param>
public SubsystemData(ClassInfo[] classInformation, ObjectInfo[] objectInformation, Dictionary<int, IArray> data)
{
this.ClassInformation =
classInformation ?? throw new ArgumentNullException(nameof(classInformation));
this.ObjectInformation =
objectInformation ?? throw new ArgumentNullException(nameof(objectInformation));
this.Data = data ?? throw new ArgumentNullException(nameof(data));
}
/// <summary>
/// Gets or sets information about all the classes occurring in the file.
/// </summary>
public ClassInfo[] ClassInformation { get; set; }
/// <summary>
/// Gets or sets the actual data: mapping of "object field" indices to their values.
/// </summary>
public IReadOnlyDictionary<int, IArray> Data { get; set; }
/// <summary>
/// Gets or sets information about all the objects occurring in the file.
/// </summary>
public ObjectInfo[] ObjectInformation { get; set; }
/// <summary>
/// Initialize this object from another object.
/// This ugly hack allows us to read the opaque objects and store references to
/// the subsystem data in them before parsing the actual subsystem data (which
/// comes later in the file).
/// </summary>
/// <param name="data">Another subsystem data.</param>
public void Set(SubsystemData data)
{
this.ClassInformation = data.ClassInformation;
this.ObjectInformation = data.ObjectInformation;
this.Data = data.Data;
}
/// <summary>
/// Stores information about a class.
/// </summary>
internal class ClassInfo
{
private readonly string[] fieldNames;
private readonly Dictionary<string, int> fieldToIndex;
/// <summary>
/// Initializes a new instance of the <see cref="ClassInfo"/> class.
/// </summary>
/// <param name="name">Class name.</param>
/// <param name="fieldNames">Names of the fields.</param>
public ClassInfo(string name, string[] fieldNames)
{
Name = name ?? throw new ArgumentNullException(nameof(name));
this.fieldNames = fieldNames ?? throw new ArgumentNullException(nameof(fieldNames));
fieldToIndex = new Dictionary<string, int>();
for (var i = 0; i < fieldNames.Length; i++)
{
fieldToIndex[fieldNames[i]] = i;
}
}
/// <summary>
/// Gets names of the fields in the class.
/// </summary>
public IReadOnlyCollection<string> FieldNames => fieldNames;
/// <summary>
/// Gets name of the class.
/// </summary>
public string Name { get; }
/// <summary>
/// Find a field index given its name.
/// </summary>
/// <param name="fieldName">Field name.</param>
/// <returns>Field index.</returns>
public int? FindField(string fieldName)
{
if (fieldToIndex.TryGetValue(fieldName, out var index))
{
return index;
}
return null;
}
}
/// <summary>
/// Stores information about an object.
/// </summary>
internal class ObjectInfo
{
private readonly Dictionary<int, int> fieldLinks;
/// <summary>
/// Initializes a new instance of the <see cref="ObjectInfo"/> class.
/// </summary>
/// <param name="fieldLinks">A dictionary mapping the field indices to "field values" indices.</param>
public ObjectInfo(Dictionary<int, int> fieldLinks)
{
this.fieldLinks = fieldLinks ?? throw new ArgumentNullException(nameof(fieldLinks));
}
/// <summary>
/// Gets mapping between the field indices and "field values" indices.
/// </summary>
public IReadOnlyDictionary<int, int> FieldLinks => fieldLinks;
}
}
}