Explorar o código

Added doc for Take.
Added null checks to IsEqualTo.

drieseng %!s(int64=9) %!d(string=hai) anos
pai
achega
49efc18690

+ 4 - 3
src/Renci.SshNet.Tests/Classes/Common/ExtensionsTest_Concat.cs

@@ -133,7 +133,7 @@ namespace Renci.SshNet.Tests.Classes.Common
 
             GC.Collect();
             GC.WaitForPendingFinalizers();
-            GC.WaitForFullGCComplete();
+            GC.Collect();
 
             stopWatch.Start();
 
@@ -145,7 +145,7 @@ namespace Renci.SshNet.Tests.Classes.Common
 
             GC.Collect();
             GC.WaitForPendingFinalizers();
-            GC.WaitForFullGCComplete();
+            GC.Collect();
 
             stopWatch.Stop();
 
@@ -160,7 +160,8 @@ namespace Renci.SshNet.Tests.Classes.Common
             }
 
             GC.Collect();
-            GC.WaitForFullGCComplete();
+            GC.WaitForPendingFinalizers();
+            GC.Collect();
 
             stopWatch.Stop();
 

+ 183 - 2
src/Renci.SshNet.Tests/Classes/Common/ExtensionsTest_IsEqualTo_ByteArray.cs

@@ -1,6 +1,187 @@
-namespace Renci.SshNet.Tests.Classes.Common
+using System;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Common;
+
+namespace Renci.SshNet.Tests.Classes.Common
 {
-    class ExtensionsTest_IsEqualTo_ByteArray
+    [TestClass]
+    [SuppressMessage("ReSharper", "InvokeAsExtensionMethod")]
+    public class ExtensionsTest_IsEqualTo_ByteArray
     {
+        private Random _random;
+
+        [TestInitialize]
+        public void Init()
+        {
+            _random = new Random();
+        }
+
+        [TestMethod]
+        public void ShouldThrowArgumentNullExceptionWhenLeftIsNull()
+        {
+            const byte[] left = null;
+            var right = CreateBuffer(1);
+
+            try
+            {
+                Extensions.IsEqualTo(left, right);
+                Assert.Fail();
+            }
+            catch (ArgumentNullException ex)
+            {
+                Assert.IsNull(ex.InnerException);
+                Assert.AreEqual("left", ex.ParamName);
+            }
+        }
+
+        [TestMethod]
+        public void ShouldThrowArgumentNullExceptionWhenRightIsNull()
+        {
+            var left = CreateBuffer(1);
+            const byte[] right = null;
+
+            try
+            {
+                Extensions.IsEqualTo(left, right);
+                Assert.Fail();
+            }
+            catch (ArgumentNullException ex)
+            {
+                Assert.IsNull(ex.InnerException);
+                Assert.AreEqual("right", ex.ParamName);
+            }
+        }
+
+        [TestMethod]
+        public void ShouldThrowArgumentNullExceptionWhenLeftAndRightAreNull()
+        {
+            const byte[] left = null;
+            const byte[] right = null;
+
+            try
+            {
+                Extensions.IsEqualTo(left, right);
+                Assert.Fail();
+            }
+            catch (ArgumentNullException ex)
+            {
+                Assert.IsNull(ex.InnerException);
+                Assert.AreEqual("left", ex.ParamName);
+            }
+        }
+
+        [TestMethod]
+        public void ShouldReturnFalseWhenLeftIsNotEqualToRight()
+        {
+            Assert.IsFalse(Extensions.IsEqualTo(new byte[] {0x0a}, new byte[] {0x0a, 0x0d}));
+            Assert.IsFalse(Extensions.IsEqualTo(new byte[] { 0x0a, 0x0d }, new byte[] { 0x0a }));
+            Assert.IsFalse(Extensions.IsEqualTo(new byte[0], new byte[] { 0x0a }));
+            Assert.IsFalse(Extensions.IsEqualTo(new byte[] { 0x0a, 0x0d }, new byte[0]));
+        }
+
+        [TestMethod]
+        public void ShouldReturnTrueWhenLeftIsEqualToRight()
+        {
+            Assert.IsTrue(Extensions.IsEqualTo(new byte[] { 0x0a, 0x0d }, new byte[] { 0x0a, 0x0d }));
+            Assert.IsTrue(Extensions.IsEqualTo(new byte[0], new byte[0]));
+        }
+
+        [TestMethod]
+        public void ShouldReturnTrueWhenLeftIsSameAsRight()
+        {
+            var left = new byte[] { 0x0d, 0x0d };
+
+            Assert.IsTrue(Extensions.IsEqualTo(left, left));
+        }
+
+        [TestMethod]
+        public void Performance_LargeArray_Equal()
+        {
+            var buffer = CreateBuffer(50000);
+            var left = buffer.Concat(new byte[] {0x0a});
+            var right = buffer.Concat(new byte[] { 0x0a });
+            const int runs = 10000;
+
+            Performance(left, right, runs);
+        }
+        [TestMethod]
+        public void Performance_LargeArray_NotEqual_DifferentLength()
+        {
+            var left = CreateBuffer(50000);
+            var right = left.Concat(new byte[] {0x0a});
+            const int runs = 10000;
+
+            Performance(left, right, runs);
+        }
+
+        [TestMethod]
+        public void Performance_LargeArray_NotEqual_SameLength()
+        {
+            var buffer = CreateBuffer(50000);
+            var left = buffer.Concat(new byte[] { 0x0a });
+            var right = buffer.Concat(new byte[] { 0x0b });
+            const int runs = 10000;
+
+            Performance(left, right, runs);
+        }
+
+        [TestMethod]
+        public void Performance_LargeArray_Same()
+        {
+            var left = CreateBuffer(50000);
+            var right = left.Concat(new byte[] { 0x0a });
+            const int runs = 10000;
+
+            Performance(left, right, runs);
+        }
+
+        private void Performance(byte[] left, byte[] right, int runs)
+        {
+            var stopWatch = new Stopwatch();
+
+            GC.Collect();
+            GC.WaitForPendingFinalizers();
+            GC.Collect();
+
+            stopWatch.Start();
+
+            for (var i = 0; i < runs; i++)
+            {
+                Extensions.IsEqualTo(left, right);
+            }
+
+            GC.Collect();
+            GC.WaitForPendingFinalizers();
+            GC.Collect();
+
+            stopWatch.Stop();
+
+            Console.WriteLine(stopWatch.ElapsedMilliseconds);
+
+            stopWatch.Restart();
+
+            for (var i = 0; i < runs; i++)
+            {
+                var result = Enumerable.SequenceEqual(left, right);
+            }
+
+            GC.Collect();
+            GC.WaitForPendingFinalizers();
+            GC.Collect();
+
+            stopWatch.Stop();
+
+            Console.WriteLine(stopWatch.ElapsedMilliseconds);
+        }
+
+        private byte[] CreateBuffer(int length)
+        {
+            var buffer = new byte[length];
+            _random.NextBytes(buffer);
+            return buffer;
+        }
     }
 }

