|
1 | 1 | /* |
2 | | - * Copyright (c) 2024 the Eclipse Milo Authors |
| 2 | + * Copyright (c) 2025 the Eclipse Milo Authors |
3 | 3 | * |
4 | 4 | * This program and the accompanying materials are made |
5 | 5 | * available under the terms of the Eclipse Public License 2.0 |
|
10 | 10 |
|
11 | 11 | package org.eclipse.milo.opcua.sdk.core.types; |
12 | 12 |
|
| 13 | +import static java.util.Objects.requireNonNull; |
13 | 14 | import static java.util.Objects.requireNonNullElse; |
14 | 15 |
|
15 | 16 | import java.util.Arrays; |
@@ -131,19 +132,26 @@ public void encodeType(EncodingContext context, UaEncoder encoder, DynamicStruct |
131 | 132 | } |
132 | 133 |
|
133 | 134 | private @NonNull DynamicStruct decodeStruct(UaDecoder decoder) { |
134 | | - StructureField[] fields = requireNonNullElse(definition.getFields(), new StructureField[0]); |
135 | | - |
136 | 135 | LinkedHashMap<String, Object> members = new LinkedHashMap<>(); |
137 | 136 |
|
138 | 137 | long switchField = 0xFFFFFFFFL; |
139 | 138 | if (definition.getStructureType() == StructureType.StructureWithOptionalFields) { |
140 | 139 | switchField = decoder.decodeUInt32("SwitchField").longValue(); |
141 | 140 | } |
142 | 141 |
|
143 | | - for (int i = 0; i < fields.length; i++) { |
144 | | - StructureField field = fields[i]; |
| 142 | + StructureField[] fields = requireNonNullElse(definition.getFields(), new StructureField[0]); |
| 143 | + |
| 144 | + if (definition.getStructureType() == StructureType.StructureWithOptionalFields) { |
| 145 | + int optionalFieldIndex = 0; |
| 146 | + for (StructureField field : fields) { |
| 147 | + if (!field.getIsOptional() || (switchField >>> optionalFieldIndex++ & 1L) == 1L) { |
| 148 | + Object value = decodeFieldValue(decoder, field); |
145 | 149 |
|
146 | | - if (!field.getIsOptional() || ((switchField >>> i) & 1) == 1) { |
| 150 | + members.put(field.getName(), value); |
| 151 | + } |
| 152 | + } |
| 153 | + } else { |
| 154 | + for (StructureField field : fields) { |
147 | 155 | Object value = decodeFieldValue(decoder, field); |
148 | 156 |
|
149 | 157 | members.put(field.getName(), value); |
@@ -175,26 +183,29 @@ public void encodeType(EncodingContext context, UaEncoder encoder, DynamicStruct |
175 | 183 | private void encodeStruct(UaEncoder encoder, DynamicStruct struct) { |
176 | 184 | StructureField[] fields = requireNonNullElse(definition.getFields(), new StructureField[0]); |
177 | 185 |
|
178 | | - long switchField = 0xFFFFFFFFL; |
| 186 | + var switchField = 0L; |
179 | 187 | if (definition.getStructureType() == StructureType.StructureWithOptionalFields) { |
180 | | - switchField = 0L; |
181 | | - for (int i = 0; i < fields.length; i++) { |
182 | | - StructureField field = fields[i]; |
183 | | - if (!field.getIsOptional() |
184 | | - || (field.getIsOptional() && struct.getMembers().containsKey(field.getName()))) { |
185 | | - |
186 | | - switchField |= (1L << i); |
| 188 | + int optionalFieldIndex = 0; |
| 189 | + for (StructureField field : fields) { |
| 190 | + if (field.getIsOptional() |
| 191 | + && struct.getMembers().containsKey(requireNonNull(field.getName()))) { |
| 192 | + switchField = switchField | (1L << optionalFieldIndex++); |
187 | 193 | } |
188 | 194 | } |
189 | 195 | encoder.encodeUInt32("SwitchField", UInteger.valueOf(switchField)); |
190 | 196 | } |
191 | 197 |
|
192 | | - for (int i = 0; i < fields.length; i++) { |
193 | | - StructureField field = fields[i]; |
194 | | - |
195 | | - if (!field.getIsOptional() || ((switchField >>> i) & 1) == 1) { |
| 198 | + if (definition.getStructureType() == StructureType.StructureWithOptionalFields) { |
| 199 | + int optionalFieldIndex = 0; |
| 200 | + for (StructureField field : fields) { |
| 201 | + if (!field.getIsOptional() || ((switchField >>> optionalFieldIndex++) & 1L) == 1L) { |
| 202 | + Object value = struct.getMembers().get(field.getName()); |
| 203 | + encodeFieldValue(encoder, field, value); |
| 204 | + } |
| 205 | + } |
| 206 | + } else { |
| 207 | + for (StructureField field : fields) { |
196 | 208 | Object value = struct.getMembers().get(field.getName()); |
197 | | - |
198 | 209 | encodeFieldValue(encoder, field, value); |
199 | 210 | } |
200 | 211 | } |
|
0 commit comments