chovy-sign/PspCrypto/Security/Cryptography/Asn1Reader/AsnValueReader.cs

223 lines
7.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace System.Formats.Asn1
{
internal ref struct AsnValueReader
{
private static readonly byte[] s_singleByte = new byte[1];
private ReadOnlySpan<byte> _span;
private readonly AsnEncodingRules _ruleSet;
internal AsnValueReader(ReadOnlySpan<byte> span, AsnEncodingRules ruleSet)
{
_span = span;
_ruleSet = ruleSet;
}
internal bool HasData => !_span.IsEmpty;
internal void ThrowIfNotEmpty()
{
if (!_span.IsEmpty)
{
new AsnReader(s_singleByte, _ruleSet).ThrowIfNotEmpty();
}
}
internal Asn1Tag PeekTag()
{
return Asn1Tag.Decode(_span, out _);
}
internal ReadOnlySpan<byte> PeekContentBytes()
{
AsnDecoder.ReadEncodedValue(
_span,
_ruleSet,
out int contentOffset,
out int contentLength,
out _);
return _span.Slice(contentOffset, contentLength);
}
internal ReadOnlySpan<byte> PeekEncodedValue()
{
AsnDecoder.ReadEncodedValue(_span, _ruleSet, out _, out _, out int consumed);
return _span.Slice(0, consumed);
}
internal ReadOnlySpan<byte> ReadEncodedValue()
{
ReadOnlySpan<byte> value = PeekEncodedValue();
_span = _span.Slice(value.Length);
return value;
}
internal bool ReadBoolean(Asn1Tag? expectedTag = default)
{
bool ret = AsnDecoder.ReadBoolean(_span, _ruleSet, out int consumed, expectedTag);
_span = _span.Slice(consumed);
return ret;
}
internal BigInteger ReadInteger(Asn1Tag? expectedTag = default)
{
BigInteger ret = AsnDecoder.ReadInteger(_span, _ruleSet, out int consumed, expectedTag);
_span = _span.Slice(consumed);
return ret;
}
internal bool TryReadInt32(out int value, Asn1Tag? expectedTag = default)
{
bool ret = AsnDecoder.TryReadInt32(_span, _ruleSet, out value, out int consumed, expectedTag);
_span = _span.Slice(consumed);
return ret;
}
internal ReadOnlySpan<byte> ReadIntegerBytes(Asn1Tag? expectedTag = default)
{
ReadOnlySpan<byte> ret = AsnDecoder.ReadIntegerBytes(_span, _ruleSet, out int consumed, expectedTag);
_span = _span.Slice(consumed);
return ret;
}
internal bool TryReadPrimitiveBitString(
out int unusedBitCount,
out ReadOnlySpan<byte> value,
Asn1Tag? expectedTag = default)
{
bool ret = AsnDecoder.TryReadPrimitiveBitString(
_span,
_ruleSet,
out unusedBitCount,
out value,
out int consumed,
expectedTag);
_span = _span.Slice(consumed);
return ret;
}
internal byte[] ReadBitString(out int unusedBitCount, Asn1Tag? expectedTag = default)
{
byte[] ret = AsnDecoder.ReadBitString(
_span,
_ruleSet,
out unusedBitCount,
out int consumed,
expectedTag);
_span = _span.Slice(consumed);
return ret;
}
internal TFlagsEnum ReadNamedBitListValue<TFlagsEnum>(Asn1Tag? expectedTag = default) where TFlagsEnum : Enum
{
TFlagsEnum ret = AsnDecoder.ReadNamedBitListValue<TFlagsEnum>(_span, _ruleSet, out int consumed, expectedTag);
_span = _span.Slice(consumed);
return ret;
}
internal bool TryReadPrimitiveOctetString(
out ReadOnlySpan<byte> value,
Asn1Tag? expectedTag = default)
{
bool ret = AsnDecoder.TryReadPrimitiveOctetString(
_span,
_ruleSet,
out value,
out int consumed,
expectedTag);
_span = _span.Slice(consumed);
return ret;
}
internal byte[] ReadOctetString(Asn1Tag? expectedTag = default)
{
byte[] ret = AsnDecoder.ReadOctetString(
_span,
_ruleSet,
out int consumed,
expectedTag);
_span = _span.Slice(consumed);
return ret;
}
internal string ReadObjectIdentifier(Asn1Tag? expectedTag = default)
{
string ret = AsnDecoder.ReadObjectIdentifier(_span, _ruleSet, out int consumed, expectedTag);
_span = _span.Slice(consumed);
return ret;
}
internal AsnValueReader ReadSequence(Asn1Tag? expectedTag = default)
{
AsnDecoder.ReadSequence(
_span,
_ruleSet,
out int contentOffset,
out int contentLength,
out int bytesConsumed,
expectedTag);
ReadOnlySpan<byte> content = _span.Slice(contentOffset, contentLength);
_span = _span.Slice(bytesConsumed);
return new AsnValueReader(content, _ruleSet);
}
internal AsnValueReader ReadSetOf(Asn1Tag? expectedTag = default, bool skipSortOrderValidation = false)
{
AsnDecoder.ReadSetOf(
_span,
_ruleSet,
out int contentOffset,
out int contentLength,
out int bytesConsumed,
skipSortOrderValidation: skipSortOrderValidation,
expectedTag: expectedTag);
ReadOnlySpan<byte> content = _span.Slice(contentOffset, contentLength);
_span = _span.Slice(bytesConsumed);
return new AsnValueReader(content, _ruleSet);
}
internal DateTimeOffset ReadUtcTime(Asn1Tag? expectedTag = default)
{
DateTimeOffset ret = AsnDecoder.ReadUtcTime(_span, _ruleSet, out int consumed, expectedTag: expectedTag);
_span = _span.Slice(consumed);
return ret;
}
internal DateTimeOffset ReadGeneralizedTime(Asn1Tag? expectedTag = default)
{
DateTimeOffset ret = AsnDecoder.ReadGeneralizedTime(_span, _ruleSet, out int consumed, expectedTag);
_span = _span.Slice(consumed);
return ret;
}
internal string ReadCharacterString(UniversalTagNumber encodingType, Asn1Tag? expectedTag = default)
{
string ret = AsnDecoder.ReadCharacterString(_span, _ruleSet, encodingType, out int consumed, expectedTag);
_span = _span.Slice(consumed);
return ret;
}
internal TEnum ReadEnumeratedValue<TEnum>(Asn1Tag? expectedTag = null) where TEnum : Enum
{
TEnum ret = AsnDecoder.ReadEnumeratedValue<TEnum>(_span, _ruleSet, out int consumed, expectedTag);
_span = _span.Slice(consumed);
return ret;
}
}
}