From c53008f0f5a295ade456e117b90adcc897a16f83 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Sun, 21 Nov 2021 13:56:31 +0700 Subject: ASN.1 perf. opts --- crypto/src/asn1/Asn1InputStream.cs | 6 +- crypto/src/asn1/DefiniteLengthInputStream.cs | 64 ++++++----- crypto/src/asn1/IndefiniteLengthInputStream.cs | 143 +++++-------------------- crypto/src/asn1/LimitedInputStream.cs | 4 +- 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); } } } -- cgit 1.4.1