summary refs log tree commit diff
path: root/crypto/src/tls/ByteQueue.cs
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/src/tls/ByteQueue.cs')
-rw-r--r--crypto/src/tls/ByteQueue.cs59
1 files changed, 59 insertions, 0 deletions
diff --git a/crypto/src/tls/ByteQueue.cs b/crypto/src/tls/ByteQueue.cs
index 45bec8be4..b85106528 100644
--- a/crypto/src/tls/ByteQueue.cs
+++ b/crypto/src/tls/ByteQueue.cs
@@ -56,6 +56,9 @@ namespace Org.BouncyCastle.Tls
         /// <param name="len">How many bytes to read from the array.</param>
         public void AddData(byte[] buf, int off, int len)
         {
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+            AddData(buf.AsSpan(off, len));
+#else
             if (m_readOnlyBuf)
                 throw new InvalidOperationException("Cannot add data to read-only buffer");
 
@@ -86,8 +89,46 @@ namespace Org.BouncyCastle.Tls
 
             Array.Copy(buf, off, m_databuf, m_skipped + m_available, len);
             m_available += len;
+#endif
         }
 
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        public void AddData(ReadOnlySpan<byte> buffer)
+        {
+            if (m_readOnlyBuf)
+                throw new InvalidOperationException("Cannot add data to read-only buffer");
+
+            int len = buffer.Length;
+            if (m_available == 0)
+            {
+                if (len > m_databuf.Length)
+                {
+                    int desiredSize = NextTwoPow(len | 256);
+                    m_databuf = new byte[desiredSize];
+                }
+                m_skipped = 0;
+            }
+            else if ((m_skipped + m_available + len) > m_databuf.Length)
+            {
+                int desiredSize = NextTwoPow(m_available + len);
+                if (desiredSize > m_databuf.Length)
+                {
+                    byte[] tmp = new byte[desiredSize];
+                    Array.Copy(m_databuf, m_skipped, tmp, 0, m_available);
+                    m_databuf = tmp;
+                }
+                else
+                {
+                    Array.Copy(m_databuf, m_skipped, m_databuf, 0, m_available);
+                }
+                m_skipped = 0;
+            }
+
+            buffer.CopyTo(m_databuf.AsSpan(m_skipped + m_available));
+            m_available += len;
+        }
+#endif
+
         /// <returns>The number of bytes which are available in this buffer.</returns>
         public int Available
         {
@@ -124,6 +165,16 @@ namespace Org.BouncyCastle.Tls
             Array.Copy(m_databuf, m_skipped + skip, buf, offset, len);
         }
 
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        public void Read(Span<byte> buffer, int skip)
+        {
+            if ((m_available - skip) < buffer.Length)
+                throw new InvalidOperationException("Not enough data to read");
+
+            m_databuf.AsSpan(m_skipped + skip, buffer.Length).CopyTo(buffer);
+        }
+#endif
+
         /// <summary>Return a <see cref="HandshakeMessageInput"/> over some bytes at the beginning of the data.
         /// </summary>
         /// <param name="length">How many bytes will be readable.</param>
@@ -182,6 +233,14 @@ namespace Org.BouncyCastle.Tls
             RemoveData(skip + len);
         }
 
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        public void RemoveData(Span<byte> buffer, int skip)
+        {
+            Read(buffer, skip);
+            RemoveData(skip + buffer.Length);
+        }
+#endif
+
         public byte[] RemoveData(int len, int skip)
         {
             byte[] buf = new byte[len];