summary refs log tree commit diff
path: root/crypto/src/asn1/DerEnumerated.cs
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2013-11-03 16:12:13 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2013-11-03 16:12:13 +0700
commite346df986347cead043ca0fe952447bd484a5db3 (patch)
tree4738910f42ae60eb9b58aa618daabaed1fc5354e /crypto/src/asn1/DerEnumerated.cs
parentAdd Poly1305 contributors entry (diff)
downloadBouncyCastle.NET-ed25519-e346df986347cead043ca0fe952447bd484a5db3.tar.xz
Port from Java of improvements to DerBoolean and DerEnumerated
Diffstat (limited to 'crypto/src/asn1/DerEnumerated.cs')
-rw-r--r--crypto/src/asn1/DerEnumerated.cs68
1 files changed, 46 insertions, 22 deletions
diff --git a/crypto/src/asn1/DerEnumerated.cs b/crypto/src/asn1/DerEnumerated.cs
index a62afb301..2638b0205 100644
--- a/crypto/src/asn1/DerEnumerated.cs
+++ b/crypto/src/asn1/DerEnumerated.cs
@@ -10,7 +10,7 @@ namespace Org.BouncyCastle.Asn1
     {
         private readonly byte[] bytes;
 
-		/**
+        /**
          * return an integer from the passed in object
          *
          * @exception ArgumentException if the object cannot be converted.
@@ -39,14 +39,14 @@ namespace Org.BouncyCastle.Asn1
             Asn1TaggedObject	obj,
             bool				isExplicit)
         {
-			Asn1Object o = obj.GetObject();
+            Asn1Object o = obj.GetObject();
 
-			if (isExplicit || o is DerEnumerated)
-			{
-				return GetInstance(o);
-			}
+            if (isExplicit || o is DerEnumerated)
+            {
+                return GetInstance(o);
+            }
 
-			return new DerEnumerated(((Asn1OctetString)o).GetOctets());
+            return FromOctetString(((Asn1OctetString)o).GetOctets());
         }
 
         public DerEnumerated(
@@ -64,37 +64,61 @@ namespace Org.BouncyCastle.Asn1
         public DerEnumerated(
             byte[]   bytes)
         {
-            this.bytes = Arrays.Clone(bytes);
+            this.bytes = bytes;
         }
 
         public BigInteger Value
         {
-            get
-            {
-                return new BigInteger(bytes);
-            }
+            get { return new BigInteger(bytes); }
         }
 
-		internal override void Encode(
+        internal override void Encode(
             DerOutputStream derOut)
         {
             derOut.WriteEncoded(Asn1Tags.Enumerated, bytes);
         }
 
-		protected override bool Asn1Equals(
-			Asn1Object asn1Object)
+        protected override bool Asn1Equals(
+            Asn1Object asn1Object)
         {
-			DerEnumerated other = asn1Object as DerEnumerated;
+            DerEnumerated other = asn1Object as DerEnumerated;
+
+            if (other == null)
+                return false;
 
-			if (other == null)
-				return false;
+            return Arrays.AreEqual(this.bytes, other.bytes);
+        }
 
-			return Arrays.AreEqual(this.bytes, other.bytes);
+        protected override int Asn1GetHashCode()
+        {
+            return Arrays.GetHashCode(bytes);
         }
 
-		protected override int Asn1GetHashCode()
-		{
-			return Arrays.GetHashCode(bytes);
+        private static readonly DerEnumerated[] cache = new DerEnumerated[12];
+
+        internal static DerEnumerated FromOctetString(byte[] enc)
+        {
+            if (enc.Length == 0)
+            {
+                throw new ArgumentException("ENUMERATED has zero length", "enc");
+            }
+
+            if (enc.Length == 1)
+            {
+                int value = enc[0];
+                if (value < cache.Length)
+                {
+                    DerEnumerated cached = cache[value];
+                    if (cached != null)
+                    {
+                        return cached;
+                    }
+
+                    return cache[value] = new DerEnumerated(Arrays.Clone(enc));
+                }
+            }
+
+            return new DerEnumerated(Arrays.Clone(enc));
         }
     }
 }