Example #1
0
 /// <summary>
 /// Initialize this object from another object.
 /// This ugly hack allows us to read the opaque objects and store references to
 /// the subsystem data in them before parsing the actual subsystem data (which
 /// comes later in the file).
 /// </summary>
 /// <param name="data">Another subsystem data.</param>
 public void Set(SubsystemData data)
 {
     _realData = new RealSubsystemData(
         data.ClassInformation,
         data.ObjectInformation,
         data.Data);
 }
Example #2
0
 private static List <RawVariable> ReadRawVariables(byte[] bytes, SubsystemData subsystemData)
 {
     using var stream = new MemoryStream(bytes);
     using var reader = new BinaryReader(stream);
     reader.ReadBytes(8);
     return(MatFileReader.ReadRawVariables(reader, -1, subsystemData));
 }
Example #3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="OpaqueLink"/> class.
 /// </summary>
 /// <param name="name">Name of the object.</param>
 /// <param name="typeDescription">Description of object's class.</param>
 /// <param name="className">Name of the object's class.</param>
 /// <param name="dimensions">Dimensions of the object.</param>
 /// <param name="data">Raw data containing links to object's storage.</param>
 /// <param name="indexToObjectId">Links to object's storage.</param>
 /// <param name="classIndex">Index of object's class.</param>
 /// <param name="subsystemData">Reference to global subsystem data.</param>
 public OpaqueLink(
     string name,
     string typeDescription,
     string className,
     int[] dimensions,
     DataElement data,
     int[] indexToObjectId,
     int classIndex,
     SubsystemData subsystemData)
     : base(name, typeDescription, className, dimensions, data)
 {
     IndexToObjectId    = indexToObjectId ?? throw new ArgumentNullException(nameof(indexToObjectId));
     ClassIndex         = classIndex;
     this.subsystemData = subsystemData ?? throw new ArgumentNullException(nameof(subsystemData));
 }
Example #4
0
        /// <summary>
        /// Read subsystem data from a given byte array.
        /// </summary>
        /// <param name="bytes">Byte array with the data.</param>
        /// <param name="subsystemData">
        /// Link to the existing subsystem data; this will be put in nested OpaqueLink objects
        /// and later replaced with the subsystem data that we are currently reading.</param>
        /// <returns>Subsystem data read.</returns>
        public static SubsystemData Read(byte[] bytes, SubsystemData subsystemData)
        {
            var rawVariables = ReadRawVariables(bytes, subsystemData);

            // Parse subsystem data.
            var mainVariable = rawVariables[0].DataElement as IStructureArray
                               ?? throw new HandlerException("Subsystem data must be a structure array.");
            var mcosData = mainVariable["MCOS", 0] as Opaque
                           ?? throw new HandlerException("MCOS data must be an opaque object.");
            var opaqueData = mcosData.RawData as ICellArray
                             ?? throw new HandlerException("Opaque data must be a cell array.");
            var info = (opaqueData[0] as IArrayOf <byte>)?.Data
                       ?? throw new HandlerException("Opaque data info must be a byte array.");

            var(offsets, position) = ReadOffsets(info, 0);
            var fieldNames                      = ReadFieldNames(info, position, offsets[1]);
            var numberOfClasses                 = ((offsets[3] - offsets[2]) / 16) - 1;
            var classIdToName                   = ReadClassIdToName(info, offsets, fieldNames, numberOfClasses);
            var numberOfEmbeddedObjects         = (offsets[4] - offsets[3] - 8) / 16;
            var embeddedObjectPositionsToValues = ReadEmbeddedObjectPositionsToValues(info, offsets, numberOfEmbeddedObjects);
            var numberOfObjects                 = ((offsets[5] - offsets[4]) / 24) - 1;
            var objectClasses                   = ReadObjectClassInformations(info, offsets, numberOfObjects);
            var numberOfObjectPositions         = objectClasses.Values.Count(x => x.ObjectPosition != 0);
            var objectPositionsToValues         = ReadObjectPositionsToValues(info, offsets, numberOfObjectPositions);

            var(classInformation, objectInformation) =
                GatherClassAndObjectInformation(
                    classIdToName,
                    fieldNames,
                    objectClasses,
                    objectPositionsToValues,
                    embeddedObjectPositionsToValues);
            var allFields = objectInformation.Values.SelectMany(obj => obj.FieldLinks.Values);
            var data      = new Dictionary <int, IArray>();

            foreach (var i in allFields)
            {
                data[i] = TransformOpaqueData(opaqueData[i + 2], subsystemData);
            }

            return(new SubsystemData(classInformation, objectInformation, data));
        }
        private static IArray TransformOpaqueData(IArray array, SubsystemData subsystemData)
        {
            if (array is MatNumericalArrayOf <uint> uintArray)
            {
                if (uintArray.Data[0] == 3707764736u)
                {
                    var(dimensions, indexToObjectId, classIndex) = DataElementReader.ParseOpaqueData(uintArray.Data);
                    return(new OpaqueLink(
                               uintArray.Name,
                               string.Empty,
                               string.Empty,
                               dimensions,
                               array as DataElement,
                               indexToObjectId,
                               classIndex,
                               subsystemData));
                }
            }

            return(array);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="DataElementReader"/> class.
 /// </summary>
 /// <param name="subsystemData">Reference to file's SubsystemData.</param>
 public DataElementReader(SubsystemData subsystemData)
 {
     this.subsystemData = subsystemData ?? throw new ArgumentNullException(nameof(subsystemData));
 }
Example #7
0
 /// <summary>
 /// Read raw variables from a .mat file.
 /// </summary>
 /// <param name="reader">Binary reader.</param>
 /// <param name="subsystemDataOffset">Offset to the subsystem data to use (read from the file header).</param>
 /// <returns>Raw variables read.</returns>
 internal static List<RawVariable> ReadRawVariables(BinaryReader reader, long subsystemDataOffset)
 {
     var subsystemData = new SubsystemData();
     return ReadRawVariables(reader, subsystemDataOffset, subsystemData);
 }
Example #8
0
        /// <summary>
        /// Read a sequence of raw variables from .mat file.
        /// </summary>
        /// <param name="reader">Reader.</param>
        /// <param name="subsystemDataOffset">Offset of subsystem data in the file;
        /// we need it because we may encounter it during reading, and
        /// the subsystem data should be parsed in a special way.</param>
        /// <param name="subsystemData">
        /// Link to the current file's subsystem data structure; initially it has dummy value
        /// which will be replaced after we parse the whole subsystem data.</param>
        /// <returns>List of "raw" variables; the actual variables are constructed from them later.</returns>
        internal static List<RawVariable> ReadRawVariables(BinaryReader reader, long subsystemDataOffset, SubsystemData subsystemData)
        {
            var variables = new List<RawVariable>();
            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<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;
                }
            }

            return variables;
        }
