SshDataStream.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. using System;
  2. using System.Globalization;
  3. using System.IO;
  4. using System.Text;
  5. namespace Renci.SshNet.Common
  6. {
  7. public class SshDataStream : MemoryStream
  8. {
  9. public SshDataStream(int capacity)
  10. : base(capacity)
  11. {
  12. }
  13. public SshDataStream(byte[] buffer)
  14. : base(buffer)
  15. {
  16. }
  17. /// <summary>
  18. /// Gets a value indicating whether all data from the SSH data stream has been read.
  19. /// </summary>
  20. /// <value>
  21. /// <c>true</c> if this instance is end of data; otherwise, <c>false</c>.
  22. /// </value>
  23. public bool IsEndOfData
  24. {
  25. get
  26. {
  27. return Position >= Length;
  28. }
  29. }
  30. /// <summary>
  31. /// Writes <see cref="uint"/> data to the SSH data stream.
  32. /// </summary>
  33. /// <param name="value"><see cref="uint"/> data to write.</param>
  34. public void Write(uint value)
  35. {
  36. var bytes = value.GetBytes();
  37. Write(bytes, 0, bytes.Length);
  38. }
  39. /// <summary>
  40. /// Writes <see cref="ulong"/> data to the SSH data stream.
  41. /// </summary>
  42. /// <param name="value"><see cref="ulong"/> data to write.</param>
  43. public void Write(ulong value)
  44. {
  45. var bytes = value.GetBytes();
  46. Write(bytes, 0, bytes.Length);
  47. }
  48. /// <summary>
  49. /// Writes string data to the SSH data stream using the specified encoding.
  50. /// </summary>
  51. /// <param name="value">The string data to write.</param>
  52. /// <param name="encoding">The character encoding to use.</param>
  53. /// <exception cref="ArgumentNullException"><paramref name="value"/> is null.</exception>
  54. /// <exception cref="ArgumentNullException"><paramref name="encoding"/> is null.</exception>
  55. public void Write(string value, Encoding encoding)
  56. {
  57. if (value == null)
  58. throw new ArgumentNullException("value");
  59. if (encoding == null)
  60. throw new ArgumentNullException("encoding");
  61. var bytes = encoding.GetBytes(value);
  62. var bytesLength = bytes.Length;
  63. Write((uint) bytesLength);
  64. Write(bytes, 0, bytesLength);
  65. }
  66. /// <summary>
  67. /// Reads the next <see cref="uint"/> data type from the SSH data stream.
  68. /// </summary>
  69. /// <returns>
  70. /// The <see cref="uint"/> read from the SSH data stream.
  71. /// </returns>
  72. public uint ReadUInt32()
  73. {
  74. var data = ReadBytes(4);
  75. return (uint)(data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]);
  76. }
  77. /// <summary>
  78. /// Reads the next <see cref="ulong"/> data type from the SSH data stream.
  79. /// </summary>
  80. /// <returns>
  81. /// The <see cref="ulong"/> read from the SSH data stream.
  82. /// </returns>
  83. public ulong ReadUInt64()
  84. {
  85. var data = ReadBytes(8);
  86. return ((ulong) data[0] << 56 | (ulong) data[1] << 48 | (ulong) data[2] << 40 | (ulong) data[3] << 32 |
  87. (ulong) data[4] << 24 | (ulong) data[5] << 16 | (ulong) data[6] << 8 | data[7]);
  88. }
  89. /// <summary>
  90. /// Reads the next <see cref="string"/> data type from the SSH data stream.
  91. /// </summary>
  92. /// <returns>
  93. /// The <see cref="string"/> read from the SSH data stream.
  94. /// </returns>
  95. public string ReadString(Encoding encoding)
  96. {
  97. var length = ReadUInt32();
  98. if (length > int.MaxValue)
  99. {
  100. throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Strings longer than {0} is not supported.", int.MaxValue));
  101. }
  102. return encoding.GetString(ReadBytes((int) length), 0, (int) length);
  103. }
  104. /// <summary>
  105. /// Reads next specified number of bytes data type from internal buffer.
  106. /// </summary>
  107. /// <param name="length">Number of bytes to read.</param>
  108. /// <returns>An array of bytes that was read from the internal buffer.</returns>
  109. /// <exception cref="ArgumentOutOfRangeException"><paramref name="length"/> is greater than the internal buffer size.</exception>
  110. private byte[] ReadBytes(int length)
  111. {
  112. var data = new byte[length];
  113. var bytesRead = base.Read(data, 0, length);
  114. if (bytesRead < length)
  115. throw new ArgumentOutOfRangeException("length");
  116. return data;
  117. }
  118. public override byte[] ToArray()
  119. {
  120. if (Capacity == Length)
  121. {
  122. return GetBuffer();
  123. }
  124. return base.ToArray();
  125. }
  126. }
  127. }