From 1edfc263ec82c0489f1e74836f01c9d412f61f8e Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Mon, 17 Aug 2026 05:31:28 -0400 Subject: [PATCH] docs(mtconnect): state AsStream's buffer aliasing and lifetime contract --- .../MTConnectStreamsParser.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.MTConnect/MTConnectStreamsParser.cs b/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.MTConnect/MTConnectStreamsParser.cs index a5409aba..b0d6bdff 100644 --- a/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.MTConnect/MTConnectStreamsParser.cs +++ b/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.MTConnect/MTConnectStreamsParser.cs @@ -241,7 +241,16 @@ internal static class MTConnectStreamsParser /// /// Views the (already trimmed) bytes as a stream without copying them where the memory is /// array-backed — which it always is on the /sample path, whose framer hands over the - /// part's own byte[]. + /// part's own byte[]. That branch aliases the caller's array; only the + /// non-array-backed fallback copies (via ToArray). + /// + /// Ownership, so a caller can reason about the aliased buffer: nothing on this path pools + /// or rents it (the framer allocates each byte[] fresh), and parsing is fully + /// synchronous, so the buffer need only stay valid and unmutated for the duration of the + /// Parse call. The returned holds no reference + /// into it — materialises its own strings — so the caller may + /// reuse or discard the buffer as soon as Parse returns. + /// /// private static MemoryStream AsStream(ReadOnlyMemory xml) => MemoryMarshal.TryGetArray(xml, out ArraySegment segment) && segment.Array is not null