summary refs log tree commit diff
path: root/Crypto/src/asn1/IndefiniteLengthInputStream.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Crypto/src/asn1/IndefiniteLengthInputStream.cs')
-rw-r--r--Crypto/src/asn1/IndefiniteLengthInputStream.cs166
1 files changed, 166 insertions, 0 deletions
diff --git a/Crypto/src/asn1/IndefiniteLengthInputStream.cs b/Crypto/src/asn1/IndefiniteLengthInputStream.cs
new file mode 100644
index 000000000..56c1bdfbc
--- /dev/null
+++ b/Crypto/src/asn1/IndefiniteLengthInputStream.cs
@@ -0,0 +1,166 @@
+using System;
+using System.IO;
+
+namespace Org.BouncyCastle.Asn1
+{
+	class IndefiniteLengthInputStream
+		: LimitedInputStream
+	{
+        private int _lookAhead;
+        private bool _eofOn00 = true;
+
+		internal IndefiniteLengthInputStream(
+			Stream	inStream,
+			int		limit)
+			: base(inStream, limit)
+		{
+            _lookAhead = RequireByte();
+            CheckForEof();
+		}
+
+		internal void SetEofOn00(
+			bool eofOn00)
+		{
+			_eofOn00 = eofOn00;
+            CheckForEof();
+        }
+
+		private bool CheckForEof()
+		{
+            if (_lookAhead == 0x00 && _eofOn00)
+            {
+                int extra = RequireByte();
+                if (extra != 0)
+                {
+                    throw new IOException("malformed end-of-contents marker");
+                }
+
+                _lookAhead = -1;
+                SetParentEofDetect(true);
+            }
+            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)
+				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();
+
+			return numRead + 1;
+		}
+
+		public override int ReadByte()
+		{
+			if (CheckForEof())
+				return -1;
+
+            int result = _lookAhead;
+            _lookAhead = RequireByte();
+            return result;
+		}
+
+        private int RequireByte()
+        {
+            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;
+//        }
+//    }
+//}