Search in sources :

Example 1 with FieldType

use of org.opcfoundation.opcua.binaryschema.FieldType in project milo by eclipse.

the class DataTypeDictionaryGenerator method createStructuredType.

private StructuredType createStructuredType(StructureDescription description) {
    QualifiedName name = description.getName();
    StructureDefinition definition = description.getStructureDefinition();
    StructureType structureType = definition.getStructureType();
    StructuredType structuredType = new StructuredType();
    structuredType.setName(name.getName());
    // Create a combined list of StructuredFields from all parent types
    LinkedList<StructureDefinition> definitions = new LinkedList<>();
    definitions.addFirst(definition);
    NodeId baseDataTypeId = definition.getBaseDataType();
    while (baseDataTypeId != null && baseDataTypeId.isNotNull() && !Identifiers.Structure.equals(baseDataTypeId) && !Identifiers.Union.equals(baseDataTypeId)) {
        StructureDescription baseDescription = structureDescriptions.get(baseDataTypeId);
        StructureDefinition baseDefinition = baseDescription.getStructureDefinition();
        definitions.addFirst(baseDefinition);
        baseDataTypeId = baseDefinition.getBaseDataType();
    }
    LinkedHashMap<String, StructureField> allFields = new LinkedHashMap<>();
    for (StructureDefinition d : definitions) {
        for (StructureField f : d.getFields()) {
            allFields.put(f.getName(), f);
        }
    }
    List<StructureField> fields = new ArrayList<>(allFields.values());
    if (structureType == StructureType.StructureWithOptionalFields) {
        int optionalFieldCount = 0;
        for (StructureField field : fields) {
            if (field.getIsOptional()) {
                optionalFieldCount++;
                FieldType fieldType = new FieldType();
                fieldType.setName(field.getName() + "Present");
                fieldType.setTypeName(new QName(Namespaces.OPC_UA_BSD, "Bit"));
                structuredType.getField().add(fieldType);
            }
        }
        if (optionalFieldCount > 0) {
            int reservedFieldCount = (optionalFieldCount + 31) / 32;
            for (int i = 0; i < reservedFieldCount; i++) {
                long reservedBits = 32 - optionalFieldCount;
                optionalFieldCount -= 32;
                FieldType fieldType = new FieldType();
                fieldType.setLength(reservedBits);
                fieldType.setName("Reserved" + i);
                fieldType.setTypeName(new QName(Namespaces.OPC_UA_BSD, "Bit"));
                structuredType.getField().add(fieldType);
            }
        }
    } else if (structureType == StructureType.Union) {
        FieldType fieldType = new FieldType();
        fieldType.setName("SwitchField");
        fieldType.setTypeName(new QName(Namespaces.OPC_UA_BSD, "UInt32"));
        structuredType.getField().add(fieldType);
    }
    long switchValue = 0L;
    for (StructureField field : fields) {
        String fieldName = field.getName();
        NodeId fieldDataTypeId = field.getDataType();
        DataTypeLocation dataTypeLocation = dataTypeLookup.apply(fieldDataTypeId);
        String dataTypeName = dataTypeLocation.dataTypeName;
        String dictionaryNamespaceUri = dataTypeLocation.dictionaryNamespaceUri;
        namespaces.add(dictionaryNamespaceUri);
        FieldType fieldType = new FieldType();
        fieldType.setName(fieldName);
        fieldType.setTypeName(new QName(dictionaryNamespaceUri, dataTypeName));
        if (structureType == StructureType.StructureWithOptionalFields) {
            if (field.getIsOptional()) {
                fieldType.setSwitchField(fieldName + "Present");
            }
        } else if (structureType == StructureType.Union) {
            fieldType.setSwitchField("SwitchField");
            fieldType.setSwitchValue(++switchValue);
        }
        if (field.getValueRank() >= 1) {
            // Fixed-dimension array... specify a LengthField
            FieldType lengthFieldType = new FieldType();
            lengthFieldType.setName(fieldName + "Length");
            lengthFieldType.setTypeName(new QName(Namespaces.OPC_UA_BSD, "Int32"));
            if (structureType == StructureType.StructureWithOptionalFields) {
                if (field.getIsOptional()) {
                    lengthFieldType.setSwitchField(fieldName + "Present");
                }
            } else if (structureType == StructureType.Union) {
                fieldType.setSwitchField("SwitchField");
                fieldType.setSwitchValue(switchValue);
            }
            structuredType.getField().add(lengthFieldType);
            fieldType.setLengthField(fieldName + "Length");
        } else if (field.getValueRank() != -1) {
            // Not scalar, not fixed-dimension, not supported
            throw new IllegalArgumentException("cannot encode field \"" + fieldName + "\" " + "with ValueRank: %s" + field.getValueRank());
        }
        structuredType.getField().add(fieldType);
    }
    return structuredType;
}
Also used : StructureField(org.eclipse.milo.opcua.stack.core.types.structured.StructureField) QName(javax.xml.namespace.QName) QualifiedName(org.eclipse.milo.opcua.stack.core.types.builtin.QualifiedName) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) StructuredType(org.opcfoundation.opcua.binaryschema.StructuredType) StructureDescription(org.eclipse.milo.opcua.stack.core.types.structured.StructureDescription) LinkedHashMap(java.util.LinkedHashMap) FieldType(org.opcfoundation.opcua.binaryschema.FieldType) StructureDefinition(org.eclipse.milo.opcua.stack.core.types.structured.StructureDefinition) StructureType(org.eclipse.milo.opcua.stack.core.types.enumerated.StructureType) NodeId(org.eclipse.milo.opcua.stack.core.types.builtin.NodeId)

