BinaryReaderExtensions.cs 4.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. using System;
  2. using System.IO;
  3. using System.Text;
  4. namespace NationalInstruments.Tdms
  5. {
  6. public static class BinaryReaderExtensions
  7. {
  8. public static string ReadString(this BinaryReader reader, int length)
  9. {
  10. return Encoding.UTF8.GetString(reader.ReadBytes(length));
  11. }
  12. public static string? ReadLengthPrefixedString(this BinaryReader reader)
  13. {
  14. return Read<string>(reader, DataType.String);
  15. }
  16. public static T? Read<T>(this BinaryReader reader, int dataType)
  17. {
  18. return (T?)Read(reader, dataType);
  19. }
  20. public static object? Read(this BinaryReader reader, int dataType)
  21. {
  22. switch (dataType)
  23. {
  24. case DataType.Empty: return null;
  25. case DataType.Void: reader.ReadByte(); return null;
  26. case DataType.Integer8: return reader.ReadSByte();
  27. case DataType.Integer16: return reader.ReadInt16();
  28. case DataType.Integer32: return reader.ReadInt32();
  29. case DataType.Integer64: return reader.ReadInt64();
  30. case DataType.UnsignedInteger8: return reader.ReadByte();
  31. case DataType.UnsignedInteger16: return reader.ReadUInt16();
  32. case DataType.UnsignedInteger32: return reader.ReadUInt32();
  33. case DataType.UnsignedInteger64: return reader.ReadUInt64();
  34. case DataType.SingleFloat:
  35. case DataType.SingleFloatWithUnit: return reader.ReadSingle();
  36. case DataType.DoubleFloat:
  37. case DataType.DoubleFloatWithUnit: return reader.ReadDouble();
  38. case DataType.String: return Encoding.UTF8.GetString(reader.ReadBytes(reader.ReadInt32()));
  39. case DataType.Boolean: return reader.ReadBoolean();
  40. case DataType.TimeStamp:
  41. return new DateTime(1904, 1, 1, 0, 0, 0, DateTimeKind.Utc)
  42. .AddSeconds(reader.ReadUInt64() / (double)ulong.MaxValue) //fixed truncate error in old code
  43. .AddSeconds(reader.ReadInt64())
  44. .ToLocalTime();
  45. default: throw new ArgumentException("Unknown data type " + dataType, "dataType");
  46. }
  47. }
  48. }
  49. public static class BinaryWriterExtensions
  50. {
  51. public static void Write(this BinaryWriter writer, int dataType, object data)
  52. {
  53. switch (dataType)
  54. {
  55. case DataType.Empty: break;
  56. case DataType.Void: writer.Write((byte)0); break;
  57. case DataType.Integer8: writer.Write((sbyte)data); break;
  58. case DataType.Integer16: writer.Write((Int16)data); break;
  59. case DataType.Integer32: writer.Write((Int32)data); break;
  60. case DataType.Integer64: writer.Write((Int64)data); break;
  61. case DataType.UnsignedInteger8: writer.Write((byte)data); break;
  62. case DataType.UnsignedInteger16: writer.Write((UInt16)data); break;
  63. case DataType.UnsignedInteger32: writer.Write((UInt32)data); break;
  64. case DataType.UnsignedInteger64: writer.Write((UInt16)data); break;
  65. case DataType.SingleFloat:
  66. case DataType.SingleFloatWithUnit: writer.Write((float)data); break;
  67. case DataType.DoubleFloat:
  68. case DataType.DoubleFloatWithUnit: writer.Write((double)data); break;
  69. case DataType.String:
  70. byte[] bytes = Encoding.UTF8.GetBytes((string)data);
  71. writer.Write((Int32)bytes.Length);
  72. writer.Write(bytes);
  73. break;
  74. case DataType.Boolean: writer.Write((bool)data); break;
  75. case DataType.TimeStamp:
  76. var t = (((DateTime)data).ToUniversalTime() - new DateTime(1904, 1, 1, 0, 0, 0, DateTimeKind.Utc));
  77. writer.Write((UInt64)((t.TotalSeconds % 1) * ulong.MaxValue));
  78. writer.Write((Int64)t.TotalSeconds);
  79. break;
  80. default: throw new ArgumentException("Unknown data type " + dataType, "dataType");
  81. }
  82. }
  83. }
  84. }