summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2021-11-21 13:56:31 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2021-11-21 13:56:31 +0700
commitc53008f0f5a295ade456e117b90adcc897a16f83 (patch)
tree354461b8ffaa71d4f8bddb238bb50307cdf3b094
parentUse Seek when available (diff)
downloadBouncyCastle.NET-ed25519-c53008f0f5a295ade456e117b90adcc897a16f83.tar.xz
ASN.1 perf. opts
-rw-r--r--crypto/src/asn1/Asn1InputStream.cs6
-rw-r--r--crypto/src/asn1/DefiniteLengthInputStream.cs64
-rw-r--r--crypto/src/asn1/IndefiniteLengthInputStream.cs143
-rw-r--r--crypto/src/asn1/LimitedInputStream.cs4
4 files changed, 69 insertions, 148 deletions
diff --git a/crypto/src/asn1/Asn1InputStream.cs b/crypto/src/asn1/Asn1InputStream.cs
index 8ddfc022b..bfa4615bd 100644
--- a/crypto/src/asn1/Asn1InputStream.cs
+++ b/crypto/src/asn1/Asn1InputStream.cs
@@ -77,7 +77,7 @@ namespace Org.BouncyCastle.Asn1
         {
             // TODO[asn1] Special-case zero length first?
 
-            DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(this, length, limit);
+            DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(s, length, limit);
 
             if (0 == (tagHdr & Asn1Tags.Flags))
                 return CreatePrimitiveDerObject(tagNo, defIn, tmpBuffers);
@@ -154,7 +154,7 @@ namespace Org.BouncyCastle.Asn1
 
         public Asn1Object ReadObject()
         {
-            int tagHdr = ReadByte();
+            int tagHdr = s.ReadByte();
             if (tagHdr <= 0)
             {
                 if (tagHdr == 0)
@@ -184,7 +184,7 @@ namespace Org.BouncyCastle.Asn1
             if (0 == (tagHdr & Asn1Tags.Constructed))
                 throw new IOException("indefinite-length primitive encoding encountered");
 
-            IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(this, limit);
+            IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(s, limit);
             Asn1StreamParser sp = new Asn1StreamParser(indIn, limit, tmpBuffers);
 
             int tagClass = tagHdr & Asn1Tags.Private;
diff --git a/crypto/src/asn1/DefiniteLengthInputStream.cs b/crypto/src/asn1/DefiniteLengthInputStream.cs
index 0e4d4c41f..ed5bd2446 100644
--- a/crypto/src/asn1/DefiniteLengthInputStream.cs
+++ b/crypto/src/asn1/DefiniteLengthInputStream.cs
@@ -21,7 +21,7 @@ namespace Org.BouncyCastle.Asn1
                 if (length < 0)
                     throw new ArgumentException("negative lengths not allowed", "length");
 
-                SetParentEofDetect(true);
+                SetParentEofDetect();
             }
 
             this._originalLength = length;
@@ -35,43 +35,49 @@ namespace Org.BouncyCastle.Asn1
 
 		public override int ReadByte()
         {
-			if (_remaining == 0)
-				return -1;
+            if (_remaining < 2)
+            {
+                if (_remaining == 0)
+                    return -1;
 
-			int b = _in.ReadByte();
+                int b = _in.ReadByte();
+                if (b < 0)
+                    throw new EndOfStreamException("DEF length " + _originalLength + " object truncated by " + _remaining);
 
-			if (b < 0)
-				throw new EndOfStreamException("DEF length " + _originalLength + " object truncated by " + _remaining);
+                _remaining = 0;
+                SetParentEofDetect();
 
-			if (--_remaining == 0)
-			{
-				SetParentEofDetect(true);
-			}
+                return b;
+            }
+            else
+            {
+                int b = _in.ReadByte();
+                if (b < 0)
+                    throw new EndOfStreamException("DEF length " + _originalLength + " object truncated by " + _remaining);
 
-			return b;
+                --_remaining;
+                return b;
+            }
         }
 
-		public override int Read(
-			byte[]	buf,
-			int		off,
-			int		len)
+		public override int Read(byte[] buf, int off, int len)
 		{
-			if (_remaining == 0)
-				return 0;
+            if (_remaining == 0)
+                return 0;
 
-			int toRead = System.Math.Min(len, _remaining);
-			int numRead = _in.Read(buf, off, toRead);
+            int toRead = System.Math.Min(len, _remaining);
+            int numRead = _in.Read(buf, off, toRead);
 
-			if (numRead < 1)
-				throw new EndOfStreamException("DEF length " + _originalLength + " object truncated by " + _remaining);
+            if (numRead < 1)
+                throw new EndOfStreamException("DEF length " + _originalLength + " object truncated by " + _remaining);
 
-			if ((_remaining -= numRead) == 0)
-			{
-				SetParentEofDetect(true);
-			}
+            if ((_remaining -= numRead) == 0)
+            {
+                SetParentEofDetect();
+            }
 
-			return numRead;
-		}
+            return numRead;
+        }
 
         internal void ReadAllIntoByteArray(byte[] buf)
         {
@@ -88,7 +94,7 @@ namespace Org.BouncyCastle.Asn1
 
             if ((_remaining -= Streams.ReadFully(_in, buf, 0, buf.Length)) != 0)
                 throw new EndOfStreamException("DEF length " + _originalLength + " object truncated by " + _remaining);
-            SetParentEofDetect(true);
+            SetParentEofDetect();
         }
 
         internal byte[] ToArray()
@@ -104,7 +110,7 @@ namespace Org.BouncyCastle.Asn1
             byte[] bytes = new byte[_remaining];
 			if ((_remaining -= Streams.ReadFully(_in, bytes, 0, bytes.Length)) != 0)
 				throw new EndOfStreamException("DEF length " + _originalLength + " object truncated by " + _remaining);
-			SetParentEofDetect(true);
+			SetParentEofDetect();
 			return bytes;
 		}
     }
