summary refs log tree commit diff
path: root/crypto/src/util/encoders/HexEncoder.cs
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2022-10-07 21:23:45 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2022-10-07 21:23:45 +0700
commit18fe04a57aa29219d63fda4d8eb6a8586a1f8091 (patch)
tree524e80ee577220eefb92207764daa6ffe10c8d81 /crypto/src/util/encoders/HexEncoder.cs
parentSpan usage in Math.Raw (diff)
downloadBouncyCastle.NET-ed25519-18fe04a57aa29219d63fda4d8eb6a8586a1f8091.tar.xz
Span usage in encoders
Diffstat (limited to 'crypto/src/util/encoders/HexEncoder.cs')
-rw-r--r--crypto/src/util/encoders/HexEncoder.cs127
1 files changed, 119 insertions, 8 deletions
diff --git a/crypto/src/util/encoders/HexEncoder.cs b/crypto/src/util/encoders/HexEncoder.cs
index bf68aff9d..6ccb184d9 100644
--- a/crypto/src/util/encoders/HexEncoder.cs
+++ b/crypto/src/util/encoders/HexEncoder.cs
@@ -1,3 +1,4 @@
+using Org.BouncyCastle.Crypto;
 using System;
 using System.IO;
 
@@ -41,6 +42,9 @@ namespace Org.BouncyCastle.Utilities.Encoders
 
         public int Encode(byte[] inBuf, int inOff, int inLen, byte[] outBuf, int outOff)
         {
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+            return Encode(inBuf.AsSpan(inOff, inLen), outBuf.AsSpan(outOff));
+#else
             int inPos = inOff;
             int inEnd = inOff + inLen;
             int outPos = outOff;
@@ -54,8 +58,28 @@ namespace Org.BouncyCastle.Utilities.Encoders
             }
 
             return outPos - outOff;
+#endif
         }
 
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        public int Encode(ReadOnlySpan<byte> input, Span<byte> output)
+        {
+            int inPos = 0;
+            int inEnd = input.Length;
+            int outPos = 0;
+
+            while (inPos < inEnd)
+            {
+                uint b = input[inPos++];
+
+                output[outPos++] = encodingTable[b >> 4];
+                output[outPos++] = encodingTable[b & 0xF];
+            }
+
+            return outPos;
+        }
+#endif
+
         /**
         * encode the input data producing a Hex output stream.
         *
@@ -63,6 +87,9 @@ namespace Org.BouncyCastle.Utilities.Encoders
         */
         public int Encode(byte[] buf, int off, int len, Stream outStream)
         {
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+            return Encode(buf.AsSpan(off, len), outStream);
+#else
             if (len < 0)
                 return 0;
 
@@ -77,8 +104,25 @@ namespace Org.BouncyCastle.Utilities.Encoders
                 remaining -= inLen;
             }
             return len * 2;
+#endif
         }
 
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        public int Encode(ReadOnlySpan<byte> data, Stream outStream)
+        {
+            Span<byte> tmp = stackalloc byte[72];
+            int result = data.Length * 2;
+            while (!data.IsEmpty)
+            {
+                int inLen = System.Math.Min(36, data.Length);
+                int outLen = Encode(data[..inLen], tmp);
+                outStream.Write(tmp[..outLen]);
+                data = data[inLen..];
+            }
+            return result;
+        }
+#endif
+
         private static bool Ignore(char c)
         {
             return c == '\n' || c =='\r' || c == '\t' || c == ' ';
@@ -90,12 +134,11 @@ namespace Org.BouncyCastle.Utilities.Encoders
         *
         * @return the number of bytes produced.
         */
-        public int Decode(
-            byte[]	data,
-            int		off,
-            int		length,
-            Stream	outStream)
+        public int Decode(byte[] data, int off, int length, Stream outStream)
         {
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+            return Decode(data.AsSpan(off, length), outStream);
+#else
             byte b1, b2;
             int outLen = 0;
             byte[] buf = new byte[36];
@@ -147,7 +190,65 @@ namespace Org.BouncyCastle.Utilities.Encoders
             }
 
             return outLen;
+#endif
+        }
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        public int Decode(ReadOnlySpan<byte> data, Stream outStream)
+        {
+            byte b1, b2;
+            int outLen = 0;
+            Span<byte> buf = stackalloc byte[36];
+            int bufOff = 0;
+            int end = data.Length;
+
+            while (end > 0)
+            {
+                if (!Ignore((char)data[end - 1]))
+                    break;
+
+                end--;
+            }
+
+            int i = 0;
+            while (i < end)
+            {
+                while (i < end && Ignore((char)data[i]))
+                {
+                    i++;
+                }
+
+                b1 = decodingTable[data[i++]];
+
+                while (i < end && Ignore((char)data[i]))
+                {
+                    i++;
+                }
+
+                b2 = decodingTable[data[i++]];
+
+                if ((b1 | b2) >= 0x80)
+                    throw new IOException("invalid characters encountered in Hex data");
+
+                buf[bufOff++] = (byte)((b1 << 4) | b2);
+
+                if (bufOff == buf.Length)
+                {
+                    outStream.Write(buf);
+                    bufOff = 0;
+                }
+
+                outLen++;
+            }
+
+            if (bufOff > 0)
+            {
+                outStream.Write(buf[..bufOff]);
+            }
+
+            return outLen;
         }
+#endif
 
         /**
         * decode the Hex encoded string data writing it to the given output stream,
@@ -155,13 +256,15 @@ namespace Org.BouncyCastle.Utilities.Encoders
         *
         * @return the number of bytes produced.
         */
-        public int DecodeString(
-            string	data,
-            Stream	outStream)
+        public int DecodeString(string data, Stream outStream)
         {
             byte b1, b2;
             int length = 0;
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+            Span<byte> buf = stackalloc byte[36];
+#else
             byte[] buf = new byte[36];
+#endif
             int bufOff = 0;
             int end = data.Length;
 
@@ -197,7 +300,11 @@ namespace Org.BouncyCastle.Utilities.Encoders
 
                 if (bufOff == buf.Length)
                 {
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+                    outStream.Write(buf);
+#else
                     outStream.Write(buf, 0, bufOff);
+#endif
                     bufOff = 0;
                 }
 
@@ -206,7 +313,11 @@ namespace Org.BouncyCastle.Utilities.Encoders
 
             if (bufOff > 0)
             {
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+                outStream.Write(buf[..bufOff]);
+#else
                 outStream.Write(buf, 0, bufOff);
+#endif
             }
 
             return length;