Detect end of stream better
This commit is contained in:
parent
1822e75fd8
commit
919014a109
@ -30,9 +30,15 @@ namespace MatFileHandler
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="reader">Input reader.</param>
|
/// <param name="reader">Input reader.</param>
|
||||||
/// <returns>Data element.</returns>
|
/// <returns>Data element.</returns>
|
||||||
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
|
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;
|
var typeHi = type >> 16;
|
||||||
if (typeHi == 0)
|
if (typeHi == 0)
|
||||||
{
|
{
|
||||||
@ -214,7 +242,7 @@ namespace MatFileHandler
|
|||||||
var classNameElement = Read(reader) as MiNum<sbyte> ??
|
var classNameElement = Read(reader) as MiNum<sbyte> ??
|
||||||
throw new HandlerException("Unexpected type in class name.");
|
throw new HandlerException("Unexpected type in class name.");
|
||||||
var className = ReadName(classNameElement);
|
var className = ReadName(classNameElement);
|
||||||
var dataElement = Read(reader);
|
var dataElement = Read(reader) ?? throw new HandlerException("Missing opaque data element.");
|
||||||
var data = ReadData(dataElement);
|
var data = ReadData(dataElement);
|
||||||
if (data is MatNumericalArrayOf<uint> linkElement)
|
if (data is MatNumericalArrayOf<uint> linkElement)
|
||||||
{
|
{
|
||||||
@ -246,7 +274,7 @@ namespace MatFileHandler
|
|||||||
throw new HandlerException("Unexpected type in row indices of a sparse array.");
|
throw new HandlerException("Unexpected type in row indices of a sparse array.");
|
||||||
var columnIndex = Read(reader) as MiNum<int> ??
|
var columnIndex = Read(reader) as MiNum<int> ??
|
||||||
throw new HandlerException("Unexpected type in column indices of a sparse array.");
|
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))
|
if (sparseArrayFlags.ArrayFlags.Variable.HasFlag(Variable.IsLogical))
|
||||||
{
|
{
|
||||||
return DataElementConverter.ConvertToMatSparseArrayOf<bool>(
|
return DataElementConverter.ConvertToMatSparseArrayOf<bool>(
|
||||||
@ -260,7 +288,7 @@ namespace MatFileHandler
|
|||||||
|
|
||||||
if (sparseArrayFlags.ArrayFlags.Variable.HasFlag(Variable.IsComplex))
|
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(
|
return DataElementConverter.ConvertToMatSparseArrayOfComplex(
|
||||||
sparseArrayFlags,
|
sparseArrayFlags,
|
||||||
dimensions,
|
dimensions,
|
||||||
@ -327,7 +355,7 @@ namespace MatFileHandler
|
|||||||
using (var positionTrackingStream = new PositionTrackingStream(bufferedStream))
|
using (var positionTrackingStream = new PositionTrackingStream(bufferedStream))
|
||||||
using (var innerReader = new BinaryReader(positionTrackingStream))
|
using (var innerReader = new BinaryReader(positionTrackingStream))
|
||||||
{
|
{
|
||||||
element = Read(innerReader);
|
element = Read(innerReader) ?? throw new HandlerException("Missing compressed data.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (substream.Position != substream.Length)
|
if (substream.Position != substream.Length)
|
||||||
@ -350,7 +378,7 @@ namespace MatFileHandler
|
|||||||
return MatArray.Empty();
|
return MatArray.Empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
var element1 = Read(reader);
|
var element1 = Read(reader) ?? throw new HandlerException("Missing matrix data.");
|
||||||
var flags = ReadArrayFlags(element1);
|
var flags = ReadArrayFlags(element1);
|
||||||
if (flags.Class == ArrayType.MxOpaque)
|
if (flags.Class == ArrayType.MxOpaque)
|
||||||
{
|
{
|
||||||
@ -372,12 +400,12 @@ namespace MatFileHandler
|
|||||||
return ContinueReadingSparseArray(reader, element1, dimensions, name);
|
return ContinueReadingSparseArray(reader, element1, dimensions, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
var element4 = Read(reader);
|
var element4 = Read(reader) ?? throw new HandlerException("Missing matrix data.");
|
||||||
var data = ReadData(element4);
|
var data = ReadData(element4);
|
||||||
DataElement? imaginaryData = null;
|
DataElement? imaginaryData = null;
|
||||||
if (flags.Variable.HasFlag(Variable.IsComplex))
|
if (flags.Variable.HasFlag(Variable.IsComplex))
|
||||||
{
|
{
|
||||||
var element5 = Read(reader);
|
var element5 = Read(reader) ?? throw new HandlerException("Missing complex matrix data.");
|
||||||
imaginaryData = ReadData(element5);
|
imaginaryData = ReadData(element5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,26 +48,24 @@ namespace MatFileHandler
|
|||||||
var dataElementReader = new DataElementReader(subsystemData);
|
var dataElementReader = new DataElementReader(subsystemData);
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
try
|
var position = reader.BaseStream.Position;
|
||||||
{
|
var dataElement = dataElementReader.Read(reader);
|
||||||
var position = reader.BaseStream.Position;
|
if (dataElement is null)
|
||||||
var dataElement = dataElementReader.Read(reader);
|
|
||||||
if (position == subsystemDataOffset)
|
|
||||||
{
|
|
||||||
var subsystemDataElement = dataElement as IArrayOf<byte>
|
|
||||||
?? 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)
|
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (position == subsystemDataOffset)
|
||||||
|
{
|
||||||
|
var subsystemDataElement = dataElement as IArrayOf<byte>
|
||||||
|
?? 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;
|
return variables;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user