diff --git a/crypto/src/asn1/IndefiniteLengthInputStream.cs b/crypto/src/asn1/IndefiniteLengthInputStream.cs
index 09d0e3a42..1c8bd9a15 100644
--- a/crypto/src/asn1/IndefiniteLengthInputStream.cs
+++ b/crypto/src/asn1/IndefiniteLengthInputStream.cs
@@ -9,61 +9,47 @@ namespace Org.BouncyCastle.Asn1
         private int _lookAhead;
         private bool _eofOn00 = true;
 
-		internal IndefiniteLengthInputStream(
-			Stream	inStream,
-			int		limit)
+		internal IndefiniteLengthInputStream(Stream	inStream, int limit)
 			: base(inStream, limit)
 		{
             _lookAhead = RequireByte();
-            CheckForEof();
-		}
 
-		internal void SetEofOn00(
-			bool eofOn00)
-		{
-			_eofOn00 = eofOn00;
-            if (_eofOn00)
+            if (0 == _lookAhead)
             {
-                CheckForEof();
+                CheckEndOfContents();
             }
         }
 
-        private bool CheckForEof()
+		internal void SetEofOn00(bool eofOn00)
 		{
-            if (_lookAhead == 0x00)
+			_eofOn00 = eofOn00;
+            if (_eofOn00 && 0 == _lookAhead)
             {
-                int extra = RequireByte();
-                if (extra != 0)
-                {
-                    throw new IOException("malformed end-of-contents marker");
-                }
-
-                _lookAhead = -1;
-                SetParentEofDetect(true);
-                return true;
+                CheckEndOfContents();
             }
-            return _lookAhead < 0;
         }
 
