Skip to content

Commit

Permalink
~ WIP arrays, enums, structs, messages
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinherron committed Mar 25, 2022
1 parent 8c9030c commit 73e12fe
Show file tree
Hide file tree
Showing 3 changed files with 224 additions and 34 deletions.
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 the Eclipse Milo Authors
* Copyright (c) 2022 the Eclipse Milo Authors
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
Expand Down Expand Up @@ -915,7 +915,7 @@ public void writeMessage(String field, UaMessage message) throws UaSerialization

if (binaryCodec == null) {
throw new UaSerializationException(
StatusCodes.Bad_DecodingError,
StatusCodes.Bad_EncodingError,
"no codec registered: " + encodingId
);
}
Expand Down Expand Up @@ -953,13 +953,13 @@ public void writeStruct(String field, Object value, NodeId dataTypeId) throws Ua

@Override
public void writeStruct(String field, Object value, ExpandedNodeId dataTypeId) throws UaSerializationException {
NodeId localDateTypeId = dataTypeId.toNodeId(context.getNamespaceTable())
NodeId localDataTypeId = dataTypeId.toNodeId(context.getNamespaceTable())
.orElseThrow(() -> new UaSerializationException(
StatusCodes.Bad_EncodingError,
"no codec registered: " + dataTypeId
));

writeStruct(field, value, localDateTypeId);
writeStruct(field, value, localDataTypeId);
}

@Override
Expand Down Expand Up @@ -1121,13 +1121,13 @@ public void writeStructArray(
ExpandedNodeId dataTypeId
) throws UaSerializationException {

NodeId localDateTypeId = dataTypeId.toNodeId(context.getNamespaceTable())
NodeId localDataTypeId = dataTypeId.toNodeId(context.getNamespaceTable())
.orElseThrow(() -> new UaSerializationException(
StatusCodes.Bad_EncodingError,
"no codec registered: " + dataTypeId
));

writeStructArray(field, value, localDateTypeId);
writeStructArray(field, value, localDataTypeId);
}

@Override
Expand Down
Expand Up @@ -27,6 +27,8 @@
import org.eclipse.milo.opcua.stack.core.StatusCodes;
import org.eclipse.milo.opcua.stack.core.UaSerializationException;
import org.eclipse.milo.opcua.stack.core.serialization.codecs.DataTypeCodec;
import org.eclipse.milo.opcua.stack.core.serialization.codecs.OpcUaJsonDataTypeCodec;
import org.eclipse.milo.opcua.stack.core.types.OpcUaDefaultJsonEncoding;
import org.eclipse.milo.opcua.stack.core.types.builtin.ByteString;
import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
import org.eclipse.milo.opcua.stack.core.types.builtin.DateTime;
Expand Down Expand Up @@ -932,172 +934,262 @@ public void writeDiagnosticInfo(String field, DiagnosticInfo value) throws UaSer

@Override
public void writeMessage(String field, UaMessage message) throws UaSerializationException {
ExpandedNodeId xEncodingId = message.getJsonEncodingId();

NodeId encodingId = xEncodingId.toNodeId(serializationContext.getNamespaceTable())
.orElseThrow(() ->
new UaSerializationException(
StatusCodes.Bad_EncodingError,
"namespace not registered: " + xEncodingId.getNamespaceUri())
);

OpcUaJsonDataTypeCodec<UaMessage> codec =
(OpcUaJsonDataTypeCodec<UaMessage>) serializationContext.getDataTypeManager().getCodec(encodingId);

if (codec == null) {
throw new UaSerializationException(StatusCodes.Bad_EncodingError, "no codec registered: " + encodingId);
}

try {
jsonWriter.beginObject();
writeNodeId("TypeId", encodingId);
writeStruct("Body", message, codec);
jsonWriter.endObject();
} catch (IOException e) {
throw new UaSerializationException(StatusCodes.Bad_EncodingError, e);
}
}

@Override
public void writeEnum(String field, UaEnumeration value) throws UaSerializationException {

writeInt32(field, value.getValue());
}

@Override
public void writeStruct(String field, Object value, NodeId dataTypeId) throws UaSerializationException {
@SuppressWarnings("unchecked")
OpcUaJsonDataTypeCodec<Object> codec =
(OpcUaJsonDataTypeCodec<Object>) serializationContext.getDataTypeManager()
.getCodec(OpcUaDefaultJsonEncoding.ENCODING_NAME, dataTypeId);

if (codec == null) {
throw new UaSerializationException(
StatusCodes.Bad_EncodingError,
"no codec registered: " + dataTypeId
);
}

writeStruct(field, value, codec);
}

@Override
public void writeStruct(String field, Object value, ExpandedNodeId dataTypeId) throws UaSerializationException {
NodeId localDataTypeId = dataTypeId.toNodeId(serializationContext.getNamespaceTable())
.orElseThrow(() -> new UaSerializationException(
StatusCodes.Bad_EncodingError,
"no codec registered: " + dataTypeId
));

writeStruct(field, value, localDataTypeId);
}

@Override
public void writeStruct(String field, Object value, DataTypeCodec codec) throws UaSerializationException {
if (codec instanceof OpcUaJsonDataTypeCodec) {
@SuppressWarnings("unchecked")
OpcUaJsonDataTypeCodec<Object> jsonCodec = (OpcUaJsonDataTypeCodec<Object>) codec;

try {
if (field != null) {
jsonWriter.name(field);
}

jsonWriter.beginObject();
jsonCodec.encode(serializationContext, this, value);
jsonWriter.endObject();
} catch (IOException e) {
throw new UaSerializationException(StatusCodes.Bad_EncodingError, e);
}
} else {
throw new UaSerializationException(
StatusCodes.Bad_EncodingError,
new IllegalArgumentException("codec: " + codec)
);
}
}

