[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;
|
inner += 1;
|
||||||
}
|
}
|
||||||
if let Some(NbfxToken::Text(NbfxText::Bytes(payload))) = tokens.get(inner) {
|
// CONCATENATE all consecutive `Bytes` text records.
|
||||||
out.push(payload.clone());
|
// .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