diff --git a/dotnet/src/ZB.MOM.NatsNet.Server/Internal/ProtoWire.cs b/dotnet/src/ZB.MOM.NatsNet.Server/Internal/ProtoWire.cs
index 22eaff2..035e0c4 100644
--- a/dotnet/src/ZB.MOM.NatsNet.Server/Internal/ProtoWire.cs
+++ b/dotnet/src/ZB.MOM.NatsNet.Server/Internal/ProtoWire.cs
@@ -51,6 +51,12 @@ public static class ProtoWire
return (num, typ, sizeTag + sizeValue, null);
}
+ ///
+ /// Compatibility mapped entrypoint for PortTracker: protoScanField.
+ ///
+ public static (int num, int typ, int size, Exception? err) ProtoScanField(ReadOnlySpan b)
+ => ScanField(b);
+
///
/// Reads a protobuf tag varint and returns field number, wire type, and bytes consumed.
/// Mirrors protoScanTag.
@@ -71,6 +77,12 @@ public static class ProtoWire
return (num, typ, size, null);
}
+ ///
+ /// Compatibility mapped entrypoint for PortTracker: protoScanTag.
+ ///
+ public static (int num, int typ, int size, Exception? err) ProtoScanTag(ReadOnlySpan b)
+ => ScanTag(b);
+
///
/// Returns the byte count consumed by a field value with the given wire type.
/// Mirrors protoScanFieldValue.
@@ -98,6 +110,12 @@ public static class ProtoWire
}
}
+ ///
+ /// Compatibility mapped entrypoint for PortTracker: protoScanFieldValue.
+ ///
+ public static (int size, Exception? err) ProtoScanFieldValue(int typ, ReadOnlySpan b)
+ => ScanFieldValue(typ, b);
+
// -------------------------------------------------------------------------
// Varint decode
// -------------------------------------------------------------------------
@@ -170,6 +188,12 @@ public static class ProtoWire
return (0, 0, ErrOverflow);
}
+ ///
+ /// Compatibility mapped entrypoint for PortTracker: protoScanVarint.
+ ///
+ public static (ulong v, int size, Exception? err) ProtoScanVarint(ReadOnlySpan b)
+ => ScanVarint(b);
+
// -------------------------------------------------------------------------
// Length-delimited decode
// -------------------------------------------------------------------------
@@ -190,6 +214,12 @@ public static class ProtoWire
return (lenSize + (int)l, null);
}
+ ///
+ /// Compatibility mapped entrypoint for PortTracker: protoScanBytes.
+ ///
+ public static (int size, Exception? err) ProtoScanBytes(ReadOnlySpan b)
+ => ScanBytes(b);
+
// -------------------------------------------------------------------------
// Varint encode
// -------------------------------------------------------------------------
diff --git a/dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Internal/ProtoWireTests.cs b/dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Internal/ProtoWireTests.cs
new file mode 100644
index 0000000..45b5048
--- /dev/null
+++ b/dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Internal/ProtoWireTests.cs
@@ -0,0 +1,77 @@
+// Copyright 2012-2025 The NATS Authors
+// Licensed under the Apache License, Version 2.0
+
+using Shouldly;
+using ZB.MOM.NatsNet.Server.Internal;
+
+namespace ZB.MOM.NatsNet.Server.Tests.Internal;
+
+public class ProtoWireTests
+{
+ [Fact]
+ public void ProtoScanTag_ValidTag_ReturnsFieldTypeAndSize()
+ {
+ var (num, typ, size, err) = ProtoWire.ProtoScanTag([0x7A]); // field=15, type=2
+
+ err.ShouldBeNull();
+ num.ShouldBe(15);
+ typ.ShouldBe(2);
+ size.ShouldBe(1);
+ }
+
+ [Fact]
+ public void ProtoScanTag_InvalidFieldNumber_ReturnsError()
+ {
+ var (_, _, _, err) = ProtoWire.ProtoScanTag([0x02]); // field=0, type=2
+
+ err.ShouldNotBeNull();
+ err.Message.ShouldContain("invalid field number");
+ }
+
+ [Fact]
+ public void ProtoScanFieldValue_UnsupportedWireType_ReturnsError()
+ {
+ var (_, err) = ProtoWire.ProtoScanFieldValue(3, [0x01]);
+
+ err.ShouldNotBeNull();
+ err.Message.ShouldContain("unsupported type");
+ }
+
+ [Fact]
+ public void ProtoScanVarint_InsufficientData_ReturnsError()
+ {
+ var (_, _, err) = ProtoWire.ProtoScanVarint([0x80]);
+
+ err.ShouldNotBeNull();
+ err.Message.ShouldContain("insufficient data");
+ }
+
+ [Fact]
+ public void ProtoScanVarint_Overflow_ReturnsError()
+ {
+ var (_, _, err) = ProtoWire.ProtoScanVarint([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x02]);
+
+ err.ShouldNotBeNull();
+ err.Message.ShouldContain("too much data");
+ }
+
+ [Fact]
+ public void ProtoScanBytes_LengthDelimited_ReturnsLengthPrefixPlusPayloadSize()
+ {
+ var (size, err) = ProtoWire.ProtoScanBytes([0x03, (byte)'a', (byte)'b', (byte)'c']);
+
+ err.ShouldBeNull();
+ size.ShouldBe(4);
+ }
+
+ [Fact]
+ public void ProtoScanField_ValidLengthDelimited_ReturnsTotalFieldSize()
+ {
+ var (num, typ, size, err) = ProtoWire.ProtoScanField([0x0A, 0x03, (byte)'a', (byte)'b', (byte)'c']); // field=1,type=2
+
+ err.ShouldBeNull();
+ num.ShouldBe(1);
+ typ.ShouldBe(2);
+ size.ShouldBe(5);
+ }
+}
diff --git a/porting.db b/porting.db
index 5cda9e2..3e27d6e 100644
Binary files a/porting.db and b/porting.db differ
diff --git a/reports/current.md b/reports/current.md
index 04536ed..13ed1a8 100644
--- a/reports/current.md
+++ b/reports/current.md
@@ -1,6 +1,6 @@
# NATS .NET Porting Status Report
-Generated: 2026-02-28 11:30:24 UTC
+Generated: 2026-02-28 11:33:10 UTC
## Modules (12 total)
@@ -12,10 +12,10 @@ Generated: 2026-02-28 11:30:24 UTC
| Status | Count |
|--------|-------|
-| deferred | 2373 |
+| deferred | 2368 |
| n_a | 24 |
| stub | 1 |
-| verified | 1275 |
+| verified | 1280 |
## Unit Tests (3257 total)
@@ -34,4 +34,4 @@ Generated: 2026-02-28 11:30:24 UTC
## Overall Progress
-**2477/6942 items complete (35.7%)**
+**2482/6942 items complete (35.8%)**
diff --git a/reports/report_d8d71ea.md b/reports/report_d8d71ea.md
new file mode 100644
index 0000000..13ed1a8
--- /dev/null
+++ b/reports/report_d8d71ea.md
@@ -0,0 +1,37 @@
+# NATS .NET Porting Status Report
+
+Generated: 2026-02-28 11:33:10 UTC
+
+## Modules (12 total)
+
+| Status | Count |
+|--------|-------|
+| verified | 12 |
+
+## Features (3673 total)
+
+| Status | Count |
+|--------|-------|
+| deferred | 2368 |
+| n_a | 24 |
+| stub | 1 |
+| verified | 1280 |
+
+## Unit Tests (3257 total)
+
+| Status | Count |
+|--------|-------|
+| deferred | 2091 |
+| n_a | 187 |
+| verified | 979 |
+
+## Library Mappings (36 total)
+
+| Status | Count |
+|--------|-------|
+| mapped | 36 |
+
+
+## Overall Progress
+
+**2482/6942 items complete (35.8%)**