Example 2 with FieldType

use of org.opcfoundation.opcua.binaryschema.FieldType in project milo by eclipse.

the class AbstractCodec method fieldIsAbsent.

private boolean fieldIsAbsent(FieldType field, Map<String, MemberT> members) {
    if (field.getSwitchField() == null) {
        return false;
    } else {
        MemberT controlField = members.get(field.getSwitchField());
        String controlTypeName = structuredType.getField().stream().filter(f -> f.getName().equals(field.getSwitchField())).findFirst().map(f -> f.getTypeName().getLocalPart()).orElse("Int32");
        long controlValue = ((Number) memberTypeToOpcUaScalar(controlField, controlTypeName)).longValue();
        long switchValue = field.getSwitchValue() != null ? field.getSwitchValue() : 1L;
        SwitchOperand switchOperand = field.getSwitchOperand() != null ? field.getSwitchOperand() : SwitchOperand.EQUALS;
        return !compareToSwitchValue(controlValue, switchOperand, switchValue);
    }
}
Also used : OpcUaBinaryDataTypeCodec(org.eclipse.milo.opcua.stack.core.serialization.codecs.OpcUaBinaryDataTypeCodec) FieldType(org.opcfoundation.opcua.binaryschema.FieldType) DataValue(org.eclipse.milo.opcua.stack.core.types.builtin.DataValue) ByteString(org.eclipse.milo.opcua.stack.core.types.builtin.ByteString) HashMap(java.util.HashMap) ExtensionObject(org.eclipse.milo.opcua.stack.core.types.builtin.ExtensionObject) DateTime(org.eclipse.milo.opcua.stack.core.types.builtin.DateTime) Function(java.util.function.Function) PeekingIterator(com.google.common.collect.PeekingIterator) Iterators(com.google.common.collect.Iterators) LinkedHashMap(java.util.LinkedHashMap) StructuredType(org.opcfoundation.opcua.binaryschema.StructuredType) QualifiedName(org.eclipse.milo.opcua.stack.core.types.builtin.QualifiedName) SerializationContext(org.eclipse.milo.opcua.stack.core.serialization.SerializationContext) UShort(org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UShort) SwitchOperand(org.opcfoundation.opcua.binaryschema.SwitchOperand) Map(java.util.Map) BiConsumer(java.util.function.BiConsumer) XmlElement(org.eclipse.milo.opcua.stack.core.types.builtin.XmlElement) BigInteger(java.math.BigInteger) OpcUaBinaryStreamDecoder(org.eclipse.milo.opcua.stack.core.serialization.OpcUaBinaryStreamDecoder) StatusCodes(org.eclipse.milo.opcua.stack.core.StatusCodes) NodeId(org.eclipse.milo.opcua.stack.core.types.builtin.NodeId) ImmutableMap(com.google.common.collect.ImmutableMap) UByte(org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UByte) ExpandedNodeId(org.eclipse.milo.opcua.stack.core.types.builtin.ExpandedNodeId) UInteger(org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger) LocalizedText(org.eclipse.milo.opcua.stack.core.types.builtin.LocalizedText) UaSerializationException(org.eclipse.milo.opcua.stack.core.UaSerializationException) UUID(java.util.UUID) ULong(org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.ULong) OpcUaBinaryStreamEncoder(org.eclipse.milo.opcua.stack.core.serialization.OpcUaBinaryStreamEncoder) DiagnosticInfo(org.eclipse.milo.opcua.stack.core.types.builtin.DiagnosticInfo) Nullable(org.jetbrains.annotations.Nullable) Variant(org.eclipse.milo.opcua.stack.core.types.builtin.Variant) StatusCode(org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode) BuiltinDataType(org.eclipse.milo.opcua.stack.core.BuiltinDataType) Namespaces(org.eclipse.milo.opcua.stack.core.util.Namespaces) SwitchOperand(org.opcfoundation.opcua.binaryschema.SwitchOperand) ByteString(org.eclipse.milo.opcua.stack.core.types.builtin.ByteString)

