namespace FSharp.Data.Tdms open System open System.Buffers.Binary open System.Numerics #if IS_DESIGNTIME open System.Runtime.InteropServices #endif open System.Text module Buffer = let readInt16 (buffer: byte ReadOnlySpan byref) bigEndian = let value = if bigEndian then BinaryPrimitives.ReadInt16BigEndian buffer else BinaryPrimitives.ReadInt16LittleEndian buffer buffer <- buffer.Slice 2 value let readInt (buffer: byte ReadOnlySpan byref) bigEndian = let value = if bigEndian then BinaryPrimitives.ReadInt32BigEndian buffer else BinaryPrimitives.ReadInt32LittleEndian buffer buffer <- buffer.Slice 4 value let readInt64 (buffer: byte ReadOnlySpan byref) bigEndian = let value = if bigEndian then BinaryPrimitives.ReadInt64BigEndian buffer else BinaryPrimitives.ReadInt64LittleEndian buffer buffer <- buffer.Slice 8 value let readUInt16 (buffer: byte ReadOnlySpan byref) bigEndian = let value = if bigEndian then BinaryPrimitives.ReadUInt16BigEndian buffer else BinaryPrimitives.ReadUInt16LittleEndian buffer buffer <- buffer.Slice 2 value let readUInt (buffer: byte ReadOnlySpan byref) bigEndian = let value = if bigEndian then BinaryPrimitives.ReadUInt32BigEndian buffer else BinaryPrimitives.ReadUInt32LittleEndian buffer buffer <- buffer.Slice 4 value let readUInt64 (buffer: byte ReadOnlySpan byref) bigEndian = let value = if bigEndian then BinaryPrimitives.ReadUInt64BigEndian buffer else BinaryPrimitives.ReadUInt64LittleEndian buffer buffer <- buffer.Slice 8 value let readFloat32 (buffer: byte ReadOnlySpan byref) bigEndian = let value = if bigEndian then #if IS_DESIGNTIME if BitConverter.IsLittleEndian then BitConverter.ToSingle(BitConverter.GetBytes(BinaryPrimitives.ReverseEndianness(MemoryMarshal.Read buffer)), 0) else MemoryMarshal.Read buffer #else BinaryPrimitives.ReadSingleBigEndian buffer #endif else #if IS_DESIGNTIME if not BitConverter.IsLittleEndian then BitConverter.ToSingle(BitConverter.GetBytes(BinaryPrimitives.ReverseEndianness(MemoryMarshal.Read buffer)), 0) else MemoryMarshal.Read buffer #else BinaryPrimitives.ReadSingleLittleEndian buffer #endif buffer <- buffer.Slice 4 value let readFloat (buffer: byte ReadOnlySpan byref) bigEndian = let value = if bigEndian then #if IS_DESIGNTIME if BitConverter.IsLittleEndian then BitConverter.ToDouble(BitConverter.GetBytes(BinaryPrimitives.ReverseEndianness(MemoryMarshal.Read buffer)), 0) else MemoryMarshal.Read buffer #else BinaryPrimitives.ReadDoubleBigEndian buffer #endif else #if IS_DESIGNTIME if not BitConverter.IsLittleEndian then BitConverter.ToDouble(BitConverter.GetBytes(BinaryPrimitives.ReverseEndianness(MemoryMarshal.Read buffer)), 0) else MemoryMarshal.Read buffer #else BinaryPrimitives.ReadDoubleLittleEndian buffer #endif buffer <- buffer.Slice 8 value let readFloat80 (buffer: byte ReadOnlySpan byref) bigEndian = if bigEndian then { RawSignificand = readUInt64 &buffer bigEndian RawSignExponent = readUInt16 &buffer bigEndian } else { RawSignExponent = readUInt16 &buffer bigEndian RawSignificand = readUInt64 &buffer bigEndian } let readType (buffer: byte ReadOnlySpan byref) bigEndian = readUInt &buffer bigEndian |> function | 0u -> typeof | 0x21u -> typeof | 1u -> typeof | 2u -> typeof | 3u -> typeof | 4u -> typeof | 5u -> typeof | 6u -> typeof | 7u -> typeof | 8u -> typeof | 9u | 0x19u -> typeof | 10u | 0x1Au -> typeof | 0x08000Cu -> typeof | 0x10000Du -> typeof | 11u | 0x1Bu -> typeof | 0x20u -> typeof | 0x44u -> typeof | value -> failwithf "Unknown type: %i" value let readString (buffer: byte ReadOnlySpan byref) bigEndian = let length = readUInt &buffer bigEndian |> int let bytes = buffer.Slice(0, length) buffer <- buffer.Slice length #if IS_DESIGNTIME Encoding.UTF8.GetString (bytes.ToArray()) #else Encoding.UTF8.GetString bytes #endif