< Summary

Information
Class: Renci.SshNet.Common.SshData
Assembly: Renci.SshNet
File(s): \home\appveyor\projects\ssh-net\src\Renci.SshNet\Common\SshData.cs
Line coverage
90%
Covered lines: 119
Uncovered lines: 13
Coverable lines: 132
Total lines: 432
Line coverage: 90.1%
Branch coverage
87%
Covered branches: 14
Total branches: 16
Branch coverage: 87.5%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity Line coverage
.cctor()100%1100%
get_DataStream()100%1100%
get_IsEndOfData()100%1100%
get_BufferCapacity()100%1100%
GetBytes()100%2100%
WriteBytes(...)100%1100%
Load(...)100%2100%
Load(...)50%266.66%
LoadInternal(...)100%1100%
ReadBytes()100%1100%
ReadBytes(...)100%2100%
ReadByte()50%271.42%
ReadBoolean()100%1100%
ReadUInt16()100%10%
ReadUInt32()100%1100%
ReadUInt64()100%10%
ReadString(...)100%1100%
ReadBinary()100%1100%
ReadNamesList()100%1100%
ReadExtensionPair()100%2100%
Write(...)100%1100%
Write(...)100%1100%
Write(...)100%1100%
Write(...)100%2100%
Write(...)100%1100%
Write(...)100%1100%
Write(...)100%1100%
Write(...)100%1100%
Write(...)100%10%
Write(...)100%1100%
Write(...)100%2100%
WriteBinaryString(...)100%1100%
WriteBinary(...)100%1100%

File(s)

