|
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