+ 5 - 5
src/Renci.SshNet.Tests/Classes/Common/ExtensionsTest_Take_Count.cs

@@ -58,8 +58,7 @@ namespace Renci.SshNet.Tests.Classes.Common
             var actual = Extensions.Take(value, count);
 
             Assert.IsNotNull(actual);
-            Assert.AreEqual(value.Length, actual.Length);
-            Assert.AreEqual(value, actual);
+            Assert.AreSame(value, actual);
         }
 
         [TestMethod]
@@ -141,7 +140,7 @@ namespace Renci.SshNet.Tests.Classes.Common
 
             GC.Collect();
             GC.WaitForPendingFinalizers();
-            GC.WaitForFullGCComplete();
+            GC.Collect();
 
             stopWatch.Start();
 
@@ -153,7 +152,7 @@ namespace Renci.SshNet.Tests.Classes.Common
 
             GC.Collect();
             GC.WaitForPendingFinalizers();
-            GC.WaitForFullGCComplete();
+            GC.Collect();
 
             stopWatch.Stop();
 
@@ -168,7 +167,8 @@ namespace Renci.SshNet.Tests.Classes.Common
             }
 
             GC.Collect();
-            GC.WaitForFullGCComplete();
+            GC.WaitForPendingFinalizers();
+            GC.Collect();
 
             stopWatch.Stop();
 

+ 28 - 8
src/Renci.SshNet/Common/Extensions.cs

@@ -228,6 +228,11 @@ namespace Renci.SshNet.Common
         /// A <see cref="byte"/> array that contains the specified number of bytes at the specified offset
         /// of the input array.
         /// </returns>
+        /// <exception cref="ArgumentNullException"><paramref name="value"/> is <c>null</c>.</exception>
+        /// <remarks>
+        /// When <paramref name="offset"/> is zero and <paramref name="count"/> equals the length of <paramref name="value"/>,
+        /// then <paramref name="value"/> is returned.
+        /// </remarks>
         public static byte[] Take(this byte[] value, int offset, int count)
         {
             if (value == null)
@@ -244,6 +249,19 @@ namespace Renci.SshNet.Common
             return taken;
         }
 
+        /// <summary>
+        /// Returns a specified number of contiguous bytes from the start of the specified byte array.
+        /// </summary>
+        /// <param name="value">The array to return a number of bytes from.</param>
+        /// <param name="count">The number of bytes to take from <paramref name="value"/>.</param>
+        /// <returns>
+        /// A <see cref="byte"/> array that contains the specified number of bytes at the start of the input array.
+        /// </returns>
+        /// <exception cref="ArgumentNullException"><paramref name="value"/> is <c>null</c>.</exception>
+        /// <remarks>
+        /// When <paramref name="count"/> equals the length of <paramref name="value"/>, then <paramref name="value"/>
+        /// is returned.
+        /// </remarks>
         public static byte[] Take(this byte[] value, int count)
         {
             if (value == null)
@@ -260,20 +278,22 @@ namespace Renci.SshNet.Common
             return taken;
         }
 
-        public static bool IsEqualTo(this byte[] first, byte[] second)
+        public static bool IsEqualTo(this byte[] left, byte[] right)
         {
-            if (first == second)
-                return true;
+            if (left == null)
+                throw new ArgumentNullException("left");
+            if (right == null)
+                throw new ArgumentNullException("right");
 
-            if (first == null || second == null)
-                return false;
+            if (left == right)
+                return true;
 
-            if (first.Length != second.Length)
+            if (left.Length != right.Length)
                 return false;
 
-            for (var i = 0; i < first.Length; i++)
+            for (var i = 0; i < left.Length; i++)
             {
-                if (first[i] != second[i])
+                if (left[i] != right[i])
                     return false;
             }