Buffer.fs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. namespace FSharp.Data.Tdms
  2. open System
  3. open System.Buffers.Binary
  4. open System.Numerics
  5. #if IS_DESIGNTIME
  6. open System.Runtime.InteropServices
  7. #endif
  8. open System.Text
  9. module Buffer =
  10. let readInt16 (buffer: byte ReadOnlySpan byref) bigEndian =
  11. let value =
  12. if bigEndian then
  13. BinaryPrimitives.ReadInt16BigEndian buffer
  14. else
  15. BinaryPrimitives.ReadInt16LittleEndian buffer
  16. buffer <- buffer.Slice 2
  17. value
  18. let readInt (buffer: byte ReadOnlySpan byref) bigEndian =
  19. let value =
  20. if bigEndian then
  21. BinaryPrimitives.ReadInt32BigEndian buffer
  22. else
  23. BinaryPrimitives.ReadInt32LittleEndian buffer
  24. buffer <- buffer.Slice 4
  25. value
  26. let readInt64 (buffer: byte ReadOnlySpan byref) bigEndian =
  27. let value =
  28. if bigEndian then
  29. BinaryPrimitives.ReadInt64BigEndian buffer
  30. else
  31. BinaryPrimitives.ReadInt64LittleEndian buffer
  32. buffer <- buffer.Slice 8
  33. value
  34. let readUInt16 (buffer: byte ReadOnlySpan byref) bigEndian =
  35. let value =
  36. if bigEndian then
  37. BinaryPrimitives.ReadUInt16BigEndian buffer
  38. else
  39. BinaryPrimitives.ReadUInt16LittleEndian buffer
  40. buffer <- buffer.Slice 2
  41. value
  42. let readUInt (buffer: byte ReadOnlySpan byref) bigEndian =
  43. let value =
  44. if bigEndian then
  45. BinaryPrimitives.ReadUInt32BigEndian buffer
  46. else
  47. BinaryPrimitives.ReadUInt32LittleEndian buffer
  48. buffer <- buffer.Slice 4
  49. value
  50. let readUInt64 (buffer: byte ReadOnlySpan byref) bigEndian =
  51. let value =
  52. if bigEndian then
  53. BinaryPrimitives.ReadUInt64BigEndian buffer
  54. else
  55. BinaryPrimitives.ReadUInt64LittleEndian buffer
  56. buffer <- buffer.Slice 8
  57. value
  58. let readFloat32 (buffer: byte ReadOnlySpan byref) bigEndian =
  59. let value =
  60. if bigEndian then
  61. #if IS_DESIGNTIME
  62. if BitConverter.IsLittleEndian
  63. then
  64. BitConverter.ToSingle(BitConverter.GetBytes(BinaryPrimitives.ReverseEndianness(MemoryMarshal.Read<int> buffer)), 0)
  65. else
  66. MemoryMarshal.Read<float32> buffer
  67. #else
  68. BinaryPrimitives.ReadSingleBigEndian buffer
  69. #endif
  70. else
  71. #if IS_DESIGNTIME
  72. if not BitConverter.IsLittleEndian
  73. then
  74. BitConverter.ToSingle(BitConverter.GetBytes(BinaryPrimitives.ReverseEndianness(MemoryMarshal.Read<int> buffer)), 0)
  75. else
  76. MemoryMarshal.Read<float32> buffer
  77. #else
  78. BinaryPrimitives.ReadSingleLittleEndian buffer
  79. #endif
  80. buffer <- buffer.Slice 4
  81. value
  82. let readFloat (buffer: byte ReadOnlySpan byref) bigEndian =
  83. let value =
  84. if bigEndian then
  85. #if IS_DESIGNTIME
  86. if BitConverter.IsLittleEndian
  87. then
  88. BitConverter.ToDouble(BitConverter.GetBytes(BinaryPrimitives.ReverseEndianness(MemoryMarshal.Read<int64> buffer)), 0)
  89. else
  90. MemoryMarshal.Read<float> buffer
  91. #else
  92. BinaryPrimitives.ReadDoubleBigEndian buffer
  93. #endif
  94. else
  95. #if IS_DESIGNTIME
  96. if not BitConverter.IsLittleEndian
  97. then
  98. BitConverter.ToDouble(BitConverter.GetBytes(BinaryPrimitives.ReverseEndianness(MemoryMarshal.Read<int64> buffer)), 0)
  99. else
  100. MemoryMarshal.Read<float> buffer
  101. #else
  102. BinaryPrimitives.ReadDoubleLittleEndian buffer
  103. #endif
  104. buffer <- buffer.Slice 8
  105. value
  106. let readFloat80 (buffer: byte ReadOnlySpan byref) bigEndian =
  107. if bigEndian then
  108. { RawSignificand = readUInt64 &buffer bigEndian
  109. RawSignExponent = readUInt16 &buffer bigEndian }
  110. else
  111. { RawSignExponent = readUInt16 &buffer bigEndian
  112. RawSignificand = readUInt64 &buffer bigEndian }
  113. let readType (buffer: byte ReadOnlySpan byref) bigEndian =
  114. readUInt &buffer bigEndian
  115. |> function
  116. | 0u -> typeof<unit>
  117. | 0x21u -> typeof<bool>
  118. | 1u -> typeof<int8>
  119. | 2u -> typeof<int16>
  120. | 3u -> typeof<int>
  121. | 4u -> typeof<int64>
  122. | 5u -> typeof<uint8>
  123. | 6u -> typeof<uint16>
  124. | 7u -> typeof<uint>
  125. | 8u -> typeof<uint64>
  126. | 9u
  127. | 0x19u -> typeof<float32>
  128. | 10u
  129. | 0x1Au -> typeof<float>
  130. | 0x08000Cu -> typeof<struct (float32 * float32)>
  131. | 0x10000Du -> typeof<Complex>
  132. | 11u
  133. | 0x1Bu -> typeof<float80>
  134. | 0x20u -> typeof<string>
  135. | 0x44u -> typeof<Timestamp>
  136. | value -> failwithf "Unknown type: %i" value
  137. let readString (buffer: byte ReadOnlySpan byref) bigEndian =
  138. let length = readUInt &buffer bigEndian |> int
  139. let bytes = buffer.Slice(0, length)
  140. buffer <- buffer.Slice length
  141. #if IS_DESIGNTIME
  142. Encoding.UTF8.GetString (bytes.ToArray())
  143. #else
  144. Encoding.UTF8.GetString bytes
  145. #endif