[M5] mxaccess-asb: collect_asbidata_payloads concatenates chunked Bytes records
.NET's `XmlBinaryWriter.WriteBase64` chunks the byte array into multiple consecutive NBFX `Bytes8/16/32` records when the total exceeds the per-record budget. Live capture of a successful .NET RegisterItemsResponse showed the Status ASBIData payload split into `Bytes8(78) + Bytes8WithEndElement(1)` — total 79 bytes. Our decoder walked tokens looking for a single `Text(Bytes(...))` after each `<ASBIData>` element and stopped at the first chunk, returning a truncated payload that hit `Codec(ShortRead)` when the consumer tried to decode an ItemStatus from the partial bytes. Fix: walk **all** consecutive `Text(Bytes)` tokens after `<ASBIData>` and concatenate into a single payload before pushing to the result vector. Mirrors WCF's reader behaviour, which reassembles the chunks into one byte array via `XmlReader.ReadElementContentAsBase64`. Workspace: 710 unit tests pass. Live state: AuthenticateMe is accepted, RegisterItemsResponse decodes structurally — the remaining "MissingField Status" error reflects a server-side semantic outcome (server returned empty Status array) rather than a protocol bug, likely tag-resolution related and outside F28's scope. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1157,8 +1157,30 @@ pub fn collect_asbidata_payloads(tokens: &[NbfxToken]) -> Vec<Vec<u8>> {
|
||||
) {
|
||||
inner += 1;
|
||||
}
|
||||
if let Some(NbfxToken::Text(NbfxText::Bytes(payload))) = tokens.get(inner) {
|
||||
out.push(payload.clone());
|
||||
// CONCATENATE all consecutive `Bytes` text records.
|
||||
// .NET's `XmlBinaryWriter.WriteBase64` chunks the byte
|
||||
// array into multiple NBFX `Bytes8/16/32` records when
|
||||
// the total exceeds the per-record budget — captured
|
||||
// live response showed an ASBIData payload split into
|
||||
// a Bytes8(78) + Bytes8WithEndElement(1) pair, total
|
||||
// 79 bytes. Earlier we only returned the first chunk
|
||||
// and the consumer hit a `ShortRead` decoding the
|
||||
// truncated ItemStatus. The decoder collapses adjacent
|
||||
// Bytes-followed-by-Bytes pairs into a single text
|
||||
// token, but a `Bytes`-then-`EndElement` (from the
|
||||
// `WithEndElement` variant) leaves a sequence of
|
||||
// `Bytes` tokens we walk here.
|
||||
let mut combined: Option<Vec<u8>> = None;
|
||||
while let Some(NbfxToken::Text(NbfxText::Bytes(payload))) = tokens.get(inner)
|
||||
{
|
||||
match combined.as_mut() {
|
||||
Some(buf) => buf.extend_from_slice(payload),
|
||||
None => combined = Some(payload.clone()),
|
||||
}
|
||||
inner += 1;
|
||||
}
|
||||
if let Some(buf) = combined {
|
||||
out.push(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user