// Copyright 2017-2018 Alexander Luzgarev using System; using System.Linq; using System.Numerics; using System.Text; namespace MatFileHandler { /// /// A better interface for using datetime objects. /// public class StringAdapter { private readonly int[] dimensions; private readonly string[] strings; /// /// Initializes a new instance of the class. /// /// Source datetime object. public StringAdapter(IArray array) { var matObject = array as IMatObject; if (matObject?.ClassName != "string") { throw new ArgumentException("The object provided is not a string."); } var binaryData = matObject["any", 0] as IArrayOf; (dimensions, strings) = ParseBinaryData(binaryData.Data); } /// /// Gets datetime array dimensions. /// public int[] Dimensions => dimensions; /// /// Gets string object at given position. /// /// Indices. /// Value. public string this[params int[] list] => strings[Dimensions.DimFlatten(list)]; private static (int[] dimensions, string[] strings) ParseBinaryData(ulong[] binaryData) { var numberOfDimensions = (int)binaryData[1]; var d = new int[numberOfDimensions]; for (var i = 0; i < numberOfDimensions; i++) { d[i] = (int)binaryData[i + 2]; } var numberOfElements = d.NumberOfElements(); var start = numberOfDimensions + 2; var lengths = new int[numberOfElements]; for (var i = 0; i < numberOfElements; i++) { lengths[i] = (int)binaryData[start + i]; } var strings = new string[numberOfElements]; start += numberOfElements; var numberOfUlongsLeft = binaryData.Length - start; var bytes = new byte[numberOfUlongsLeft * sizeof(ulong)]; Buffer.BlockCopy(binaryData, start * sizeof(ulong), bytes, 0, bytes.Length); var counter = 0; for (var i = 0; i < numberOfElements; i++) { strings[i] = Encoding.Unicode.GetString(bytes, counter * 2, lengths[i] * 2); counter += lengths[i]; } return (d, strings); } } }