summary refs log tree commit diff
path: root/crypto
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2024-05-24 22:21:22 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2024-05-24 22:21:22 +0700
commit1232f3b7a583484cd8eda4874cfcdee0c724fa75 (patch)
treedbc5a22c66fc5b0b4a748a636d9107453ae0e4e8 /crypto
parentSetup stable URLs for NuGet (diff)
downloadBouncyCastle.NET-ed25519-1232f3b7a583484cd8eda4874cfcdee0c724fa75.tar.xz
Add helper methods for optional tagged fields
Diffstat (limited to 'crypto')
-rw-r--r--crypto/src/asn1/Asn1Utilities.cs52
1 files changed, 52 insertions, 0 deletions
diff --git a/crypto/src/asn1/Asn1Utilities.cs b/crypto/src/asn1/Asn1Utilities.cs
index eacbf499a..ea61ab01a 100644
--- a/crypto/src/asn1/Asn1Utilities.cs
+++ b/crypto/src/asn1/Asn1Utilities.cs
@@ -649,5 +649,57 @@ namespace Org.BouncyCastle.Asn1
         {
             return TryParseExplicitBaseObject(taggedObjectParser, Asn1Tags.ContextSpecific, tagNo, out baseObject);
         }
+
+        #region Sequence cursor
+
+        public static TResult ReadOptionalContextTagged<TState, TResult>(Asn1Sequence sequence, ref int sequencePosition,
+            int tagNo, TState state, Func<Asn1TaggedObject, TState, TResult> constructor)
+            where TResult : class
+        {
+            return ReadOptionalTagged(sequence, ref sequencePosition, Asn1Tags.ContextSpecific, tagNo, state,
+                constructor);
+        }
+
+        public static TResult ReadOptionalTagged<TState, TResult>(Asn1Sequence sequence, ref int sequencePosition, int tagClass,
+            int tagNo, TState state, Func<Asn1TaggedObject, TState, TResult> constructor)
+            where TResult : class
+        {
+            if (sequencePosition < sequence.Count &&
+                sequence[sequencePosition] is Asn1TaggedObject taggedObject &&
+                taggedObject.HasTag(tagClass, tagNo))
+            {
+                sequencePosition++;
+                return constructor(taggedObject, state);
+            }
+
+            return null;
+        }
+
+        public static bool TryReadOptionalContextTagged<TState, TResult>(Asn1Sequence sequence,
+            ref int sequencePosition, int tagNo, TState state, out TResult result,
+            Func<Asn1TaggedObject, TState, TResult> constructor)
+        {
+            return TryReadOptionalTagged(sequence, ref sequencePosition, Asn1Tags.ContextSpecific, tagNo,
+                state, out result, constructor);
+        }
+
+        public static bool TryReadOptionalTagged<TState, TResult>(Asn1Sequence sequence, ref int sequencePosition,
+            int tagClass, int tagNo, TState state, out TResult result,
+            Func<Asn1TaggedObject, TState, TResult> constructor)
+        {
+            if (sequencePosition < sequence.Count &&
+                sequence[sequencePosition] is Asn1TaggedObject taggedObject &&
+                taggedObject.HasTag(tagClass, tagNo))
+            {
+                sequencePosition++;
+                result = constructor(taggedObject, state);
+                return true;
+            }
+
+            result = default;
+            return false;
+        }
+
+        #endregion
     }
 }