diff --git a/MatFileHandler.Tests/ArrayHandlingTests.cs b/MatFileHandler.Tests/ArrayHandlingTests.cs
index f15599e..7ac644b 100755
--- a/MatFileHandler.Tests/ArrayHandlingTests.cs
+++ b/MatFileHandler.Tests/ArrayHandlingTests.cs
@@ -10,8 +10,11 @@ namespace MatFileHandler.Tests
///
/// Tests of Matlab array manipulation.
///
- public class ArrayHandlingTests : IDisposable
+ public sealed class ArrayHandlingTests : IDisposable
{
+ ///
+ /// Setup for array handling tests.
+ ///
public ArrayHandlingTests()
{
Builder = new DataBuilder();
@@ -108,7 +111,7 @@ namespace MatFileHandler.Tests
var file = Builder.NewFile(new List());
Assert.NotNull(file);
}
-
+
private static void TestCreateArrayOf()
where T : struct
{
@@ -116,8 +119,12 @@ namespace MatFileHandler.Tests
Assert.NotNull(array);
}
+ ///
+ /// Cleanup.
+ ///
public void Dispose()
{
+
}
}
}
\ No newline at end of file
diff --git a/MatFileHandler.Tests/MatFileReaderTests.cs b/MatFileHandler.Tests/MatFileReaderTests.cs
index 8645b82..a06ad71 100755
--- a/MatFileHandler.Tests/MatFileReaderTests.cs
+++ b/MatFileHandler.Tests/MatFileReaderTests.cs
@@ -164,6 +164,23 @@ namespace MatFileHandler.Tests
Assert.Null(array.ConvertToComplexArray());
}
+ ///
+ /// Test reading an enumeration.
+ ///
+ [Fact]
+ public void TestEnum()
+ {
+ var matFile = GetTests("good")["enum"];
+ var days = matFile["days"].Value;
+ var enumeration = new EnumAdapter(days);
+ Assert.Equal(5, enumeration.Values.Count);
+ Assert.Equal("Wednesday", enumeration.ValueNames[enumeration.Values[0]]);
+ Assert.Equal("Saturday", enumeration.ValueNames[enumeration.Values[1]]);
+ Assert.Equal("Monday", enumeration.ValueNames[enumeration.Values[2]]);
+ Assert.Equal("Wednesday", enumeration.ValueNames[enumeration.Values[3]]);
+ Assert.Equal("Saturday", enumeration.ValueNames[enumeration.Values[4]]);
+ }
+
///
/// Test reading a structure array.
///
@@ -487,6 +504,9 @@ namespace MatFileHandler.Tests
Assert.Null(d0);
}
+ ///
+ /// Test 3-dimensional arrays.
+ ///
[Fact]
public void Test_3DArrays()
{
@@ -518,7 +538,10 @@ namespace MatFileHandler.Tests
Assert.Equal(expected, obj.ConvertToMultidimensionalDoubleArray());
Assert.Null(obj.ConvertTo2dDoubleArray());
}
-
+
+ ///
+ /// Test four-dimensional arrays.
+ ///
[Fact]
public void Test_4DArrays()
{
diff --git a/MatFileHandler.Tests/test-data/good/enum.mat b/MatFileHandler.Tests/test-data/good/enum.mat
new file mode 100644
index 0000000..8450715
Binary files /dev/null and b/MatFileHandler.Tests/test-data/good/enum.mat differ
diff --git a/MatFileHandler/DataElementReader.cs b/MatFileHandler/DataElementReader.cs
index a116c80..c5e2679 100755
--- a/MatFileHandler/DataElementReader.cs
+++ b/MatFileHandler/DataElementReader.cs
@@ -258,7 +258,7 @@ namespace MatFileHandler
}
else
{
- return new Opaque(name, typeDescription, className, new int[] { }, data);
+ return new Opaque(name, typeDescription, className, new int[] { }, data, subsystemData);
}
}
diff --git a/MatFileHandler/EnumAdapter.cs b/MatFileHandler/EnumAdapter.cs
new file mode 100644
index 0000000..ada3cba
--- /dev/null
+++ b/MatFileHandler/EnumAdapter.cs
@@ -0,0 +1,60 @@
+// Copyright 2017-2018 Alexander Luzgarev
+
+namespace MatFileHandler
+{
+ ///
+ /// A better interface for using enum adapter.
+ ///
+ public class EnumAdapter
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Source enum object.
+ public EnumAdapter(IArray array)
+ {
+ var matObject = array as Opaque;
+ if (matObject?.RawData is not IStructureArray rawData)
+ {
+ throw new HandlerException("Cannot extract data for the enum adapter.");
+ }
+
+ if (rawData["ValueNames"] is not IArrayOf valueNamesData)
+ {
+ throw new HandlerException("Cannot extract data for the enum adapter.");
+ }
+
+ var numberOfNames = valueNamesData.Count;
+ var valueNames = new string[numberOfNames];
+ var names = matObject.SubsystemData.FieldNames;
+ for (var i = 0; i < numberOfNames; i++)
+ {
+ valueNames[i] = names[valueNamesData[i] - 1];
+ }
+
+ if (rawData["ValueIndices"] is not IArrayOf valueIndices)
+ {
+ throw new HandlerException("Cannot extract data for the enum adapter.");
+ }
+
+ ClassName = matObject.ClassName;
+ ValueNames = valueNames;
+ Values = valueIndices;
+ }
+
+ ///
+ /// Gets name of the enumeration class.
+ ///
+ public string ClassName { get; }
+
+ ///
+ /// Gets names of the enumeration values.
+ ///
+ public string[] ValueNames { get; }
+
+ ///
+ /// Gets indices of values stored in the variable.
+ ///
+ public IArrayOf Values { get; }
+ }
+}
\ No newline at end of file
diff --git a/MatFileHandler/Opaque.cs b/MatFileHandler/Opaque.cs
index 9ce69b7..ba5711a 100644
--- a/MatFileHandler/Opaque.cs
+++ b/MatFileHandler/Opaque.cs
@@ -26,12 +26,14 @@ namespace MatFileHandler
/// Class name.
/// Dimensions of the object.
/// Raw object's data.
- public Opaque(string name, string typeDescription, string className, int[] dimensions, DataElement rawData)
+ /// Subsystem data.
+ public Opaque(string name, string typeDescription, string className, int[] dimensions, DataElement rawData, SubsystemData subsystemData)
: base(new ArrayFlags(ArrayType.MxOpaque, 0), dimensions, name)
{
TypeDescription = typeDescription ?? throw new ArgumentNullException(nameof(typeDescription));
ClassName = className ?? throw new ArgumentNullException(nameof(className));
RawData = rawData ?? throw new ArgumentNullException(nameof(rawData));
+ SubsystemData = subsystemData ?? throw new ArgumentNullException(nameof(subsystemData));
}
///
@@ -49,6 +51,11 @@ namespace MatFileHandler
///
public string TypeDescription { get; }
+ ///
+ /// Gets subsystem data.
+ ///
+ public SubsystemData SubsystemData { get; }
+
///
public override Complex[]? ConvertToComplexArray() => null;
diff --git a/MatFileHandler/OpaqueLink.cs b/MatFileHandler/OpaqueLink.cs
index da69fc1..003b4dc 100644
--- a/MatFileHandler/OpaqueLink.cs
+++ b/MatFileHandler/OpaqueLink.cs
@@ -12,8 +12,6 @@ namespace MatFileHandler
///
internal class OpaqueLink : Opaque, IMatObject
{
- private readonly SubsystemData subsystemData;
-
///
/// Initializes a new instance of the class.
///
@@ -34,11 +32,10 @@ namespace MatFileHandler
int[] indexToObjectId,
int classIndex,
SubsystemData subsystemData)
- : base(name, typeDescription, className, dimensions, data)
+ : base(name, typeDescription, className, dimensions, data, subsystemData)
{
IndexToObjectId = indexToObjectId ?? throw new ArgumentNullException(nameof(indexToObjectId));
ClassIndex = classIndex;
- this.subsystemData = subsystemData ?? throw new ArgumentNullException(nameof(subsystemData));
}
///
@@ -74,9 +71,9 @@ namespace MatFileHandler
///
/// Gets name of this object's class.
///
- public override string ClassName => subsystemData.ClassInformation[ClassIndex].Name;
+ public override string ClassName => SubsystemData.ClassInformation[ClassIndex].Name;
- private string[] FieldNamesArray => subsystemData.ClassInformation[ClassIndex].FieldNames.ToArray();
+ private string[] FieldNamesArray => SubsystemData.ClassInformation[ClassIndex].FieldNames.ToArray();
///
public IArray this[string field, params int[] list]
@@ -108,7 +105,7 @@ namespace MatFileHandler
private bool TryGetValue(string field, out IArray? output, params int[] list)
{
var index = Dimensions.DimFlatten(list);
- var maybeFieldIndex = subsystemData.ClassInformation[ClassIndex].FindField(field);
+ var maybeFieldIndex = SubsystemData.ClassInformation[ClassIndex].FindField(field);
if (!(maybeFieldIndex is int fieldIndex))
{
output = default;
@@ -122,9 +119,9 @@ namespace MatFileHandler
}
var objectId = IndexToObjectId[index];
- var objectInfo = subsystemData.ObjectInformation[objectId];
+ var objectInfo = SubsystemData.ObjectInformation[objectId];
var fieldId = objectInfo.FieldLinks[fieldIndex];
- output = subsystemData.Data[fieldId];
+ output = SubsystemData.Data[fieldId];
return true;
}
diff --git a/MatFileHandler/SubsystemData.cs b/MatFileHandler/SubsystemData.cs
index f14ffae..fe1947e 100644
--- a/MatFileHandler/SubsystemData.cs
+++ b/MatFileHandler/SubsystemData.cs
@@ -29,15 +29,18 @@ namespace MatFileHandler
///
/// Information about the classes.
/// Information about the objects.
+ /// Field names.
/// Field values.
public SubsystemData(
Dictionary classInformation,
Dictionary objectInformation,
+ string[] fieldNames,
Dictionary data)
{
_realData = new RealSubsystemData(
classInformation,
objectInformation,
+ fieldNames,
data);
}
@@ -59,6 +62,12 @@ namespace MatFileHandler
public Dictionary ObjectInformation =>
_realData?.ObjectInformation ?? throw new HandlerException("Subsystem data missing.");
+ ///
+ /// Gets field names.
+ ///
+ public string[] FieldNames =>
+ _realData?.FieldNames ?? throw new HandlerException("Subsystem data missing.");
+
///
/// Initialize this object from another object.
/// This ugly hack allows us to read the opaque objects and store references to
@@ -71,6 +80,7 @@ namespace MatFileHandler
_realData = new RealSubsystemData(
data.ClassInformation,
data.ObjectInformation,
+ data.FieldNames,
data.Data);
}
@@ -147,14 +157,17 @@ namespace MatFileHandler
///
/// Class information.
/// Object information.
+ /// Field names.
/// Data.
public RealSubsystemData(
Dictionary classInformation,
Dictionary objectInformation,
+ string[] fieldNames,
IReadOnlyDictionary data)
{
ClassInformation = classInformation ?? throw new ArgumentNullException(nameof(classInformation));
ObjectInformation = objectInformation ?? throw new ArgumentNullException(nameof(objectInformation));
+ FieldNames = fieldNames;
Data = data ?? throw new ArgumentNullException(nameof(data));
}
@@ -172,6 +185,11 @@ namespace MatFileHandler
/// Gets information about all the objects occurring in the file.
///
public Dictionary ObjectInformation { get; }
+
+ ///
+ /// Gets field names.
+ ///
+ public string[] FieldNames { get; }
}
}
}
\ No newline at end of file
diff --git a/MatFileHandler/SubsystemDataReader.cs b/MatFileHandler/SubsystemDataReader.cs
index 39ee74b..b6141d8 100644
--- a/MatFileHandler/SubsystemDataReader.cs
+++ b/MatFileHandler/SubsystemDataReader.cs
@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
@@ -58,7 +59,7 @@ namespace MatFileHandler
data[i] = TransformOpaqueData(opaqueData[i + 2], subsystemData);
}
- return new SubsystemData(classInformation, objectInformation, data);
+ return new SubsystemData(classInformation, objectInformation, fieldNames, data);
}
private static Dictionary> ReadObjectPositionsToValues(byte[] info, int[] offsets, int numberOfObjectPositions)
@@ -303,20 +304,15 @@ namespace MatFileHandler
{
var next = BitConverter.ToInt32(bytes, position);
position += 4;
- if (next == 0)
+ if (next == bytes.Length)
{
- if (position % 8 != 0)
- {
- position += 4;
- }
-
break;
}
offsets.Add(next);
}
- return (offsets.ToArray(), position);
+ return (offsets.ToArray(), 40);
}
private static IArray TransformOpaqueData(IArray array, SubsystemData subsystemData)