Example 3 with FieldType

use of org.opcfoundation.opcua.binaryschema.FieldType in project milo by eclipse.

the class AbstractCodec method encodeField.

private void encodeField(SerializationContext context, OpcUaBinaryStreamEncoder encoder, LinkedHashMap<String, MemberT> members, FieldType field) {
    String typeName = field.getTypeName().getLocalPart();
    String typeNamespace = field.getTypeName().getNamespaceURI();
    MemberT member = members.get(field.getName());
    boolean typeNamespaceIsUa = Namespaces.OPC_UA.equals(typeNamespace) || Namespaces.OPC_UA_BSD.equals(typeNamespace);
    if (fieldIsScalar(field)) {
        Object scalarValue = memberTypeToOpcUaScalar(member, typeName);
        if (typeNamespaceIsUa && WRITERS.containsKey(typeName)) {
            WRITERS.get(typeName).accept(encoder, scalarValue);
        } else {
            context.encode(typeNamespace, typeName, scalarValue, encoder);
        }
    } else {
        if (field.isIsLengthInBytes()) {
            throw new UaSerializationException(StatusCodes.Bad_EncodingError, "IsLengthInBytes=true not supported");
        }
        if ("Bit".equals(typeName) && typeNamespaceIsUa) {
            int length = fieldLength(field, members);
            Number number = (Number) memberTypeToOpcUaArray(member, typeName);
            BigInteger bi = BigInteger.valueOf(number.longValue());
            for (int i = 0; i < length; i++) {
                encoder.writeBit(bi.shiftRight(i).and(BigInteger.ONE).intValue());
            }
        } else {
            Object[] valueArray = (Object[]) memberTypeToOpcUaArray(member, typeName);
            FieldType lengthField = fields.get(field.getLengthField());
            if (lengthField != null) {
                int length = valueArray.length;
                members.put(lengthField.getName(), opcUaToMemberTypeScalar(lengthField.getName(), length, lengthField.getTypeName().getLocalPart()));
                encodeField(context, encoder, members, lengthField);
            }
            if (valueArray != null) {
                if (typeNamespaceIsUa && WRITERS.containsKey(typeName)) {
                    for (Object value : valueArray) {
                        WRITERS.get(typeName).accept(encoder, value);
                    }
                } else {
                    for (Object value : valueArray) {
                        context.encode(typeNamespace, typeName, value, encoder);
                    }
                }
            }
        }
    }
}
Also used : UaSerializationException(org.eclipse.milo.opcua.stack.core.UaSerializationException) BigInteger(java.math.BigInteger) ExtensionObject(org.eclipse.milo.opcua.stack.core.types.builtin.ExtensionObject) ByteString(org.eclipse.milo.opcua.stack.core.types.builtin.ByteString) FieldType(org.opcfoundation.opcua.binaryschema.FieldType)

Example 4 with FieldType

use of org.opcfoundation.opcua.binaryschema.FieldType in project milo by eclipse.

the class AbstractCodec method decode.