-		public override int Read(
-			byte[]	buffer,
-			int		offset,
-			int		count)
-		{
-			// Only use this optimisation if we aren't checking for 00
-			if (_eofOn00 || count <= 1)
+        private void CheckEndOfContents()
+        {
+            if (0 != RequireByte())
+                throw new IOException("malformed end-of-contents marker");
+
+            _lookAhead = -1;
+            SetParentEofDetect();
+        }
+
+        public override int Read(byte[] buffer, int offset, int count)
+        {
+            // Only use this optimisation if we aren't checking for 00
+            if (_eofOn00 || count <= 1)
 				return base.Read(buffer, offset, count);
 
 			if (_lookAhead < 0)
 				return 0;
 
 			int numRead = _in.Read(buffer, offset + 1, count - 1);
-
 			if (numRead <= 0)
-			{
-				// Corrupted stream
 				throw new EndOfStreamException();
-			}
 
 			buffer[offset] = (byte)_lookAhead;
 			_lookAhead = RequireByte();
@@ -73,8 +59,14 @@ namespace Org.BouncyCastle.Asn1
 
 		public override int ReadByte()
 		{
-            if (_eofOn00 && CheckForEof())
-				return -1;
+            if (_eofOn00 && _lookAhead <= 0)
+            {
+                if (0 == _lookAhead)
+                {
+                    CheckEndOfContents();
+                }
+                return -1;
+            }
 
             int result = _lookAhead;
             _lookAhead = RequireByte();
@@ -85,86 +77,9 @@ namespace Org.BouncyCastle.Asn1
         {
             int b = _in.ReadByte();
             if (b < 0)
-            {
-                // Corrupted stream
                 throw new EndOfStreamException();
-            }
+
             return b;
         }
 	}
 }
-
-//using System;
-//using System.IO;
-
-//namespace Org.BouncyCastle.Asn1
-//{
-//    class IndefiniteLengthInputStream
-//        : LimitedInputStream
-//    {
-//        private bool _eofReached = false;
-//        private bool _eofOn00 = true;
-
-//        internal IndefiniteLengthInputStream(
-//            Stream	inStream,
-//            int		limit)
-//            : base(inStream, limit)
-//        {
-//        }
-
-//        internal void SetEofOn00(
-//            bool eofOn00)
-//        {
-//            _eofOn00 = eofOn00;
-//        }
-
-//        public override int Read(
-//            byte[]	buffer,
-//            int		offset,
-//            int		count)
-//        {
-//            if (_eofReached)
-//                return 0;
-
-//            if (_eofOn00)
-//                return base.Read(buffer, offset, count);
-
-//            int numRead = _in.Read(buffer, offset, count);
-
-//            if (numRead <= 0)
-//                throw new EndOfStreamException();
-
-//            return numRead;
-//        }
-
-//        public override int ReadByte()
-//        {
-//            if (_eofReached)
-//                return -1;
-
-//            int b1 = _in.ReadByte();
-
-//            if (b1 < 0)
-//                throw new EndOfStreamException();
-
-//            if (b1 == 0 && _eofOn00)
-//            {
-//                int b2 = _in.ReadByte();
-
-//                if (b2 < 0)
-//                    throw new EndOfStreamException();
-
-//                if (b2 == 0)
-//                {
-//                    _eofReached = true;
-//                    SetParentEofDetect(true);
-//                    return -1;
-//                }
-
-//                throw new InvalidDataException();
-//            }
-
-//            return b1;
-//        }
-//    }
-//}
diff --git a/crypto/src/asn1/LimitedInputStream.cs b/crypto/src/asn1/LimitedInputStream.cs
index 98a45876d..95bf0b63a 100644
--- a/crypto/src/asn1/LimitedInputStream.cs
+++ b/crypto/src/asn1/LimitedInputStream.cs
@@ -21,11 +21,11 @@ namespace Org.BouncyCastle.Asn1
             get { return _limit; }
         }
 
-        protected virtual void SetParentEofDetect(bool on)
+        protected void SetParentEofDetect()
         {
             if (_in is IndefiniteLengthInputStream)
             {
-                ((IndefiniteLengthInputStream)_in).SetEofOn00(on);
+                ((IndefiniteLengthInputStream)_in).SetEofOn00(true);
             }
         }
     }