Skip to content

Commit c7a683e

Browse files
committed
even better use of spans in string and Enumerated types
1 parent c1f3fbd commit c7a683e

7 files changed

Lines changed: 35 additions & 22 deletions

File tree

Asn1Parser/Asn1Utils.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.IO;
33
using System.Text;
44
using SysadminsLV.Asn1Parser.Universal;
5+
using SysadminsLV.Asn1Parser.Utils.CLRExtensions;
56

67
namespace SysadminsLV.Asn1Parser;
78

@@ -213,7 +214,7 @@ static String decodeOctetString(Asn1Reader asn) {
213214
EncodingFormat.NOCRLF);
214215
}
215216
static String decodeAsciiString(Asn1Reader asn) {
216-
return Encoding.ASCII.GetString(asn.GetRawDataAsMemory().ToArray(), asn.PayloadStartOffset, asn.PayloadLength);
217+
return Encoding.ASCII.GetString(asn.GetRawDataAsMemory().Slice(asn.PayloadStartOffset, asn.PayloadLength).Span);
217218
}
218219
static String decodeUtcTime(Asn1Reader asn) {
219220
DateTime dt = new Asn1UtcTime(asn).Value;

Asn1Parser/Universal/Asn1BmpString.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
using System;
22
using System.Text;
3+
using SysadminsLV.Asn1Parser.Utils.CLRExtensions;
34

45
namespace SysadminsLV.Asn1Parser.Universal;
56

67
/// <summary>
7-
/// Represents a <strong>BMPString</strong> ASN.1 tag object. <Strong>BMPString</Strong> is a 16-bit unicode
8+
/// Represents a <strong>BMPString</strong> ASN.1 tag object. <Strong>BMPString</Strong> is a 16-bit Unicode
89
/// string where each character is encoded by using two bytes in Big-Endian encoding.
910
/// </summary>
1011
public sealed class Asn1BMPString : Asn1String {
@@ -22,15 +23,15 @@ public Asn1BMPString(Asn1Reader asn) : base(asn, TYPE) {
2223
m_decode(asn);
2324
}
2425
/// <summary>
25-
/// Initializes a new instance of <strong>Asn1BitString</strong> from a ASN.1-encoded memory buffer.
26+
/// Initializes a new instance of <strong>Asn1BitString</strong> from an ASN.1-encoded memory buffer.
2627
/// </summary>
2728
/// <param name="rawData">ASN.1-encoded memory buffer.</param>
2829
/// <exception cref="Asn1InvalidTagException">
2930
/// <strong>rawData</strong> is not <strong>BMPString</strong> data type.
3031
/// </exception>
3132
public Asn1BMPString(ReadOnlyMemory<Byte> rawData) : this(new Asn1Reader(rawData)) { }
3233
/// <summary>
33-
/// Initializes a new instance of the <strong>Asn1BMPString</strong> class from a unicode string.
34+
/// Initializes a new instance of the <strong>Asn1BMPString</strong> class from a Unicode Basic Multilingual Plane string.
3435
/// </summary>
3536
/// <param name="inputString">A unicode string to encode.</param>
3637
public Asn1BMPString(String inputString) : base(TYPE) {
@@ -42,6 +43,6 @@ void m_encode(String inputString) {
4243
Initialize(Asn1Utils.EncodeAsReader(Encoding.BigEndianUnicode.GetBytes(inputString).AsSpan(), TYPE));
4344
}
4445
void m_decode(Asn1Reader asn) {
45-
Value = Encoding.BigEndianUnicode.GetString(asn.GetPayload());
46+
Value = Encoding.BigEndianUnicode.GetString(asn.GetPayloadAsMemory().Span);
4647
}
4748
}

Asn1Parser/Universal/Asn1Enumerated.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,14 @@ void m_encode(BigInteger inputInteger) {
4949
Initialize(Asn1Utils.EncodeAsReader(inputInteger.GetAsnBytes(), TYPE));
5050
}
5151
void m_decode(Asn1Reader asn) {
52-
var value = new BigInteger(asn.GetPayload().Cast<Byte>().Reverse().ToArray());
52+
ReadOnlySpan<Byte> payload = asn.GetPayloadAsMemory().Span;
53+
#if NET8_0_OR_GREATER
54+
// BigInteger constructor with isBigEndian parameter (available in .NET 5+)
55+
var value = new BigInteger(payload, isUnsigned: true, isBigEndian: true);
56+
#else
57+
// Fallback for .NET Framework: reverse to little-endian
58+
var value = new BigInteger(payload.ToArray().Cast<Byte>().Reverse().ToArray());
59+
#endif
5360
if (value > UInt64.MaxValue) {
5461
throw new InvalidDataException(String.Format(InvalidType, TYPE.ToString()));
5562
}

Asn1Parser/Universal/Asn1PrintableString.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public Asn1PrintableString(Asn1Reader asn) : base(asn, TYPE) {
3030
m_decode(asn);
3131
}
3232
/// <summary>
33-
/// Initializes a new instance of <strong>Asn1PrintableString</strong> from a ASN.1-encoded memory buffer.
33+
/// Initializes a new instance of <strong>Asn1PrintableString</strong> from an ASN.1-encoded memory buffer.
3434
/// </summary>
3535
/// <param name="rawData">ASN.1-encoded memory buffer.</param>
3636
/// <exception cref="Asn1InvalidTagException">
@@ -41,7 +41,7 @@ public Asn1PrintableString(Asn1Reader asn) : base(asn, TYPE) {
4141
/// </exception>
4242
public Asn1PrintableString(ReadOnlyMemory<Byte> rawData) : this(new Asn1Reader(rawData)) { }
4343
/// <summary>
44-
/// Initializes a new instance of the <strong>Asn1PrintableString</strong> class from a unicode string.
44+
/// Initializes a new instance of the <strong>Asn1PrintableString</strong> class from a string that contains printable characters.
4545
/// </summary>
4646
/// <param name="inputString">A unicode string to encode.</param>
4747
/// <exception cref="InvalidDataException">

Asn1Parser/Universal/Asn1UTF8String.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public Asn1UTF8String(Asn1Reader asn) : base(asn, TYPE) {
2828
m_decode(asn);
2929
}
3030
/// <summary>
31-
/// Initializes a new instance of <strong>Asn1UTF8String</strong> from a ASN.1-encoded memory buffer.
31+
/// Initializes a new instance of <strong>Asn1UTF8String</strong> from an ASN.1-encoded memory buffer.
3232
/// </summary>
3333
/// <param name="rawData">ASN.1-encoded memory buffer.</param>
3434
/// <exception cref="Asn1InvalidTagException">
@@ -39,7 +39,7 @@ public Asn1UTF8String(Asn1Reader asn) : base(asn, TYPE) {
3939
/// </exception>
4040
public Asn1UTF8String(ReadOnlyMemory<Byte> rawData) : this(new Asn1Reader(rawData)) { }
4141
/// <summary>
42-
/// Initializes a new instance of the <strong>Asn1UTF8String</strong> class from a Unicode string.
42+
/// Initializes a new instance of the <strong>Asn1UTF8String</strong> class from a UTF-8 string.
4343
/// </summary>
4444
/// <param name="inputString">A unicode string to encode.</param>
4545
/// <exception cref="InvalidDataException">

Asn1Parser/Universal/Asn1UniversalString.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using System;
22
using System.IO;
3-
using System.Linq;
43
using System.Text;
4+
using SysadminsLV.Asn1Parser.Utils.CLRExtensions;
55

66
namespace SysadminsLV.Asn1Parser.Universal;
77

@@ -32,7 +32,7 @@ public Asn1UniversalString(Asn1Reader asn) : base(asn, TYPE) {
3232
/// </exception>
3333
public Asn1UniversalString(ReadOnlyMemory<Byte> rawData) : this(new Asn1Reader(rawData)) { }
3434
/// <summary>
35-
/// Initializes a new instance of the <strong>Asn1UniversalString</strong> class from a unicode string.
35+
/// Initializes a new instance of the <strong>Asn1UniversalString</strong> class from a Unicode string.
3636
/// </summary>
3737
/// <param name="inputString">A unicode string to encode.</param>
3838
/// <exception cref="InvalidDataException">
@@ -44,14 +44,14 @@ public Asn1UniversalString(String inputString) : base(TYPE) {
4444

4545
void m_encode(String inputString) {
4646
Value = inputString;
47-
Initialize(Asn1Utils.EncodeAsReader(Encoding.UTF32.GetBytes(inputString.Reverse().ToArray())
48-
.Cast<Byte>()
49-
.Reverse()
50-
.ToArray()
51-
.AsSpan(),
52-
TYPE));
47+
// UTF-32BE encoding (big-endian, no BOM)
48+
var utf32be = new UTF32Encoding(bigEndian: true, byteOrderMark: false);
49+
Initialize(Asn1Utils.EncodeAsReader(utf32be.GetBytes(inputString).AsSpan(), TYPE));
5350
}
5451
void m_decode(Asn1Reader asn) {
55-
Value = new String(Encoding.UTF32.GetString(asn.GetPayload().Cast<Byte>().Reverse().ToArray()).Reverse().ToArray());
52+
// UTF-32BE decoding (big-endian, no BOM)
53+
var utf32be = new UTF32Encoding(bigEndian: true, byteOrderMark: false);
54+
ReadOnlySpan<Byte> payload = asn.GetPayloadAsMemory().Span;
55+
Value = utf32be.GetString(payload);
5656
}
5757
}

Asn1Parser/Universal/Asn1VisibleString.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.IO;
33
using System.Linq;
44
using System.Text;
5+
using SysadminsLV.Asn1Parser.Utils.CLRExtensions;
56

67
namespace SysadminsLV.Asn1Parser.Universal;
78

@@ -58,9 +59,12 @@ void m_encode(String inputString) {
5859
Initialize(Asn1Utils.EncodeAsReader(Encoding.ASCII.GetBytes(inputString).AsSpan(), TYPE));
5960
}
6061
void m_decode(Asn1Reader asn) {
61-
if (asn.GetPayload().Any(b => b is < 32 or > 126)) {
62-
throw new InvalidDataException(String.Format(InvalidType, TYPE.ToString()));
62+
ReadOnlySpan<Byte> payload = asn.GetPayloadAsMemory().Span;
63+
foreach (Byte b in payload) {
64+
if (b is < 32 or > 126) {
65+
throw new InvalidDataException(String.Format(InvalidType, TYPE.ToString()));
66+
}
6367
}
64-
Value = Encoding.ASCII.GetString(asn.GetPayload());
68+
Value = Encoding.ASCII.GetString(payload);
6569
}
6670
}

0 commit comments

Comments
 (0)