@Override
public StructureT decode(SerializationContext context, OpcUaBinaryStreamDecoder decoder) throws UaSerializationException {
    LinkedHashMap<String, MemberT> members = new LinkedHashMap<>();
    PeekingIterator<FieldType> fieldIterator = Iterators.peekingIterator(structuredType.getField().iterator());
    while (fieldIterator.hasNext()) {
        FieldType field = fieldIterator.next();
        String fieldName = field.getName();
        String typeName = field.getTypeName().getLocalPart();
        String typeNamespace = field.getTypeName().getNamespaceURI();
        if (fieldIsAbsent(field, members)) {
            continue;
        }
        boolean typeNamespaceIsUa = Namespaces.OPC_UA.equals(typeNamespace) || Namespaces.OPC_UA_BSD.equals(typeNamespace);
        if (fieldIsScalar(field)) {
            if (typeNamespaceIsUa && READERS.containsKey(typeName)) {
                Object value = READERS.get(typeName).apply(decoder);
                members.put(fieldName, opcUaToMemberTypeScalar(fieldName, value, typeName));
            } else {
                Object value = context.decode(typeNamespace, typeName, decoder);
                members.put(fieldName, opcUaToMemberTypeScalar(fieldName, value, typeName));
            }
        } else {
            if (field.isIsLengthInBytes()) {
                throw new UaSerializationException(StatusCodes.Bad_DecodingError, "IsLengthInBytes=true not supported");
            }
            int length = fieldLength(field, members);
            if ("Bit".equals(typeName) && typeNamespaceIsUa) {
                BigInteger bitAccumulation = BigInteger.valueOf(0L);
                for (int i = 0; i < length; i++) {
                    BigInteger bitValue = BigInteger.valueOf(decoder.readBit());
                    bitAccumulation = bitAccumulation.or(bitValue.shiftLeft(i));
                }
                members.put(fieldName, opcUaToMemberTypeArray(fieldName, bitAccumulation.intValue(), typeName));
            } else {
                Object[] values = null;
                if (length >= 0) {
                    values = new Object[length];
                    if (typeNamespaceIsUa && READERS.containsKey(typeName)) {
                        for (int i = 0; i < length; i++) {
                            Object value = READERS.get(typeName).apply(decoder);
                            values[i] = value;
                        }
                    } else {
                        for (int i = 0; i < length; i++) {
                            Object value = context.decode(typeNamespace, typeName, decoder);
                            values[i] = value;
                        }
                    }
                }
                members.put(fieldName, opcUaToMemberTypeArray(fieldName, values, typeName));
            }
        }
    }
    for (String lengthField : lengthFields.keySet()) {
        members.remove(lengthField);
    }
    return createStructure(structuredType.getName(), members);
}
Also used : UaSerializationException(org.eclipse.milo.opcua.stack.core.UaSerializationException) BigInteger(java.math.BigInteger) ExtensionObject(org.eclipse.milo.opcua.stack.core.types.builtin.ExtensionObject) ByteString(org.eclipse.milo.opcua.stack.core.types.builtin.ByteString) LinkedHashMap(java.util.LinkedHashMap) FieldType(org.opcfoundation.opcua.binaryschema.FieldType)

Example 5 with FieldType

use of org.opcfoundation.opcua.binaryschema.FieldType in project milo by eclipse.

the class AbstractCodec method encode.

@Override
public void encode(SerializationContext context, OpcUaBinaryStreamEncoder encoder, StructureT structure) throws UaSerializationException {
    LinkedHashMap<String, MemberT> members = new LinkedHashMap<>(getMembers(structure));
    PeekingIterator<FieldType> fieldIterator = Iterators.peekingIterator(structuredType.getField().iterator());
    while (fieldIterator.hasNext()) {
        FieldType field = fieldIterator.next();
        if (fieldIsAbsent(field, members)) {
            continue;
        }
        if (lengthFields.containsKey(field.getName())) {
            // structure representation isn't required to include it
            continue;
        }
        encodeField(context, encoder, members, field);
    }
}
Also used : ByteString(org.eclipse.milo.opcua.stack.core.types.builtin.ByteString) LinkedHashMap(java.util.LinkedHashMap) FieldType(org.opcfoundation.opcua.binaryschema.FieldType)

Aggregations

FieldType (org.opcfoundation.opcua.binaryschema.FieldType)5 LinkedHashMap (java.util.LinkedHashMap)4 ByteString (org.eclipse.milo.opcua.stack.core.types.builtin.ByteString)4 BigInteger (java.math.BigInteger)3 UaSerializationException (org.eclipse.milo.opcua.stack.core.UaSerializationException)3 ExtensionObject (org.eclipse.milo.opcua.stack.core.types.builtin.ExtensionObject)3 NodeId (org.eclipse.milo.opcua.stack.core.types.builtin.NodeId)2 QualifiedName (org.eclipse.milo.opcua.stack.core.types.builtin.QualifiedName)2 StructuredType (org.opcfoundation.opcua.binaryschema.StructuredType)2 ImmutableMap (com.google.common.collect.ImmutableMap)1 Iterators (com.google.common.collect.Iterators)1 PeekingIterator (com.google.common.collect.PeekingIterator)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 LinkedList (java.util.LinkedList)1 Map (java.util.Map)1 UUID (java.util.UUID)1 BiConsumer (java.util.function.BiConsumer)1 Function (java.util.function.Function)1 QName (javax.xml.namespace.QName)1