summary refs log tree commit diff
path: root/crypto/src/asn1/tsp/Accuracy.cs
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2024-07-01 19:23:46 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2024-07-01 19:23:46 +0700
commit4e97fa1cbee0072938c5ea33ca51f4e3964f2998 (patch)
tree0aad9c9bc277429ee733c8383672cb7c6aed329a /crypto/src/asn1/tsp/Accuracy.cs
parentRefactoring in Asn1.Smime (diff)
downloadBouncyCastle.NET-ed25519-4e97fa1cbee0072938c5ea33ca51f4e3964f2998.tar.xz
Refactoring in Asn1.Tsp
Diffstat (limited to 'crypto/src/asn1/tsp/Accuracy.cs')
-rw-r--r--crypto/src/asn1/tsp/Accuracy.cs105
1 files changed, 50 insertions, 55 deletions
diff --git a/crypto/src/asn1/tsp/Accuracy.cs b/crypto/src/asn1/tsp/Accuracy.cs
index a4fd0443b..a5c801c93 100644
--- a/crypto/src/asn1/tsp/Accuracy.cs
+++ b/crypto/src/asn1/tsp/Accuracy.cs
@@ -1,10 +1,8 @@
 using System;
 
-using Org.BouncyCastle.Utilities;
-
 namespace Org.BouncyCastle.Asn1.Tsp
 {
-	public class Accuracy
+    public class Accuracy
 		: Asn1Encodable
 	{
         protected const int MinMillis = 1;
@@ -21,73 +19,54 @@ namespace Org.BouncyCastle.Asn1.Tsp
             return new Accuracy(Asn1Sequence.GetInstance(obj));
         }
 
-        public static Accuracy GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        public static Accuracy GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) =>
+            new Accuracy(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+
+        public static Accuracy GetOptional(Asn1Encodable element)
         {
-            return new Accuracy(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+            if (element == null)
+                throw new ArgumentNullException(nameof(element));
+
+            if (element is Accuracy accuracy)
+                return accuracy;
+
+            Asn1Sequence asn1Sequence = Asn1Sequence.GetOptional(element);
+            if (asn1Sequence != null)
+                return new Accuracy(asn1Sequence);
+
+            return null;
         }
 
+        public static Accuracy GetTagged(Asn1TaggedObject taggedObject, bool declaredExplicit) =>
+            new Accuracy(Asn1Sequence.GetTagged(taggedObject, declaredExplicit));
+
         private readonly DerInteger m_seconds;
         private readonly DerInteger m_millis;
         private readonly DerInteger m_micros;
 
-        public Accuracy(DerInteger seconds, DerInteger millis, DerInteger micros)
+        private Accuracy(Asn1Sequence seq)
         {
-            if (null != millis)
-            {
-                int millisValue = millis.IntValueExact;
-                if (millisValue < MinMillis || millisValue > MaxMillis)
-                    throw new ArgumentException("Invalid millis field : not in (1..999)");
-            }
-            if (null != micros)
-            {
-                int microsValue = micros.IntValueExact;
-                if (microsValue < MinMicros || microsValue > MaxMicros)
-                    throw new ArgumentException("Invalid micros field : not in (1..999)");
-            }
+            int count = seq.Count, pos = 0;
+            if (count < 0 || count > 3)
+                throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
 
-            m_seconds = seconds;
-            m_millis = millis;
-            m_micros = micros;
-        }
+            m_seconds = Asn1Utilities.ReadOptional(seq, ref pos, DerInteger.GetOptional);
+            m_millis = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 0, false, DerInteger.GetTagged);
+            m_micros = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 1, false, DerInteger.GetTagged);
 
-        private Accuracy(Asn1Sequence seq)
-        {
-            DerInteger seconds = null;
-            DerInteger millis = null;
-            DerInteger micros = null;
+            if (pos != count)
+                throw new ArgumentException("Unexpected elements in sequence", nameof(seq));
 
-            for (int i = 0; i < seq.Count; ++i)
-            {
-                // seconds
-                if (seq[i] is DerInteger derInteger)
-                {
-                    seconds = derInteger;
-                }
-                else if (seq[i] is Asn1TaggedObject extra)
-                {
-                    switch (extra.TagNo)
-                    {
-                    case 0:
-                        millis = DerInteger.GetInstance(extra, false);
-                        int millisValue = millis.IntValueExact;
-                        if (millisValue < MinMillis || millisValue > MaxMillis)
-                            throw new ArgumentException("Invalid millis field : not in (1..999)");
-                        break;
-                    case 1:
-                        micros = DerInteger.GetInstance(extra, false);
-                        int microsValue = micros.IntValueExact;
-                        if (microsValue < MinMicros || microsValue > MaxMicros)
-                            throw new ArgumentException("Invalid micros field : not in (1..999)");
-                        break;
-                    default:
-                        throw new ArgumentException("Invalid tag number");
-                    }
-                }
-            }
+            Validate();
+        }
 
+        public Accuracy(DerInteger seconds, DerInteger millis, DerInteger micros)
+        {
             m_seconds = seconds;
             m_millis = millis;
             m_micros = micros;
+
+            Validate();
         }
 
         public DerInteger Seconds => m_seconds;
@@ -113,5 +92,21 @@ namespace Org.BouncyCastle.Asn1.Tsp
             v.AddOptionalTagged(false, 1, m_micros);
             return new DerSequence(v);
         }
+
+        private void Validate()
+        {
+            if (m_millis != null)
+            {
+                int millisValue = m_millis.IntValueExact;
+                if (millisValue < MinMillis || millisValue > MaxMillis)
+                    throw new ArgumentException("Invalid millis field : not in (1..999)");
+            }
+            if (m_micros != null)
+            {
+                int microsValue = m_micros.IntValueExact;
+                if (microsValue < MinMicros || microsValue > MaxMicros)
+                    throw new ArgumentException("Invalid micros field : not in (1..999)");
+            }
+        }
     }
 }