@Override
public void writeBooleanArray(String field, Boolean[] value) throws UaSerializationException {

writeArray(field, value, this::writeBoolean);
}

@Override
public void writeSByteArray(String field, Byte[] value) throws UaSerializationException {

writeArray(field, value, this::writeSByte);
}

@Override
public void writeInt16Array(String field, Short[] value) throws UaSerializationException {

writeArray(field, value, this::writeInt16);
}

@Override
public void writeInt32Array(String field, Integer[] value) throws UaSerializationException {

writeArray(field, value, this::writeInt32);
}

@Override
public void writeInt64Array(String field, Long[] value) throws UaSerializationException {

writeArray(field, value, this::writeInt64);
}

@Override
public void writeByteArray(String field, UByte[] value) throws UaSerializationException {

writeArray(field, value, this::writeByte);
}

@Override
public void writeUInt16Array(String field, UShort[] value) throws UaSerializationException {

writeArray(field, value, this::writeUInt16);
}

@Override
public void writeUInt32Array(String field, UInteger[] value) throws UaSerializationException {

writeArray(field, value, this::writeUInt32);
}

@Override
public void writeUInt64Array(String field, ULong[] value) throws UaSerializationException {

writeArray(field, value, this::writeUInt64);
}

@Override
public void writeFloatArray(String field, Float[] value) throws UaSerializationException {

writeArray(field, value, this::writeFloat);
}

@Override
public void writeDoubleArray(String field, Double[] value) throws UaSerializationException {

writeArray(field, value, this::writeDouble);
}

@Override
public void writeStringArray(String field, String[] value) throws UaSerializationException {

writeArray(field, value, this::writeString);
}

@Override
public void writeDateTimeArray(String field, DateTime[] value) throws UaSerializationException {

writeArray(field, value, this::writeDateTime);
}

@Override
public void writeGuidArray(String field, UUID[] value) throws UaSerializationException {

writeArray(field, value, this::writeGuid);
}

@Override
public void writeByteStringArray(String field, ByteString[] value) throws UaSerializationException {

writeArray(field, value, this::writeByteString);
}

@Override
public void writeXmlElementArray(String field, XmlElement[] value) throws UaSerializationException {

writeArray(field, value, this::writeXmlElement);
}

@Override
public void writeNodeIdArray(String field, NodeId[] value) throws UaSerializationException {

writeArray(field, value, this::writeNodeId);
}

@Override
public void writeExpandedNodeIdArray(String field, ExpandedNodeId[] value) throws UaSerializationException {

writeArray(field, value, this::writeExpandedNodeId);
}

@Override
public void writeStatusCodeArray(String field, StatusCode[] value) throws UaSerializationException {

writeArray(field, value, this::writeStatusCode);
}

@Override
public void writeQualifiedNameArray(String field, QualifiedName[] value) throws UaSerializationException {

writeArray(field, value, this::writeQualifiedName);
}

@Override
public void writeLocalizedTextArray(String field, LocalizedText[] value) throws UaSerializationException {

writeArray(field, value, this::writeLocalizedText);
}

@Override
public void writeExtensionObjectArray(String field, ExtensionObject[] value) throws UaSerializationException {

writeArray(field, value, this::writeExtensionObject);
}

@Override
public void writeDataValueArray(String field, DataValue[] value) throws UaSerializationException {

writeArray(field, value, this::writeDataValue);
}

@Override
public void writeVariantArray(String field, Variant[] value) throws UaSerializationException {

writeArray(field, value, this::writeVariant);
}

@Override
public void writeDiagnosticInfoArray(String field, DiagnosticInfo[] value) throws UaSerializationException {

writeArray(field, value, this::writeDiagnosticInfo);
}

@Override
public void writeEnumArray(String field, UaEnumeration[] value) throws UaSerializationException {

writeArray(field, value, this::writeEnum);
}

@Override
public void writeStructArray(String field, Object[] value, NodeId dataTypeId) throws UaSerializationException {

writeArray(field, value, (f, v) -> writeStruct(null, v, dataTypeId));
}

@Override
public void writeStructArray(String field, Object[] value, ExpandedNodeId dataTypeId) throws UaSerializationException {
NodeId localDataTypeId = dataTypeId.toNodeId(serializationContext.getNamespaceTable())
.orElseThrow(() -> new UaSerializationException(
StatusCodes.Bad_EncodingError,
"no codec registered: " + dataTypeId
));

writeStructArray(field, value, localDataTypeId);
}

@Override
public <T> void writeArray(String field, T[] values, BiConsumer<String, T> encoder) throws UaSerializationException {
if (values == null) {
return;
}

if (values.length > serializationContext.getEncodingLimits().getMaxMessageSize()) {
throw new UaSerializationException(
StatusCodes.Bad_EncodingLimitsExceeded,
"array length exceeds max message size"
);
}

try {
if (field != null) {
jsonWriter.name(field);
}

jsonWriter.beginArray();
for (T value : values) {
encoder.accept(null, value);
}
jsonWriter.endArray();
} catch (IOException e) {
throw new UaSerializationException(StatusCodes.Bad_EncodingError, e);
}
}

}

0 comments on commit 73e12fe

Please sign in to comment.