summary refs log tree commit diff
path: root/crypto/src/asn1/LazyDLSet.cs
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2021-11-08 20:14:47 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2021-11-08 20:14:47 +0700
commit2f23f0acb5dba40ed9fb7e9d340c0dfaf3db035b (patch)
tree99ea424d4c8718f8db82a945d082c5f0f9e49bc8 /crypto/src/asn1/LazyDLSet.cs
parentASN.1 refactoring (diff)
downloadBouncyCastle.NET-ed25519-2f23f0acb5dba40ed9fb7e9d340c0dfaf3db035b.tar.xz
Lazy ASN.1 enumeration and refactoring
Diffstat (limited to '')
-rw-r--r--crypto/src/asn1/LazyDLSet.cs116
1 files changed, 116 insertions, 0 deletions
diff --git a/crypto/src/asn1/LazyDLSet.cs b/crypto/src/asn1/LazyDLSet.cs
new file mode 100644
index 000000000..f644f69e5
--- /dev/null
+++ b/crypto/src/asn1/LazyDLSet.cs
@@ -0,0 +1,116 @@
+using System;
+using System.Collections;
+using System.IO;
+
+namespace Org.BouncyCastle.Asn1
+{
+    internal class LazyDLSet
+        : DerSet
+    {
+        private byte[] encoded;
+
+        internal LazyDLSet(byte[] encoded)
+            : base()
+        {
+            if (null == encoded)
+                throw new ArgumentNullException("encoded");
+
+            this.encoded = encoded;
+        }
+
+        public override Asn1Encodable this[int index]
+        {
+            get
+            {
+                Force();
+
+                return base[index];
+            }
+        }
+
+        public override IEnumerator GetEnumerator()
+        {
+            byte[] encoded = GetContents();
+            if (null != encoded)
+            {
+                return new LazyDLEnumerator(encoded);
+            }
+
+            return base.GetEnumerator();
+        }
+
+        public override int Count
+        {
+            get
+            {
+                Force();
+
+                return base.Count;
+            }
+        }
+
+        public override Asn1Encodable[] ToArray()
+        {
+            Force();
+
+            return base.ToArray();
+        }
+
+        public override string ToString()
+        {
+            Force();
+
+            return base.ToString();
+        }
+
+        internal override int EncodedLength(bool withID)
+        {
+            byte[] encoded = GetContents();
+            if (encoded != null)
+            {
+                return Asn1OutputStream.GetLengthOfEncodingDL(withID, encoded.Length);
+            }
+
+            return base.EncodedLength(withID);
+        }
+
+        internal override void Encode(Asn1OutputStream asn1Out, bool withID)
+        {
+            byte[] encoded = GetContents();
+            if (encoded != null)
+            {
+                asn1Out.WriteEncodingDL(withID, Asn1Tags.Constructed | Asn1Tags.Set, encoded);
+                return;
+            }
+
+            base.Encode(asn1Out, withID);
+        }
+
+        private void Force()
+        {
+            lock (this)
+            {
+                if (null != encoded)
+                {
+                    Asn1InputStream input = new LazyAsn1InputStream(encoded);
+                    try
+                    {
+                        Asn1EncodableVector v = input.ReadVector();
+
+                        this.elements = v.TakeElements();
+                        this.encoded = null;
+                    }
+                    catch (IOException e)
+                    {
+                        throw new Asn1ParsingException("malformed ASN.1: " + e.Message, e);
+                    }
+                }
+            }
+        }
+
+        private byte[] GetContents()
+        {
+            lock (this) return encoded;
+        }
+    }
+}