diff --git a/MatFileHandler/ArrayFlags.cs b/MatFileHandler/ArrayFlags.cs index 4167e9d..21e6db2 100755 --- a/MatFileHandler/ArrayFlags.cs +++ b/MatFileHandler/ArrayFlags.cs @@ -138,20 +138,4 @@ namespace MatFileHandler Variable = variable; } } - - /// - /// Sparse array properties. - /// - internal struct SparseArrayFlags - { - /// - /// Usual array properties. - /// - public ArrayFlags ArrayFlags; - - /// - /// Maximal number of non-zero elements. - /// - public uint NzMax; - } } \ No newline at end of file diff --git a/MatFileHandler/DataBuilder.cs b/MatFileHandler/DataBuilder.cs index 88042b1..a0c692a 100755 --- a/MatFileHandler/DataBuilder.cs +++ b/MatFileHandler/DataBuilder.cs @@ -28,9 +28,7 @@ namespace MatFileHandler where T : struct { return new MatNumericalArrayOf( - GetStandardFlags(), dimensions, - string.Empty, new T[dimensions.NumberOfElements()]); } @@ -54,7 +52,7 @@ namespace MatFileHandler { throw new ArgumentException("Data size does not match the specified dimensions", "data"); } - return new MatNumericalArrayOf(GetStandardFlags(), dimensions, string.Empty, data); + return new MatNumericalArrayOf(dimensions, data); } /// @@ -84,7 +82,7 @@ namespace MatFileHandler { dictionary[field] = elements.ToList(); } - return new MatStructureArray(flags, dimensions, string.Empty, dictionary); + return new MatStructureArray(dimensions, dictionary); } /// @@ -107,7 +105,7 @@ namespace MatFileHandler { var flags = ConstructArrayFlags(ArrayType.MxChar); var ushortArray = contents.ToCharArray().Select(c => (ushort)c).ToArray(); - return new MatCharArrayOf(flags, dimensions, string.Empty, ushortArray, contents); + return new MatCharArrayOf(dimensions, ushortArray, contents); } /// @@ -129,9 +127,7 @@ namespace MatFileHandler where T : struct { return new MatSparseArrayOf( - GetStandardSparseArrayFlags(), dimensions, - string.Empty, new Dictionary<(int, int), T>()); } @@ -255,15 +251,5 @@ namespace MatFileHandler } return ConstructArrayFlags(ArrayType.MxObject); } - - private SparseArrayFlags GetStandardSparseArrayFlags() - { - var arrayFlags = GetStandardFlags(); - return new SparseArrayFlags - { - ArrayFlags = arrayFlags, - NzMax = 0, - }; - } } } \ No newline at end of file diff --git a/MatFileHandler/DataElementConverter.cs b/MatFileHandler/DataElementConverter.cs index d4e34b7..f8ae04d 100755 --- a/MatFileHandler/DataElementConverter.cs +++ b/MatFileHandler/DataElementConverter.cs @@ -16,18 +16,14 @@ namespace MatFileHandler /// /// Construct a complex sparse array. /// - /// Array flags. /// Array dimensions. - /// Array name. /// Row indices. /// Denotes index ranges for each column. /// Real parts of the values. /// Imaginary parts of the values. /// A constructed array. public static MatArray ConvertToMatSparseArrayOfComplex( - SparseArrayFlags flags, int[] dimensions, - string name, int[] rowIndex, int[] columnIndex, DataElement data, @@ -44,7 +40,7 @@ namespace MatFileHandler rowIndex, columnIndex, j => new Complex(realParts[j], imaginaryParts[j])); - return new MatSparseArrayOf(flags, dimensions, name, dataDictionary); + return new MatSparseArrayOf(dimensions, dataDictionary); } /// @@ -53,15 +49,13 @@ namespace MatFileHandler /// Element type (Double or Boolean). /// Array flags. /// Array dimensions. - /// Array name. /// Row indices. /// Denotes index ranges for each column. /// The values. /// A constructed array. public static MatArray ConvertToMatSparseArrayOf( - SparseArrayFlags flags, + ArrayFlags flags, int[] dimensions, - string name, int[] rowIndex, int[] columnIndex, DataElement data) @@ -76,14 +70,14 @@ namespace MatFileHandler throw new ArgumentException("Null data found.", "data"); } var elements = - ConvertDataToSparseProperType(data, flags.ArrayFlags.Variable.HasFlag(Variable.IsLogical)); + ConvertDataToSparseProperType(data, flags.Variable.HasFlag(Variable.IsLogical)); if (elements == null) { throw new HandlerException("Couldn't read sparse array."); } var dataDictionary = DataExtraction.ConvertMatlabSparseToDictionary(rowIndex, columnIndex, j => elements[j]); - return new MatSparseArrayOf(flags, dimensions, name, dataDictionary); + return new MatSparseArrayOf(dimensions, dataDictionary); } /// @@ -92,7 +86,6 @@ namespace MatFileHandler /// Element type. /// Array flags. /// Array dimensions. - /// Array name. /// Real parts of the values. /// Imaginary parts of the values. /// A constructed array. @@ -104,7 +97,6 @@ namespace MatFileHandler public static MatArray ConvertToMatNumericalArrayOf( ArrayFlags flags, int[] dimensions, - string name, DataElement realData, DataElement imaginaryData) where T : struct @@ -112,7 +104,7 @@ namespace MatFileHandler if (flags.Variable.HasFlag(Variable.IsLogical)) { var data = DataExtraction.GetDataAsUInt8(realData).ToArrayLazily().Select(x => x != 0).ToArray(); - return new MatNumericalArrayOf(flags, dimensions, name, data); + return new MatNumericalArrayOf(dimensions, data); } switch (flags.Class) { @@ -120,9 +112,9 @@ namespace MatFileHandler switch (realData) { case MiNum dataByte: - return ConvertToMatCharArray(flags, dimensions, name, dataByte); + return ConvertToMatCharArray(dimensions, dataByte); case MiNum dataUshort: - return ConvertToMatCharArray(flags, dimensions, name, dataUshort); + return ConvertToMatCharArray(dimensions, dataUshort); default: throw new NotSupportedException("Only utf8, utf16 or ushort char arrays are supported."); } @@ -146,25 +138,23 @@ namespace MatFileHandler (dataArray as double[]) .Zip(dataArray2 as double[], (x, y) => new Complex(x, y)) .ToArray(); - return new MatNumericalArrayOf(flags, dimensions, name, complexArray); + return new MatNumericalArrayOf(dimensions, complexArray); } var complexDataArray = dataArray.Zip(dataArray2, (x, y) => new ComplexOf(x, y)).ToArray(); - return new MatNumericalArrayOf>(flags, dimensions, name, complexDataArray); + return new MatNumericalArrayOf>(dimensions, complexDataArray); } - return new MatNumericalArrayOf(flags, dimensions, name, dataArray); + return new MatNumericalArrayOf(dimensions, dataArray); default: throw new NotSupportedException(); } } private static MatCharArrayOf ConvertToMatCharArray( - ArrayFlags flags, int[] dimensions, - string name, MiNum dataElement) { var data = dataElement?.Data; - return new MatCharArrayOf(flags, dimensions, name, data, Encoding.UTF8.GetString(data)); + return new MatCharArrayOf(dimensions, data, Encoding.UTF8.GetString(data)); } private static T[] ConvertDataToProperType(DataElement data, ArrayType arrayType) @@ -212,16 +202,12 @@ namespace MatFileHandler } private static MatCharArrayOf ConvertToMatCharArray( - ArrayFlags flags, int[] dimensions, - string name, MiNum dataElement) { var data = dataElement?.Data; return new MatCharArrayOf( - flags, dimensions, - name, data, new string(data.Select(x => (char)x).ToArray())); } diff --git a/MatFileHandler/DataElementReader.cs b/MatFileHandler/DataElementReader.cs index f01af12..6e070c9 100755 --- a/MatFileHandler/DataElementReader.cs +++ b/MatFileHandler/DataElementReader.cs @@ -25,59 +25,60 @@ namespace MatFileHandler this.subsystemData = subsystemData ?? throw new ArgumentNullException(nameof(subsystemData)); } + private DataElement ReadElementWithoutFlags(Tag tag, BinaryReader reader) + { + switch (tag.Type) + { + case DataType.MiInt8: + return ReadNum(tag, reader); + case DataType.MiUInt8: + case DataType.MiUtf8: + return ReadNum(tag, reader); + case DataType.MiInt16: + return ReadNum(tag, reader); + case DataType.MiUInt16: + case DataType.MiUtf16: + return ReadNum(tag, reader); + case DataType.MiInt32: + return ReadNum(tag, reader); + case DataType.MiUInt32: + return ReadNum(tag, reader); + case DataType.MiSingle: + return ReadNum(tag, reader); + case DataType.MiDouble: + return ReadNum(tag, reader); + case DataType.MiInt64: + return ReadNum(tag, reader); + case DataType.MiUInt64: + return ReadNum(tag, reader); + default: + throw new NotSupportedException("Unknown element."); + } + } + + private DataElementWithArrayFlags ReadElementWithFlags(Tag tag, BinaryReader reader) + { + switch (tag.Type) + { + case DataType.MiMatrix: + return ReadMatrix(tag, reader); + case DataType.MiCompressed: + return ReadCompressed(tag, reader); + default: + var element = ReadElementWithoutFlags(tag, reader); + return new DataElementWithArrayFlags(element); + } + } + /// /// Read a data element. /// /// Input reader. /// Data element. - public DataElement Read(BinaryReader reader) + public DataElementWithArrayFlags Read(BinaryReader reader) { var (dataReader, tag) = ReadTag(reader); - DataElement result; - switch (tag.Type) - { - case DataType.MiInt8: - result = ReadNum(tag, dataReader); - break; - case DataType.MiUInt8: - case DataType.MiUtf8: - result = ReadNum(tag, dataReader); - break; - case DataType.MiInt16: - result = ReadNum(tag, dataReader); - break; - case DataType.MiUInt16: - case DataType.MiUtf16: - result = ReadNum(tag, dataReader); - break; - case DataType.MiInt32: - result = ReadNum(tag, dataReader); - break; - case DataType.MiUInt32: - result = ReadNum(tag, dataReader); - break; - case DataType.MiSingle: - result = ReadNum(tag, dataReader); - break; - case DataType.MiDouble: - result = ReadNum(tag, dataReader); - break; - case DataType.MiInt64: - result = ReadNum(tag, dataReader); - break; - case DataType.MiUInt64: - result = ReadNum(tag, dataReader); - break; - case DataType.MiMatrix: - result = ReadMatrix(tag, dataReader); - break; - case DataType.MiCompressed: - result = ReadCompressed(tag, dataReader); - break; - default: - throw new NotSupportedException("Unknown element."); - } - + DataElementWithArrayFlags result = ReadElementWithFlags(tag, dataReader); if (tag.Type != DataType.MiCompressed) { var position = reader.BaseStream.Position; @@ -181,17 +182,13 @@ namespace MatFileHandler return new MiNum(result); } - private static SparseArrayFlags ReadSparseArrayFlags(DataElement element) + private static (ArrayFlags flags, uint nzMax) ReadSparseArrayFlags(DataElement element) { var arrayFlags = ReadArrayFlags(element); var flagData = (element as MiNum)?.Data ?? throw new HandlerException("Unexpected type in sparse array flags."); var nzMax = flagData[1]; - return new SparseArrayFlags - { - ArrayFlags = arrayFlags, - NzMax = nzMax, - }; + return (arrayFlags, nzMax); } private static (BinaryReader, Tag) ReadTag(BinaryReader reader) @@ -222,91 +219,108 @@ namespace MatFileHandler var elements = new List(); for (var i = 0; i < numberOfElements; i++) { - var element = Read(reader) as IArray; + var element = Read(reader).Element as IArray; elements.Add(element); } return new MatCellArray(flags, dimensions, name, elements); } - private DataElement ContinueReadingOpaque(BinaryReader reader) + private DataElementWithArrayFlags ContinueReadingOpaque(BinaryReader reader) { - var nameElement = Read(reader) as MiNum ?? + var nameElement = Read(reader).Element as MiNum ?? throw new HandlerException("Unexpected type in object name."); var name = ReadName(nameElement); - var anotherElement = Read(reader) as MiNum ?? + var anotherElement = Read(reader).Element as MiNum ?? throw new HandlerException("Unexpected type in object type description."); var typeDescription = ReadName(anotherElement); - var classNameElement = Read(reader) as MiNum ?? + var classNameElement = Read(reader).Element as MiNum ?? throw new HandlerException("Unexpected type in class name."); var className = ReadName(classNameElement); - var dataElement = Read(reader); + var dataElement = Read(reader).Element; var data = ReadData(dataElement); if (data is MatNumericalArrayOf linkElement) { var (dimensions, indexToObjectId, classIndex) = ParseOpaqueData(linkElement.Data); - return new OpaqueLink( - name, - typeDescription, - className, - dimensions, - data, - indexToObjectId, - classIndex, - subsystemData); + return new DataElementWithArrayFlags( + new OpaqueLink( + typeDescription, + className, + dimensions, + data, + indexToObjectId, + classIndex, + subsystemData), + default, + name); } else { - return new Opaque(name, typeDescription, className, new int[] { }, data); + return new DataElementWithArrayFlags( + new Opaque( + typeDescription, + className, + new int[] { }, + data), + default, + name); } } - private DataElement ContinueReadingSparseArray( + private DataElementWithArrayFlags ContinueReadingSparseArray( BinaryReader reader, DataElement firstElement, int[] dimensions, string name) { - var sparseArrayFlags = ReadSparseArrayFlags(firstElement); - var rowIndex = Read(reader) as MiNum ?? + var (arrayFlags, nzMax) = ReadSparseArrayFlags(firstElement); + var rowIndex = Read(reader).Element as MiNum ?? throw new HandlerException("Unexpected type in row indices of a sparse array."); - var columnIndex = Read(reader) as MiNum ?? + var columnIndex = Read(reader).Element as MiNum ?? throw new HandlerException("Unexpected type in column indices of a sparse array."); - var data = Read(reader); - if (sparseArrayFlags.ArrayFlags.Variable.HasFlag(Variable.IsLogical)) + var data = Read(reader).Element; + if (arrayFlags.Variable.HasFlag(Variable.IsLogical)) { - return DataElementConverter.ConvertToMatSparseArrayOf( - sparseArrayFlags, - dimensions, + return new DataElementWithArrayFlags( + DataElementConverter.ConvertToMatSparseArrayOf( + arrayFlags, + dimensions, + rowIndex.Data, + columnIndex.Data, + data), + arrayFlags, name, - rowIndex.Data, - columnIndex.Data, - data); + nzMax); } - if (sparseArrayFlags.ArrayFlags.Variable.HasFlag(Variable.IsComplex)) + if (arrayFlags.Variable.HasFlag(Variable.IsComplex)) { - var imaginaryData = Read(reader); - return DataElementConverter.ConvertToMatSparseArrayOfComplex( - sparseArrayFlags, - dimensions, + var imaginaryData = Read(reader).Element; + return new DataElementWithArrayFlags( + DataElementConverter.ConvertToMatSparseArrayOfComplex( + dimensions, + rowIndex.Data, + columnIndex.Data, + data, + imaginaryData), + arrayFlags, name, - rowIndex.Data, - columnIndex.Data, - data, - imaginaryData); + nzMax); } switch (data) { case MiNum _: - return DataElementConverter.ConvertToMatSparseArrayOf( - sparseArrayFlags, - dimensions, + return new DataElementWithArrayFlags( + DataElementConverter.ConvertToMatSparseArrayOf( + arrayFlags, + dimensions, + rowIndex.Data, + columnIndex.Data, + data), + arrayFlags, name, - rowIndex.Data, - columnIndex.Data, - data); + nzMax); default: throw new NotSupportedException("Only double and logical sparse arrays are supported."); } @@ -314,12 +328,10 @@ namespace MatFileHandler private DataElement ContinueReadingStructure( BinaryReader reader, - ArrayFlags flags, int[] dimensions, - string name, int fieldNameLength) { - var element = Read(reader); + var element = Read(reader).Element; var fieldNames = ReadFieldNames(element as MiNum, fieldNameLength); var fields = new Dictionary>(); foreach (var fieldName in fieldNames) @@ -332,15 +344,15 @@ namespace MatFileHandler { foreach (var fieldName in fieldNames) { - var field = Read(reader) as IArray; + var field = Read(reader).Element as IArray; fields[fieldName].Add(field); } } - return new MatStructureArray(flags, dimensions, name, fields); + return new MatStructureArray(dimensions, fields); } - private DataElement Read(Stream stream) + private DataElementWithArrayFlags Read(Stream stream) { using (var reader = new BinaryReader(stream)) { @@ -348,7 +360,7 @@ namespace MatFileHandler } } - private DataElement ReadCompressed(Tag tag, BinaryReader reader) + private DataElementWithArrayFlags ReadCompressed(Tag tag, BinaryReader reader) { reader.ReadBytes(2); var compressedData = new byte[tag.Length - 6]; @@ -367,28 +379,31 @@ namespace MatFileHandler return Read(resultStream); } - private DataElement ReadMatrix(Tag tag, BinaryReader reader) + private DataElementWithArrayFlags ReadMatrix(Tag tag, BinaryReader reader) { if (tag.Length == 0) { - return MatArray.Empty(); + return new DataElementWithArrayFlags(MatArray.Empty()); } - var element1 = Read(reader); + var element1 = Read(reader).Element; var flags = ReadArrayFlags(element1); if (flags.Class == ArrayType.MxOpaque) { return ContinueReadingOpaque(reader); } - var element2 = Read(reader) as MiNum ?? - throw new HandlerException("Unexpected type in array dimensions data."); + var element2 = + Read(reader).Element as MiNum + ?? throw new HandlerException("Unexpected type in array dimensions data."); var dimensions = ReadDimensionsArray(element2); - var element3 = Read(reader) as MiNum ?? throw new HandlerException("Unexpected type in array name."); + var element3 = + Read(reader).Element as MiNum + ?? throw new HandlerException("Unexpected type in array name."); var name = ReadName(element3); if (flags.Class == ArrayType.MxCell) { - return ContinueReadingCellArray(reader, flags, dimensions, name); + return new DataElementWithArrayFlags(ContinueReadingCellArray(reader, flags, dimensions, name)); } if (flags.Class == ArrayType.MxSparse) @@ -396,12 +411,12 @@ namespace MatFileHandler return ContinueReadingSparseArray(reader, element1, dimensions, name); } - var element4 = Read(reader); + var element4 = Read(reader).Element; var data = ReadData(element4); DataElement imaginaryData = null; if (flags.Variable.HasFlag(Variable.IsComplex)) { - var element5 = Read(reader); + var element5 = Read(reader).Element; imaginaryData = ReadData(element5); } @@ -410,7 +425,10 @@ namespace MatFileHandler var fieldNameLengthElement = data as MiNum ?? throw new HandlerException( "Unexpected type in structure field name length."); - return ContinueReadingStructure(reader, flags, dimensions, name, fieldNameLengthElement.Data[0]); + return new DataElementWithArrayFlags( + ContinueReadingStructure(reader, dimensions, fieldNameLengthElement.Data[0]), + flags, + name); } switch (flags.Class) @@ -419,103 +437,129 @@ namespace MatFileHandler switch (data) { case MiNum _: - return DataElementConverter.ConvertToMatNumericalArrayOf( + return new DataElementWithArrayFlags( + DataElementConverter.ConvertToMatNumericalArrayOf( + flags, + dimensions, + data, + imaginaryData), flags, - dimensions, - name, - data, - imaginaryData); + name); case MiNum _: - return DataElementConverter.ConvertToMatNumericalArrayOf( + return new DataElementWithArrayFlags( + DataElementConverter.ConvertToMatNumericalArrayOf( + flags, + dimensions, + data, + imaginaryData), flags, - dimensions, - name, - data, - imaginaryData); + name); default: throw new NotSupportedException( $"This type of char array ({data.GetType()}) is not supported."); } case ArrayType.MxInt8: - return DataElementConverter.ConvertToMatNumericalArrayOf( + return new DataElementWithArrayFlags( + DataElementConverter.ConvertToMatNumericalArrayOf( + flags, + dimensions, + data, + imaginaryData), flags, - dimensions, - name, - data, - imaginaryData); + name); case ArrayType.MxUInt8: if (flags.Variable.HasFlag(Variable.IsLogical)) { - return DataElementConverter.ConvertToMatNumericalArrayOf( + return new DataElementWithArrayFlags( + DataElementConverter.ConvertToMatNumericalArrayOf( + flags, + dimensions, + data, + imaginaryData), flags, - dimensions, - name, - data, - imaginaryData); + name); } - return DataElementConverter.ConvertToMatNumericalArrayOf( + return new DataElementWithArrayFlags( + DataElementConverter.ConvertToMatNumericalArrayOf( + flags, + dimensions, + data, + imaginaryData), flags, - dimensions, - name, - data, - imaginaryData); + name); case ArrayType.MxInt16: - return DataElementConverter.ConvertToMatNumericalArrayOf( + return new DataElementWithArrayFlags( + DataElementConverter.ConvertToMatNumericalArrayOf( + flags, + dimensions, + data, + imaginaryData), flags, - dimensions, - name, - data, - imaginaryData); + name); case ArrayType.MxUInt16: - return DataElementConverter.ConvertToMatNumericalArrayOf( + return new DataElementWithArrayFlags( + DataElementConverter.ConvertToMatNumericalArrayOf( + flags, + dimensions, + data, + imaginaryData), flags, - dimensions, - name, - data, - imaginaryData); + name); case ArrayType.MxInt32: - return DataElementConverter.ConvertToMatNumericalArrayOf( + return new DataElementWithArrayFlags( + DataElementConverter.ConvertToMatNumericalArrayOf( + flags, + dimensions, + data, + imaginaryData), flags, - dimensions, - name, - data, - imaginaryData); + name); case ArrayType.MxUInt32: - return DataElementConverter.ConvertToMatNumericalArrayOf( + return new DataElementWithArrayFlags( + DataElementConverter.ConvertToMatNumericalArrayOf( + flags, + dimensions, + data, + imaginaryData), flags, - dimensions, - name, - data, - imaginaryData); + name); case ArrayType.MxInt64: - return DataElementConverter.ConvertToMatNumericalArrayOf( + return new DataElementWithArrayFlags( + DataElementConverter.ConvertToMatNumericalArrayOf( + flags, + dimensions, + data, + imaginaryData), flags, - dimensions, - name, - data, - imaginaryData); + name); case ArrayType.MxUInt64: - return DataElementConverter.ConvertToMatNumericalArrayOf( + return new DataElementWithArrayFlags( + DataElementConverter.ConvertToMatNumericalArrayOf( + flags, + dimensions, + data, + imaginaryData), flags, - dimensions, - name, - data, - imaginaryData); + name); case ArrayType.MxSingle: - return DataElementConverter.ConvertToMatNumericalArrayOf( + return new DataElementWithArrayFlags( + DataElementConverter.ConvertToMatNumericalArrayOf( + flags, + dimensions, + data, + imaginaryData), flags, - dimensions, - name, - data, - imaginaryData); + name); case ArrayType.MxDouble: - return DataElementConverter.ConvertToMatNumericalArrayOf( + return new DataElementWithArrayFlags( + DataElementConverter.ConvertToMatNumericalArrayOf( + flags, + dimensions, + data, + imaginaryData), flags, - dimensions, - name, - data, - imaginaryData); + name); default: throw new HandlerException("Unknown data type."); } diff --git a/MatFileHandler/DataElementWithArrayFlags.cs b/MatFileHandler/DataElementWithArrayFlags.cs new file mode 100644 index 0000000..ce48154 --- /dev/null +++ b/MatFileHandler/DataElementWithArrayFlags.cs @@ -0,0 +1,28 @@ +namespace MatFileHandler +{ + internal class DataElementWithArrayFlags + { + public DataElementWithArrayFlags(DataElement element, ArrayFlags flags, string name, uint nzMax = 0) + { + Element = element; + Flags = flags; + Name = name; + NzMax = nzMax; + } + + public DataElementWithArrayFlags(DataElement element) + { + Element = element; + Flags = default; + Name = default; + } + + public DataElement Element { get; } + + public ArrayFlags Flags { get; } + + public string Name { get; } + + public uint NzMax { get; } + } +} \ No newline at end of file diff --git a/MatFileHandler/MatArray.cs b/MatFileHandler/MatArray.cs index b35fa50..576054e 100755 --- a/MatFileHandler/MatArray.cs +++ b/MatFileHandler/MatArray.cs @@ -12,45 +12,28 @@ namespace MatFileHandler /// /// Initializes a new instance of the class. /// - /// Array properties. /// Dimensions of the array. - /// Array name. - protected MatArray( - ArrayFlags flags, - int[] dimensions, - string name) + protected MatArray(int[] dimensions) { - Flags = flags; Dimensions = dimensions; - Name = name; } /// public int[] Dimensions { get; } - /// - /// Gets the array name. - /// - public string Name { get; } - /// public int Count => Dimensions.NumberOfElements(); /// public bool IsEmpty => Dimensions.Length == 0; - /// - /// Gets properties of the array. - /// - internal ArrayFlags Flags { get; } - /// /// Returns a new empty array. /// /// Empty array. public static MatArray Empty() { - return new MatArray(new ArrayFlags { Class = ArrayType.MxCell, Variable = 0 }, new int[] { }, string.Empty); + return new MatArray(new int[] { }); } /// diff --git a/MatFileHandler/MatCellArray.cs b/MatFileHandler/MatCellArray.cs index 8ac8973..3f0fba3 100755 --- a/MatFileHandler/MatCellArray.cs +++ b/MatFileHandler/MatCellArray.cs @@ -18,7 +18,7 @@ namespace MatFileHandler /// Array name. /// Array elements. public MatCellArray(ArrayFlags flags, int[] dimensions, string name, IEnumerable elements) - : base(flags, dimensions, name) + : base(dimensions) { Data = elements.ToArray(); } diff --git a/MatFileHandler/MatCharArrayOf.cs b/MatFileHandler/MatCharArrayOf.cs index 5a94ea0..015906f 100755 --- a/MatFileHandler/MatCharArrayOf.cs +++ b/MatFileHandler/MatCharArrayOf.cs @@ -15,13 +15,11 @@ namespace MatFileHandler /// /// Initializes a new instance of the class. /// - /// Array parameters. /// Dimensions of the array. - /// Array name. /// Raw data (UTF-8 or UTF-16). /// Contents as a string. - internal MatCharArrayOf(ArrayFlags flags, int[] dimensions, string name, T[] rawData, string stringData) - : base(flags, dimensions, name, rawData) + internal MatCharArrayOf(int[] dimensions, T[] rawData, string stringData) + : base(dimensions, rawData) { StringData = stringData; } diff --git a/MatFileHandler/MatFileLevel5Reader.cs b/MatFileHandler/MatFileLevel5Reader.cs index fc7a81e..5a70629 100644 --- a/MatFileHandler/MatFileLevel5Reader.cs +++ b/MatFileHandler/MatFileLevel5Reader.cs @@ -3,9 +3,11 @@ using System.IO; namespace MatFileHandler { + /// + /// Reader for MATLAB "Level 5" .mat files. + /// internal static class MatFileLevel5Reader { - /// /// Read a sequence of raw variables from .mat file. /// @@ -29,13 +31,13 @@ namespace MatFileHandler var dataElement = dataElementReader.Read(reader); if (position == subsystemDataOffset) { - var subsystemDataElement = dataElement as IArrayOf; + var subsystemDataElement = dataElement.Element as IArrayOf; var newSubsystemData = ReadSubsystemData(subsystemDataElement.Data, subsystemData); subsystemData.Set(newSubsystemData); } else { - variables.Add(new RawVariable(position, dataElement)); + variables.Add(new RawVariable(position, dataElement.Element, dataElement.Flags, dataElement.Name)); } } catch (EndOfStreamException) @@ -63,18 +65,17 @@ namespace MatFileHandler { var rawVariables = ReadRawVariables(reader, header.SubsystemDataOffset); var variables = new List(); - foreach (var variable in rawVariables) + foreach (var rawVariable in rawVariables) { - var array = variable.DataElement as MatArray; - if (array is null) + if (!(rawVariable.DataElement is MatArray array)) { continue; } variables.Add(new MatVariable( array, - array.Name, - array.Flags.Variable.HasFlag(Variable.IsGlobal))); + rawVariable.Name, + rawVariable.Flags.Variable.HasFlag(Variable.IsGlobal))); } return new MatFile(variables); diff --git a/MatFileHandler/MatFileReader.cs b/MatFileHandler/MatFileReader.cs index 9a1b77e..1b79b3b 100755 --- a/MatFileHandler/MatFileReader.cs +++ b/MatFileHandler/MatFileReader.cs @@ -1,7 +1,6 @@ // Copyright 2017-2018 Alexander Luzgarev using System; -using System.Collections.Generic; using System.IO; namespace MatFileHandler diff --git a/MatFileHandler/MatFileWriter.cs b/MatFileHandler/MatFileWriter.cs index 414ab39..1dd6c16 100755 --- a/MatFileHandler/MatFileWriter.cs +++ b/MatFileHandler/MatFileWriter.cs @@ -226,14 +226,14 @@ namespace MatFileHandler writer.Write(new byte[] { 0, 0, 0, 0, 0, 0 }); } - private void WriteSparseArrayFlags(BinaryWriter writer, SparseArrayFlags flags) + private void WriteSparseArrayFlags(BinaryWriter writer, ArrayFlags flags, uint nzMax) { - var flag = (byte)flags.ArrayFlags.Variable; + var flag = (byte)flags.Variable; WriteTag(writer, new Tag(DataType.MiUInt32, 8)); - writer.Write((byte)flags.ArrayFlags.Class); + writer.Write((byte)flags.Class); writer.Write(flag); writer.Write(new byte[] { 0, 0 }); - writer.Write(flags.NzMax); + writer.Write(nzMax); } private void WriteName(BinaryWriter writer, string name) @@ -373,19 +373,16 @@ namespace MatFileHandler } } - private SparseArrayFlags GetSparseArrayFlags(ISparseArrayOf array, bool isGlobal, uint nonZero) + private (ArrayFlags flags, uint nzMax) GetSparseArrayFlags(ISparseArrayOf array, bool isGlobal, uint nonZero) where T : struct { var flags = GetArrayFlags(array, isGlobal); - return new SparseArrayFlags - { - ArrayFlags = new ArrayFlags + return (new ArrayFlags { Class = ArrayType.MxSparse, Variable = flags.Variable, }, - NzMax = nonZero, - }; + nonZero); } private ArrayFlags GetCharArrayFlags(bool isGlobal) @@ -513,7 +510,8 @@ namespace MatFileHandler where T : struct, IEquatable { (var rows, var columns, var data, var nonZero) = PrepareSparseArrayData(array); - WriteSparseArrayFlags(writer, GetSparseArrayFlags(array, isGlobal, nonZero)); + var (flags, nzMax) = GetSparseArrayFlags(array, isGlobal, nonZero); + WriteSparseArrayFlags(writer, flags, nzMax); WriteDimensions(writer, array.Dimensions); WriteName(writer, name); WriteSparseArrayValues(writer, rows, columns, data); diff --git a/MatFileHandler/MatNumericalArrayOf.cs b/MatFileHandler/MatNumericalArrayOf.cs index 80bde49..a791ba2 100755 --- a/MatFileHandler/MatNumericalArrayOf.cs +++ b/MatFileHandler/MatNumericalArrayOf.cs @@ -17,12 +17,10 @@ namespace MatFileHandler /// /// Initializes a new instance of the class. /// - /// Array parameters. /// Dimensions of the array. - /// Array name. /// Array contents. - public MatNumericalArrayOf(ArrayFlags flags, int[] dimensions, string name, T[] data) - : base(flags, dimensions, name) + public MatNumericalArrayOf(int[] dimensions, T[] data) + : base(dimensions) { Data = data; } diff --git a/MatFileHandler/MatSparseArrayOf.cs b/MatFileHandler/MatSparseArrayOf.cs index db9fd5d..fd11039 100755 --- a/MatFileHandler/MatSparseArrayOf.cs +++ b/MatFileHandler/MatSparseArrayOf.cs @@ -18,16 +18,10 @@ namespace MatFileHandler /// /// Initializes a new instance of the class. /// - /// Array properties. /// Dimensions of the array. - /// Array name. /// Array contents. - public MatSparseArrayOf( - SparseArrayFlags flags, - int[] dimensions, - string name, - Dictionary<(int, int), T> data) - : base(flags.ArrayFlags, dimensions, name) + public MatSparseArrayOf(int[] dimensions, Dictionary<(int, int), T> data) + : base(dimensions) { DataDictionary = data; } diff --git a/MatFileHandler/MatStructureArray.cs b/MatFileHandler/MatStructureArray.cs index 9422d06..cf3ce64 100755 --- a/MatFileHandler/MatStructureArray.cs +++ b/MatFileHandler/MatStructureArray.cs @@ -15,16 +15,10 @@ namespace MatFileHandler /// /// Initializes a new instance of the class. /// - /// Array properties. /// Dimensions of the array. - /// Array name. /// Array contents. - public MatStructureArray( - ArrayFlags flags, - int[] dimensions, - string name, - Dictionary> fields) - : base(flags, dimensions, name) + public MatStructureArray(int[] dimensions, Dictionary> fields) + : base(dimensions) { Fields = fields; } diff --git a/MatFileHandler/Opaque.cs b/MatFileHandler/Opaque.cs index b574d22..6c60f57 100644 --- a/MatFileHandler/Opaque.cs +++ b/MatFileHandler/Opaque.cs @@ -21,13 +21,12 @@ namespace MatFileHandler /// /// Initializes a new instance of the class. /// - /// Name of the object. /// Type description. /// Class name. /// Dimensions of the object. /// Raw object's data. - public Opaque(string name, string typeDescription, string className, int[] dimensions, DataElement rawData) - : base(new ArrayFlags(ArrayType.MxOpaque, 0), dimensions, name) + public Opaque(string typeDescription, string className, int[] dimensions, DataElement rawData) + : base(dimensions) { TypeDescription = typeDescription ?? throw new ArgumentNullException(nameof(typeDescription)); ClassName = className ?? throw new ArgumentNullException(nameof(className)); diff --git a/MatFileHandler/OpaqueLink.cs b/MatFileHandler/OpaqueLink.cs index ed71d2f..c8eb3ac 100644 --- a/MatFileHandler/OpaqueLink.cs +++ b/MatFileHandler/OpaqueLink.cs @@ -17,7 +17,6 @@ namespace MatFileHandler /// /// Initializes a new instance of the class. /// - /// Name of the object. /// Description of object's class. /// Name of the object's class. /// Dimensions of the object. @@ -26,7 +25,6 @@ namespace MatFileHandler /// Index of object's class. /// Reference to global subsystem data. public OpaqueLink( - string name, string typeDescription, string className, int[] dimensions, @@ -34,7 +32,7 @@ namespace MatFileHandler int[] indexToObjectId, int classIndex, SubsystemData subsystemData) - : base(name, typeDescription, className, dimensions, data) + : base(typeDescription, className, dimensions, data) { IndexToObjectId = indexToObjectId ?? throw new ArgumentNullException(nameof(indexToObjectId)); ClassIndex = classIndex; diff --git a/MatFileHandler/RawVariable.cs b/MatFileHandler/RawVariable.cs index c384b21..b37008d 100644 --- a/MatFileHandler/RawVariable.cs +++ b/MatFileHandler/RawVariable.cs @@ -17,10 +17,12 @@ namespace MatFileHandler /// /// Offset of the variable in the source file. /// Data element parsed from the file. - internal RawVariable(long offset, DataElement dataElement) + internal RawVariable(long offset, DataElement dataElement, ArrayFlags flags, string name) { Offset = offset; DataElement = dataElement ?? throw new ArgumentNullException(nameof(dataElement)); + Flags = flags; + Name = name; } /// @@ -28,6 +30,10 @@ namespace MatFileHandler /// public DataElement DataElement { get; } + public ArrayFlags Flags { get; } + + public string Name { get; } + /// /// Gets offset of the variable in the .mat file. /// diff --git a/MatFileHandler/SubsystemDataReader.cs b/MatFileHandler/SubsystemDataReader.cs index 9799549..1fb3708 100644 --- a/MatFileHandler/SubsystemDataReader.cs +++ b/MatFileHandler/SubsystemDataReader.cs @@ -314,7 +314,6 @@ namespace MatFileHandler { var (dimensions, indexToObjectId, classIndex) = DataElementReader.ParseOpaqueData(uintArray.Data); return new OpaqueLink( - uintArray.Name, string.Empty, string.Empty, dimensions,