/// <summary> /// Attempts to read the next value as an OCTET STRING with a specified tag, returning the contents /// as a <see cref="ReadOnlyMemory{T}"/> over the original data. /// </summary> /// <param name="expectedTag">The tag to check for before reading.</param> /// <param name="contents"> /// On success, receives a <see cref="ReadOnlyMemory{T}"/> over the original data /// corresponding to the value of the OCTET STRING. /// </param> /// <returns> /// <see langword="true"/> and advances the reader if the OCTET STRING value had a primitive encoding, /// <see langword="false"/> and does not advance the reader if it had a constructed encoding. /// </returns> /// <exception cref="AsnContentException"> /// the next value does not have the correct tag. /// /// -or- /// /// the length encoding is not valid under the current encoding rules. /// /// -or- /// /// the contents are not valid under the current encoding rules. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="expectedTag"/>.<see cref="Asn1Tag.TagClass"/> is /// <see cref="TagClass.Universal"/>, but /// <paramref name="expectedTag"/>.<see cref="Asn1Tag.TagValue"/> is not correct for /// the method. /// </exception> /// <seealso cref="TryReadOctetString"/> public bool TryReadPrimitiveOctetString(out ReadOnlyMemory <byte> contents, Asn1Tag?expectedTag = null) { bool ret = AsnDecoder.TryReadPrimitiveOctetString( _data.Span, RuleSet, out ReadOnlySpan <byte> span, out int consumed, expectedTag); if (ret) { contents = AsnDecoder.Slice(_data, span); _data = _data.Slice(consumed); } else { contents = default; } return(ret); }
/// <summary> /// Write a single value which has already been encoded. /// </summary> /// <param name="value">The value to write.</param> /// <remarks> /// This method only checks that the tag and length are encoded according to the current ruleset, /// and that the end of the value is the end of the input. The contents are not evaluated for /// semantic meaning. /// </remarks> /// <exception cref="ArgumentException"> /// <paramref name="value"/> could not be read under the current encoding rules. /// /// -or- /// /// <paramref name="value"/> has data beyond the end of the first value. /// </exception> public void WriteEncodedValue(ReadOnlySpan <byte> value) { // Is it legal under the current rules? bool read = AsnDecoder.TryReadEncodedValue( value, RuleSet, out _, out _, out _, out int consumed); if (!read || consumed != value.Length) { throw new ArgumentException( SR.Argument_WriteEncodedValue_OneValueAtATime, nameof(value)); } EnsureWriteCapacity(value.Length); value.CopyTo(_buffer.AsSpan(_offset)); _offset += value.Length; }
/// <summary> /// Reads the next value as a BIT STRING with a specified tag, copying the value /// into a provided destination buffer. /// </summary> /// <param name="destination">The buffer in which to write.</param> /// <param name="unusedBitCount"> /// On success, receives the number of bits in the last byte which were reported as /// "unused" by the writer. /// </param> /// <param name="bytesWritten"> /// On success, receives the number of bytes written to <paramref name="destination"/>. /// </param> /// <param name="expectedTag"> /// The tag to check for before reading, or <see langword="null"/> for the default tag (Universal 1). /// </param> /// <returns> /// <see langword="true"/> and advances the reader if <paramref name="destination"/> had sufficient /// length to receive the value, otherwise /// <see langword="false"/> and the reader does not advance. /// </returns> /// <exception cref="AsnContentException"> /// the next value does not have the correct tag. /// /// -or- /// /// the length encoding is not valid under the current encoding rules. /// /// -or- /// /// the contents are not valid under the current encoding rules. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="expectedTag"/>.<see cref="Asn1Tag.TagClass"/> is /// <see cref="TagClass.Universal"/>, but /// <paramref name="expectedTag"/>.<see cref="Asn1Tag.TagValue"/> is not correct for /// the method. /// </exception> /// <seealso cref="TryReadPrimitiveBitString"/> /// <seealso cref="ReadBitString"/> public bool TryReadBitString( Span <byte> destination, out int unusedBitCount, out int bytesWritten, Asn1Tag?expectedTag = null) { bool ret = AsnDecoder.TryReadBitString( _data.Span, destination, RuleSet, out unusedBitCount, out int consumed, out bytesWritten, expectedTag); if (ret) { _data = _data.Slice(consumed); } return(ret); }
/// <summary> /// Reads the next value as a character with a specified tag, returning the contents /// as an unprocessed <see cref="ReadOnlyMemory{T}"/> over the original data. /// </summary> /// <param name="expectedTag">The tag to check for before reading.</param> /// <param name="contents"> /// On success, receives a <see cref="ReadOnlyMemory{T}"/> over the original data /// corresponding to the value of the character string. /// </param> /// <returns> /// <see langword="true"/> and advances the reader if the character string value had a primitive encoding, /// <see langword="false"/> and does not advance the reader if it had a constructed encoding. /// </returns> /// <remarks> /// This method does not determine if the string used only characters defined by the encoding. /// </remarks> /// <exception cref="AsnContentException"> /// the next value does not have the correct tag. /// /// -or- /// /// the length encoding is not valid under the current encoding rules. /// /// -or- /// /// the contents are not valid under the current encoding rules. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="expectedTag"/>.<see cref="Asn1Tag.TagClass"/> is /// <see cref="TagClass.Universal"/>, but /// <paramref name="expectedTag"/>.<see cref="Asn1Tag.TagValue"/> is not a character /// string tag type. /// </exception> /// <seealso cref="TryReadCharacterStringBytes"/> public bool TryReadPrimitiveCharacterStringBytes( Asn1Tag expectedTag, out ReadOnlyMemory <byte> contents) { bool ret = AsnDecoder.TryReadPrimitiveCharacterStringBytes( _data.Span, RuleSet, expectedTag, out ReadOnlySpan <byte> span, out int consumed); if (ret) { contents = AsnDecoder.Slice(_data, span); _data = _data.Slice(consumed); } else { contents = default; } return(ret); }
internal ReadOnlySpan <byte> PeekEncodedValue() { AsnDecoder.ReadEncodedValue(_span, _ruleSet, out _, out _, out int consumed); return(_span.Slice(0, consumed)); }
/// <summary> /// Reads the next value as an OCTET STRING with tag UNIVERSAL 4, returning the value /// in a byte array. /// </summary> /// <param name="expectedTag"> /// The tag to check for before reading, or <see langword="null"/> for the default tag (Universal 4). /// </param> /// <returns> /// A copy of the value in a newly allocated, precisely sized, array. /// </returns> /// <exception cref="AsnContentException"> /// the next value does not have the correct tag. /// /// -or- /// /// the length encoding is not valid under the current encoding rules. /// /// -or- /// /// the contents are not valid under the current encoding rules. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="expectedTag"/>.<see cref="Asn1Tag.TagClass"/> is /// <see cref="TagClass.Universal"/>, but /// <paramref name="expectedTag"/>.<see cref="Asn1Tag.TagValue"/> is not correct for /// the method. /// </exception> /// <seealso cref="TryReadPrimitiveOctetString"/> /// <seealso cref="TryReadOctetString"/> public byte[] ReadOctetString(Asn1Tag?expectedTag = null) { byte[] ret = AsnDecoder.ReadOctetString(_data.Span, RuleSet, out int consumed, expectedTag); _data = _data.Slice(consumed); return(ret); }