[F34 evidence] dump WCF binary-header dictionary for AddMonitoredItems
rust / build / test / clippy / fmt (push) Has been cancelled
rust / build / test / clippy / fmt (push) Has been cancelled
Extends tests/add_monitored_items_request_capture.rs with a manual binary-header walk that prints every pre-interned string + its wire id. The captured request's binary header pre-declares **23 strings** covering the entire DataContract field set: wire-id 1 http://ASB.IDataV2:addMonitoredItemsIn wire-id 3 AddMonitoredItemsRequest wire-id 5 SubscriptionId wire-id 7 Items wire-id 9 http://schemas.datacontract.org/.../ASBIDataV2Contract wire-id 11 MonitoredItem wire-id 13 activeField wire-id 15 activeFieldSpecified wire-id 17 bufferedField wire-id 19 itemField wire-id 21 contextNameField wire-id 23 idField wire-id 25 idFieldSpecified wire-id 27 nameField wire-id 29 referenceTypeField wire-id 31 typeField wire-id 33 sampleIntervalField wire-id 35 timeDeadbandField wire-id 37 timeDeadbandFieldSpecified wire-id 39 userDataField wire-id 41 lengthField wire-id 43 payloadField wire-id 45 valueDeadbandField That gives F34's binary-builder rewrite the exact dict-id mapping to target — every MonitoredItem child can be emitted as a DictionaryStatic(odd-id) reference instead of an inline string, matching WCF's compression. The "RequireId" mystery from the earlier inline-name decode is also resolved: the wire body has NO `RequireId` element at the bottom — the trailing `Inline("referenceTypeField")` was a dict-id wraparound or auto-intern artifact, not actual content. design/followups.md F34 updated with the full ground-truth header, plus a refined "Resolves when" pointing at the underlying `nbfx.rs::decode_tokens` auto-intern semantics. The current codec's doc comment ("the codec doesn't auto-intern") is correct for raw [MC-NBFX] but wrong for WCF binary messages where the writer auto-interns by convention; that's the structural fix the F34 binary rewrite depends on. No code-path change in this commit beyond the test improvements. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -38,6 +38,29 @@ fn add_monitored_items_request_capture_decoder_trace() {
|
||||
let envelope = &raw[3..];
|
||||
assert_eq!(envelope.len(), 692);
|
||||
|
||||
// Manually walk the leading WCF binary header (length-prefixed
|
||||
// string list) so we can dump every interned string + its wire
|
||||
// id. Mirrors what `decode_envelope::parse_binary_header_prefix`
|
||||
// does internally; reproducing it inline so the test sees the
|
||||
// raw strings.
|
||||
use mxaccess_asb_nettcp::nmf::decode_multibyte_int31;
|
||||
let mut cursor = 0usize;
|
||||
let outer_len = decode_multibyte_int31(envelope, &mut cursor).expect("outer-len varint");
|
||||
eprintln!("=== binary-header outer length: {outer_len} ===");
|
||||
let header_start = cursor;
|
||||
let header_end = header_start + outer_len as usize;
|
||||
let mut p = header_start;
|
||||
let mut idx = 0usize;
|
||||
while p < header_end {
|
||||
let len = decode_multibyte_int31(envelope, &mut p).expect("string-len varint");
|
||||
let bytes = &envelope[p..p + len as usize];
|
||||
let s = std::str::from_utf8(bytes).expect("utf-8 header string");
|
||||
let wire_id = (idx as u32) * 2 + 1;
|
||||
eprintln!(" header[{idx}] (wire-id {wire_id}) = {s:?}");
|
||||
p += len as usize;
|
||||
idx += 1;
|
||||
}
|
||||
|
||||
let mut dict = DynamicDictionary::new();
|
||||
let decoded = decode_envelope(envelope, &mut dict).expect("decode_envelope succeeds");
|
||||
eprintln!("=== body tokens ({} total) ===", decoded.body_tokens.len());
|
||||
|
||||
Reference in New Issue
Block a user