From bdd04a80b7e8c97cf469f2133f794d566a2560c7 Mon Sep 17 00:00:00 2001 From: Alexander Luzgarev Date: Wed, 20 Mar 2019 22:15:22 +0100 Subject: [PATCH] Unify HDF and old-style datatypes --- MatFileHandler/DataBuilder.cs | 2 +- MatFileHandler/DataElementReader.cs | 2 +- MatFileHandler/Hdf/Array.cs | 45 -------- MatFileHandler/Hdf/CellArray.cs | 24 ----- MatFileHandler/Hdf/CharArray.cs | 41 -------- MatFileHandler/Hdf/NumericalArrayOf.cs | 97 ----------------- MatFileHandler/Hdf/SparseArrayOf.cs | 85 --------------- MatFileHandler/Hdf/StructureArray.cs | 140 ------------------------- MatFileHandler/HdfFileReader.cs | 24 +++-- MatFileHandler/MatCellArray.cs | 4 +- MatFileHandler/MatFileHdfReader.cs | 4 +- 11 files changed, 18 insertions(+), 450 deletions(-) delete mode 100644 MatFileHandler/Hdf/Array.cs delete mode 100644 MatFileHandler/Hdf/CellArray.cs delete mode 100644 MatFileHandler/Hdf/CharArray.cs delete mode 100644 MatFileHandler/Hdf/NumericalArrayOf.cs delete mode 100644 MatFileHandler/Hdf/SparseArrayOf.cs delete mode 100644 MatFileHandler/Hdf/StructureArray.cs diff --git a/MatFileHandler/DataBuilder.cs b/MatFileHandler/DataBuilder.cs index a0c692a..b709d12 100755 --- a/MatFileHandler/DataBuilder.cs +++ b/MatFileHandler/DataBuilder.cs @@ -64,7 +64,7 @@ namespace MatFileHandler { var flags = ConstructArrayFlags(ArrayType.MxCell); var elements = Enumerable.Repeat(MatArray.Empty() as IArray, dimensions.NumberOfElements()).ToList(); - return new MatCellArray(flags, dimensions, string.Empty, elements); + return new MatCellArray(dimensions, elements); } /// diff --git a/MatFileHandler/DataElementReader.cs b/MatFileHandler/DataElementReader.cs index 6e070c9..9138b7b 100755 --- a/MatFileHandler/DataElementReader.cs +++ b/MatFileHandler/DataElementReader.cs @@ -223,7 +223,7 @@ namespace MatFileHandler elements.Add(element); } - return new MatCellArray(flags, dimensions, name, elements); + return new MatCellArray(dimensions, elements); } private DataElementWithArrayFlags ContinueReadingOpaque(BinaryReader reader) diff --git a/MatFileHandler/Hdf/Array.cs b/MatFileHandler/Hdf/Array.cs deleted file mode 100644 index 737377f..0000000 --- a/MatFileHandler/Hdf/Array.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System.Numerics; - -namespace MatFileHandler.Hdf -{ - internal class Array : IArray - { - /// - /// Initializes a new instance of the class. - /// - /// Dimensions of the array. - protected Array( - int[] dimensions) - { - Dimensions = dimensions; - } - - /// - public int[] Dimensions { get; } - - /// - public int Count => Dimensions.NumberOfElements(); - - /// - /// Returns a new empty array. - /// - /// Empty array. - public static Array Empty() - { - return new Array(System.Array.Empty()); - } - - public virtual double[] ConvertToDoubleArray() - { - return null; - } - - public virtual Complex[] ConvertToComplexArray() - { - return null; - } - - /// - public bool IsEmpty => Dimensions.Length == 0; - } -} \ No newline at end of file diff --git a/MatFileHandler/Hdf/CellArray.cs b/MatFileHandler/Hdf/CellArray.cs deleted file mode 100644 index ed893c6..0000000 --- a/MatFileHandler/Hdf/CellArray.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Collections.Generic; -using System.Linq; - -namespace MatFileHandler.Hdf -{ - internal class CellArray : Array, ICellArray - { - public CellArray(int[] dimensions, IEnumerable elements) - : base(dimensions) - { - Data = elements.ToArray(); - } - - /// - public IArray[] Data { get; } - - /// - public IArray this[params int[] indices] - { - get => Data[Dimensions.DimFlatten(indices)]; - set => Data[Dimensions.DimFlatten(indices)] = value; - } - } -} \ No newline at end of file diff --git a/MatFileHandler/Hdf/CharArray.cs b/MatFileHandler/Hdf/CharArray.cs deleted file mode 100644 index 1f60ca8..0000000 --- a/MatFileHandler/Hdf/CharArray.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using System.Linq; -using System.Numerics; - -namespace MatFileHandler.Hdf -{ - internal class CharArray : Array, ICharArray - { - public CharArray(int[] dimensions, string data) - : base(dimensions) - { - StringData = data; - } - - public override double[] ConvertToDoubleArray() - { - return Data.Select(Convert.ToDouble).ToArray(); - } - - public override Complex[] ConvertToComplexArray() - { - return ConvertToDoubleArray().Select(x => new Complex(x, 0.0)).ToArray(); - } - - public char[] Data => StringData.ToCharArray(); - - public char this[params int[] list] - { - get => StringData[Dimensions.DimFlatten(list)]; - set { - var chars = StringData.ToCharArray(); - chars[Dimensions.DimFlatten(list)] = value; - StringData = chars.ToString(); - } - } - - public string String => StringData; - - private string StringData { get; set; } - } -} \ No newline at end of file diff --git a/MatFileHandler/Hdf/NumericalArrayOf.cs b/MatFileHandler/Hdf/NumericalArrayOf.cs deleted file mode 100644 index 34a2343..0000000 --- a/MatFileHandler/Hdf/NumericalArrayOf.cs +++ /dev/null @@ -1,97 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Numerics; - -namespace MatFileHandler.Hdf -{ - /// - /// A numerical array. - /// - /// Element type. - internal class NumericalArrayOf : Array, IArrayOf - where T : struct - { - /// - /// Initializes a new instance of the class. - /// - /// Dimensions of the array. - /// Array name. - /// Array contents. - public NumericalArrayOf(int[] dimensions, T[] data) - : base(dimensions) - { - Data = data; - } - - /// - public T[] Data { get; } - - /// - public T this[params int[] list] - { - get => Data[Dimensions.DimFlatten(list)]; - set => Data[Dimensions.DimFlatten(list)] = value; - } - - /// - /// Tries to convert the array to an array of Double values. - /// - /// Array of values of the array, converted to Double, or null if the conversion is not possible. - public override double[] ConvertToDoubleArray() - { - return Data as double[] ?? Data.Select(x => Convert.ToDouble((object)x)).ToArray(); - } - - /// - /// Tries to convert the array to an array of Complex values. - /// - /// Array of values of the array, converted to Complex, or null if the conversion is not possible. - public override Complex[] ConvertToComplexArray() - { - if (Data is Complex[]) - { - return Data as Complex[]; - } - if (Data is ComplexOf[]) - { - return ConvertToComplex(Data as ComplexOf[]); - } - if (Data is ComplexOf[]) - { - return ConvertToComplex(Data as ComplexOf[]); - } - if (Data is ComplexOf[]) - { - return ConvertToComplex(Data as ComplexOf[]); - } - if (Data is ComplexOf[]) - { - return ConvertToComplex(Data as ComplexOf[]); - } - if (Data is ComplexOf[]) - { - return ConvertToComplex(Data as ComplexOf[]); - } - if (Data is ComplexOf[]) - { - return ConvertToComplex(Data as ComplexOf[]); - } - if (Data is ComplexOf[]) - { - return ConvertToComplex(Data as ComplexOf[]); - } - if (Data is ComplexOf[]) - { - return ConvertToComplex(Data as ComplexOf[]); - } - return ConvertToDoubleArray().Select(x => new Complex(x, 0.0)).ToArray(); - } - - private static Complex[] ConvertToComplex(IEnumerable> array) - where TS : struct - { - return array.Select(x => new Complex(Convert.ToDouble(x.Real), Convert.ToDouble(x.Imaginary))).ToArray(); - } - } -} \ No newline at end of file diff --git a/MatFileHandler/Hdf/SparseArrayOf.cs b/MatFileHandler/Hdf/SparseArrayOf.cs deleted file mode 100644 index 0600106..0000000 --- a/MatFileHandler/Hdf/SparseArrayOf.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Numerics; -using System.Text; - -namespace MatFileHandler.Hdf -{ - /// - /// Sparse array. - /// - /// Element type. - /// Possible values of T: Double, Complex, Boolean. - internal class SparseArrayOf : Array, ISparseArrayOf - where T : struct - { - /// - /// Initializes a new instance of the class. - /// - /// Dimensions of the array. - /// Array contents. - public SparseArrayOf( - int[] dimensions, - Dictionary<(int, int), T> data) - : base(dimensions) - { - DataDictionary = data; - } - - /// - T[] IArrayOf.Data => - Enumerable.Range(0, Dimensions[0] * Dimensions[1]) - .Select(i => this[i]) - .ToArray(); - - /// - public IReadOnlyDictionary<(int, int), T> Data => DataDictionary; - - private Dictionary<(int, int), T> DataDictionary { get; } - - /// - public T this[params int[] list] - { - get - { - var rowAndColumn = GetRowAndColumn(list); - return DataDictionary.ContainsKey(rowAndColumn) ? DataDictionary[rowAndColumn] : default(T); - } - set => DataDictionary[GetRowAndColumn(list)] = value; - } - - /// - /// Tries to convert the array to an array of Double values. - /// - /// Array of values of the array, converted to Double, or null if the conversion is not possible. - public override double[] ConvertToDoubleArray() - { - var data = ((IArrayOf)this).Data; - return data as double[] ?? data.Select(x => Convert.ToDouble(x)).ToArray(); - } - - /// - /// Tries to convert the array to an array of Complex values. - /// - /// Array of values of the array, converted to Complex, or null if the conversion is not possible. - public override Complex[] ConvertToComplexArray() - { - var data = ((IArrayOf)this).Data; - return data as Complex[] ?? ConvertToDoubleArray().Select(x => new Complex(x, 0.0)).ToArray(); - } - - private (int row, int column) GetRowAndColumn(int[] indices) - { - switch (indices.Length) - { - case 1: - return (indices[0] % Dimensions[0], indices[0] / Dimensions[0]); - case 2: - return (indices[0], indices[1]); - default: - throw new NotSupportedException("Invalid index for sparse array."); - } - } - } -} diff --git a/MatFileHandler/Hdf/StructureArray.cs b/MatFileHandler/Hdf/StructureArray.cs deleted file mode 100644 index 057e0c1..0000000 --- a/MatFileHandler/Hdf/StructureArray.cs +++ /dev/null @@ -1,140 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; - -namespace MatFileHandler.Hdf -{ - internal class StructureArray : Array, IStructureArray - { - public StructureArray( - int[] dimensions, - Dictionary> fields) - : base(dimensions) - { - Fields = fields; - } - - /// - public IEnumerable FieldNames => Fields.Keys; - - /// - /// Gets null: not implemented. - /// - public IReadOnlyDictionary[] Data => null; - - /// - /// Gets a dictionary that maps field names to lists of values. - /// - internal Dictionary> Fields { get; } - - /// - public IArray this[string field, params int[] list] - { - get => Fields[field][Dimensions.DimFlatten(list)]; - set => Fields[field][Dimensions.DimFlatten(list)] = value; - } - - /// - IReadOnlyDictionary IArrayOf>.this[params int[] list] - { - get => ExtractStructure(Dimensions.DimFlatten(list)); - set => throw new NotSupportedException( - "Cannot set structure elements via this[params int[]] indexer. Use this[string, int[]] instead."); - } - - private IReadOnlyDictionary ExtractStructure(int i) - { - return new HdfStructureArrayElement(this, i); - } - - /// - /// Provides access to an element of a structure array by fields. - /// - internal class HdfStructureArrayElement : IReadOnlyDictionary - { - /// - /// Initializes a new instance of the class. - /// - /// Parent structure array. - /// Index in the structure array. - internal HdfStructureArrayElement(StructureArray parent, int index) - { - Parent = parent; - Index = index; - } - - /// - /// Gets the number of fields. - /// - public int Count => Parent.Fields.Count; - - /// - /// Gets a list of all fields. - /// - public IEnumerable Keys => Parent.Fields.Keys; - - /// - /// Gets a list of all values. - /// - public IEnumerable Values => Parent.Fields.Values.Select(array => array[Index]); - - private StructureArray Parent { get; } - - private int Index { get; } - - /// - /// Gets the value of a given field. - /// - /// Field name. - /// The corresponding value. - public IArray this[string key] => Parent.Fields[key][Index]; - - /// - /// Enumerates fieldstructure/value pairs of the dictionary. - /// - /// All field/value pairs in the structure. - public IEnumerator> GetEnumerator() - { - foreach (var field in Parent.Fields) - { - yield return new KeyValuePair(field.Key, field.Value[Index]); - } - } - - /// - /// Enumerates field/value pairs of the structure. - /// - /// All field/value pairs in the structure. - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - /// - /// Checks if the structure has a given field. - /// - /// Field name - /// True iff the structure has a given field. - public bool ContainsKey(string key) => Parent.Fields.ContainsKey(key); - - /// - /// Tries to get the value of a given field. - /// - /// Field name. - /// Value (or null if the field is not present). - /// Success status of the query. - public bool TryGetValue(string key, out IArray value) - { - var success = Parent.Fields.TryGetValue(key, out var array); - if (!success) - { - value = default(IArray); - return false; - } - value = array[Index]; - return true; - } - } - } -} \ No newline at end of file diff --git a/MatFileHandler/HdfFileReader.cs b/MatFileHandler/HdfFileReader.cs index 7ceaa77..312bb41 100644 --- a/MatFileHandler/HdfFileReader.cs +++ b/MatFileHandler/HdfFileReader.cs @@ -186,15 +186,17 @@ namespace MatFileHandler } } - return new CellArray(dims, elements); + return new MatCellArray(dims, elements); } private static IArray ReadCharArray(Dataset dataset, int[] dims) { var storageSize = dataset.GetStorageSize(); var data = ReadDataset(dataset, Hdf.Type.NativeUInt16, storageSize); + var uInt16Data = new ushort[data.Length / sizeof(ushort)]; + Buffer.BlockCopy(data, 0, uInt16Data, 0, data.Length); var str = Encoding.Unicode.GetString(data); - return new CharArray(dims, str); + return new MatCharArrayOf(dims, uInt16Data, str); } private static (T[] real, T[] imaginary) ReadComplexData( @@ -226,7 +228,7 @@ namespace MatFileHandler switch (arrayType) { case MatlabClass.MEmpty: - return Hdf.Array.Empty(); + return MatArray.Empty(); case MatlabClass.MLogical: return ReadNumericalArray(dataset, dims, arrayType); case MatlabClass.MChar: @@ -321,7 +323,7 @@ namespace MatFileHandler switch (arrayType) { case MatlabClass.MEmpty: - return Hdf.Array.Empty(); + return MatArray.Empty(); case MatlabClass.MLogical: return ReadSparseArray(group.Id, arrayType); case MatlabClass.MInt8: @@ -390,7 +392,7 @@ namespace MatFileHandler convertedRealData as double[], convertedImaginaryData as double[]) .ToArray(); - return new NumericalArrayOf(dims, complexData); + return new MatNumericalArrayOf(dims, complexData); } else { @@ -399,7 +401,7 @@ namespace MatFileHandler convertedRealData, convertedImaginaryData) .ToArray(); - return new NumericalArrayOf>(dims, complexData); + return new MatNumericalArrayOf>(dims, complexData); } } @@ -410,7 +412,7 @@ namespace MatFileHandler var data = ReadDataset(dataset, H5tTypeFromHdfMatlabClass(arrayType), dataSize); var convertedData = ConvertDataToProperType(data, arrayType); - return new NumericalArrayOf(dims, convertedData); + return new MatNumericalArrayOf(dims, convertedData); } private static IArray ReadSparseArray(long groupId, MatlabClass arrayType) @@ -469,7 +471,7 @@ namespace MatFileHandler rowIndex, columnIndex, j => complexData[j]); - return new SparseArrayOf(dims, complexDataDictionary); + return new MatSparseArrayOf(dims, complexDataDictionary); } else { @@ -483,7 +485,7 @@ namespace MatFileHandler rowIndex, columnIndex, j => complexData[j]); - return new SparseArrayOf>(dims, complexDataDictionary); + return new MatSparseArrayOf>(dims, complexDataDictionary); } } @@ -496,7 +498,7 @@ namespace MatFileHandler var elements = ConvertDataToProperType(d, arrayType); var dataDictionary = DataExtraction.ConvertMatlabSparseToDictionary(rowIndex, columnIndex, j => elements[j]); - return new SparseArrayOf(dims, dataDictionary); + return new MatSparseArrayOf(dims, dataDictionary); } } } @@ -547,7 +549,7 @@ namespace MatFileHandler } } - return new StructureArray(dimensions, dictionary); + return new MatStructureArray(dimensions, dictionary); } } else diff --git a/MatFileHandler/MatCellArray.cs b/MatFileHandler/MatCellArray.cs index 3f0fba3..4a380c4 100755 --- a/MatFileHandler/MatCellArray.cs +++ b/MatFileHandler/MatCellArray.cs @@ -13,11 +13,9 @@ namespace MatFileHandler /// /// Initializes a new instance of the class. /// - /// Array properties. /// Dimensions of the array. - /// Array name. /// Array elements. - public MatCellArray(ArrayFlags flags, int[] dimensions, string name, IEnumerable elements) + public MatCellArray(int[] dimensions, IEnumerable elements) : base(dimensions) { Data = elements.ToArray(); diff --git a/MatFileHandler/MatFileHdfReader.cs b/MatFileHandler/MatFileHdfReader.cs index d2d6036..8b6642c 100644 --- a/MatFileHandler/MatFileHdfReader.cs +++ b/MatFileHandler/MatFileHdfReader.cs @@ -1,7 +1,7 @@ -using HDF.PInvoke; -using System; +using System; using System.IO; using System.Runtime.InteropServices; +using HDF.PInvoke; namespace MatFileHandler {