diff --git a/MatFileHandler/DataElementReader.cs b/MatFileHandler/DataElementReader.cs
index 8a4ae9c..b05406e 100755
--- a/MatFileHandler/DataElementReader.cs
+++ b/MatFileHandler/DataElementReader.cs
@@ -30,9 +30,15 @@ namespace MatFileHandler
///
/// Input reader.
/// Data element.
- public DataElement Read(BinaryReader reader)
+ public DataElement? Read(BinaryReader reader)
{
- var (dataReader, tag) = ReadTag(reader);
+ var maybeTagPair = ReadTag(reader);
+ if (maybeTagPair is not { } tagPair)
+ {
+ return null;
+ }
+
+ var (dataReader, tag) = tagPair;
var result = tag.Type switch
{
@@ -167,9 +173,31 @@ namespace MatFileHandler
};
}
- private static (BinaryReader reader, Tag tag) ReadTag(BinaryReader reader)
+ private static int? TryReadInt32(BinaryReader reader)
{
- var type = reader.ReadInt32();
+ var buffer = new byte[4];
+ var position = 0;
+ while (position < 4)
+ {
+ var actually = reader.BaseStream.Read(buffer, position, 4 - position);
+ if (actually == 0)
+ {
+ return null;
+ }
+ position += actually;
+ }
+
+ return BitConverter.ToInt32(buffer, 0);
+ }
+
+ private static (BinaryReader reader, Tag tag)? ReadTag(BinaryReader reader)
+ {
+ var maybeType = TryReadInt32(reader);
+ if (maybeType is not int type)
+ {
+ return null;
+ }
+
var typeHi = type >> 16;
if (typeHi == 0)
{
@@ -214,7 +242,7 @@ namespace MatFileHandler
var classNameElement = Read(reader) as MiNum ??
throw new HandlerException("Unexpected type in class name.");
var className = ReadName(classNameElement);
- var dataElement = Read(reader);
+ var dataElement = Read(reader) ?? throw new HandlerException("Missing opaque data element.");
var data = ReadData(dataElement);
if (data is MatNumericalArrayOf linkElement)
{
@@ -246,7 +274,7 @@ namespace MatFileHandler
throw new HandlerException("Unexpected type in row indices of a sparse array.");
var columnIndex = Read(reader) as MiNum ??
throw new HandlerException("Unexpected type in column indices of a sparse array.");
- var data = Read(reader);
+ var data = Read(reader) ?? throw new HandlerException("Missing sparse array data.");
if (sparseArrayFlags.ArrayFlags.Variable.HasFlag(Variable.IsLogical))
{
return DataElementConverter.ConvertToMatSparseArrayOf(
@@ -260,7 +288,7 @@ namespace MatFileHandler
if (sparseArrayFlags.ArrayFlags.Variable.HasFlag(Variable.IsComplex))
{
- var imaginaryData = Read(reader);
+ var imaginaryData = Read(reader) ?? throw new HandlerException("Missing imaginary part of sparse array data.");
return DataElementConverter.ConvertToMatSparseArrayOfComplex(
sparseArrayFlags,
dimensions,
@@ -327,7 +355,7 @@ namespace MatFileHandler
using (var positionTrackingStream = new PositionTrackingStream(bufferedStream))
using (var innerReader = new BinaryReader(positionTrackingStream))
{
- element = Read(innerReader);
+ element = Read(innerReader) ?? throw new HandlerException("Missing compressed data.");
}
if (substream.Position != substream.Length)
@@ -350,7 +378,7 @@ namespace MatFileHandler
return MatArray.Empty();
}
- var element1 = Read(reader);
+ var element1 = Read(reader) ?? throw new HandlerException("Missing matrix data.");
var flags = ReadArrayFlags(element1);
if (flags.Class == ArrayType.MxOpaque)
{
@@ -372,12 +400,12 @@ namespace MatFileHandler
return ContinueReadingSparseArray(reader, element1, dimensions, name);
}
- var element4 = Read(reader);
+ var element4 = Read(reader) ?? throw new HandlerException("Missing matrix data.");
var data = ReadData(element4);
DataElement? imaginaryData = null;
if (flags.Variable.HasFlag(Variable.IsComplex))
{
- var element5 = Read(reader);
+ var element5 = Read(reader) ?? throw new HandlerException("Missing complex matrix data.");
imaginaryData = ReadData(element5);
}
diff --git a/MatFileHandler/MatFileReader.cs b/MatFileHandler/MatFileReader.cs
index af48d17..6c9e5d5 100755
--- a/MatFileHandler/MatFileReader.cs
+++ b/MatFileHandler/MatFileReader.cs
@@ -48,26 +48,24 @@ namespace MatFileHandler
var dataElementReader = new DataElementReader(subsystemData);
while (true)
{
- try
- {
- var position = reader.BaseStream.Position;
- var dataElement = dataElementReader.Read(reader);
- if (position == subsystemDataOffset)
- {
- var subsystemDataElement = dataElement as IArrayOf
- ?? throw new HandlerException("Cannot parse subsystem data element.");
- var newSubsystemData = ReadSubsystemData(subsystemDataElement.Data, subsystemData);
- subsystemData.Set(newSubsystemData);
- }
- else
- {
- variables.Add(new RawVariable(position, dataElement));
- }
- }
- catch (EndOfStreamException)
+ var position = reader.BaseStream.Position;
+ var dataElement = dataElementReader.Read(reader);
+ if (dataElement is null)
{
break;
}
+
+ if (position == subsystemDataOffset)
+ {
+ var subsystemDataElement = dataElement as IArrayOf
+ ?? throw new HandlerException("Cannot parse subsystem data element.");
+ var newSubsystemData = ReadSubsystemData(subsystemDataElement.Data, subsystemData);
+ subsystemData.Set(newSubsystemData);
+ }
+ else
+ {
+ variables.Add(new RawVariable(position, dataElement));
+ }
}
return variables;