using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Net; using System.Net.Sockets; using System.Text; using Renci.SshNet.Abstractions; using Renci.SshNet.Common; using Renci.SshNet.Messages; namespace Renci.SshNet { /// /// Collection of different extension method /// internal static partial class Extensions { /// /// Determines whether [is null or white space] [the specified value]. /// /// The value. /// /// true if [is null or white space] [the specified value]; otherwise, false. /// public static bool IsNullOrWhiteSpace(this string value) { if (string.IsNullOrEmpty(value)) return true; for (var i = 0; i < value.Length; i++) { if (!char.IsWhiteSpace(value[i])) return false; } return true; } internal static byte[] ToArray(this ServiceName serviceName) { switch (serviceName) { case ServiceName.UserAuthentication: return SshData.Ascii.GetBytes("ssh-userauth"); case ServiceName.Connection: return SshData.Ascii.GetBytes("ssh-connection"); default: throw new NotSupportedException(string.Format("Service name '{0}' is not supported.", serviceName)); } } internal static ServiceName ToServiceName(this byte[] data) { var sshServiceName = SshData.Ascii.GetString(data, 0, data.Length); switch (sshServiceName) { case "ssh-userauth": return ServiceName.UserAuthentication; case "ssh-connection": return ServiceName.Connection; default: throw new NotSupportedException(string.Format("Service name '{0}' is not supported.", sshServiceName)); } } internal static BigInteger ToBigInteger(this byte[] data) { var reversed = new byte[data.Length]; Buffer.BlockCopy(data, 0, reversed, 0, data.Length); return new BigInteger(reversed.Reverse()); } /// /// Reverses the sequence of the elements in the entire one-dimensional . /// /// The one-dimensional to reverse. /// /// The with its elements reversed. /// internal static T[] Reverse(this T[] array) { Array.Reverse(array); return array; } /// /// Prints out /// /// The bytes. internal static void DebugPrint(this IEnumerable bytes) { var sb = new StringBuilder(); foreach (var b in bytes) { sb.AppendFormat(CultureInfo.CurrentCulture, "0x{0:x2}, ", b); } Debug.WriteLine(sb.ToString()); } /// /// Creates an instance of the specified type using that type's default constructor. /// /// The type to create. /// Type of the instance to create. /// A reference to the newly created object. internal static T CreateInstance(this Type type) where T : class { if (type == null) return null; return Activator.CreateInstance(type) as T; } internal static void ValidatePort(this uint value, string argument) { if (value > IPEndPoint.MaxPort) throw new ArgumentOutOfRangeException(argument, string.Format(CultureInfo.InvariantCulture, "Specified value cannot be greater than {0}.", IPEndPoint.MaxPort)); } internal static void ValidatePort(this int value, string argument) { if (value < IPEndPoint.MinPort) throw new ArgumentOutOfRangeException(argument, string.Format(CultureInfo.InvariantCulture, "Specified value cannot be less than {0}.", IPEndPoint.MinPort)); if (value > IPEndPoint.MaxPort) throw new ArgumentOutOfRangeException(argument, string.Format(CultureInfo.InvariantCulture, "Specified value cannot be greater than {0}.", IPEndPoint.MaxPort)); } /// /// Returns a specified number of contiguous bytes from a given offset. /// /// The array to return a number of bytes from. /// The zero-based offset in at which to begin taking bytes. /// The number of bytes to take from . /// /// A array that contains the specified number of bytes at the specified offset /// of the input array. /// /// is null. /// /// When is zero and equals the length of , /// then is returned. /// public static byte[] Take(this byte[] value, int offset, int count) { if (value == null) throw new ArgumentNullException("value"); if (count == 0) return Array.Empty; if (offset == 0 && value.Length == count) return value; var taken = new byte[count]; Buffer.BlockCopy(value, offset, taken, 0, count); return taken; } /// /// Returns a specified number of contiguous bytes from the start of the specified byte array. /// /// The array to return a number of bytes from. /// The number of bytes to take from . /// /// A array that contains the specified number of bytes at the start of the input array. /// /// is null. /// /// When equals the length of , then /// is returned. /// public static byte[] Take(this byte[] value, int count) { if (value == null) throw new ArgumentNullException("value"); if (count == 0) return Array.Empty; if (value.Length == count) return value; var taken = new byte[count]; Buffer.BlockCopy(value, 0, taken, 0, count); return taken; } public static bool IsEqualTo(this byte[] left, byte[] right) { if (left == null) throw new ArgumentNullException("left"); if (right == null) throw new ArgumentNullException("right"); if (left == right) return true; if (left.Length != right.Length) return false; for (var i = 0; i < left.Length; i++) { if (left[i] != right[i]) return false; } return true; } /// /// Trims the leading zero from a byte array. /// /// The value. /// /// without leading zeros. /// public static byte[] TrimLeadingZeros(this byte[] value) { if (value == null) throw new ArgumentNullException("value"); for (var i = 0; i < value.Length; i++) { if (value[i] == 0) continue; // if the first byte is non-zero, then we return the byte array as is if (i == 0) return value; var remainingBytes = value.Length - i; var cleaned = new byte[remainingBytes]; Buffer.BlockCopy(value, i, cleaned, 0, remainingBytes); return cleaned; } return value; } public static byte[] Concat(this byte[] first, byte[] second) { if (first == null || first.Length == 0) return second; if (second == null || second.Length == 0) return first; var concat = new byte[first.Length + second.Length]; Buffer.BlockCopy(first, 0, concat, 0, first.Length); Buffer.BlockCopy(second, 0, concat, first.Length, second.Length); return concat; } internal static bool CanRead(this Socket socket) { return SocketAbstraction.CanRead(socket); } internal static bool CanWrite(this Socket socket) { return SocketAbstraction.CanWrite(socket); } internal static bool IsConnected(this Socket socket) { if (socket == null) return false; return socket.Connected; } } }