Implement XML Matrix decoding in OpcUaXmlDecoder#1763
Conversation
The four Matrix decode methods (decodeMatrix, decodeEnumMatrix, and the two decodeStructMatrix overloads) were stubs that returned Matrix.ofNull(), so a Matrix encoded by OpcUaXmlEncoder did not round-trip through the XML encoding: the value was silently lost on decode. Decode the <Dimensions> and <Elements> children written by the encoder. decodeMatrix reads each element by its builtin type and rebuilds the Matrix with the requested OpcUaDataType. decodeEnumMatrix reads each element as an enum value and reduces it to Int32. decodeStructMatrix decodes the self-describing ExtensionObject elements back into their structures, so it returns a Matrix of UaStructuredType; all three mirror the reductions OpcUaBinaryDecoder performs and keep the decode-encode round-trip intact. The <Dimensions>/<Elements> wrappers are located by element type so the decoder also accepts indented XML (e.g. from a UANodeSet). Add OpcUaXmlDecoderMatrixTest, which round-trips the same fixtures the encoder tests use across the builtin, enumerated, and structured types. Fixes eclipse-milo#1762 Signed-off-by: Jooyoung Jung <livinglikekrillin@gmail.com>
Matrix.ofNull().toString() threw a NullPointerException because ArrayUtil.getType was called with a null flatArray. Return early with a flatArray=null rendering instead. Signed-off-by: Jooyoung Jung <livinglikekrillin@gmail.com>
Cover malformed Matrix XML that should be rejected instead of producing invalid Matrix values, including mismatched dimensions, non-positive dimensions, wrong element names, and unexpected structured element types.
|
I pushed a small set of failing test cases in
|
The decoder trusted the XML structure and could build invalid Matrix values from malformed input. Reject it instead, per OPC 10000-6 §5.3, covering the cases added in the previous commit: - dimensions whose product does not match the number of decoded elements (§5.3.1.17); - non-positive dimensions (§5.3.1.17 requires every dimension > 0); - a builtin element whose XML tag name is not the requested type name, e.g. a <String> element in an Int32 Matrix (§5.3.4); - decodeStructMatrix now resolves the codec for the requested dataTypeId and rejects ExtensionObjects that decode to a different structure type, mirroring decodeStructArray. Signed-off-by: Jooyoung Jung <livinglikekrillin@gmail.com>
|
Thanks, these probes were helpful — they map cleanly onto four validation gaps. I've pushed a follow-up commit (
I've also dropped the now-inaccurate "dataTypeId is not needed" note from the PR description. |
Summary
OpcUaXmlDecoder's four Matrix decode methods (decodeMatrix,decodeEnumMatrix,and the two
decodeStructMatrixoverloads) were stubs that returnedMatrix.ofNull().The encoder side (
OpcUaXmlEncoder.encode*Matrix) is fully implemented, so a Matrixencoded to XML produced well-formed output but did not round-trip — the value was
silently lost on decode.
This was raised in #1762, where the maintainer confirmed it was missed during the
1.0
OpcUaXmlEncoderwork and gave the go-ahead (pointing to OPC 10000-6 §5.3).Changes
decodeMatrixreads the<Dimensions>and<Elements>the encoder writes andrebuilds the Matrix with the requested
OpcUaDataType.decodeEnumMatrixreduces each element toInt32, anddecodeStructMatrixdecodesthe self-describing
ExtensionObjectelements back into their structures (returninga Matrix of
UaStructuredType) — both mirrorOpcUaBinaryDecoderand keep thedecode→encode round-trip intact.
<Dimensions>/<Elements>wrappers by element type, so indented XML(e.g. copied from a UANodeSet) also decodes.
Bad_DecodingErrorinstead of building an invalidMatrix, per OPC 10000-6 §5.3: dimensions whose product does not match the element
count, non-positive dimensions, builtin elements whose XML tag name is not the
requested type name, and (for
decodeStructMatrix)ExtensionObjects that decode toa different structure type than the requested
dataTypeId— the last resolves thecodec for
dataTypeIdand validates against it, mirroringdecodeStructArray.Matrix.toString()against the null-MatrixNullPointerExceptionnoted inthe issue (
ArrayUtil.getTypeon a nullflatArray).Tests
OpcUaXmlDecoderMatrixTest: round-trips the sameMatrixArgumentsfixtures theencoder tests use across the builtin, enumerated, and structured types; asserts that
struct matrices decode back to
UaStructuredType; indented-XML and null-Matrixdecode cases; plus the validation cases for malformed XML (mismatched/non-positive
dimensions, wrong element name, unexpected struct type).
MatrixTest:toString()on a null Matrix no longer throws.Fixes #1762
Developed with AI assistance (Anthropic Claude Opus 4.8); the human contributor
reviewed, verified, and tested all changes.