protected virtual TypeConstructor FindTypeConstructor(DerAsnIdentifier identifier) { if (_registeredClassSpecificTypes.TryGetValue(identifier, out var classSpecificTypeConstructor)) { return(classSpecificTypeConstructor); } var typeKey = new TypeKey { EncodingType = identifier.EncodingType, Tag = identifier.Tag }; if (_registeredTypes.TryGetValue(typeKey, out classSpecificTypeConstructor)) { return(classSpecificTypeConstructor); } return(null); }
/// <summary> /// Decode a single ASN.1 type encoded in the given byte queue. /// </summary> /// <param name="data">The data.</param> /// <returns>The decoded ASN.1 type (primitive or constructed set/sequence).</returns> public DerAsnType Decode(Queue <byte> data) { var identifier = DerAsnIdentifier.Decode(data); var typeConstructor = FindTypeConstructor(identifier) ?? throw new InvalidOperationException($"No type registered for identifier {identifier}"); var length = DerAsnLength.Decode(data); if (data.Count < length) { throw new InvalidOperationException($"Expected {length} bytes to decode type with identifier {identifier} but got {data.Count} bytes"); } var dataForType = new Queue <byte>(data.Dequeue(length.Length)); return(typeConstructor(this, identifier, dataForType)); }
/// <summary> /// Registers a class dependent type. /// </summary> /// <param name="identifier">The exact tag identifier of the type.</param> /// <param name="typeConstructor">The type constructor.</param> /// <param name="replace">True to allow replacing an existing registration, otherwise false</param> /// <returns>The <see cref="DefaultDerAsnDecoder"/> instance.</returns> public DefaultDerAsnDecoder RegisterType(DerAsnIdentifier identifier, TypeConstructor typeConstructor, bool replace = false) { if (identifier == null) { throw new ArgumentNullException(nameof(identifier)); } if (typeConstructor == null) { throw new ArgumentNullException(nameof(typeConstructor)); } if (!replace && _registeredClassSpecificTypes.ContainsKey(identifier)) { throw new InvalidOperationException($"Type with class {identifier.TagClass}, encoding type {identifier.EncodingType} and tag number {identifier.Tag} already registered"); } _registeredClassSpecificTypes[identifier] = typeConstructor; return(this); }
protected DerAsnType(DerAsnIdentifier identifier) { Identifier = identifier; }