private DataElement ContinueReadingSparseArray( BinaryReader reader, DataElement firstElement, int[] dimensions, string name) { var sparseArrayFlags = ReadSparseArrayFlags(firstElement); var rowIndex = Read(reader) as MiNum <int> ?? throw new HandlerException("Unexpected type in row indices of a sparse array."); var columnIndex = Read(reader) as MiNum <int> ?? throw new HandlerException("Unexpected type in column indices of a sparse array."); var data = Read(reader); if (sparseArrayFlags.ArrayFlags.Variable.HasFlag(Variable.IsLogical)) { return(DataElementConverter.ConvertToMatSparseArrayOf <bool>( sparseArrayFlags, dimensions, name, rowIndex.Data, columnIndex.Data, data)); } if (sparseArrayFlags.ArrayFlags.Variable.HasFlag(Variable.IsComplex)) { var imaginaryData = Read(reader); return(DataElementConverter.ConvertToMatSparseArrayOfComplex( sparseArrayFlags, dimensions, name, rowIndex.Data, columnIndex.Data, data, imaginaryData)); } switch (data) { case MiNum <double> _: return(DataElementConverter.ConvertToMatSparseArrayOf <double>( sparseArrayFlags, dimensions, name, rowIndex.Data, columnIndex.Data, data)); default: throw new NotSupportedException("Only double and logical sparse arrays are supported."); } }
private DataElement ReadMatrix(Tag tag, BinaryReader reader) { if (tag.Length == 0) { return(MatArray.Empty()); } var element1 = Read(reader); var flags = ReadArrayFlags(element1); if (flags.Class == ArrayType.MxOpaque) { return(ContinueReadingOpaque(reader)); } var element2 = Read(reader) as MiNum <int> ?? throw new HandlerException("Unexpected type in array dimensions data."); var dimensions = ReadDimensionsArray(element2); var element3 = Read(reader) as MiNum <sbyte> ?? throw new HandlerException("Unexpected type in array name."); var name = ReadName(element3); if (flags.Class == ArrayType.MxCell) { return(ContinueReadingCellArray(reader, flags, dimensions, name)); } if (flags.Class == ArrayType.MxSparse) { return(ContinueReadingSparseArray(reader, element1, dimensions, name)); } var element4 = Read(reader); var data = ReadData(element4); DataElement imaginaryData = null; if (flags.Variable.HasFlag(Variable.IsComplex)) { var element5 = Read(reader); imaginaryData = ReadData(element5); } if (flags.Class == ArrayType.MxStruct) { var fieldNameLengthElement = data as MiNum <int> ?? throw new HandlerException( "Unexpected type in structure field name length."); return(ContinueReadingStructure(reader, flags, dimensions, name, fieldNameLengthElement.Data[0])); } switch (flags.Class) { case ArrayType.MxChar: switch (data) { case MiNum <byte> _: return(DataElementConverter.ConvertToMatNumericalArrayOf <byte>( flags, dimensions, name, data, imaginaryData)); case MiNum <ushort> _: return(DataElementConverter.ConvertToMatNumericalArrayOf <ushort>( flags, dimensions, name, data, imaginaryData)); default: throw new NotSupportedException( $"This type of char array ({data.GetType()}) is not supported."); } case ArrayType.MxInt8: return(DataElementConverter.ConvertToMatNumericalArrayOf <sbyte>( flags, dimensions, name, data, imaginaryData)); case ArrayType.MxUInt8: if (flags.Variable.HasFlag(Variable.IsLogical)) { return(DataElementConverter.ConvertToMatNumericalArrayOf <bool>( flags, dimensions, name, data, imaginaryData)); } return(DataElementConverter.ConvertToMatNumericalArrayOf <byte>( flags, dimensions, name, data, imaginaryData)); case ArrayType.MxInt16: return(DataElementConverter.ConvertToMatNumericalArrayOf <short>( flags, dimensions, name, data, imaginaryData)); case ArrayType.MxUInt16: return(DataElementConverter.ConvertToMatNumericalArrayOf <ushort>( flags, dimensions, name, data, imaginaryData)); case ArrayType.MxInt32: return(DataElementConverter.ConvertToMatNumericalArrayOf <int>( flags, dimensions, name, data, imaginaryData)); case ArrayType.MxUInt32: return(DataElementConverter.ConvertToMatNumericalArrayOf <uint>( flags, dimensions, name, data, imaginaryData)); case ArrayType.MxInt64: return(DataElementConverter.ConvertToMatNumericalArrayOf <long>( flags, dimensions, name, data, imaginaryData)); case ArrayType.MxUInt64: return(DataElementConverter.ConvertToMatNumericalArrayOf <ulong>( flags, dimensions, name, data, imaginaryData)); case ArrayType.MxSingle: return(DataElementConverter.ConvertToMatNumericalArrayOf <float>( flags, dimensions, name, data, imaginaryData)); case ArrayType.MxDouble: return(DataElementConverter.ConvertToMatNumericalArrayOf <double>( flags, dimensions, name, data, imaginaryData)); default: throw new HandlerException("Unknown data type."); } }