\home\appveyor\projects\ssh-net\src\Renci.SshNet\Common\SshData.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.Text;
 4
 5namespace Renci.SshNet.Common
 6{
 7    /// <summary>
 8    /// Base ssh data serialization type.
 9    /// </summary>
 10#pragma warning disable CA1001 // Types that own disposable fields should be disposable
 11    public abstract class SshData
 12#pragma warning restore CA1001 // Types that own disposable fields should be disposable
 13    {
 14        internal const int DefaultCapacity = 64;
 15
 416        internal static readonly Encoding Ascii = Encoding.ASCII;
 17
 418        internal static readonly Encoding Utf8 = Encoding.UTF8;
 19
 20        private SshDataStream _stream;
 21
 22        /// <summary>
 23        /// Gets the underlying <see cref="SshDataStream"/> that is used for reading and writing SSH data.
 24        /// </summary>
 25        /// <value>
 26        /// The underlying <see cref="SshDataStream"/> that is used for reading and writing SSH data.
 27        /// </value>
 28        protected SshDataStream DataStream
 29        {
 6650430            get { return _stream; }
 31        }
 32
 33        /// <summary>
 34        /// Gets a value indicating whether all data from the buffer has been read.
 35        /// </summary>
 36        /// <value>
 37        /// <see langword="true"/> if this instance is end of data; otherwise, <see langword="false"/>.
 38        /// </value>
 39        protected bool IsEndOfData
 40        {
 41            get
 2616642            {
 2616643                return _stream.Position >= _stream.Length;
 2616644            }
 45        }
 46
 47        /// <summary>
 48        /// Gets the size of the message in bytes.
 49        /// </summary>
 50        /// <value>
 51        /// The size of the messages in bytes.
 52        /// </value>
 53        protected virtual int BufferCapacity
 54        {
 5237455            get { return 0; }
 56        }
 57
 58        /// <summary>
 59        /// Gets data bytes array.
 60        /// </summary>
 61        /// <returns>
 62        /// A <see cref="byte"/> array representation of data structure.
 63        /// </returns>
 64        public byte[] GetBytes()
 5231365        {
 5231366            var messageLength = BufferCapacity;
 5231367            var capacity = messageLength != -1 ? messageLength : DefaultCapacity;
 68
 5231369            using (var dataStream = new SshDataStream(capacity))
 5231370            {
 5231371                WriteBytes(dataStream);
 5231372                return dataStream.ToArray();
 73            }
 5231374        }
 75
 76        /// <summary>
 77        /// Writes the current message to the specified <see cref="SshDataStream"/>.
 78        /// </summary>
 79        /// <param name="stream">The <see cref="SshDataStream"/> to write the message to.</param>
 80        protected virtual void WriteBytes(SshDataStream stream)
 10682381        {
 10682382            _stream = stream;
 10682383            SaveData();
 10682384        }
 85
 86        /// <summary>
 87        /// Loads data from specified bytes.
 88        /// </summary>
 89        /// <param name="data">Bytes array.</param>
 90        /// <exception cref="ArgumentNullException"><paramref name="data"/> is <see langword="null"/>.</exception>
 91        public void Load(byte[] data)
 427192        {
 427193            if (data is null)
 394            {
 395                throw new ArgumentNullException(nameof(data));
 96            }
 97
 426898            LoadInternal(data, 0, data.Length);
 426899        }
 100
 101        /// <summary>
 102        /// Loads data from the specified buffer.
 103        /// </summary>
 104        /// <param name="data">Bytes array.</param>
 105        /// <param name="offset">The zero-based offset in <paramref name="data"/> at which to begin reading SSH data.</p
 106        /// <param name="count">The number of bytes to load.</param>
 107        /// <exception cref="ArgumentNullException"><paramref name="data"/> is <see langword="null"/>.</exception>
 108        public void Load(byte[] data, int offset, int count)
 90451109        {
 90451110            if (data is null)
 0111            {
 0112                throw new ArgumentNullException(nameof(data));
 113            }
 114
 90451115            LoadInternal(data, offset, count);
 90448116        }
 117
 118        private void LoadInternal(byte[] value, int offset, int count)
 94719119        {
 94719120            _stream = new SshDataStream(value, offset, count);
 94719121            LoadData();
 94716122        }
 123
 124        /// <summary>
 125        /// Called when type specific data need to be loaded.
 126        /// </summary>
 127        protected abstract void LoadData();
 128
 129        /// <summary>
 130        /// Called when type specific data need to be saved.
 131        /// </summary>
 132        protected abstract void SaveData();
 133
 134        /// <summary>
 135        /// Reads all data left in internal buffer at current position.
 136        /// </summary>
 137        /// <returns>
 138        /// An array of bytes containing the remaining data in the internal buffer.
 139        /// </returns>
 140        protected byte[] ReadBytes()
 1742141        {
 1742142            var bytesLength = (int) (_stream.Length - _stream.Position);
 1742143            var data = new byte[bytesLength];
 1742144            _ = _stream.Read(data, 0, bytesLength);
 1742145            return data;
 1742146        }
 147
 148        /// <summary>
 149        /// Reads next specified number of bytes data type from internal buffer.
 150        /// </summary>
 151        /// <param name="length">Number of bytes to read.</param>
 152        /// <returns>
 153        /// An array of bytes that was read from the internal buffer.
 154        /// </returns>
 155        /// <exception cref="ArgumentOutOfRangeException"><paramref name="length"/> is greater than the number of bytes 
 156        protected byte[] ReadBytes(int length)
 119753157        {
 119753158            var data = new byte[length];
 119753159            var bytesRead = _stream.Read(data, 0, length);
 160
 119753161            if (bytesRead < length)
 3162            {
 3163                throw new ArgumentOutOfRangeException(nameof(length));
 164            }
 165
 119750166            return data;
 119750167        }
 168
 169        /// <summary>
 170        /// Reads next byte data type from internal buffer.
 171        /// </summary>
 172        /// <returns>
 173        /// The <see cref="byte"/> read.
 174        /// </returns>
 175        /// <exception cref="InvalidOperationException">Attempt to read past the end of the stream.</exception>
 176        protected byte ReadByte()
 7183177        {
 7183178            var byteRead = _stream.ReadByte();
 7183179            if (byteRead == -1)
 0180            {
 0181                throw new InvalidOperationException("Attempt to read past the end of the SSH data stream.");
 182            }
 183
 7183184            return (byte) byteRead;
 7183185        }
 186
 187        /// <summary>
 188        /// Reads the next <see cref="bool"/> from the internal buffer.
 189        /// </summary>
 190        /// <returns>
 191        /// The <see cref="bool"/> that was read.
 192        /// </returns>
 193        /// <exception cref="InvalidOperationException">Attempt to read past the end of the stream.</exception>
 194        protected bool ReadBoolean()
 7183195        {
 7183196            return ReadByte() != 0;
 7183197        }
 198
 199        /// <summary>
 200        /// Reads the next <see cref="ushort"/> from the internal buffer.
 201        /// </summary>
 202        /// <returns>
 203        /// The <see cref="ushort"/> that was read.
 204        /// </returns>
 205        /// <exception cref="InvalidOperationException">Attempt to read past the end of the stream.</exception>
 206        protected ushort ReadUInt16()
 0207        {
 0208            return Pack.BigEndianToUInt16(ReadBytes(2));
 0209        }
 210
 211        /// <summary>
 212        /// Reads the next <see cref="uint"/> from the internal buffer.
 213        /// </summary>
 214        /// <returns>
 215        /// The <see cref="uint"/> that was read.
 216        /// </returns>
 217        /// <exception cref="InvalidOperationException">Attempt to read past the end of the stream.</exception>
 218        protected uint ReadUInt32()
 117607219        {
 117607220            return Pack.BigEndianToUInt32(ReadBytes(4));
 117607221        }
 222
 223        /// <summary>
 224        /// Reads the next <see cref="ulong"/> from the internal buffer.
 225        /// </summary>
 226        /// <returns>
 227        /// The <see cref="ulong"/> that was read.
 228        /// </returns>
 229        /// <exception cref="InvalidOperationException">Attempt to read past the end of the stream.</exception>
 230        protected ulong ReadUInt64()
 0231        {
 0232            return Pack.BigEndianToUInt64(ReadBytes(8));
 0233        }
 234
 235        /// <summary>
 236        /// Reads the next <see cref="string"/> from the internal buffer using the specified encoding.
 237        /// </summary>
 238        /// <param name="encoding">The character encoding to use.</param>
 239        /// <returns>
 240        /// The <see cref="string"/> that was read.
 241        /// </returns>
 242        protected string ReadString(Encoding encoding)
 106911243        {
 106911244            return _stream.ReadString(encoding);
 106911245        }
 246
 247        /// <summary>
 248        /// Reads next data type as byte array from internal buffer.
 249        /// </summary>
 250        /// <returns>
 251        /// The bytes read.
 252        /// </returns>
 253        protected byte[] ReadBinary()
 57951254        {
 57951255            return _stream.ReadBinary();
 57951256        }
 257
 258        /// <summary>
 259        /// Reads next name-list data type from internal buffer.
 260        /// </summary>
 261        /// <returns>
 262        /// String array or read data.
 263        /// </returns>
 264        protected string[] ReadNamesList()
 19393265        {
 19393266            var namesList = ReadString(Ascii);
 19393267            return namesList.Split(',');
 19393268        }
 269
 270        /// <summary>
 271        /// Reads next extension-pair data type from internal buffer.
 272        /// </summary>
 273        /// <returns>
 274        /// Extensions pair dictionary.
 275        /// </returns>
 276        protected Dictionary<string, string> ReadExtensionPair()
 641277        {
 641278            var result = new Dictionary<string, string>();
 279
 7434280            while (!IsEndOfData)
 6793281            {
 6793282                var extensionName = ReadString(Ascii);
 6793283                var extensionData = ReadString(Ascii);
 6793284                result.Add(extensionName, extensionData);
 6793285            }
 286
 641287            return result;
 641288        }
 289
 290        /// <summary>
 291        /// Writes bytes array data into internal buffer.
 292        /// </summary>
 293        /// <param name="data">Byte array data to write.</param>
 294        /// <exception cref="ArgumentNullException"><paramref name="data"/> is <see langword="null"/>.</exception>
 295        protected void Write(byte[] data)
 32600296        {
 32600297            _stream.Write(data);
 32600298        }
 299
 300        /// <summary>
 301        /// Writes a sequence of bytes to the current SSH data stream and advances the current position
 302        /// within this stream by the number of bytes written.
 303        /// </summary>
 304        /// <param name="buffer">An array of bytes. This method write <paramref name="count"/> bytes from buffer to the 
 305        /// <param name="offset">The zero-based offset in <paramref name="buffer"/> at which to begin writing bytes to t
 306        /// <param name="count">The number of bytes to be written to the current SSH data stream.</param>
 307        /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is <see langword="null"/>.</exception>
 308        /// <exception cref="ArgumentException">The sum of <paramref name="offset"/> and <paramref name="count"/> is gre
 309        /// <exception cref="ArgumentOutOfRangeException"><paramref name="offset"/> or <paramref name="count"/> is negat
 310        protected void Write(byte[] buffer, int offset, int count)
 3311        {
 3312            _stream.Write(buffer, offset, count);
 3313        }
 314
 315        /// <summary>
 316        /// Writes <see cref="byte"/> data into internal buffer.
 317        /// </summary>
 318        /// <param name="data"><see cref="byte"/> data to write.</param>
 319        protected void Write(byte data)
 48809320        {
 48809321            _stream.WriteByte(data);
 48809322        }
 323
 324        /// <summary>
 325        /// Writes <see cref="bool"/> into internal buffer.
 326        /// </summary>
 327        /// <param name="data"><see cref="bool" /> data to write.</param>
 328        protected void Write(bool data)
 7845329        {
 7845330            Write(data ? (byte) 1 : (byte) 0);
 7845331        }
 332
 333        /// <summary>
 334        /// Writes <see cref="uint"/> data into internal buffer.
 335        /// </summary>
 336        /// <param name="data"><see cref="uint"/> data to write.</param>
 337        protected void Write(uint data)
 90067338        {
 90067339            _stream.Write(data);
 90067340        }
 341
 342        /// <summary>
 343        /// Writes <see cref="ulong" /> data into internal buffer.
 344        /// </summary>
 345        /// <param name="data"><see cref="ulong"/> data to write.</param>
 346        protected void Write(ulong data)
 8046347        {
 8046348            _stream.Write(data);
 8046349        }
 350
 351        /// <summary>
 352        /// Writes <see cref="string"/> data into internal buffer using default encoding.
 353        /// </summary>
 354        /// <param name="data"><see cref="string"/> data to write.</param>
 355        /// <exception cref="ArgumentNullException"><paramref name="data"/> is <see langword="null"/>.</exception>
 356        protected void Write(string data)
 22357        {
 22358            Write(data, Utf8);
 22359        }
 360
 361        /// <summary>
 362        /// Writes <see cref="string"/> data into internal buffer using the specified encoding.
 363        /// </summary>
 364        /// <param name="data"><see cref="string"/> data to write.</param>
 365        /// <param name="encoding">The character encoding to use.</param>
 366        /// <exception cref="ArgumentNullException"><paramref name="data"/> is <see langword="null"/>.</exception>
 367        /// <exception cref="ArgumentNullException"><paramref name="encoding"/> is <see langword="null"/>.</exception>
 368        protected void Write(string data, Encoding encoding)
 42208369        {
 42208370            _stream.Write(data, encoding);
 42208371        }
 372
 373        /// <summary>
 374        /// Writes mpint data into internal buffer.
 375        /// </summary>
 376        /// <param name="data">mpint data to write.</param>
 377        protected void Write(BigInteger data)
 0378        {
 0379            _stream.Write(data);
 0380        }
 381
 382        /// <summary>
 383        /// Writes name-list data into internal buffer.
 384        /// </summary>
 385        /// <param name="data">name-list data to write.</param>
 386        protected void Write(string[] data)
 42150387        {
 388#if NET || NETSTANDARD2_1_OR_GREATER
 40090389            Write(string.Join(',', data), Ascii);
 390#else
 2060391            Write(string.Join(",", data), Ascii);
 392#endif // NET || NETSTANDARD2_1_OR_GREATER
 42150393        }
 394
 395        /// <summary>
 396        /// Writes extension-pair data into internal buffer.
 397        /// </summary>
 398        /// <param name="data">extension-pair data to write.</param>
 399        protected void Write(IDictionary<string, string> data)
 24400        {
 84401            foreach (var item in data)
 6402            {
 6403                Write(item.Key, Ascii);
 6404                Write(item.Value, Ascii);
 6405            }
 24406        }
 407
 408        /// <summary>
 409        /// Writes data into internal buffer.
 410        /// </summary>
 411        /// <param name="buffer">The data to write.</param>
 412        /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is <see langword="null"/>.</exception>
 413        protected void WriteBinaryString(byte[] buffer)
 96491414        {
 96491415            _stream.WriteBinary(buffer);
 96491416        }
 417
 418        /// <summary>
 419        /// Writes data into internal buffer.
 420        /// </summary>
 421        /// <param name="buffer">An array of bytes. This method write <paramref name="count"/> bytes from buffer to the 
 422        /// <param name="offset">The zero-based byte offset in <paramref name="buffer"/> at which to begin writing bytes
 423        /// <param name="count">The number of bytes to be written to the current SSH data stream.</param>
 424        /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is <see langword="null"/>.</exception>
 425        /// <exception cref="ArgumentException">The sum of <paramref name="offset"/> and <paramref name="count"/> is gre
 426        /// <exception cref="ArgumentOutOfRangeException"><paramref name="offset"/> or <paramref name="count"/> is negat
 427        protected void WriteBinary(byte[] buffer, int offset, int count)
 40880428        {
 40880429            _stream.WriteBinary(buffer, offset, count);
 40880430        }
 431    }
 432}