// Copyright 2017-2018 Alexander Luzgarev using System; using System.Collections.Generic; using System.Linq; namespace MatFileHandler { /// /// Functions for extracting values from data elements. /// internal static class DataExtraction { /// /// Convert IEnumerable to array. /// /// Element type. /// Input IEnumerable. /// An equivalent array. /// In contrast to the stanard ToArray() method, this doesn't create a copy if the input already was an array. public static T[] ToArrayLazily(this IEnumerable somethingEnumerable) { return somethingEnumerable as T[] ?? somethingEnumerable.ToArray(); } /// /// Convert the contents of the Matlab data element to a sequence of Double values. /// /// Data element. /// Contents of the elements, converted to Double. public static IEnumerable GetDataAsDouble(DataElement element) { switch (element) { case MiNum sbyteElement: return sbyteElement.Data.Select(Convert.ToDouble); case MiNum byteElement: return byteElement.Data.Select(Convert.ToDouble); case MiNum intElement: return intElement.Data.Select(Convert.ToDouble); case MiNum uintElement: return uintElement.Data.Select(Convert.ToDouble); case MiNum shortElement: return shortElement.Data.Select(Convert.ToDouble); case MiNum ushortElement: return ushortElement.Data.Select(Convert.ToDouble); case MiNum longElement: return longElement.Data.Select(Convert.ToDouble); case MiNum ulongElement: return ulongElement.Data.Select(Convert.ToDouble); case MiNum floatElement: return floatElement.Data.Select(Convert.ToDouble); case MiNum doubleElement: return doubleElement.Data; } throw new HandlerException( $"Expected data element that would be convertible to double, found {element.GetType()}."); } /// /// Convert the contents of the Matlab data element to a sequence of Single values. /// /// Data element. /// Contents of the elements, converted to Single. public static IEnumerable GetDataAsSingle(DataElement element) { switch (element) { case MiNum sbyteElement: return sbyteElement.Data.Select(Convert.ToSingle); case MiNum byteElement: return byteElement.Data.Select(Convert.ToSingle); case MiNum intElement: return intElement.Data.Select(Convert.ToSingle); case MiNum uintElement: return uintElement.Data.Select(Convert.ToSingle); case MiNum shortElement: return shortElement.Data.Select(Convert.ToSingle); case MiNum ushortElement: return ushortElement.Data.Select(Convert.ToSingle); case MiNum longElement: return longElement.Data.Select(Convert.ToSingle); case MiNum ulongElement: return ulongElement.Data.Select(Convert.ToSingle); case MiNum floatElement: return floatElement.Data; case MiNum doubleElement: return doubleElement.Data.Select(Convert.ToSingle); } throw new HandlerException( $"Expected data element that would be convertible to float, found {element.GetType()}."); } /// /// Convert the contents of the Matlab data element to a sequence of Int8 values. /// /// Data element. /// Contents of the elements, converted to Int8. public static IEnumerable GetDataAsInt8(DataElement element) { switch (element) { case MiNum sbyteElement: return sbyteElement.Data; case MiNum byteElement: return byteElement.Data.Select(Convert.ToSByte); case MiNum intElement: return intElement.Data.Select(Convert.ToSByte); case MiNum uintElement: return uintElement.Data.Select(Convert.ToSByte); case MiNum shortElement: return shortElement.Data.Select(Convert.ToSByte); case MiNum ushortElement: return ushortElement.Data.Select(Convert.ToSByte); case MiNum longElement: return longElement.Data.Select(Convert.ToSByte); case MiNum ulongElement: return ulongElement.Data.Select(Convert.ToSByte); case MiNum floatElement: return floatElement.Data.Select(Convert.ToSByte); case MiNum doubleElement: return doubleElement.Data.Select(Convert.ToSByte); } throw new HandlerException( $"Expected data element that would be convertible to int8, found {element.GetType()}."); } /// /// Convert the contents of the Matlab data element to a sequence of Uint8 values. /// /// Data element. /// Contents of the elements, converted to UInt8. public static IEnumerable GetDataAsUInt8(DataElement element) { switch (element) { case MiNum sbyteElement: return sbyteElement.Data.Select(Convert.ToByte); case MiNum byteElement: return byteElement.Data; case MiNum intElement: return intElement.Data.Select(Convert.ToByte); case MiNum uintElement: return uintElement.Data.Select(Convert.ToByte); case MiNum shortElement: return shortElement.Data.Select(Convert.ToByte); case MiNum ushortElement: return ushortElement.Data.Select(Convert.ToByte); case MiNum longElement: return longElement.Data.Select(Convert.ToByte); case MiNum ulongElement: return ulongElement.Data.Select(Convert.ToByte); case MiNum floatElement: return floatElement.Data.Select(Convert.ToByte); case MiNum doubleElement: return doubleElement.Data.Select(Convert.ToByte); } throw new HandlerException( $"Expected data element that would be convertible to uint8, found {element.GetType()}."); } /// /// Convert the contents of the Matlab data element to a sequence of Int16 values. /// /// Data element. /// Contents of the elements, converted to Int16. public static IEnumerable GetDataAsInt16(DataElement element) { switch (element) { case MiNum sbyteElement: return sbyteElement.Data.Select(Convert.ToInt16); case MiNum byteElement: return byteElement.Data.Select(Convert.ToInt16); case MiNum intElement: return intElement.Data.Select(Convert.ToInt16); case MiNum uintElement: return uintElement.Data.Select(Convert.ToInt16); case MiNum shortElement: return shortElement.Data; case MiNum ushortElement: return ushortElement.Data.Select(Convert.ToInt16); case MiNum longElement: return longElement.Data.Select(Convert.ToInt16); case MiNum ulongElement: return ulongElement.Data.Select(Convert.ToInt16); case MiNum floatElement: return floatElement.Data.Select(Convert.ToInt16); case MiNum doubleElement: return doubleElement.Data.Select(Convert.ToInt16); } throw new HandlerException( $"Expected data element that would be convertible to int16, found {element.GetType()}."); } /// /// Convert the contents of the Matlab data element to a sequence of UInt16 values. /// /// Data element. /// Contents of the elements, converted to UInt16. public static IEnumerable GetDataAsUInt16(DataElement element) { switch (element) { case MiNum sbyteElement: return sbyteElement.Data.Select(Convert.ToUInt16); case MiNum byteElement: return byteElement.Data.Select(Convert.ToUInt16); case MiNum intElement: return intElement.Data.Select(Convert.ToUInt16); case MiNum uintElement: return uintElement.Data.Select(Convert.ToUInt16); case MiNum shortElement: return shortElement.Data.Select(Convert.ToUInt16); case MiNum ushortElement: return ushortElement.Data; case MiNum longElement: return longElement.Data.Select(Convert.ToUInt16); case MiNum ulongElement: return ulongElement.Data.Select(Convert.ToUInt16); case MiNum floatElement: return floatElement.Data.Select(Convert.ToUInt16); case MiNum doubleElement: return doubleElement.Data.Select(Convert.ToUInt16); } throw new HandlerException( $"Expected data element that would be convertible to uint16, found {element.GetType()}."); } /// /// Convert the contents of the Matlab data element to a sequence of Int32 values. /// /// Data element. /// Contents of the elements, converted to Int32. public static IEnumerable GetDataAsInt32(DataElement element) { switch (element) { case MiNum sbyteElement: return sbyteElement.Data.Select(Convert.ToInt32); case MiNum byteElement: return byteElement.Data.Select(Convert.ToInt32); case MiNum intElement: return intElement.Data; case MiNum uintElement: return uintElement.Data.Select(Convert.ToInt32); case MiNum shortElement: return shortElement.Data.Select(Convert.ToInt32); case MiNum ushortElement: return ushortElement.Data.Select(Convert.ToInt32); case MiNum longElement: return longElement.Data.Select(Convert.ToInt32); case MiNum ulongElement: return ulongElement.Data.Select(Convert.ToInt32); case MiNum floatElement: return floatElement.Data.Select(Convert.ToInt32); case MiNum doubleElement: return doubleElement.Data.Select(Convert.ToInt32); } throw new HandlerException( $"Expected data element that would be convertible to int32, found {element.GetType()}."); } /// /// Convert the contents of the Matlab data element to a sequence of UInt32 values. /// /// Data element. /// Contents of the elements, converted to UInt32. public static IEnumerable GetDataAsUInt32(DataElement element) { switch (element) { case MiNum sbyteElement: return sbyteElement.Data.Select(Convert.ToUInt32); case MiNum byteElement: return byteElement.Data.Select(Convert.ToUInt32); case MiNum intElement: return intElement.Data.Select(Convert.ToUInt32); case MiNum uintElement: return uintElement.Data; case MiNum shortElement: return shortElement.Data.Select(Convert.ToUInt32); case MiNum ushortElement: return ushortElement.Data.Select(Convert.ToUInt32); case MiNum longElement: return longElement.Data.Select(Convert.ToUInt32); case MiNum ulongElement: return ulongElement.Data.Select(Convert.ToUInt32); case MiNum floatElement: return floatElement.Data.Select(Convert.ToUInt32); case MiNum doubleElement: return doubleElement.Data.Select(Convert.ToUInt32); } throw new HandlerException( $"Expected data element that would be convertible to uint32, found {element.GetType()}."); } /// /// Convert the contents of the Matlab data element to a sequence of Int64 values. /// /// Data element. /// Contents of the elements, converted to Int64. public static IEnumerable GetDataAsInt64(DataElement element) { switch (element) { case MiNum sbyteElement: return sbyteElement.Data.Select(Convert.ToInt64); case MiNum byteElement: return byteElement.Data.Select(Convert.ToInt64); case MiNum intElement: return intElement.Data.Select(Convert.ToInt64); case MiNum uintElement: return uintElement.Data.Select(Convert.ToInt64); case MiNum shortElement: return shortElement.Data.Select(Convert.ToInt64); case MiNum ushortElement: return ushortElement.Data.Select(Convert.ToInt64); case MiNum longElement: return longElement.Data; case MiNum ulongElement: return ulongElement.Data.Select(Convert.ToInt64); case MiNum floatElement: return floatElement.Data.Select(Convert.ToInt64); case MiNum doubleElement: return doubleElement.Data.Select(Convert.ToInt64); } throw new HandlerException( $"Expected data element that would be convertible to int64, found {element.GetType()}."); } /// /// Convert the contents of the Matlab data element to a sequence of UInt64 values. /// /// Data element. /// Contents of the elements, converted to UInt64. public static IEnumerable GetDataAsUInt64(DataElement element) { switch (element) { case MiNum sbyteElement: return sbyteElement.Data.Select(Convert.ToUInt64); case MiNum byteElement: return byteElement.Data.Select(Convert.ToUInt64); case MiNum intElement: return intElement.Data.Select(Convert.ToUInt64); case MiNum uintElement: return uintElement.Data.Select(Convert.ToUInt64); case MiNum shortElement: return shortElement.Data.Select(Convert.ToUInt64); case MiNum ushortElement: return ushortElement.Data.Select(Convert.ToUInt64); case MiNum longElement: return longElement.Data.Select(Convert.ToUInt64); case MiNum ulongElement: return ulongElement.Data; case MiNum floatElement: return floatElement.Data.Select(Convert.ToUInt64); case MiNum doubleElement: return doubleElement.Data.Select(Convert.ToUInt64); } throw new HandlerException( $"Expected data element that would be convertible to uint64, found {element.GetType()}."); } } }