Example #9
0
 private static SubsystemData ReadSubsystemData(byte[] bytes, SubsystemData subsystemData)
 {
     return SubsystemDataReader.Read(bytes, subsystemData);
 }
        /// <summary>
        /// Read subsystem data from a given byte array.
        /// </summary>
        /// <param name="bytes">Byte array with the data.</param>
        /// <param name="subsystemData">
        /// Link to the existing subsystem data; this will be put in nested OpaqueLink objects
        /// and later replaced with the subsystem data that we are currently reading.</param>
        /// <returns>Subsystem data read.</returns>
        public static SubsystemData Read(byte[] bytes, SubsystemData subsystemData)
        {
            List <RawVariable> rawVariables = null;

            using (var stream = new MemoryStream(bytes))
            {
                using (var reader = new BinaryReader(stream))
                {
                    reader.ReadBytes(8);
                    rawVariables = MatFileReader.ReadRawVariables(reader, -1, subsystemData);
                }
            }

            // Parse subsystem data.
            var mainVariable = rawVariables[0].DataElement as IStructureArray;
            var mcosData     = mainVariable["MCOS", 0] as Opaque;
            var opaqueData   = mcosData.RawData as ICellArray;
            var info         = (opaqueData[0] as IArrayOf <byte>).Data;

            var(offsets, position) = ReadOffsets(info, 0);
            var fieldNames      = ReadFieldNames(info, position, offsets[1]);
            var numberOfClasses = ((offsets[3] - offsets[2]) / 16) - 1;
            Dictionary <int, string> classIdToName = null;

            using (var stream = new MemoryStream(info, offsets[2], offsets[3] - offsets[2]))
            {
                using (var reader = new BinaryReader(stream))
                {
                    classIdToName = ReadClassNames(reader, fieldNames, numberOfClasses);
                }
            }

            var numberOfObjects = ((offsets[5] - offsets[4]) / 24) - 1;
            Dictionary <int, (int, int)> objectClasses = null;

            using (var stream = new MemoryStream(info, offsets[4], offsets[5] - offsets[4]))
            {
                using (var reader = new BinaryReader(stream))
                {
                    objectClasses = ReadObjectClasses(reader, numberOfObjects);
                }
            }

            Dictionary <int, Dictionary <int, int> > objectToFields = null;

            using (var stream = new MemoryStream(info, offsets[5], offsets[6] - offsets[5]))
            {
                using (var reader = new BinaryReader(stream))
                {
                    objectToFields = ReadObjectToFieldsMapping(reader, numberOfObjects);
                }
            }

            var(classInformation, objectInformation) =
                GatherClassAndObjectInformation(
                    classIdToName,
                    fieldNames,
                    objectClasses,
                    objectToFields);

            var allFields = objectInformation.Values.SelectMany(obj => obj.FieldLinks.Values);
            var data      = new Dictionary <int, IArray>();

            foreach (var i in allFields)
            {
                data[i] = TransformOpaqueData(opaqueData[i + 2], subsystemData);
            }
            return(new SubsystemData(classInformation, objectInformation, data));
        }
 /// <summary>
 /// Initialize this object from another object.
 /// This ugly hack allows us to read the opaque objects and store references to
 /// the subsystem data in them before parsing the actual subsystem data (which
 /// comes later in the file).
 /// </summary>
 /// <param name="data">Another subsystem data.</param>
 public void Set(SubsystemData data)
 {
     this.ClassInformation  = data.ClassInformation;
     this.ObjectInformation = data.ObjectInformation;
     this.Data = data.Data;
 }