diff --git a/CMakeLists.txt b/CMakeLists.txt index ae0bddcc..a12b9be5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -186,7 +186,6 @@ endif() add_subdirectory(backends) set(NODESETLOADER_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/src/PrintfLogger.c ${CMAKE_CURRENT_SOURCE_DIR}/src/InternalRefService.c ${CMAKE_CURRENT_SOURCE_DIR}/src/CharAllocator.c ${CMAKE_CURRENT_SOURCE_DIR}/src/AliasList.c @@ -216,16 +215,11 @@ set(NODESETLOADER_DEPS_LIBS CACHE INTERNAL "") set(NODESETLOADER_PUBLIC_HEADERS - ${PROJECT_SOURCE_DIR}/include/NodesetLoader/Extension.h - ${PROJECT_SOURCE_DIR}/include/NodesetLoader/Logger.h - ${PROJECT_SOURCE_DIR}/include/NodesetLoader/ReferenceService.h - ${PROJECT_SOURCE_DIR}/include/NodesetLoader/arch.h ${PROJECT_SOURCE_DIR}/include/NodesetLoader/NodesetLoader.h ${NODESETLOADER_BACKEND_PUBLIC_HEADERS} CACHE INTERNAL "") set(NODESETLOADER_PRIVATE_HEADERS - ${PROJECT_SOURCE_DIR}/src/InternalLogger.h ${PROJECT_SOURCE_DIR}/src/InternalRefService.h ${PROJECT_SOURCE_DIR}/src/CharAllocator.h ${PROJECT_SOURCE_DIR}/src/AliasList.h diff --git a/backends/open62541/CMakeLists.txt b/backends/open62541/CMakeLists.txt index b58ce84c..d10831d8 100644 --- a/backends/open62541/CMakeLists.txt +++ b/backends/open62541/CMakeLists.txt @@ -1,6 +1,4 @@ set(NODESETLOADER_BACKEND_OPEN62541_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/src/customDataType.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/DataTypeImporter.c ${CMAKE_CURRENT_SOURCE_DIR}/src/ServerContext.c ${CMAKE_CURRENT_SOURCE_DIR}/src/RefServiceImpl.c ${CMAKE_CURRENT_SOURCE_DIR}/src/import.c @@ -19,16 +17,10 @@ set(NODESETLOADER_BACKEND_OPEN62541_DEPS_LIBS "" PARENT_SCOPE) set(NODESETLOADER_BACKEND_OPEN62541_PUBLIC_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/include/NodesetLoader/backendOpen62541.h - ${CMAKE_CURRENT_SOURCE_DIR}/include/NodesetLoader/dataTypes.h PARENT_SCOPE) set(NODESETLOADER_BACKEND_OPEN62541_PRIVATE_HEADERS - ${CMAKE_CURRENT_SOURCE_DIR}/src/DataTypeImporter.h - ${CMAKE_CURRENT_SOURCE_DIR}/src/conversion.h - ${CMAKE_CURRENT_SOURCE_DIR}/src/customDataType.h - ${CMAKE_CURRENT_SOURCE_DIR}/src/padding.h ${CMAKE_CURRENT_SOURCE_DIR}/src/ServerContext.h - ${CMAKE_CURRENT_SOURCE_DIR}/src/nodeset_base64.h ${CMAKE_CURRENT_SOURCE_DIR}/src/RefServiceImpl.h PARENT_SCOPE) diff --git a/backends/open62541/examples/dataTypeImport.c b/backends/open62541/examples/dataTypeImport.c index 7a00bcea..23604aac 100644 --- a/backends/open62541/examples/dataTypeImport.c +++ b/backends/open62541/examples/dataTypeImport.c @@ -3,7 +3,6 @@ #include #include -#include #include #include @@ -35,9 +34,12 @@ void addPoint(UA_Server *server) struct Point p1 = {1, 2, 3}; + UA_ServerConfig *config; + UA_Variant var; UA_Variant_init(&var); - UA_Variant_setScalar(&var, &p1, NodesetLoader_getCustomDataType(server, &attr.dataType)); + UA_Variant_setScalar(&var, &p1, + UA_findDataTypeWithCustom(&attr.dataType, config->customDataTypes)); UA_Server_writeValue(server, UA_NODEID_NUMERIC(1, 1000), var); } @@ -64,9 +66,12 @@ void addStructWithArray(UA_Server *server) s.valid = true; s.size = 3; + UA_ServerConfig *config; + UA_Variant var; UA_Variant_init(&var); - UA_Variant_setScalar(&var, &s, NodesetLoader_getCustomDataType(server, &attr.dataType)); + UA_Variant_setScalar(&var, &s, + UA_findDataTypeWithCustom(&attr.dataType, config->customDataTypes)); UA_Server_writeValue(server, UA_NODEID_NUMERIC(1, 1001), var); } @@ -102,8 +107,10 @@ void addStructWithPointArray(UA_Server *server) UA_Variant var; UA_Variant_init(&var); + UA_ServerConfig *config; + UA_Variant_setScalar(&var, &structWithPointData, - NodesetLoader_getCustomDataType(server, &attr.dataType)); + UA_findDataTypeWithCustom(&attr.dataType, config->customDataTypes)); UA_StatusCode retval = UA_Server_writeValue(server, UA_NODEID_NUMERIC(1, 1002), var); diff --git a/backends/open62541/examples/iterate.c b/backends/open62541/examples/iterate.c index 54d6a95c..0ba34abf 100644 --- a/backends/open62541/examples/iterate.c +++ b/backends/open62541/examples/iterate.c @@ -4,7 +4,6 @@ #include #include -#include #include #include diff --git a/backends/open62541/examples/server.c b/backends/open62541/examples/server.c index 64e2c33d..bb3b8beb 100644 --- a/backends/open62541/examples/server.c +++ b/backends/open62541/examples/server.c @@ -3,7 +3,6 @@ #include #include -#include #include #include diff --git a/backends/open62541/include/NodesetLoader/backendOpen62541.h b/backends/open62541/include/NodesetLoader/backendOpen62541.h index 3ec8d62c..8bceb1dc 100644 --- a/backends/open62541/include/NodesetLoader/backendOpen62541.h +++ b/backends/open62541/include/NodesetLoader/backendOpen62541.h @@ -9,32 +9,17 @@ #define __NODESETLOADER_BACKEND_OPEN62541_H__ #include -#include "NodesetLoader/Extension.h" #include #include -#if defined(_WIN32) -#ifdef __GNUC__ -#define LOADER_EXPORT __attribute__((dllexport)) -#else -#define LOADER_EXPORT __declspec(dllexport) -#endif -#else /* non win32 */ -#if __GNUC__ || __clang__ -#define LOADER_EXPORT __attribute__((visibility("default"))) -#endif -#endif -#ifndef LOADER_EXPORT -#define LOADER_EXPORT /* fallback to default */ -#endif - #ifdef __cplusplus extern "C" { #endif -LOADER_EXPORT bool NodesetLoader_loadFile(struct UA_Server *, const char *path, - NodesetLoader_ExtensionInterface *extensionHandling); +UA_EXPORT bool +NodesetLoader_loadFile(struct UA_Server *, const char *path, + void *options); #ifdef __cplusplus } diff --git a/backends/open62541/include/NodesetLoader/dataTypes.h b/backends/open62541/include/NodesetLoader/dataTypes.h deleted file mode 100644 index 9500590a..00000000 --- a/backends/open62541/include/NodesetLoader/dataTypes.h +++ /dev/null @@ -1,39 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * Copyright 2020 (c) Matthias Konnerth - */ - -#ifndef __NODESETLOADER_BACKEND_OPEN62541_DATATYPES_H__ -#define __NODESETLOADER_BACKEND_OPEN62541_DATATYPES_H__ -#include - -#if defined(_WIN32) -#ifdef __GNUC__ -#define LOADER_EXPORT __attribute__((dllexport)) -#else -#define LOADER_EXPORT __declspec(dllexport) -#endif -#else /* non win32 */ -#if __GNUC__ || __clang__ -#define LOADER_EXPORT __attribute__((visibility("default"))) -#endif -#endif -#ifndef LOADER_EXPORT -#define LOADER_EXPORT /* fallback to default */ -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -LOADER_EXPORT const struct UA_DataType * -NodesetLoader_getCustomDataType(struct UA_Server *server, - const UA_NodeId *typeId); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/backends/open62541/src/DataTypeImporter.c b/backends/open62541/src/DataTypeImporter.c deleted file mode 100644 index 23267075..00000000 --- a/backends/open62541/src/DataTypeImporter.c +++ /dev/null @@ -1,620 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * Copyright 2020 (c) Matthias Konnerth - */ - -#include -#include - -#include "DataTypeImporter.h" -#include "conversion.h" -#include "customDataType.h" -#include "padding.h" - -#include - -struct DataTypeImporter { - UA_DataTypeArray *types; - const NL_DataTypeNode **nodes; - size_t nodesSize; - size_t firstNewDataType; -}; - -static UA_NodeId -getBinaryEncodingId(const NL_DataTypeNode *node) { - UA_NodeId encodingRefType = UA_NODEID_NUMERIC(0, 38); - NL_Reference *ref = node->nonHierachicalRefs; - while (ref) { - if (UA_NodeId_equal(&encodingRefType, &ref->refType)) { - UA_NodeId id = ref->target; - return id; - } - ref = ref->next; - } - return UA_NODEID_NULL; -} - -static const UA_DataType * -getDataType(const UA_NodeId *id, const UA_DataTypeArray *customTypes, - const DataTypeImporter *importer) { - const UA_DataType *type = UA_findDataType(id); - if (type) - return type; - - // if it is abstract, a Variant is returned - if (id->namespaceIndex == 0) - return &UA_TYPES[UA_TYPES_VARIANT]; - - type = findCustomDataType(id, customTypes); - if (type && importer) { - for (size_t i = 0; i < importer->nodesSize; i++) { - if (UA_NodeId_equal(&importer->nodes[i]->id, &type->typeId)) { - if (strcmp(importer->nodes[i]->isAbstract, "true") == 0) - return &UA_TYPES[UA_TYPES_VARIANT]; - } - } - } - return type; -} - -typedef struct { - char c; - UA_Boolean member; -} TempBoolean; - -typedef struct { - char c; - UA_SByte member; -} TempSByte; - -typedef struct { - char c; - UA_Byte member; -} TempByte; - -typedef struct { - char c; - UA_Int16 member; -} TempInt16; - -typedef struct { - char c; - UA_UInt16 member; -} TempUInt16; - -typedef struct { - char c; - UA_Int32 member; -} TempInt32; - -typedef struct { - char c; - UA_UInt32 member; -} TempUInt32; - -typedef struct { - char c; - UA_Int64 member; -} TempInt64; - -typedef struct { - char c; - UA_UInt64 member; -} TempUInt64; - -typedef struct { - char c; - UA_Float member; -} TempFloat; - -typedef struct { - char c; - UA_Double member; -} TempDouble; - -typedef struct { - char c; - UA_QualifiedName member; -} TempQualifiedName; - -typedef struct { - char c; - UA_LocalizedText member; -} TempLocalizedText; - -typedef struct { - char c; - UA_StatusCode member; -} TempStatusCode; - -typedef struct { - char c; - UA_String member; -} TempString; - -typedef struct { - char c; - UA_XmlElement member; -} TempXmlElement; - -typedef struct { - char c; - UA_ByteString member; -} TempByteString; - -typedef struct { - char c; - UA_DateTime member; -} TempDateTime; - -typedef struct { - char c; - UA_ExpandedNodeId member; -} TempExpandedNodeId; - -typedef struct { - char c; - UA_NodeId member; -} TempNodeId; - -typedef struct { - char c; - UA_DiagnosticInfo member; -} TempDiagnosticInfo; - -typedef struct { - char c; - UA_Variant member; -} TempVariant; - -typedef struct { - char c; - UA_ExtensionObject member; -} TempExtensionObject; - -typedef struct { - char c; - UA_Guid member; -} TempGuid; - -static int -getAlignment(const UA_DataType *type, - const UA_DataTypeArray *customTypes) { - switch (type->typeKind) - { - case UA_DATATYPEKIND_BOOLEAN: - return offsetof(TempBoolean, member); - case UA_DATATYPEKIND_SBYTE: - return offsetof(TempSByte, member); - case UA_DATATYPEKIND_BYTE: - return offsetof(TempByte, member); - case UA_DATATYPEKIND_INT16: - return offsetof(TempInt16, member); - case UA_DATATYPEKIND_UINT16: - return offsetof(TempUInt16, member); - case UA_DATATYPEKIND_INT32: - return offsetof(TempInt32, member); - case UA_DATATYPEKIND_UINT32: - return offsetof(TempUInt32, member); - case UA_DATATYPEKIND_INT64: - return offsetof(TempInt64, member); - case UA_DATATYPEKIND_UINT64: - return offsetof(TempUInt64, member); - case UA_DATATYPEKIND_FLOAT: - return offsetof(TempFloat, member); - case UA_DATATYPEKIND_DOUBLE: - return offsetof(TempDouble, member); - case UA_DATATYPEKIND_QUALIFIEDNAME: - return offsetof(TempQualifiedName, member); - case UA_DATATYPEKIND_LOCALIZEDTEXT: - return offsetof(TempLocalizedText, member); - case UA_DATATYPEKIND_STATUSCODE: - return offsetof(TempStatusCode, member); - case UA_DATATYPEKIND_STRING: - return offsetof(TempString, member); - case UA_DATATYPEKIND_BYTESTRING: - return offsetof(TempByteString, member); - case UA_DATATYPEKIND_XMLELEMENT: - return offsetof(TempXmlElement, member); - case UA_DATATYPEKIND_DATETIME: - return offsetof(TempDateTime, member); - case UA_DATATYPEKIND_EXPANDEDNODEID: - return offsetof(TempExpandedNodeId, member); - case UA_DATATYPEKIND_NODEID: - return offsetof(TempNodeId, member); - case UA_DATATYPEKIND_DIAGNOSTICINFO: - return offsetof(TempDiagnosticInfo, member); - case UA_DATATYPEKIND_VARIANT: - return offsetof(TempVariant, member); - case UA_DATATYPEKIND_ENUM: - return offsetof(TempInt32, member); - case UA_DATATYPEKIND_EXTENSIONOBJECT: - return offsetof(TempExtensionObject, member); - case UA_DATATYPEKIND_UNION: - return 0; - case UA_DATATYPEKIND_GUID: - return offsetof(TempGuid, member); - case UA_DATATYPEKIND_STRUCTURE: - case UA_DATATYPEKIND_OPTSTRUCT: - // here we have to take a look on the first member - assert(type->members); - int retAlignment = 0; - for (UA_UInt32 i = 0; i < type->membersSize; i++) - { - const UA_DataType *memberType = type->members[i].memberType; - int tmp = getAlignment(memberType, customTypes); - if (tmp > retAlignment) - { - retAlignment = tmp; - } - } - return retAlignment; - } - - assert(false && "typeKind not handled"); - return 0; -} - -typedef struct { - char c; - size_t member; -} TempSizeT; - -typedef struct { - char c; - void *member; -} TempVoidPtr; - -static void -setPaddingMemsize(UA_DataType *type, - const UA_DataTypeArray *customTypes) { - if (!type->members) - return; - - int offset = 0; - int endPadding = 0; - UA_UInt16 biggestMemberSize = 0; - UA_Boolean hasArrayMember = false; - - for (UA_DataTypeMember *tm = type->members; - tm < type->members + type->membersSize; tm++) { - const UA_DataType *memberType = tm->memberType; - type->pointerFree = type->pointerFree && memberType->pointerFree; - - if (tm->isArray) { - // for arrays we have to take the size_t for the arraySize into - // account if the open changes the implementation of array - // serialization, we have a serious problem - // we rely here that its an size_t - int align = offsetof(TempSizeT, member); - tm->padding = (UA_Byte)(0x3F & getPadding(align, offset)); - offset = offset + tm->padding + (UA_Byte)sizeof(size_t); - // the void* for data - align = offsetof(TempVoidPtr, member); - int padding2 = getPadding(align, offset); - offset = offset + padding2 + (UA_Byte)sizeof(void *); - // datatype is not pointerfree - type->pointerFree = false; - - if (sizeof(void *) > biggestMemberSize) - biggestMemberSize = sizeof(void *); - - hasArrayMember = true; - } else if (tm->isOptional) { - int align = offsetof(TempVoidPtr, member); - tm->padding = (UA_Byte)(0x3F & getPadding(align, offset)); - offset = offset + tm->padding + (UA_Byte)sizeof(void *); - type->pointerFree = false; - if (sizeof(void *) > biggestMemberSize) - biggestMemberSize = sizeof(void *); - } else { - // add the switchfield to the padding of the first datatype member - if (type->typeKind == UA_DATATYPEKIND_UNION) { - tm->padding = (UA_Byte)sizeof(UA_UInt32); - } else if (memberType->typeKind != UA_DATATYPEKIND_UNION) { - int align = getAlignment(memberType, customTypes); - tm->padding = (UA_Byte)(0x3F & getPadding(align, offset)); - } - - offset = offset + tm->padding + memberType->memSize; - // padding after struct at end is needed - if (memberType->memSize > sizeof(size_t)) { - endPadding = memberType->memSize % sizeof(size_t); - } - if (memberType->memSize > biggestMemberSize) { - biggestMemberSize = memberType->memSize; - } - } - } - - if (type->typeKind == UA_DATATYPEKIND_UNION) { - // add the switch field - type->memSize = sizeof(UA_Int32); - int padding = getPadding(offsetof(TempUInt32, member), 0); - type->memSize = (UA_UInt16)(type->memSize + padding); - type->memSize = (UA_UInt16)(type->memSize + biggestMemberSize); - if (hasArrayMember) - type->memSize = (UA_UInt16)(type->memSize + sizeof(size_t)); - endPadding = getPadding(offsetof(TempSizeT, member), type->memSize); - type->memSize = (UA_UInt16)(type->memSize + endPadding); - } else { - type->memSize = (UA_UInt16)(offset + endPadding); - } -} - -static UA_NodeId -getParentNode(const NL_DataTypeNode *node) { - NL_Reference *ref = node->hierachicalRefs; - while (ref) { - if (!ref->isForward) - return ref->target; - ref = ref->next; - } - return UA_NODEID_NULL; -} - -static void -setDataTypeMembersTypeIndex(DataTypeImporter *importer, - UA_DataType *type, const NL_DataTypeNode *node) { - // member of supertype have to be added, if there is one - UA_NodeId parent = getParentNode(node); - UA_NodeId structId = UA_NODEID_NUMERIC(0, UA_NS0ID_STRUCTURE); - size_t memberOffset = 0; - if (!UA_NodeId_equal(&parent, &structId)) { - const UA_DataType *parentType = getDataType(&parent, importer->types, NULL); - // copy over parent members, if no members (abstract type), nothing is - // done - // First need to check if parentType exists at all. NodesetCompiler in - // open62541 would not generate a type if it had no members. - if (parentType && parentType->members) { - UA_DataTypeMember *members = (UA_DataTypeMember *)calloc( - (size_t)(parentType->membersSize + type->membersSize), - sizeof(UA_DataTypeMember)); - memcpy(members, parentType->members, - parentType->membersSize * sizeof(UA_DataTypeMember)); - - size_t cnt = 0; - for (UA_DataTypeMember *m = members; - m != members + parentType->membersSize; m++) { - char *memberNameCopy = - (char *)UA_calloc(strlen(m->memberName) + 1, sizeof(char)); - memcpy(memberNameCopy, m->memberName, strlen(m->memberName)); - members[cnt].memberName = memberNameCopy; - cnt++; - } - - memcpy(members + parentType->membersSize, type->members, - type->membersSize * sizeof(UA_DataTypeMember)); - free(type->members); - type->members = members; - type->membersSize = - (uint8_t)(parentType->membersSize + type->membersSize); - type->memSize = parentType->memSize; - memberOffset = parentType->membersSize; - } - } - - size_t i = 0; - for (UA_DataTypeMember *member = type->members + memberOffset; - member != type->members + type->membersSize; member++) { - UA_NodeId memberTypeId = node->definition->fields[i].dataType; - member->memberType = - getDataType(&memberTypeId, importer->types, importer); - i++; - } -} - -static void -addDataTypeMembers(const UA_DataTypeArray *customTypes, - UA_DataType *type, const NL_DataTypeNode *node) { - - if (!node->definition) { - type->membersSize = 0; - type->members = NULL; - type->memSize = sizeof(void *); - return; - } - - type->membersSize = (unsigned char)node->definition->fieldCnt; - type->members = (UA_DataTypeMember *)calloc(node->definition->fieldCnt, - sizeof(UA_DataTypeMember)); - - for (size_t i = 0; i < node->definition->fieldCnt; i++) { - UA_DataTypeMember *member = type->members + i; - member->isArray = node->definition->fields[i].valueRank >= 0; - UA_NodeId typeId = node->definition->fields[i].dataType; - member->memberType = getDataType(&typeId, customTypes, NULL); - - char *memberNameCopy = (char *)UA_calloc( - strlen(node->definition->fields[i].name) + 1, sizeof(char)); - memcpy(memberNameCopy, node->definition->fields[i].name, - strlen(node->definition->fields[i].name)); - member->memberName = memberNameCopy; - member->isOptional = node->definition->fields[i].isOptional; - if (member->isOptional) { - type->pointerFree = false; - type->typeKind = UA_DATATYPEKIND_OPTSTRUCT; - } - } -} - -static void -StructureDataType_init(const DataTypeImporter *importer, - UA_DataType *type, - const NL_DataTypeNode *node, - bool isOptionSet) { - if (node->definition && node->definition->isUnion) { - type->typeKind = UA_DATATYPEKIND_UNION; - } else { - type->typeKind = UA_DATATYPEKIND_STRUCTURE; - } - type->typeId = node->id; - type->binaryEncodingId = getBinaryEncodingId(node); - type->pointerFree = true; - if (!isOptionSet) - addDataTypeMembers(importer->types, type, node); - type->overlayable = false; -} - -static void -EnumDataType_init(const DataTypeImporter *importer, - UA_DataType *enumType, - const NL_DataTypeNode *node) { - enumType->typeId = node->id; - enumType->typeKind = UA_DATATYPEKIND_ENUM; - enumType->binaryEncodingId = UA_NODEID_NULL; - enumType->pointerFree = true; - enumType->overlayable = UA_BINARY_OVERLAYABLE_INTEGER; - enumType->members = NULL; - enumType->membersSize = 0; - enumType->memSize = sizeof(UA_Int32); -} - -static void -SubtypeOfBase_init(const DataTypeImporter *importer, - UA_DataType *type, const NL_DataTypeNode *node, - const UA_NodeId parent) { - const UA_DataType *parentType = UA_findDataType(&parent); - assert(parentType); - type->typeId = node->id; - type->binaryEncodingId = parentType->binaryEncodingId; - type->members = NULL; - type->membersSize = 0; - type->memSize = parentType->memSize; - type->overlayable = parentType->overlayable; - type->pointerFree = parentType->pointerFree; - type->typeKind = parentType->typeKind; -} - -static bool -readyForMemsizeCalc(const UA_DataType *type, - const UA_DataType *customTypes) { - if (type->typeKind != UA_DATATYPEKIND_STRUCTURE && - type->typeKind != UA_DATATYPEKIND_OPTSTRUCT) - return true; - - if (type->membersSize == 0) - return true; - - bool ready = true; - for (UA_DataTypeMember *m = type->members; - m != type->members + type->membersSize; m++) { - if (m->memberType && m->memberType->memSize > 0) - continue; - ready = false; - break; - } - return ready; -} - -static void -calcMemSize(DataTypeImporter *importer) { - bool allTypesFinished = false; - // datatype nodes could be sorted upfront to detect cyclic dependencies - while (!allTypesFinished) { - allTypesFinished = true; - for (UA_DataType *type = - (UA_DataType *)(uintptr_t)importer->types->types + - importer->firstNewDataType; - type != importer->types->types + importer->types->typesSize; - type++) { - // we can calculate the memsize if the memsize of all membertypes is - // known - if (readyForMemsizeCalc(type, importer->types->types)) { - setPaddingMemsize(type, importer->types); - } else { - allTypesFinished = false; - } - } - } -} - -void -DataTypeImporter_initMembers(DataTypeImporter *importer) { - - size_t cnt = 0; - for (UA_DataType *type = (UA_DataType *)(uintptr_t)importer->types->types + - importer->firstNewDataType; - type != importer->types->types + importer->types->typesSize; type++) { - if (type->typeKind == UA_DATATYPEKIND_STRUCTURE || - type->typeKind == UA_DATATYPEKIND_OPTSTRUCT || - type->typeKind == UA_DATATYPEKIND_UNION) { - setDataTypeMembersTypeIndex(importer, type, importer->nodes[cnt]); - } - cnt++; - } - calcMemSize(importer); -} - -void -DataTypeImporter_addCustomDataType(DataTypeImporter *importer, - const NL_DataTypeNode *node, - const UA_NodeId parent) { - // there is an open issue for that - // the user of the library should provide the memory for the custom - // dataTypes, then it is clear that he has to clean it up - if (!importer->types->types) { - importer->types->types = - (UA_DataType *)calloc(1000, sizeof(UA_DataType)); - } - assert(importer->types->typesSize < 1000); - - UA_DataType *type = (UA_DataType *)(uintptr_t)&importer->types - ->types[importer->types->typesSize]; - memset(type, 0, sizeof(UA_DataType)); - type->typeId = node->id; - size_t len = node->browseName.name.length; - type->typeName = (char *)calloc(len + 1, sizeof(char)); - memcpy((void*)(uintptr_t)type->typeName, node->browseName.name.data, len); - - UA_NodeId enumeration = UA_NODEID_NUMERIC(0, UA_NS0ID_ENUMERATION); - UA_NodeId structure = UA_NODEID_NUMERIC(0, UA_NS0ID_STRUCTURE); - UA_NodeId optionset = UA_NODEID_NUMERIC(0, UA_NS0ID_OPTIONSET); - if (UA_NodeId_equal(&parent, &enumeration)) { - EnumDataType_init(importer, type, node); - } else if (UA_NodeId_equal(&parent, &optionset)) { - // treat optionset like a struct - StructureDataType_init(importer, type, node, true); - } else if (UA_NodeId_equal(&parent, &structure)) { - StructureDataType_init(importer, type, node, false); - } else { - SubtypeOfBase_init(importer, type, node, parent); - } - - importer->nodes = (const NL_DataTypeNode **)realloc( - (void *)importer->nodes, (importer->nodesSize + 1) * sizeof(void *)); - importer->nodes[importer->nodesSize] = node; - importer->nodesSize++; - - (*(size_t *)(uintptr_t)&importer->types->typesSize)++; -} - -DataTypeImporter * -DataTypeImporter_new(struct UA_Server *server) { - DataTypeImporter *importer = - (DataTypeImporter *)calloc(1, sizeof(DataTypeImporter)); - if (!importer) - return NULL; - - UA_ServerConfig *config = UA_Server_getConfig(server); - if (!config->customDataTypes) { - // we append all types to customTypes array - UA_DataTypeArray *newCustomTypes = - (UA_DataTypeArray *)UA_calloc(1, sizeof(UA_DataTypeArray)); - if (!newCustomTypes) - return importer; - newCustomTypes->cleanup = UA_TRUE; - newCustomTypes->next = config->customDataTypes; - config->customDataTypes = newCustomTypes; - } - importer->types = (UA_DataTypeArray *)(uintptr_t)config->customDataTypes; - importer->firstNewDataType = importer->types->typesSize; - return importer; -} - -void DataTypeImporter_delete(DataTypeImporter *importer) { - free((void *)importer->nodes); - free(importer); -} diff --git a/backends/open62541/src/DataTypeImporter.h b/backends/open62541/src/DataTypeImporter.h deleted file mode 100644 index 40665b73..00000000 --- a/backends/open62541/src/DataTypeImporter.h +++ /dev/null @@ -1,25 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * Copyright 2020 (c) Matthias Konnerth - */ - -#ifndef DATATYPEIMPORTER_H -#define DATATYPEIMPORTER_H - -#include - -#include "NodesetLoader/NodesetLoader.h" - -struct DataTypeImporter; -typedef struct DataTypeImporter DataTypeImporter; - -DataTypeImporter *DataTypeImporter_new(struct UA_Server *server); -void DataTypeImporter_addCustomDataType(DataTypeImporter *importer, - const NL_DataTypeNode *node, const UA_NodeId parentId); -// has to be called after all dependent types where added -void DataTypeImporter_initMembers(DataTypeImporter *importer); -void DataTypeImporter_delete(DataTypeImporter *importer); - -#endif diff --git a/backends/open62541/src/RefServiceImpl.h b/backends/open62541/src/RefServiceImpl.h index 1e83c9ea..4c3453e9 100644 --- a/backends/open62541/src/RefServiceImpl.h +++ b/backends/open62541/src/RefServiceImpl.h @@ -9,7 +9,7 @@ #define REFSERVICEIMPL_H #include -#include "NodesetLoader/ReferenceService.h" +#include "NodesetLoader/NodesetLoader.h" NL_ReferenceService *RefServiceImpl_new(struct UA_Server *server); void RefServiceImpl_delete(NL_ReferenceService *service); diff --git a/backends/open62541/src/ServerContext.c b/backends/open62541/src/ServerContext.c index d94f69f3..8bdc2f6f 100644 --- a/backends/open62541/src/ServerContext.c +++ b/backends/open62541/src/ServerContext.c @@ -3,87 +3,116 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 2021 (c) Jan Murzyn + * Copyright 2025 (c) Fraunhofer IOSB (Author: Julius Pfrommer) */ #include "ServerContext.h" #include -struct ServerContext -{ - UA_Server *server; - size_t namespaceCnt; - UA_UInt16 *namespaceIdxMapping; -}; +AddNodeContext * +AddNodeContext_new(UA_Server *server) { + // Allocate the context + AddNodeContext *ctx = (AddNodeContext *)UA_calloc(1, sizeof(AddNodeContext)); + if(!ctx) + return NULL; + ctx->server = server; -ServerContext *ServerContext_new(UA_Server *server) -{ - ServerContext *serverContext = (ServerContext *)calloc(1, sizeof(ServerContext)); - if (serverContext) - { - serverContext->server = server; - serverContext->namespaceCnt = 0; - serverContext->namespaceIdxMapping = NULL; + ctx->customTypes = (UA_DataTypeArray*)UA_calloc(1, sizeof(UA_DataTypeArray)); + if(!ctx->customTypes) { + UA_free(ctx); + return NULL; } - return serverContext; -} + // Initialize the container for nodes that could not be added right away + NodeContainer_init(&ctx->problemNodes, 64, false); -void ServerContext_delete(ServerContext *serverContext) -{ - free(serverContext->namespaceIdxMapping); - free(serverContext); -} + // Load initial namespaces from the server + UA_StatusCode res = UA_STATUSCODE_GOOD; + size_t idx = 0; + while(res == UA_STATUSCODE_GOOD) { + UA_String nsUri = UA_STRING_NULL;; + res = UA_Server_getNamespaceByIndex(server, idx, &nsUri); + if(res != UA_STATUSCODE_GOOD) + continue; + AddNodeContext_addNamespace(ctx, nsUri); + UA_String_clear(&nsUri); + idx++; + } -UA_Server *ServerContext_getServerObject(const ServerContext *serverContext) -{ - if (!serverContext) - return NULL; + // Set the server-logger as the default + UA_ServerConfig *config = UA_Server_getConfig(server); + ctx->logger = config->logging; - return serverContext->server; + return ctx; } -// Adding server side namespace indices to an array of UA_UInt16. -// Position in the array (minus 1) corresponds to the namespace index in the nodeset file. -// E.g. -// namespaceIdxMapping [0] = x -// [1] = y -// [2] = z -// ... -// y is a server side namespace index of the namespace that in the nodeset file has index 2. -void ServerContext_addNamespaceIdx(ServerContext *serverContext, UA_UInt16 serverIdx) -{ - if (!serverContext) - return; - - void *newNamespaceIdxMapping = - realloc(serverContext->namespaceIdxMapping, sizeof(UA_UInt16) * (serverContext->namespaceCnt + 1)); - - if (newNamespaceIdxMapping) - { - serverContext->namespaceIdxMapping = (UA_UInt16 *)newNamespaceIdxMapping; - serverContext->namespaceCnt++; - serverContext->namespaceIdxMapping[serverContext->namespaceCnt - 1] = serverIdx; +void AddNodeContext_delete(AddNodeContext *ctx) { + UA_NamespaceMapping_clear(&ctx->nsMapping); + NodeContainer_clear(&ctx->problemNodes); + if(ctx->customTypes) { + for(size_t i = 0; i < ctx->customTypes->typesSize; i++) { + UA_DataType *t = &ctx->customTypes->types[i]; + UA_DataType_clear(t); + } + UA_free(ctx->customTypes->types); + UA_free(ctx->customTypes); } + free(ctx); } -// See the comment above ServerContext_addNamespaceIdx -UA_UInt16 ServerContext_translateToServerIdx(const ServerContext *serverContext, UA_UInt16 nodesetIdx) -{ - if (!serverContext) - return UA_UINT16_MAX; +UA_StatusCode + AddNodeContext_addDataType(AddNodeContext *ctx, UA_DataType *t) { + UA_DataType *tmp = (UA_DataType*) + UA_realloc(ctx->customTypes->types, + sizeof(UA_DataType) * (ctx->customTypes->typesSize + 1)); + if(!tmp) + return UA_STATUSCODE_BADOUTOFMEMORY; + ctx->customTypes->types = tmp; + ctx->customTypes->types[ctx->customTypes->typesSize] = *t; + ctx->customTypes->typesSize++; + return UA_STATUSCODE_GOOD; +} - if (nodesetIdx == 0) - { - // Zero is always 0, no need for translation - return 0; +UA_UInt16 +AddNodeContext_addNamespace(AddNodeContext *ctx, + const UA_String nsUri) { + // Already in the mapping? + for(size_t i = 0; i < ctx->nsMapping.namespaceUrisSize; i++) { + if(UA_String_equal(&nsUri, &ctx->nsMapping.namespaceUris[i])) + return (UA_UInt16)i; } - else if ((nodesetIdx > 0) && ((size_t)nodesetIdx <= serverContext->namespaceCnt)) - { - return serverContext->namespaceIdxMapping[nodesetIdx - 1]; - } - else - { - // Error case. Should it rather be handled by assert(false)? - return UA_UINT16_MAX; + + // Add to the server + char namebuf[512]; + memcpy(namebuf, nsUri.data, nsUri.length); + namebuf[nsUri.length] = 0; + UA_UInt16 serverIdx = UA_Server_addNamespace(ctx->server, namebuf); + if(serverIdx == 0) + return 0; + + // Add to the local mapping + UA_UInt16 localIdx = (UA_UInt16)ctx->nsMapping.namespaceUrisSize; + UA_StatusCode res = + UA_Array_appendCopy((void**)&ctx->nsMapping.namespaceUris, + &ctx->nsMapping.namespaceUrisSize, + &nsUri, &UA_TYPES[UA_TYPES_STRING]); + if(res != UA_STATUSCODE_GOOD) + return 0; + + // Add to remote2local + if(serverIdx > ctx->nsMapping.remote2localSize - 1) { + // Assert: Nobody else is modifying the server-side namespacearray at the same time + UA_assert(serverIdx == ctx->nsMapping.remote2localSize); + res = UA_Array_append((void**)&ctx->nsMapping.remote2local, + &ctx->nsMapping.remote2localSize, + &localIdx, &UA_TYPES[UA_TYPES_UINT16]); + (void)res; } + + res = UA_Array_append((void**)&ctx->nsMapping.local2remote, + &ctx->nsMapping.local2remoteSize, + &serverIdx, &UA_TYPES[UA_TYPES_UINT16]); + (void)res; + + return localIdx; } diff --git a/backends/open62541/src/ServerContext.h b/backends/open62541/src/ServerContext.h index 6b460c3f..eb9fef9e 100644 --- a/backends/open62541/src/ServerContext.h +++ b/backends/open62541/src/ServerContext.h @@ -9,26 +9,26 @@ #define SERVERCONTEXT_H #include - -// ServerContext struct bundles the open62541's UA_Server object -// and a table that maps indices used in the nodeset file to indices used in the server. -struct ServerContext; -typedef struct ServerContext ServerContext; - -// ServerContext_new allocates memory that has to released by ServerContext_delete -ServerContext *ServerContext_new(struct UA_Server *server); - -// Releases memory allocated by ServerContext_new -void ServerContext_delete(ServerContext *serverContext); - -// Gets pointer to the UA_Server object -struct UA_Server *ServerContext_getServerObject(const ServerContext *serverContext); - -// Use ServerContext_addNamespaceIdx to sequentially add namespaces as they appear in the -// nodeset file. -void ServerContext_addNamespaceIdx(ServerContext *serverContext, UA_UInt16 serverIdx); - -// Translates from an index used in the nodeset file to an index used in the server -UA_UInt16 ServerContext_translateToServerIdx(const ServerContext *serverContext, UA_UInt16 nodesetIdx); +#include "NodesetLoader/NodesetLoader.h" +#include "Node.h" + +typedef struct { + UA_Server *server; + NodeContainer problemNodes; + UA_NamespaceMapping nsMapping; // From the nodeset (local) to the server (remote) + UA_Logger *logger; + UA_DataTypeArray *customTypes; // To be added to the server +} AddNodeContext; + +AddNodeContext * AddNodeContext_new(struct UA_Server *server); +void AddNodeContext_delete(AddNodeContext *ctx); + +/* Moves the datatype into the addnodecontext */ +UA_StatusCode AddNodeContext_addDataType(AddNodeContext *ctx, UA_DataType *t); + +// Use AddNodeContext_addNamespaceIdx to sequentially add namespaces as they +// appear in the nodeset file. This adds the namespaces to the server also. +// Returns the local mapping index, not the in-server mapping index. +UA_UInt16 AddNodeContext_addNamespace(AddNodeContext *ctx, const UA_String nsUri); #endif diff --git a/backends/open62541/src/conversion.h b/backends/open62541/src/conversion.h deleted file mode 100644 index 4bc697d8..00000000 --- a/backends/open62541/src/conversion.h +++ /dev/null @@ -1,71 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * Copyright 2020 (c) Matthias Konnerth - */ - -#ifndef CONVERSION_H -#define CONVERSION_H -#include - -#include "NodesetLoader/NodesetLoader.h" - -#include - -static inline UA_Boolean isNodeId(const char *s) -{ - if (!s) - { - return UA_FALSE; - } - if (!strncmp(s, "ns=", 3) || !strncmp(s, "i=", 2) || !strncmp(s, "s=", 2) || - !strncmp(s, "g=", 2) || !strncmp(s, "b=", 2)) - { - return UA_TRUE; - } - return UA_FALSE; -} - -static inline UA_Boolean isValTrue(const char *s) -{ - if (!s) - { - return UA_FALSE; - } - if (strcmp(s, "true")) - { - return UA_FALSE; - } - return UA_TRUE; -} - -static inline UA_NodeId extractNodeId(char *s) -{ - UA_NodeId id = UA_NODEID_NULL; - if(!s) - { - return id; - } - UA_String idString; - idString.length=strlen(s); - idString.data = (UA_Byte*)s; - UA_StatusCode result = UA_NodeId_parse(&id, idString); - if(result!=UA_STATUSCODE_GOOD) - { - return id; - } - return id; -} - -static inline UA_DateTime UA_DateTime_fromString(const char *dateString) -{ - UA_DateTimeStruct dt; - memset(&dt, 0, sizeof(UA_DateTimeStruct)); - sscanf(dateString, "%hi-%hu-%huT%hu:%hu:%huZ", - &dt.year, &dt.month, &dt.day, &dt.hour, &dt.min, &dt.sec); - UA_DateTime dateTime = UA_DateTime_fromStruct(dt); - return dateTime; -} - -#endif diff --git a/backends/open62541/src/customDataType.c b/backends/open62541/src/customDataType.c deleted file mode 100644 index 806014e9..00000000 --- a/backends/open62541/src/customDataType.c +++ /dev/null @@ -1,42 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * Copyright 2020 (c) Matthias Konnerth - */ - -#include - -#include -#include "customDataType.h" - -const struct UA_DataType *findCustomDataType(const UA_NodeId *typeId, - const UA_DataTypeArray *types) -{ - while (types) - { - const UA_DataTypeArray *next = types->next; - if (types->types) - { - for (const UA_DataType *type = types->types; - type != types->types + types->typesSize; type++) - { - if (UA_NodeId_equal(&type->typeId, typeId)) - { - return type; - } - } - } - types = next; - } - return NULL; -} - -const struct UA_DataType * -NodesetLoader_getCustomDataType(struct UA_Server *server, - const UA_NodeId *typeId) -{ - UA_ServerConfig *config = UA_Server_getConfig(server); - const UA_DataTypeArray *types = config->customDataTypes; - return findCustomDataType(typeId, types); -} diff --git a/backends/open62541/src/customDataType.h b/backends/open62541/src/customDataType.h deleted file mode 100644 index 2823cd20..00000000 --- a/backends/open62541/src/customDataType.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef CUSTOMDATATYPE_H -#define CUSTOMDATATYPE_H -const struct UA_DataType *findCustomDataType(const UA_NodeId *typeId, - const UA_DataTypeArray *types); - -#endif diff --git a/backends/open62541/src/import.c b/backends/open62541/src/import.c index 5197a1d1..2554cda2 100644 --- a/backends/open62541/src/import.c +++ b/backends/open62541/src/import.c @@ -8,86 +8,31 @@ #include #include -#include -#include "DataTypeImporter.h" #include "ServerContext.h" -#include "conversion.h" #include "NodesetLoader/NodesetLoader.h" #include "RefServiceImpl.h" #include "Node.h" #include -struct AddNodeContext { - ServerContext *serverContext; - NodeContainer *problemNodes; - UA_NamespaceMapping *nsMapping; - NodesetLoader_Logger *logger; -}; - -typedef struct AddNodeContext AddNodeContext; - - -static UA_NodeId getParentDataType(UA_Server *server, const UA_NodeId id) -{ - UA_BrowseDescription bd; - UA_BrowseDescription_init(&bd); - bd.nodeId = id; - bd.browseDirection = UA_BROWSEDIRECTION_INVERSE; - bd.nodeClassMask = UA_NODECLASS_DATATYPE; - - UA_BrowseResult br = UA_Server_browse(server, 10, &bd); - if (br.statusCode != UA_STATUSCODE_GOOD || br.referencesSize != 1) - { - return UA_NODEID_NULL; - } - UA_NodeId parentId = br.references[0].nodeId.nodeId; - UA_BrowseResult_clear(&br); - return parentId; -} - -static bool isKnownParent(const UA_NodeId typeId) -{ - if (typeId.namespaceIndex == 0 && - typeId.identifierType == UA_NODEIDTYPE_NUMERIC && - typeId.identifier.numeric <= 29) - { - return true; - } - UA_NodeId optionSetId = UA_NODEID_NUMERIC(0, UA_NS0ID_OPTIONSET); - if (UA_NodeId_equal(&typeId, &optionSetId)) - { - return true; - } - return false; -} - -static UA_NodeId getParentType(UA_Server *server, const UA_NodeId dataTypeId) -{ - UA_NodeId current = dataTypeId; - while (!isKnownParent(current)) - { - current = getParentDataType(server, current); - } - return current; +static inline UA_Boolean isValTrue(const char *s) { + if(!s) + return UA_FALSE; + if(strcmp(s, "true")) + return false; + return true; } -static UA_NodeId getReferenceTypeId(const NL_Reference *ref) -{ +static UA_NodeId getReferenceTypeId(const NL_Reference *ref) { if (!ref) - { return UA_NODEID_NULL; - } return ref->refType; } -static UA_NodeId getReferenceTarget(const NL_Reference *ref) -{ +static UA_NodeId getReferenceTarget(const NL_Reference *ref) { if (!ref) - { return UA_NODEID_NULL; - } return ref->target; } @@ -95,31 +40,23 @@ static NL_Reference *getHierachicalInverseReference(const NL_Node *node) { NL_Reference *hierachicalRef = node->hierachicalRefs; - while (hierachicalRef) - { + while (hierachicalRef) { if (!hierachicalRef->isForward) - { return hierachicalRef; - } hierachicalRef = hierachicalRef->next; } return NULL; } -static UA_NodeId getParentId(const NL_Node *node, UA_NodeId *parentRefId) -{ +static UA_NodeId getParentId(const NL_Node *node, UA_NodeId *parentRefId) { UA_NodeId parentId = UA_NODEID_NULL; if(NodesetLoader_isInstanceNode(node)) - { parentId = ((const NL_InstanceNode*)node)->parentNodeId; - } NL_Reference *ref = getHierachicalInverseReference((const NL_Node *)node); *parentRefId = getReferenceTypeId(ref); if (UA_NodeId_equal(&parentId, &UA_NODEID_NULL)) - { parentId = getReferenceTarget(ref); - } return parentId; } @@ -127,8 +64,7 @@ static UA_StatusCode handleObjectNode(const NL_ObjectNode *node, UA_NodeId *id, const UA_NodeId *parentId, const UA_NodeId *parentReferenceId, const UA_LocalizedText *lt, const UA_QualifiedName *qn, - const UA_LocalizedText *description, UA_Server *server) -{ + const UA_LocalizedText *description, UA_Server *server) { UA_ObjectAttributes oAttr = UA_ObjectAttributes_default; oAttr.displayName = *lt; oAttr.description = *description; @@ -136,9 +72,7 @@ handleObjectNode(const NL_ObjectNode *node, UA_NodeId *id, UA_NodeId typeDefId = UA_NODEID_NULL; if (node->refToTypeDef) - { typeDefId = node->refToTypeDef->target; - } // addNode_begin is used, otherwise all mandatory childs from type are // instantiated @@ -152,8 +86,7 @@ static UA_StatusCode handleViewNode(const NL_ViewNode *node, UA_NodeId *id, const UA_NodeId *parentId, const UA_NodeId *parentReferenceId, const UA_LocalizedText *lt, const UA_QualifiedName *qn, const UA_LocalizedText *description, - UA_Server *server) -{ + UA_Server *server) { UA_ViewAttributes attr = UA_ViewAttributes_default; attr.displayName = *lt; attr.description = *description; @@ -167,27 +100,22 @@ static UA_StatusCode handleMethodNode(const NL_MethodNode *node, UA_NodeId *id, const UA_NodeId *parentId, const UA_NodeId *parentReferenceId, const UA_LocalizedText *lt, const UA_QualifiedName *qn, - const UA_LocalizedText *description, UA_Server *server) -{ + const UA_LocalizedText *description, UA_Server *server) { UA_MethodAttributes attr = UA_MethodAttributes_default; attr.executable = isValTrue(node->executable); attr.userExecutable = isValTrue(node->userExecutable); attr.displayName = *lt; attr.description = *description; - return UA_Server_addMethodNode(server, *id, *parentId, *parentReferenceId, *qn, - attr, NULL, 0, NULL, 0, NULL, node->extension, - NULL); + attr, NULL, 0, NULL, 0, NULL, node->extension, NULL); } -static size_t getArrayDimensions(const char *s, UA_UInt32 **dims) -{ +static size_t getArrayDimensions(const char *s, UA_UInt32 **dims) { size_t length = strlen(s); size_t arrSize = 0; if (0 == length) - { return 0; - } + // add the first one int val = atoi(s); arrSize++; @@ -196,8 +124,7 @@ static size_t getArrayDimensions(const char *s, UA_UInt32 **dims) const char *subString = strchr(s, ','); - while (subString != NULL) - { + while (subString != NULL) { arrSize++; *dims = (UA_UInt32 *)realloc(*dims, arrSize * sizeof(UA_UInt32)); (*dims)[arrSize - 1] = (UA_UInt32)atoi(subString + 1); @@ -214,7 +141,7 @@ handleVariableNode(const NL_VariableNode *node, UA_NodeId *id, const UA_QualifiedName *qn, const UA_LocalizedText *description, AddNodeContext *context) { - UA_Server *server = ServerContext_getServerObject(context->serverContext); + UA_Server *server = context->server; UA_VariableAttributes attr = UA_VariableAttributes_default; attr.displayName = *lt; @@ -240,13 +167,11 @@ handleVariableNode(const NL_VariableNode *node, UA_NodeId *id, memset(&opts, 0, sizeof(UA_DecodeXmlOptions)); opts.unwrapped = true; opts.customTypes = sc->customDataTypes; - opts.namespaceMapping = context->nsMapping; + opts.namespaceMapping = &context->nsMapping; UA_StatusCode ret = UA_decodeXml(&node->value, &attr.value, &UA_TYPES[UA_TYPES_VARIANT], &opts); - if(ret != UA_STATUSCODE_GOOD) { - context->logger->log(context->logger->context, NODESETLOADER_LOGLEVEL_WARNING, - "Failed to parse the value of %s", buf); - } + if(ret != UA_STATUSCODE_GOOD) + UA_LOG_WARNING(context->logger, UA_LOGCATEGORY_SERVER, "NodesetLoader: Failed to parse the value of %s", buf); // this case is only needed for the euromap83 comparison, think the nodeset // is not valid @@ -343,21 +268,43 @@ static UA_StatusCode handleVariableTypeNode(const NL_VariableTypeNode *node, UA_ node->extension, NULL); } -static UA_StatusCode handleDataTypeNode(const NL_DataTypeNode *node, UA_NodeId *id, - const UA_NodeId *parentId, - const UA_NodeId *parentReferenceId, - const UA_LocalizedText *lt, - const UA_QualifiedName *qn, - const UA_LocalizedText *description, - UA_Server *server) -{ +static UA_StatusCode +handleDataTypeNode(AddNodeContext *ctx, + const NL_DataTypeNode *node, UA_NodeId *id, + const UA_NodeId *parentId, + const UA_NodeId *parentReferenceId, + const UA_LocalizedText *lt, + const UA_QualifiedName *qn, + const UA_LocalizedText *description) { + UA_ServerConfig *sc = UA_Server_getConfig(ctx->server); + + return UA_STATUSCODE_GOOD; + + UA_StructureDefinition *sd = NULL; + + // Generate the UA_DataType + UA_DataType type; + memset(&type, 0, sizeof(UA_DataType)); + UA_StatusCode res = + UA_DataType_fromStructureDefinition(&type, sd, *id, lt->text, sc->customDataTypes); + if(res != UA_STATUSCODE_GOOD) + return res; + + // Add the UA_DataType the the server + res = AddNodeContext_addDataType(ctx, &type); + if(res != UA_STATUSCODE_GOOD) { + UA_DataType_clear(&type); + return res; + } + + // Add the DataTypeNode UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; attr.displayName = *lt; attr.description = *description; attr.isAbstract = isValTrue(node->isAbstract); - - return UA_Server_addDataTypeNode(server, *id, *parentId, *parentReferenceId, *qn, - attr, node->extension, NULL); + return UA_Server_addDataTypeNode(ctx->server, *id, *parentId, + *parentReferenceId, *qn, + attr, node->extension, NULL); } static void @@ -369,7 +316,7 @@ addNodeImpl(AddNodeContext *context, NL_Node *node) { UA_QualifiedName qn = node->browseName; UA_LocalizedText description = node->description; - UA_Server *server = ServerContext_getServerObject(context->serverContext); + UA_Server *server = context->server; UA_StatusCode res = UA_STATUSCODE_BADNOTFOUND; switch (node->nodeClass) { @@ -403,8 +350,9 @@ addNodeImpl(AddNodeContext *context, NL_Node *node) { &parentReferenceId, <, &qn, &description, context); break; case NODECLASS_DATATYPE: - res = handleDataTypeNode((const NL_DataTypeNode *)node, &id, &parentId, - &parentReferenceId, <, &qn, &description, server); + res = handleDataTypeNode(context, (const NL_DataTypeNode *)node, + &id, &parentId, &parentReferenceId, + <, &qn, &description); break; case NODECLASS_VIEW: res = handleViewNode((const NL_ViewNode *)node, &id, &parentId, @@ -414,8 +362,8 @@ addNodeImpl(AddNodeContext *context, NL_Node *node) { // If a node was not added to the server due to an error, we add such a node // to a special node container. We can then try to add such nodes later. - if(context->problemNodes != NULL && UA_StatusCode_isBad(res)) - NodeContainer_add(context->problemNodes, node); + if(UA_StatusCode_isBad(res)) + NodeContainer_add(&context->problemNodes, node); } static void @@ -423,261 +371,94 @@ NodesetLoader_BackendOpen62541_addNamespace(void *userContext, size_t localNamespaceUrisSize, UA_String *localNamespaceUris, UA_NamespaceMapping *nsMapping) { - ServerContext *serverContext = (ServerContext *)userContext; - UA_Server *server = ServerContext_getServerObject(serverContext); - - /* Build up the mapping tables */ - UA_NamespaceMapping_clear(nsMapping); - - nsMapping->remote2local = (UA_UInt16*)UA_calloc(localNamespaceUrisSize, sizeof(UA_UInt16)); - nsMapping->remote2localSize = localNamespaceUrisSize; - - /* Add all the namespaces */ - char nsbuf[256]; + AddNodeContext *ctx = (AddNodeContext*)userContext; for(size_t i = 0; i < localNamespaceUrisSize; i++) { - memcpy(nsbuf, localNamespaceUris[i].data, localNamespaceUris[i].length); - nsbuf[localNamespaceUris[i].length] = 0; - nsMapping->remote2local[i] = UA_Server_addNamespace(server, nsbuf); - } -} - -static void -logToOpen(void *context, enum NodesetLoader_LogLevel level, - const char *message, ...) { - UA_Logger *logger = (UA_Logger *)context; - va_list vl; - va_start(vl, message); - UA_LogLevel uaLevel = UA_LOGLEVEL_DEBUG; - switch (level) { - case NODESETLOADER_LOGLEVEL_DEBUG: - uaLevel = UA_LOGLEVEL_DEBUG; - break; - case NODESETLOADER_LOGLEVEL_ERROR: - uaLevel = UA_LOGLEVEL_ERROR; - break; - case NODESETLOADER_LOGLEVEL_WARNING: - uaLevel = UA_LOGLEVEL_WARNING; - break; - } - logger->log(logger->context, uaLevel, UA_LOGCATEGORY_USERLAND, message, vl); - va_end(vl); -} - -struct DataTypeImportCtx { - DataTypeImporter *importer; - const NL_BiDirectionalReference *hasEncodingRef; - UA_Server *server; -}; - -static void -addDataType(struct DataTypeImportCtx *ctx, NL_Node *node) { - // add only the types - const NL_BiDirectionalReference *r = ctx->hasEncodingRef; - while (r) { - if (UA_NodeId_equal(&r->source, &node->id)) { - NL_Reference *ref = (NL_Reference *)calloc(1, sizeof(NL_Reference)); - ref->refType = r->refType; - ref->target = r->target; - - NL_Reference *lastRef = node->nonHierachicalRefs; - node->nonHierachicalRefs = ref; - ref->next = lastRef; - break; - } - r = r->next; + AddNodeContext_addNamespace(ctx, localNamespaceUris[i]); } - const UA_NodeId parent = getParentType(ctx->server, node->id); - DataTypeImporter_addCustomDataType(ctx->importer, (NL_DataTypeNode *)node, parent); + *nsMapping = ctx->nsMapping; } static void -importDataTypes(NodesetLoader *loader, UA_Server *server) { - const NL_BiDirectionalReference *hasEncodingRef = - NodesetLoader_getBidirectionalRefs(loader); - DataTypeImporter *importer = DataTypeImporter_new(server); - struct DataTypeImportCtx ctx; - ctx.hasEncodingRef = hasEncodingRef; - ctx.server = server; - ctx.importer = importer; - NodesetLoader_forEachNode(loader, NODECLASS_DATATYPE, &ctx, - (NodesetLoader_forEachNode_Func)addDataType); - DataTypeImporter_initMembers(importer); - DataTypeImporter_delete(importer); -} - -static void addNonHierachicalRefs(UA_Server *server, NL_Node *node) -{ +addNonHierachicalRefs(AddNodeContext *ctx, NL_Node *node) { NL_Reference *ref = node->nonHierachicalRefs; - while (ref) - { - + while(ref) { UA_NodeId src = node->id; UA_ExpandedNodeId target = UA_EXPANDEDNODEID_NULL; target.nodeId = ref->target; UA_NodeId refType = ref->refType; - UA_Server_addReference(server, src, refType, target, ref->isForward); + UA_Server_addReference(ctx->server, src, refType, target, ref->isForward); ref = ref->next; } + // brute force, maybe not the best way to do this ref = node->hierachicalRefs; - while (ref) - { + while(ref) { UA_NodeId src = node->id; UA_ExpandedNodeId target = UA_EXPANDEDNODEID_NULL; target.nodeId = ref->target; UA_NodeId refType = ref->refType; - UA_Server_addReference(server, src, refType, target, ref->isForward); + UA_Server_addReference(ctx->server, src, refType, target, ref->isForward); ref = ref->next; } } -static size_t -secondChanceAddNodes(AddNodeContext *context, - NodesetLoader_Logger *logger) { - const size_t attemptsNum = 10; - - NodeContainer *problemNodes = context->problemNodes; - - size_t numberOfAllAddedNodes = 0; - // We will try to add all failed nodes in a certain number of attempts. - // This gives us the opportunity to add a chain like Object(child) -> - // Variable(parent). - // For example, this reference is used in the HasHistoricalConfiguration - // reference type. - size_t attempt = 1; - while (attempt != attemptsNum && problemNodes->size != 0) { - NodeContainer *local_badStatusNodes = NodeContainer_new(problemNodes->size, false); - AddNodeContext c2; - c2.problemNodes = local_badStatusNodes; - c2.serverContext = context->serverContext; - c2.nsMapping = context->nsMapping; - c2.logger = logger; - for (size_t counter = 0; counter < problemNodes->size; counter++) { - // Import to server again - addNodeImpl(&c2, problemNodes->nodes[counter]); - } - size_t counterOfAdddedNodesForOneAttempt = problemNodes->size - local_badStatusNodes->size; - numberOfAllAddedNodes += counterOfAdddedNodesForOneAttempt; - logger->log(logger->context, NODESETLOADER_LOGLEVEL_DEBUG, - "attempt (%zu), imported nodes: %zu", attempt, - counterOfAdddedNodesForOneAttempt); - if(problemNodes != context->problemNodes) - NodeContainer_delete(problemNodes); - problemNodes = local_badStatusNodes; - attempt++; - } - if(problemNodes != context->problemNodes) - NodeContainer_delete(problemNodes); - return numberOfAllAddedNodes; -} - -static void -addNodes(NodesetLoader *loader, NL_FileContext *handler, - ServerContext *serverContext, NodesetLoader_Logger *logger) { - const NL_NodeClass order[NL_NODECLASS_COUNT] = { - NODECLASS_REFERENCETYPE, NODECLASS_DATATYPE, NODECLASS_OBJECTTYPE, - NODECLASS_VARIABLETYPE, NODECLASS_OBJECT, NODECLASS_METHOD, - NODECLASS_VARIABLE, NODECLASS_VIEW}; - const size_t containerInitialSize = 100; - - // If we have a problem adding nodes to the server, let's add references - // to these nodes to the container. - NodeContainer* badStatusNodes = NodeContainer_new(containerInitialSize, false); - // Since every cycle we add one node class we need to save - // counter of previous badStatusNodes because badStatusNodes - // will always be adding new bad nodes to one list, and we have to calculate - // the real number of bad status nodes on every single cycle. - size_t previous_loop_badStatusNodes_size = 0; - - AddNodeContext context; - context.problemNodes = badStatusNodes; - context.serverContext = serverContext; - context.nsMapping = &handler->nsMapping; - context.logger = logger; - - for (size_t i = 0; i < NL_NODECLASS_COUNT; i++) { - const NL_NodeClass classToImport = order[i]; - size_t cnt = - NodesetLoader_forEachNode(loader, classToImport, &context, - (NodesetLoader_forEachNode_Func)addNodeImpl); - if (classToImport == NODECLASS_DATATYPE) { - importDataTypes(loader, ServerContext_getServerObject(serverContext)); - } - - // Now we can see the nodes that could not be added and can calculate - // and show the actual nodes added. - logger->log(logger->context, NODESETLOADER_LOGLEVEL_DEBUG, - "imported %ss: %zu", NL_NODECLASS_NAME[classToImport], - cnt - (badStatusNodes->size - previous_loop_badStatusNodes_size)); - previous_loop_badStatusNodes_size = badStatusNodes->size; - } - - // second chance algorithm - if (badStatusNodes->size != 0) { - logger->log(logger->context, NODESETLOADER_LOGLEVEL_WARNING, - "Couldn't import: %zu. Let's try adding non-imported " - "nodes a few more times.", badStatusNodes->size); - size_t numberOfAllAddedNodes = secondChanceAddNodes(&context, logger); - logger->log(logger->context, NODESETLOADER_LOGLEVEL_WARNING, - "imported after attempts: %zu", numberOfAllAddedNodes); - } - - // Delete only reference and container. Not NL_Nodes objects. - NodeContainer_delete(badStatusNodes); - - for (size_t i = 0; i < NL_NODECLASS_COUNT; i++) - { - const NL_NodeClass classToImport = order[i]; - NodesetLoader_forEachNode( - loader, classToImport, ServerContext_getServerObject(serverContext), - (NodesetLoader_forEachNode_Func)addNonHierachicalRefs); - } -} - bool NodesetLoader_loadFile(struct UA_Server *server, const char *path, - NodesetLoader_ExtensionInterface *extensionHandling) { - if (!server) + void *options) { + if(!server || !path) return false; - if (!path) + AddNodeContext *ctx = AddNodeContext_new(server); + if(!ctx) return false; - ServerContext *serverContext = ServerContext_new(server); - NL_FileContext handler; memset(&handler, 0, sizeof(NL_FileContext)); handler.addNamespace = NodesetLoader_BackendOpen62541_addNamespace; - handler.userContext = serverContext; + handler.userContext = ctx; handler.file = path; - handler.extensionHandling = extensionHandling; + handler.nsMapping = ctx->nsMapping; // Provide the pre-filled mapping UA_ServerConfig *config = UA_Server_getConfig(server); - NodesetLoader_Logger *logger = - (NodesetLoader_Logger *)calloc(1, sizeof(NodesetLoader_Logger)); -#if UA_OPEN62541_VER_MAJOR == 1 && UA_OPEN62541_VER_MINOR < 4 - logger->context = (void*)(uintptr_t)&config->logger; -#else - logger->context = (void*)(uintptr_t)config->logging; -#endif - logger->log = &logToOpen; NL_ReferenceService *refService = RefServiceImpl_new(server); - NodesetLoader *loader = NodesetLoader_new(logger, refService); - logger->log(logger->context, NODESETLOADER_LOGLEVEL_DEBUG, + NodesetLoader *loader = NodesetLoader_new(config->logging, refService); + UA_LOG_DEBUG(config->logging, UA_LOGCATEGORY_SERVER, "NodesetLoader: " "Start import nodeset: %s", path); - bool importStatus = NodesetLoader_importFile(loader, &handler); - bool sortStatus = NodesetLoader_sort(loader); - bool retStatus = importStatus && sortStatus; - if (retStatus && sortStatus) { - addNodes(loader, &handler, serverContext, logger); + + // Import from XML + bool status = NodesetLoader_importFile(loader, &handler); + + // Sort + if(status) + status = NodesetLoader_sort(loader); + + // Load + if(status) { + static const NL_NodeClass order[NL_NODECLASS_COUNT] = { + NODECLASS_REFERENCETYPE, NODECLASS_DATATYPE, NODECLASS_OBJECTTYPE, + NODECLASS_VARIABLETYPE, NODECLASS_OBJECT, NODECLASS_METHOD, + NODECLASS_VARIABLE, NODECLASS_VIEW}; + + for(size_t i = 0; i < NL_NODECLASS_COUNT; i++) { + const NL_NodeClass classToImport = order[i]; + NodesetLoader_forEachNode(loader, classToImport, ctx, + (NodesetLoader_forEachNode_Func)addNodeImpl); + } + + for(size_t i = 0; i < NL_NODECLASS_COUNT; i++) { + const NL_NodeClass classToImport = order[i]; + NodesetLoader_forEachNode(loader, classToImport, ctx, + (NodesetLoader_forEachNode_Func)addNonHierachicalRefs); + } } else { - logger->log(logger->context, NODESETLOADER_LOGLEVEL_ERROR, - "importing the nodeset failed, nodes were not added"); + UA_LOG_ERROR(config->logging, UA_LOGCATEGORY_SERVER, "NodesetLoader: " + "importing the nodeset failed, nodes were not added"); } + + // Clean up RefServiceImpl_delete(refService); NodesetLoader_delete(loader); - ServerContext_delete(serverContext); - UA_NamespaceMapping_clear(&handler.nsMapping); - free(logger); - return retStatus; + AddNodeContext_delete(ctx); + + return UA_STATUSCODE_GOOD; } diff --git a/backends/open62541/src/nodeset_base64.h b/backends/open62541/src/nodeset_base64.h deleted file mode 100644 index 8af13a6c..00000000 --- a/backends/open62541/src/nodeset_base64.h +++ /dev/null @@ -1,224 +0,0 @@ -/* - https://github.com/superwills/NibbleAndAHalf - nodeset_base64.h -- Fast base64 encoding and decoding. - version 1.0.0, April 17, 2013 143a - Copyright (C) 2013 William Sherif - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - William Sherif - will.sherif@gmail.com - YWxsIHlvdXIgYmFzZSBhcmUgYmVsb25nIHRvIHVz -*/ -#ifndef NODESET_BASE64_H -#define NODESET_BASE64_H - -#include -#include -#include - -static const char *b64 = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -// maps A=>0,B=>1.. -static const unsigned char unb64[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 10 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 30 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40 - 0, 0, 0, 62, 0, 0, 0, 63, 52, 53, // 50 - 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, // 60 - 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, // 70 - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 80 - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, // 90 - 25, 0, 0, 0, 0, 0, 0, 26, 27, 28, // 100 - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // 110 - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, // 120 - 49, 50, 51, 0, 0, 0, 0, 0, 0, 0, // 130 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 140 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 150 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 160 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 170 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 180 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 190 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 200 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 210 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 220 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 230 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 240 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 250 - 0, 0, 0, 0, 0, 0, -}; // This array has 256 elements - -// Converts binary data of length=len to base64 characters. -// Length of the resultant string is stored in flen -// (you must pass pointer flen). -char *base64(const void *binaryData, int len, int *flen); -char *base64(const void *binaryData, int len, int *flen) -{ - const unsigned char *bin = (const unsigned char *)binaryData; - char *res; - - int rc = 0; // result counter - int byteNo; // I need this after the loop - - int modulusLen = len % 3; - int pad = - ((modulusLen & 1) << 1) + - ((modulusLen & 2) >> 1); // 2 gives 1 and 1 gives 2, but 0 gives 0. - - *flen = 4 * (len + pad) / 3; - res = (char *)malloc((size_t)(*flen + 1)); // and one for the null - if (!res) - { - puts("ERROR: base64 could not allocate enough memory."); - puts("I must stop because I could not get enough"); - return 0; - } - - for (byteNo = 0; byteNo <= len - 3; byteNo += 3) - { - unsigned char BYTE0 = bin[byteNo]; - unsigned char BYTE1 = bin[byteNo + 1]; - unsigned char BYTE2 = bin[byteNo + 2]; - res[rc++] = b64[BYTE0 >> 2]; - res[rc++] = b64[((0x3 & BYTE0) << 4) + (BYTE1 >> 4)]; - res[rc++] = b64[((0x0f & BYTE1) << 2) + (BYTE2 >> 6)]; - res[rc++] = b64[0x3f & BYTE2]; - } - - if (pad == 2) - { - res[rc++] = b64[bin[byteNo] >> 2]; - res[rc++] = b64[(0x3 & bin[byteNo]) << 4]; - res[rc++] = '='; - res[rc++] = '='; - } - else if (pad == 1) - { - res[rc++] = b64[bin[byteNo] >> 2]; - res[rc++] = b64[((0x3 & bin[byteNo]) << 4) + (bin[byteNo + 1] >> 4)]; - res[rc++] = b64[(0x0f & bin[byteNo + 1]) << 2]; - res[rc++] = '='; - } - - res[rc] = 0; // NULL TERMINATOR! ;) - return res; -} -unsigned char *unbase64(const char *ascii, int len, int *flen); - -unsigned char *unbase64(const char *ascii, int len, int *flen) -{ - unsigned char *safeAsciiPtr; - unsigned char *bin; - int cb = 0; - int charNo = 0; - int pad = 0; - - safeAsciiPtr = (unsigned char *)malloc((size_t)len); - if (!safeAsciiPtr) - { - puts("ERROR: unbase64 could not allocate enough memory."); - puts("I must stop because I could not get enough"); - return 0; - } - - for (charNo = 0; charNo < len; charNo++) - { - // remove all space characters e.g. LF, CR, space and tab - if (!isspace(ascii[charNo])) - { - if (((ascii[charNo] >= '0') && - (ascii[charNo] <= '9')) || - ((ascii[charNo] >= 'A') && - (ascii[charNo] <= 'Z')) || - ((ascii[charNo] >= 'a') && - (ascii[charNo] <= 'z')) || - (ascii[charNo] == '+') || - (ascii[charNo] == '/') || - (ascii[charNo] == '=')) - { - safeAsciiPtr[cb++] = (unsigned char)ascii[charNo]; - } - else - { - puts("ERROR: You passed an invalid base64 string (illegal character). " - "You get NULL back."); - free(safeAsciiPtr); - *flen = 0; - return 0; - } - } - } - - len = cb; - if (len < 2) - { // 2 accesses below would be OOB. - // catch empty string, return NULL as result. - puts("ERROR: You passed an invalid base64 string (too short). You get " - "NULL back."); - *flen = 0; - free(safeAsciiPtr); - return 0; - } - if (safeAsciiPtr[len - 1] == '=') - ++pad; - if (safeAsciiPtr[len - 2] == '=') - ++pad; - - *flen = 3 * len / 4 - pad; - bin = (unsigned char *)malloc((size_t)*flen); - if (!bin) - { - puts("ERROR: unbase64 could not allocate enough memory."); - puts("I must stop because I could not get enough"); - free(safeAsciiPtr); - return 0; - } - - cb = 0; - for (charNo = 0; charNo <= len - 4 - pad; charNo += 4) - { - unsigned char A = unb64[safeAsciiPtr[charNo]]; - unsigned char B = unb64[safeAsciiPtr[charNo + 1]]; - unsigned char C = unb64[safeAsciiPtr[charNo + 2]]; - unsigned char D = unb64[safeAsciiPtr[charNo + 3]]; - - bin[cb++] = (unsigned char)(A << 2) | (B >> 4); - bin[cb++] = (unsigned char)(B << 4) | (C >> 2); - bin[cb++] = (unsigned char)(C << 6) | (D); - } - - if (pad == 1 && (charNo + 2) < len) - { - unsigned char A = unb64[safeAsciiPtr[charNo]]; - unsigned char B = unb64[safeAsciiPtr[charNo + 1]]; - unsigned char C = unb64[safeAsciiPtr[charNo + 2]]; - - bin[cb++] = (unsigned char)(A << 2) | (B >> 4); - bin[cb++] = (unsigned char)(B << 4) | (C >> 2); - } - else if (pad == 2 && (charNo + 1) < len) - { - unsigned char A = (unsigned char)unb64[safeAsciiPtr[charNo]]; - unsigned char B = (unsigned char)unb64[safeAsciiPtr[charNo + 1]]; - - bin[cb++] = (unsigned char)(A << 2) | (B >> 4); - } - - free(safeAsciiPtr); - - return bin; -} - -#endif /* NODESET_BASE64_H */ diff --git a/backends/open62541/src/padding.h b/backends/open62541/src/padding.h deleted file mode 100644 index de6bbe8f..00000000 --- a/backends/open62541/src/padding.h +++ /dev/null @@ -1,19 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * Copyright 2020 (c) Matthias Konnerth - */ - -#ifndef PADDING_H -#define PADDING_H - -#include - -static inline UA_Byte getPadding(int alignment, int offset) -{ - assert(alignment != 0); - return (UA_Byte)((alignment - (offset % alignment)) % alignment); -} - -#endif diff --git a/backends/open62541/tests/CMakeLists.txt b/backends/open62541/tests/CMakeLists.txt index f0555f91..ecfd1068 100644 --- a/backends/open62541/tests/CMakeLists.txt +++ b/backends/open62541/tests/CMakeLists.txt @@ -75,13 +75,6 @@ add_test(NAME cornerCases_Test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND cornerCases ${CMAKE_CURRENT_SOURCE_DIR}/cornerCases.xml) -add_executable(extension extension.c) -target_include_directories(extension PRIVATE ${CHECK_INCLUDE_DIR}) -target_link_libraries(extension PRIVATE NodesetLoader open62541::open62541 ${CHECK_LIBRARIES} ${CHECK_LIBRARIES} ${PTHREAD_LIB}) -add_test(NAME extension_Test - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND extension ${CMAKE_CURRENT_SOURCE_DIR}/extension.xml) - add_executable(newHierachicalRef newHierachicalRef.c) target_include_directories(newHierachicalRef PRIVATE ${CHECK_INCLUDE_DIR}) target_link_libraries(newHierachicalRef PRIVATE NodesetLoader open62541::open62541 ${CHECK_LIBRARIES} ${CHECK_LIBRARIES} ${PTHREAD_LIB}) @@ -132,13 +125,6 @@ add_test(NAME primitiveValues_Test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND primitiveValues ${CMAKE_CURRENT_SOURCE_DIR}/primitiveValues.xml) -add_executable(conversion conversion.c) -target_include_directories(conversion PRIVATE ${CHECK_INCLUDE_DIR}) -target_link_libraries(conversion PRIVATE NodesetLoader open62541::open62541 ${CHECK_LIBRARIES} ${CHECK_LIBRARIES} ${PTHREAD_LIB}) -add_test(NAME conversion_Test - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND conversion) - add_executable(issue_246 issue_246.c) target_include_directories(issue_246 PRIVATE ${CHECK_INCLUDE_DIR}) target_link_libraries(issue_246 PRIVATE NodesetLoader open62541::open62541 ${CHECK_LIBRARIES} ${CHECK_LIBRARIES} ${PTHREAD_LIB}) diff --git a/backends/open62541/tests/basicNodeClasses.c b/backends/open62541/tests/basicNodeClasses.c index 69cb279b..96b84207 100644 --- a/backends/open62541/tests/basicNodeClasses.c +++ b/backends/open62541/tests/basicNodeClasses.c @@ -4,7 +4,6 @@ #include "check.h" #include -#include #include #include #include diff --git a/backends/open62541/tests/conversion.c b/backends/open62541/tests/conversion.c deleted file mode 100644 index c99a6a4b..00000000 --- a/backends/open62541/tests/conversion.c +++ /dev/null @@ -1,56 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "../src/conversion.h" -#include "check.h" -#include - -#include "testHelper.h" - -static void setup(void) -{ - -} - -static void teardown(void) -{ - -} - -START_TEST(dateTime) -{ - UA_DateTime dt = UA_DateTime_fromString("1970-01-01T00:00:00Z"); - ck_assert_int_eq(dt, UA_DATETIME_UNIX_EPOCH); -} -END_TEST - -START_TEST(dateTime2022) -{ - UA_DateTime dt = UA_DateTime_fromString("2022-02-11T19:02:01Z"); - UA_DateTime fromUnix = UA_DateTime_fromUnixTime(1644606121LL); - ck_assert_int_eq(dt, fromUnix); -} -END_TEST - -static Suite *testSuite_Client(void) -{ - Suite *s = suite_create("conversion"); - TCase *tc_server = tcase_create("conversion"); - tcase_add_unchecked_fixture(tc_server, setup, teardown); - tcase_add_test(tc_server, dateTime); - tcase_add_test(tc_server, dateTime2022); - suite_add_tcase(s, tc_server); - return s; -} - -int main(int argc, char *argv[]) -{ - Suite *s = testSuite_Client(); - SRunner *sr = srunner_create(s); - srunner_set_fork_status(sr, CK_NOFORK); - srunner_run_all(sr, CK_NORMAL); - int number_failed = srunner_ntests_failed(sr); - srunner_free(sr); - return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; -} diff --git a/backends/open62541/tests/cornerCases.c b/backends/open62541/tests/cornerCases.c index 280757ec..99908492 100644 --- a/backends/open62541/tests/cornerCases.c +++ b/backends/open62541/tests/cornerCases.c @@ -4,7 +4,6 @@ #include "check.h" #include -#include #include #include #include diff --git a/backends/open62541/tests/customTypesWithValues.c b/backends/open62541/tests/customTypesWithValues.c index 2f70701d..1724556d 100644 --- a/backends/open62541/tests/customTypesWithValues.c +++ b/backends/open62541/tests/customTypesWithValues.c @@ -10,7 +10,6 @@ #include "testHelper.h" #include -#include UA_Server *server; char *nodesetPath = NULL; diff --git a/backends/open62541/tests/extension.c b/backends/open62541/tests/extension.c deleted file mode 100644 index c7254d2e..00000000 --- a/backends/open62541/tests/extension.c +++ /dev/null @@ -1,108 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "check.h" -#include -#include -#include -#include -#include - -#include "testHelper.h" - -UA_Server *server; -char *nodesetPath = NULL; - -static void setup(void) -{ - printf("path to testnodesets %s\n", nodesetPath); - server = UA_Server_new(); - UA_ServerConfig *config = UA_Server_getConfig(server); - UA_ServerConfig_setDefault(config); -} - -static void teardown(void) -{ - UA_Server_run_shutdown(server); - UA_Server_delete(server); -} - -struct MyExtension -{ - char *address; -}; - -void *Extension_new() -{ - struct MyExtension *newExt = calloc(1, sizeof(struct MyExtension)); - if (!newExt) - { - return NULL; - } - return newExt; -} - -void startExtension(void *ext, const char *name, int attrCnt, - const char **attributes) -{ -} - -void endExtension(void *ext, const char *name, const char *value) -{ - if (ext && !strcmp(name, "Address")) - { - ((struct MyExtension *)ext)->address = - calloc(strlen(value) + 1, sizeof(char)); - memcpy(((struct MyExtension *)ext)->address, value, strlen(value)); - } -} - -void finishExtension(void *ext) {} - -START_TEST(extensions) -{ - NodesetLoader_ExtensionInterface extIf; - extIf.userContext = NULL; - extIf.newExtension = (NodesetLoader_newExtensionCb)Extension_new; - extIf.start = (NodesetLoader_startExtensionCb)startExtension; - extIf.end = (NodesetLoader_endExtensionCb)endExtension; - extIf.finish = (NodesetLoader_finishExtensionCb)finishExtension; - ck_assert(NodesetLoader_loadFile(server, nodesetPath, &extIf)); - ck_assert(UA_NODECLASS_VARIABLE == - getNodeClass(server, UA_NODEID_NUMERIC(2, 6002))); - - struct MyExtension *parsedContext = NULL; - ck_assert(UA_STATUSCODE_GOOD == - UA_Server_getNodeContext(server, UA_NODEID_NUMERIC(2, 6002), - (void **)&parsedContext)); - ck_assert(!strcmp(parsedContext->address, "demo.test")); - free(parsedContext->address); - free(parsedContext); -} -END_TEST - -static Suite *testSuite_Client(void) -{ - Suite *s = suite_create("extensions"); - TCase *tc_server = tcase_create("extensions"); - tcase_add_unchecked_fixture(tc_server, setup, teardown); - tcase_add_test(tc_server, extensions); - suite_add_tcase(s, tc_server); - return s; -} - -int main(int argc, char *argv[]) -{ - printf("%s", argv[0]); - if (!(argc > 1)) - return 1; - nodesetPath = argv[1]; - Suite *s = testSuite_Client(); - SRunner *sr = srunner_create(s); - srunner_set_fork_status(sr, CK_NOFORK); - srunner_run_all(sr, CK_NORMAL); - int number_failed = srunner_ntests_failed(sr); - srunner_free(sr); - return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; -} diff --git a/backends/open62541/tests/extension.xml b/backends/open62541/tests/extension.xml deleted file mode 100644 index 3c864218..00000000 --- a/backends/open62541/tests/extension.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - http://yourorganisation.org/extension/ - - - i=6 - i=35 - i=40 - - - - - - - - VarWithExtension - - i=63 - i=85 - - - -
demo.test
-
-
-
-
diff --git a/backends/open62541/tests/import.c b/backends/open62541/tests/import.c index a15feb80..dab3b726 100644 --- a/backends/open62541/tests/import.c +++ b/backends/open62541/tests/import.c @@ -10,7 +10,6 @@ #include "testHelper.h" #include -#include UA_Server *server; char* nodesetPath=NULL; diff --git a/backends/open62541/tests/issue_201.c b/backends/open62541/tests/issue_201.c index 13d256bd..9c804183 100644 --- a/backends/open62541/tests/issue_201.c +++ b/backends/open62541/tests/issue_201.c @@ -4,7 +4,6 @@ #include "check.h" #include -#include #include #include #include diff --git a/backends/open62541/tests/issue_241.c b/backends/open62541/tests/issue_241.c index 4012133a..858b1e01 100644 --- a/backends/open62541/tests/issue_241.c +++ b/backends/open62541/tests/issue_241.c @@ -4,7 +4,6 @@ #include "check.h" #include -#include #include #include #include diff --git a/backends/open62541/tests/issue_246.c b/backends/open62541/tests/issue_246.c index 2465ac36..a971e46c 100644 --- a/backends/open62541/tests/issue_246.c +++ b/backends/open62541/tests/issue_246.c @@ -4,7 +4,6 @@ #include "check.h" #include -#include #include #include diff --git a/backends/open62541/tests/issue_246_2.c b/backends/open62541/tests/issue_246_2.c index f721f7e6..bb937854 100644 --- a/backends/open62541/tests/issue_246_2.c +++ b/backends/open62541/tests/issue_246_2.c @@ -4,7 +4,6 @@ #include "check.h" #include -#include #include #include diff --git a/backends/open62541/tests/issue_266_testdata.c b/backends/open62541/tests/issue_266_testdata.c index 4783b914..65e130b3 100644 --- a/backends/open62541/tests/issue_266_testdata.c +++ b/backends/open62541/tests/issue_266_testdata.c @@ -4,7 +4,6 @@ #include "check.h" #include -#include #include #include diff --git a/backends/open62541/tests/multipleNamespaces.c b/backends/open62541/tests/multipleNamespaces.c index 8becadb2..71c44bbb 100644 --- a/backends/open62541/tests/multipleNamespaces.c +++ b/backends/open62541/tests/multipleNamespaces.c @@ -10,7 +10,6 @@ #include "testHelper.h" #include -#include UA_Server *server; char* nodesetPath=NULL; diff --git a/backends/open62541/tests/namespaceZeroValues.c b/backends/open62541/tests/namespaceZeroValues.c index f4053021..c4fb1f13 100644 --- a/backends/open62541/tests/namespaceZeroValues.c +++ b/backends/open62541/tests/namespaceZeroValues.c @@ -10,7 +10,6 @@ #include "testHelper.h" #include -#include UA_Server *server; char* nodesetPath=NULL; diff --git a/backends/open62541/tests/newHierachicalRef.c b/backends/open62541/tests/newHierachicalRef.c index 2a240114..86bc1232 100644 --- a/backends/open62541/tests/newHierachicalRef.c +++ b/backends/open62541/tests/newHierachicalRef.c @@ -10,7 +10,6 @@ #include "testHelper.h" #include -#include UA_Server *server; char *nodesetPath1 = NULL; diff --git a/backends/open62541/tests/nodeAttributes.c b/backends/open62541/tests/nodeAttributes.c index 0e624de4..81efc137 100644 --- a/backends/open62541/tests/nodeAttributes.c +++ b/backends/open62541/tests/nodeAttributes.c @@ -10,7 +10,6 @@ #include "testHelper.h" #include -#include UA_Server *server; char *nodesetPath = NULL; diff --git a/backends/open62541/tests/orderingStringNodeIds.c b/backends/open62541/tests/orderingStringNodeIds.c index 3c8fc8dc..4701b8b6 100644 --- a/backends/open62541/tests/orderingStringNodeIds.c +++ b/backends/open62541/tests/orderingStringNodeIds.c @@ -4,7 +4,6 @@ #include "check.h" #include -#include #include #include #include diff --git a/backends/open62541/tests/primitiveValues.c b/backends/open62541/tests/primitiveValues.c index 0b502f3f..559f3971 100644 --- a/backends/open62541/tests/primitiveValues.c +++ b/backends/open62541/tests/primitiveValues.c @@ -4,7 +4,6 @@ #include "check.h" #include -#include #include #include #include diff --git a/backends/open62541/tests/references.c b/backends/open62541/tests/references.c index 8c71caa9..67a281d9 100644 --- a/backends/open62541/tests/references.c +++ b/backends/open62541/tests/references.c @@ -10,7 +10,6 @@ #include "testHelper.h" #include -#include UA_Server *server; char *nodesetPath = NULL; diff --git a/backends/open62541/tests/stringNodeId_issue_224.c b/backends/open62541/tests/stringNodeId_issue_224.c index 312b5243..11cf66f6 100644 --- a/backends/open62541/tests/stringNodeId_issue_224.c +++ b/backends/open62541/tests/stringNodeId_issue_224.c @@ -4,7 +4,6 @@ #include "check.h" #include -#include #include #include #include diff --git a/backends/open62541/tests/structMultipleNamespaces.c b/backends/open62541/tests/structMultipleNamespaces.c index f3e214c0..22b72ac6 100644 --- a/backends/open62541/tests/structMultipleNamespaces.c +++ b/backends/open62541/tests/structMultipleNamespaces.c @@ -10,7 +10,6 @@ #include "testHelper.h" #include -#include UA_Server *server; char *nodesetPath1 = NULL; diff --git a/backends/open62541/tests/structwitharray.c b/backends/open62541/tests/structwitharray.c index 6921b886..b087020a 100644 --- a/backends/open62541/tests/structwitharray.c +++ b/backends/open62541/tests/structwitharray.c @@ -10,7 +10,6 @@ #include "testHelper.h" #include -#include UA_Server *server; char *nodesetPath = NULL; diff --git a/backends/open62541/tests/subDataTypes.c b/backends/open62541/tests/subDataTypes.c index 92e51cc8..9185edb1 100644 --- a/backends/open62541/tests/subDataTypes.c +++ b/backends/open62541/tests/subDataTypes.c @@ -10,7 +10,6 @@ #include "testHelper.h" #include -#include UA_Server *server; char *nodesetPath = NULL; diff --git a/backends/open62541/tests/valueRank.c b/backends/open62541/tests/valueRank.c index 48b054e5..d393551f 100644 --- a/backends/open62541/tests/valueRank.c +++ b/backends/open62541/tests/valueRank.c @@ -10,7 +10,6 @@ #include "testHelper.h" #include -#include UA_Server *server; char *nodesetPath = NULL; diff --git a/cmake/FindCheck.cmake b/cmake/FindCheck.cmake index fc1172fe..ea681198 100644 --- a/cmake/FindCheck.cmake +++ b/cmake/FindCheck.cmake @@ -2,7 +2,7 @@ # Once done this will define # # CHECK_FOUND - system has check -# CHECK_INCLUDE_DIR - the check include directory +# CHECK_INCLUDE_DIRS - the check include directory # CHECK_LIBRARIES - check library # # This configuration file for finding libcheck is originally from @@ -16,41 +16,67 @@ # BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. - -INCLUDE( FindPkgConfig ) - -# Take care about check.pc settings -PKG_SEARCH_MODULE( CHECK check ) +if(WIN32) + # Manually define CHECK_INSTALL_DIR if vcpkg is not used + if(DEFINED VCPKG_INSTALLED_DIR) + set(CHECK_INSTALL_DIR "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}") + # find_package(check CONFIG REQUIRED) + else() + if(NOT CHECK_INSTALL_DIR) + if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8") + file(TO_CMAKE_PATH "$ENV{PROGRAMFILES}" _programfiles) + else() + set(_progfiles_x86 "ProgramFiles(x86)") + if(NOT "$ENV{${_progfiles_x86}}" STREQUAL "") + # under windows 64 bit machine + file(TO_CMAKE_PATH "$ENV{${_progfiles_x86}}" _programfiles) + else() + # under windows 32 bit machine + file(TO_CMAKE_PATH "$ENV{ProgramFiles}" _programfiles) + endif() + unset(_progfiles_x86) + endif() + if(EXISTS ${_programfiles}/Check/lib/check.lib) + MESSAGE(STATUS "${_programfiles}/Check/lib/check.lib exists") + set(CHECK_INSTALL_DIR "${_programfiles}/Check") + endif() + unset (_programfiles) + endif() + endif() +else() + # Take care about check.pc settings + find_package(PkgConfig REQUIRED) + PKG_SEARCH_MODULE( CHECK check ) +endif() # Look for CHECK include dir and libraries IF( NOT CHECK_FOUND ) - IF ( CHECK_INSTALL_DIR ) - MESSAGE ( STATUS "Using override CHECK_INSTALL_DIR to find check" ) - SET ( CHECK_INCLUDE_DIR "${CHECK_INSTALL_DIR}/include" ) - SET ( CHECK_INCLUDE_DIRS "${CHECK_INCLUDE_DIR}" ) - FIND_LIBRARY( CHECK_LIBRARY NAMES check PATHS "${CHECK_INSTALL_DIR}/lib" ) - FIND_LIBRARY( COMPAT_LIBRARY NAMES compat PATHS "${CHECK_INSTALL_DIR}/lib" ) - SET ( CHECK_LIBRARIES "${CHECK_LIBRARY}" "${COMPAT_LIBRARY}" ) - ELSE ( CHECK_INSTALL_DIR ) - FIND_PATH( CHECK_INCLUDE_DIR check.h ) - FIND_LIBRARY( CHECK_LIBRARIES NAMES check ) - ENDIF ( CHECK_INSTALL_DIR ) + IF ( CHECK_INSTALL_DIR ) + MESSAGE ( STATUS "Using override CHECK_INSTALL_DIR to find check: ${CHECK_INSTALL_DIR}" ) + SET ( CHECK_INCLUDE_DIRS "${CHECK_INSTALL_DIR}/include" ) +# Find_library() always returns the 64-bit version in "C:/Program Files/Check/lib" no matter what path is passed in +# FIND_LIBRARY( CHECK_LIBRARIES NAMES check PATHS "${CHECK_INSTALL_DIR}/lib" NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH ) + SET ( CHECK_LIBRARIES "${CHECK_INSTALL_DIR}/lib/check.lib" ) + ELSE ( CHECK_INSTALL_DIR ) + FIND_PATH( CHECK_INCLUDE_DIRS check.h ) + FIND_LIBRARY( CHECK_LIBRARIES NAMES check ) + ENDIF ( CHECK_INSTALL_DIR ) - IF ( CHECK_INCLUDE_DIR AND CHECK_LIBRARIES ) - SET( CHECK_FOUND 1 ) - IF ( NOT Check_FIND_QUIETLY ) - MESSAGE ( STATUS "Found CHECK: ${CHECK_LIBRARIES}" ) - ENDIF ( NOT Check_FIND_QUIETLY ) - ELSE ( CHECK_INCLUDE_DIR AND CHECK_LIBRARIES ) - IF ( Check_FIND_REQUIRED ) - MESSAGE( FATAL_ERROR "Could NOT find CHECK" ) - ELSE ( Check_FIND_REQUIRED ) - IF ( NOT Check_FIND_QUIETLY ) - MESSAGE( STATUS "Could NOT find CHECK" ) - ENDIF ( NOT Check_FIND_QUIETLY ) - ENDIF ( Check_FIND_REQUIRED ) - ENDIF ( CHECK_INCLUDE_DIR AND CHECK_LIBRARIES ) + IF ( CHECK_INCLUDE_DIRS AND CHECK_LIBRARIES ) + SET( CHECK_FOUND 1 ) + IF ( NOT Check_FIND_QUIETLY ) + MESSAGE ( STATUS "Found CHECK: ${CHECK_LIBRARIES}" ) + ENDIF ( NOT Check_FIND_QUIETLY ) + ELSE ( CHECK_INCLUDE_DIRS AND CHECK_LIBRARIES ) + IF ( Check_FIND_REQUIRED ) + MESSAGE( FATAL_ERROR "Could NOT find CHECK" ) + ELSE ( Check_FIND_REQUIRED ) + IF ( NOT Check_FIND_QUIETLY ) + MESSAGE( STATUS "Could NOT find CHECK" ) + ENDIF ( NOT Check_FIND_QUIETLY ) + ENDIF ( Check_FIND_REQUIRED ) + ENDIF ( CHECK_INCLUDE_DIRS AND CHECK_LIBRARIES ) ENDIF( NOT CHECK_FOUND ) # Hide advanced variables from CMake GUIs -MARK_AS_ADVANCED( CHECK_INCLUDE_DIR CHECK_LIBRARIES ) \ No newline at end of file +MARK_AS_ADVANCED( CHECK_INCLUDE_DIRS CHECK_LIBRARY_DIRS CHECK_LIBRARIES ) diff --git a/include/NodesetLoader/Extension.h b/include/NodesetLoader/Extension.h deleted file mode 100644 index 40f29cc7..00000000 --- a/include/NodesetLoader/Extension.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef NODESETLOADER_EXTENSION_H -#define NODESETLOADER_EXTENSION_H - -typedef void *(*NodesetLoader_newExtensionCb)(void); -typedef void (*NodesetLoader_startExtensionCb)(void *extensionData, - const char *name, - int nAttributes, - const char **attributes); -typedef void (*NodesetLoader_endExtensionCb)(void *extensionData, - const char *name, - const char *value); -typedef void (*NodesetLoader_finishExtensionCb)(void *extensionData); - -typedef struct -{ - void *userContext; - NodesetLoader_newExtensionCb newExtension; - NodesetLoader_startExtensionCb start; - NodesetLoader_endExtensionCb end; - NodesetLoader_finishExtensionCb finish; -} NodesetLoader_ExtensionInterface; - -#endif diff --git a/include/NodesetLoader/Logger.h b/include/NodesetLoader/Logger.h deleted file mode 100644 index bc02913e..00000000 --- a/include/NodesetLoader/Logger.h +++ /dev/null @@ -1,30 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * Copyright 2020 (c) Matthias Konnerth - */ - -#ifndef NODESETLOADER_LOGGER_H -#define NODESETLOADER_LOGGER_H - -struct NodesetLoader_Logger; -typedef struct NodesetLoader_Logger NodesetLoader_Logger; - -enum NodesetLoader_LogLevel -{ - NODESETLOADER_LOGLEVEL_DEBUG, - NODESETLOADER_LOGLEVEL_WARNING, - NODESETLOADER_LOGLEVEL_ERROR -}; - -typedef void (*NodesetLoader_Logger_log)(void *context, - enum NodesetLoader_LogLevel level, - const char *message, ...); -struct NodesetLoader_Logger -{ - void *context; - NodesetLoader_Logger_log log; -}; - -#endif diff --git a/include/NodesetLoader/NodesetLoader.h b/include/NodesetLoader/NodesetLoader.h index a8b76f6c..117db1d5 100644 --- a/include/NodesetLoader/NodesetLoader.h +++ b/include/NodesetLoader/NodesetLoader.h @@ -9,13 +9,9 @@ #define NODESETLOADER_NODESETLOADER_H #include +#include #include -#include "Extension.h" -#include "Logger.h" -#include "ReferenceService.h" -#include "arch.h" - #include #include #include @@ -26,20 +22,11 @@ extern "C" { #endif -#define NL_NODECLASS_COUNT 8 -typedef enum { - NODECLASS_OBJECT = 0, - NODECLASS_OBJECTTYPE = 1, - NODECLASS_VARIABLE = 2, - NODECLASS_DATATYPE = 3, - NODECLASS_METHOD = 4, - NODECLASS_REFERENCETYPE = 5, - NODECLASS_VARIABLETYPE = 6, - NODECLASS_VIEW = 7 - // eventtype is handled like a object type -} NL_NodeClass; +/**********************/ +/* Reference Handling */ +/**********************/ -LOADER_EXPORT extern const char *NL_NODECLASS_NAME[NL_NODECLASS_COUNT]; +struct NL_ReferenceTypeNode; struct NL_Reference; typedef struct NL_Reference { @@ -57,6 +44,40 @@ typedef struct NL_BiDirectionalReference { struct NL_BiDirectionalReference *next; } NL_BiDirectionalReference; +/* This "Service" allows different backends to be queried on the ReferenceTypes + * encountered during the load */ +typedef bool (*RefService_isRefHierachical)(void* context, const struct NL_Reference* ref); +typedef bool (*RefService_isRefNonHierachical)(void* context, const struct NL_Reference *ref); +typedef bool (*RefService_isHasTypeDefRef)(void *context, const struct NL_Reference *ref); +typedef void (*RefService_addNewReferenceType)(void* context, const struct NL_ReferenceTypeNode* node); + +typedef struct { + void* context; + RefService_isRefHierachical isHierachicalRef; + RefService_isRefNonHierachical isNonHierachicalRef; + RefService_isHasTypeDefRef isHasTypeDefRef; + RefService_addNewReferenceType addNewReferenceType; +} NL_ReferenceService; + +/******************************/ +/* Node Classes in the Loader */ +/******************************/ + +#define NL_NODECLASS_COUNT 8 +typedef enum { + NODECLASS_OBJECT = 0, + NODECLASS_OBJECTTYPE = 1, + NODECLASS_VARIABLE = 2, + NODECLASS_DATATYPE = 3, + NODECLASS_METHOD = 4, + NODECLASS_REFERENCETYPE = 5, + NODECLASS_VARIABLETYPE = 6, + NODECLASS_VIEW = 7 + // eventtype is handled like a object type +} NL_NodeClass; + +UA_EXPORT extern const char *NL_NODECLASS_NAME[NL_NODECLASS_COUNT]; + #define NL_NODE_ATTRIBUTES \ NL_NodeClass nodeClass; \ UA_NodeId id; \ @@ -156,6 +177,10 @@ typedef struct NL_ViewNode { char *eventNotifier; } NL_ViewNode; +/*********************/ +/* NodesetLoader API */ +/*********************/ + typedef void (*NL_addNamespaceCallback)(void *userContext, size_t localNamespaceUrisSize, UA_String *localNamespaceUris, @@ -165,37 +190,36 @@ typedef struct NL_FileContext { void *userContext; const char *file; NL_addNamespaceCallback addNamespace; - NodesetLoader_ExtensionInterface *extensionHandling; UA_NamespaceMapping nsMapping; } NL_FileContext; struct NodesetLoader; typedef struct NodesetLoader NodesetLoader; -LOADER_EXPORT NodesetLoader * -NodesetLoader_new(NodesetLoader_Logger *logger, - struct NL_ReferenceService *refService); +UA_EXPORT NodesetLoader * +NodesetLoader_new(UA_Logger *logger, + NL_ReferenceService *refService); -LOADER_EXPORT bool +UA_EXPORT bool NodesetLoader_importFile(NodesetLoader *loader, const NL_FileContext *fileContext); -LOADER_EXPORT void +UA_EXPORT void NodesetLoader_delete(NodesetLoader *loader); -LOADER_EXPORT const NL_BiDirectionalReference * +UA_EXPORT const NL_BiDirectionalReference * NodesetLoader_getBidirectionalRefs(const NodesetLoader *loader); -LOADER_EXPORT bool +UA_EXPORT bool NodesetLoader_sort(NodesetLoader *loader); typedef void (*NodesetLoader_forEachNode_Func)(void *context, NL_Node *node); -LOADER_EXPORT size_t +UA_EXPORT size_t NodesetLoader_forEachNode(NodesetLoader *loader, NL_NodeClass nodeClass, void *context, NodesetLoader_forEachNode_Func fn); -LOADER_EXPORT bool +UA_EXPORT bool NodesetLoader_isInstanceNode (const NL_Node *baseNode); #ifdef __cplusplus diff --git a/include/NodesetLoader/ReferenceService.h b/include/NodesetLoader/ReferenceService.h deleted file mode 100644 index 5c89a8fc..00000000 --- a/include/NodesetLoader/ReferenceService.h +++ /dev/null @@ -1,27 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * Copyright 2020 (c) Matthias Konnerth - */ - -#ifndef NODESETLOADER_REFERENCESERVICE_H -#define NODESETLOADER_REFERENCESERVICE_H -#include - -struct NL_Reference; -struct NL_ReferenceTypeNode; -typedef bool (*RefService_isRefHierachical)(void* context, const struct NL_Reference* ref); -typedef bool (*RefService_isRefNonHierachical)(void* context, const struct NL_Reference *ref); -typedef bool (*RefService_isHasTypeDefRef)(void *context, const struct NL_Reference *ref); -typedef void (*RefService_addNewReferenceType)(void* context, const struct NL_ReferenceTypeNode* node); -struct NL_ReferenceService -{ - void* context; - RefService_isRefHierachical isHierachicalRef; - RefService_isRefNonHierachical isNonHierachicalRef; - RefService_isHasTypeDefRef isHasTypeDefRef; - RefService_addNewReferenceType addNewReferenceType; -}; -typedef struct NL_ReferenceService NL_ReferenceService; -#endif diff --git a/include/NodesetLoader/arch.h b/include/NodesetLoader/arch.h deleted file mode 100644 index 96cb27a3..00000000 --- a/include/NodesetLoader/arch.h +++ /dev/null @@ -1,28 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * Copyright 2020 (c) Matthias Konnerth - */ - -#ifndef NODESETLOADER_ARCH_H -#define NODESETLOADER_ARCH_H - -/* this is taken from open62541.com */ -#if defined(_WIN32) -#ifdef __GNUC__ -#define LOADER_EXPORT __attribute__((dllexport)) -#else -#define LOADER_EXPORT __declspec(dllexport) -#endif -#else /* non win32 */ -#if __GNUC__ || __clang__ -#define LOADER_EXPORT __attribute__((visibility("default"))) -#endif -#endif - -#ifndef LOADER_EXPORT -#define LOADER_EXPORT /* fallback to default */ -#endif - -#endif diff --git a/src/InternalLogger.h b/src/InternalLogger.h deleted file mode 100644 index bcb124c9..00000000 --- a/src/InternalLogger.h +++ /dev/null @@ -1,16 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * Copyright 2020 (c) Matthias Konnerth - */ - -#ifndef INTERNALLOGGER_H -#define INTERNALLOGGER_H - -#include "NodesetLoader/Logger.h" - -NodesetLoader_Logger *InternalLogger_new(void); -void InternalLogger_delete(NodesetLoader_Logger *logger); - -#endif diff --git a/src/InternalRefService.c b/src/InternalRefService.c index 3f13f2cb..573b2d8d 100644 --- a/src/InternalRefService.c +++ b/src/InternalRefService.c @@ -13,7 +13,7 @@ struct InternalRefService { size_t hierachicalRefsSize; NL_ReferenceTypeNode *hierachicalRefs; - struct NodeContainer *nonHierachicalRefs; + NodeContainer nonHierachicalRefs; }; typedef struct InternalRefService InternalRefService; @@ -139,9 +139,9 @@ isRefNonHierachical(const InternalRefService *service, if (ref->refType.namespaceIndex == 0) return true; - for (size_t i = 0; i < service->nonHierachicalRefs->size; i++) { + for (size_t i = 0; i < service->nonHierachicalRefs.size; i++) { if (UA_NodeId_equal(&ref->refType, - &service->nonHierachicalRefs->nodes[i]->id)) + &service->nonHierachicalRefs.nodes[i]->id)) return true; } return false; @@ -181,21 +181,19 @@ addnewRefTypeImpl(InternalRefService *service, NL_ReferenceTypeNode *node) { ref = ref->next; } if (!isHierachical) { - NodeContainer_add(service->nonHierachicalRefs, (NL_Node *)node); + NodeContainer_add(&service->nonHierachicalRefs, (NL_Node *)node); } } NL_ReferenceService *InternalRefService_new(void) { - InternalRefService *service = - (InternalRefService *)calloc(1, sizeof(InternalRefService)); + InternalRefService *service = (InternalRefService *)calloc(1, sizeof(InternalRefService)); if(!service) - { return NULL; - } + service->hierachicalRefs = hierachicalRefs; service->hierachicalRefsSize = 9; - service->nonHierachicalRefs = NodeContainer_new(100, false); + NodeContainer_init(&service->nonHierachicalRefs, 100, false); NL_ReferenceService *refService = (NL_ReferenceService *)calloc(1, sizeof(NL_ReferenceService)); if(!refService) @@ -218,7 +216,7 @@ void InternalRefService_delete(NL_ReferenceService *refService) { InternalRefService *internalService = (InternalRefService *)refService->context; - NodeContainer_delete(internalService->nonHierachicalRefs); + NodeContainer_clear(&internalService->nonHierachicalRefs); free(internalService); free(refService); } diff --git a/src/InternalRefService.h b/src/InternalRefService.h index 9c110821..62bd8d99 100644 --- a/src/InternalRefService.h +++ b/src/InternalRefService.h @@ -7,7 +7,8 @@ #ifndef INTERNALREFSERVICE_H #define INTERNALREFSERVICE_H -#include "NodesetLoader/ReferenceService.h" + +#include "NodesetLoader/NodesetLoader.h" NL_ReferenceService *InternalRefService_new(void); void InternalRefService_delete(NL_ReferenceService *service); diff --git a/src/Node.c b/src/Node.c index fef9d8d7..b8642cf5 100644 --- a/src/Node.c +++ b/src/Node.c @@ -7,24 +7,16 @@ #include "Node.h" -NodeContainer * -NodeContainer_new(size_t initialSize, bool owner) { - NodeContainer *container = - (NodeContainer *)calloc(1, sizeof(NodeContainer)); - if(!container) - return NULL; - - container->nodes = - (NL_Node **)calloc(initialSize, sizeof(NL_Node*)); - if(!container->nodes) { - free(container); - return NULL; - } +void +NodeContainer_init(NodeContainer *container, size_t initialSize, bool owner) { + memset(container, 0, sizeof(NodeContainer)); + container->nodes = (NL_Node **)calloc(initialSize, sizeof(NL_Node*)); + if(!container->nodes) + return; container->size = 0; container->capacity = initialSize; container->incrementSize = initialSize; container->owner = owner; - return container; } void @@ -42,13 +34,19 @@ NodeContainer_add(NodeContainer *container, NL_Node *node) { } void -NodeContainer_delete(NodeContainer *container) { - if (container->owner) { - for (size_t i = 0; i < container->size; i++) { +NodeContainer_clear(NodeContainer *container) { + if(container->owner) { + for (size_t i = 0; i < container->size; i++) Node_delete(container->nodes[i]); - } } free(container->nodes); + memset(container, 0, sizeof(NodeContainer)); + container->nodes = NULL; +} + +void +NodeContainer_delete(NodeContainer *container) { + NodeContainer_clear(container); free(container); } @@ -105,10 +103,6 @@ Node_delete(NL_Node *node) { deleteRef(node->hierachicalRefs); deleteRef(node->nonHierachicalRefs); - if(node->nodeClass == NODECLASS_DATATYPE) { - DataTypeNode_clear((NL_DataTypeNode *)node); - } - if(node->nodeClass == NODECLASS_VARIABLE) { NL_VariableNode* varNode = (NL_VariableNode*)node; free(varNode->refToTypeDef); @@ -131,35 +125,3 @@ NodesetLoader_isInstanceNode(const NL_Node *baseNode) { baseNode->nodeClass == NODECLASS_METHOD || baseNode->nodeClass == NODECLASS_VIEW); } - -static NL_DataTypeDefinitionField * -getNewField(NL_DataTypeDefinition *definition) { - definition->fieldCnt++; - definition->fields = (NL_DataTypeDefinitionField *) - realloc(definition->fields, - definition->fieldCnt * sizeof(NL_DataTypeDefinitionField)); - if(!definition->fields) - return NULL; - return &definition->fields[definition->fieldCnt - 1]; -} - -NL_DataTypeDefinition * -DataTypeDefinition_new(NL_DataTypeNode* node) { - node->definition = (NL_DataTypeDefinition *) - calloc(1, sizeof(NL_DataTypeDefinition)); - if(!node->definition) - return NULL; - return node->definition; -} - -NL_DataTypeDefinitionField * -DataTypeNode_addDefinitionField(NL_DataTypeDefinition *def) { - return getNewField(def); -} - -void -DataTypeNode_clear(NL_DataTypeNode *node) { - if(node->definition) - free(node->definition->fields); - free(node->definition); -} diff --git a/src/Node.h b/src/Node.h index 71072b01..38c92828 100644 --- a/src/Node.h +++ b/src/Node.h @@ -9,26 +9,21 @@ #define NODE_H #include "NodesetLoader/NodesetLoader.h" -#include "Nodeset.h" -struct NodeContainer { +typedef struct { NL_Node **nodes; size_t size; size_t capacity; size_t incrementSize; bool owner; -}; -typedef struct NodeContainer NodeContainer; +} NodeContainer; -NodeContainer *NodeContainer_new(size_t initialSize, bool owner); +void NodeContainer_init(NodeContainer *container, size_t initialSize, bool owner); +void NodeContainer_clear(NodeContainer *container); void NodeContainer_delete(NodeContainer *container); void NodeContainer_add(NodeContainer *container, NL_Node *node); NL_Node *Node_new(NL_NodeClass nodeClass); void Node_delete(NL_Node *node); -void DataTypeNode_clear(NL_DataTypeNode *node); -NL_DataTypeDefinition *DataTypeDefinition_new(NL_DataTypeNode *node); -NL_DataTypeDefinitionField *DataTypeNode_addDefinitionField(NL_DataTypeDefinition *def); - #endif diff --git a/src/Nodeset.c b/src/Nodeset.c index c23c4fe2..c8db4f76 100644 --- a/src/Nodeset.c +++ b/src/Nodeset.c @@ -87,7 +87,7 @@ alias2Id(const Nodeset *nodeset, char *name) { Nodeset * Nodeset_new(NL_addNamespaceCallback nsCallback, - NodesetLoader_Logger *logger, + UA_Logger *logger, NL_ReferenceService *refService) { Nodeset *nodeset = (Nodeset *)calloc(1, sizeof(Nodeset)); if(!nodeset) @@ -95,16 +95,16 @@ Nodeset_new(NL_addNamespaceCallback nsCallback, nodeset->aliasList = AliasList_new(); nodeset->charArena = CharArenaAllocator_new(1024 * 1024); - nodeset->nodes[NODECLASS_OBJECT] = NodeContainer_new(10000, true); - nodeset->nodes[NODECLASS_VARIABLE] = NodeContainer_new(10000, true); - nodeset->nodes[NODECLASS_METHOD] = NodeContainer_new(1000, true); - nodeset->nodes[NODECLASS_OBJECTTYPE] = NodeContainer_new(100, true); - nodeset->nodes[NODECLASS_DATATYPE] = NodeContainer_new(100, true); - nodeset->nodes[NODECLASS_REFERENCETYPE] = NodeContainer_new(100, true); - nodeset->nodes[NODECLASS_VARIABLETYPE] = NodeContainer_new(100, true); - nodeset->nodes[NODECLASS_VIEW] = NodeContainer_new(10, true); - nodeset->nodesWithUnknownRefs = NodeContainer_new(100, false); - nodeset->refTypesWithUnknownRefs = NodeContainer_new(100, false); + NodeContainer_init(&nodeset->nodes[NODECLASS_OBJECT], 10000, true); + NodeContainer_init(&nodeset->nodes[NODECLASS_VARIABLE], 10000, true); + NodeContainer_init(&nodeset->nodes[NODECLASS_METHOD], 10000, true); + NodeContainer_init(&nodeset->nodes[NODECLASS_OBJECTTYPE], 100, true); + NodeContainer_init(&nodeset->nodes[NODECLASS_DATATYPE], 100, true); + NodeContainer_init(&nodeset->nodes[NODECLASS_REFERENCETYPE], 100, true); + NodeContainer_init(&nodeset->nodes[NODECLASS_VARIABLETYPE], 100, true); + NodeContainer_init(&nodeset->nodes[NODECLASS_VIEW], 10, true); + NodeContainer_init(&nodeset->nodesWithUnknownRefs, 100, false); + NodeContainer_init(&nodeset->refTypesWithUnknownRefs, 100, false); nodeset->refService = refService; nodeset->sortCtx = Sort_init(); nodeset->logger = logger; @@ -112,7 +112,7 @@ Nodeset_new(NL_addNamespaceCallback nsCallback, } static void Nodeset_addNode(Nodeset *nodeset, NL_Node *node) { - NodeContainer_add(nodeset->nodes[node->nodeClass], node); + NodeContainer_add(&nodeset->nodes[node->nodeClass], node); } static void insertElementAtFront(NL_Reference **toList, NL_Reference *elem) { @@ -149,14 +149,14 @@ lookupReferenceTypes(Nodeset *nodeset) { bool allRefTypesKnown = false; while (!allRefTypesKnown) { allRefTypesKnown = true; - for (size_t i = 0; i < nodeset->refTypesWithUnknownRefs->size; i++) { + for (size_t i = 0; i < nodeset->refTypesWithUnknownRefs.size; i++) { allRefTypesKnown = - lookupUnknownReferences(nodeset, nodeset->refTypesWithUnknownRefs->nodes[i]); + lookupUnknownReferences(nodeset, nodeset->refTypesWithUnknownRefs.nodes[i]); } } - for (size_t i = 0; i < nodeset->refTypesWithUnknownRefs->size; i++) { - Sort_addNode(nodeset->sortCtx, nodeset->refTypesWithUnknownRefs->nodes[i]); + for (size_t i = 0; i < nodeset->refTypesWithUnknownRefs.size; i++) { + Sort_addNode(nodeset->sortCtx, nodeset->refTypesWithUnknownRefs.nodes[i]); } } @@ -167,19 +167,19 @@ bool Nodeset_sort(Nodeset *nodeset) { // all hierachical references of a node should be known at this point // if there are nodes with unknown references, the import will be aborted - for (size_t i = 0; i < nodeset->nodesWithUnknownRefs->size; i++) { + for (size_t i = 0; i < nodeset->nodesWithUnknownRefs.size; i++) { bool result = lookupUnknownReferences( - nodeset, nodeset->nodesWithUnknownRefs->nodes[i]); + nodeset, nodeset->nodesWithUnknownRefs.nodes[i]); if (!result) { UA_String nodeIdStr = {0}; - UA_NodeId_print(&nodeset->nodesWithUnknownRefs->nodes[i]->id, &nodeIdStr); - nodeset->logger->log(nodeset->logger->context, NODESETLOADER_LOGLEVEL_ERROR, - "node with unresolved reference(s): NodeId(%.*s)", + UA_NodeId_print(&nodeset->nodesWithUnknownRefs.nodes[i]->id, &nodeIdStr); + UA_LOG_ERROR(nodeset->logger, UA_LOGCATEGORY_SERVER, + "NodesetLoader: Node with unresolved reference(s): NodeId(%.*s)", (int)nodeIdStr.length, (char *)nodeIdStr.data); UA_String_clear(&nodeIdStr); return false; } - Sort_addNode(nodeset->sortCtx, nodeset->nodesWithUnknownRefs->nodes[i]); + Sort_addNode(nodeset->sortCtx, nodeset->nodesWithUnknownRefs.nodes[i]); } return Sort_start(nodeset->sortCtx, nodeset, Nodeset_addNode, nodeset->logger); @@ -189,10 +189,10 @@ void Nodeset_cleanup(Nodeset *nodeset) { CharArenaAllocator_delete(nodeset->charArena); AliasList_delete(nodeset->aliasList); for (size_t cnt = 0; cnt < NL_NODECLASS_COUNT; cnt++) { - NodeContainer_delete(nodeset->nodes[cnt]); + NodeContainer_clear(&nodeset->nodes[cnt]); } - NodeContainer_delete(nodeset->nodesWithUnknownRefs); - NodeContainer_delete(nodeset->refTypesWithUnknownRefs); + NodeContainer_clear(&nodeset->nodesWithUnknownRefs); + NodeContainer_clear(&nodeset->refTypesWithUnknownRefs); Sort_cleanup(nodeset->sortCtx); NL_BiDirectionalReference *ref = nodeset->hasEncodingRefs; while (ref) @@ -289,6 +289,8 @@ extractAttributes(Nodeset *nodeset, NL_Node *node, case NODECLASS_DATATYPE: ((NL_DataTypeNode *)node)->isAbstract = getAttributeValue(nodeset, &attrIsAbstract, attributes, attributeSize); + ((NL_DataTypeNode *)node)->typeDefinition = + getAttributeValue(nodeset, &attrIsAbstract, attributes, attributeSize); break; case NODECLASS_METHOD: @@ -410,10 +412,8 @@ Nodeset_newNamespaceFinish(Nodeset *nodeset, void *userContext, void Nodeset_newNodeFinish(Nodeset *nodeset, NL_Node *node) { if (!node->unknownRefs) { if(!Sort_addNode(nodeset->sortCtx, node)) { - if (nodeset->logger) { - nodeset->logger->log(nodeset->logger->context, NODESETLOADER_LOGLEVEL_ERROR, - "node was not added to sorting algorithm, already exists"); - } + UA_LOG_ERROR(nodeset->logger, UA_LOGCATEGORY_SERVER, + "NodesetLoader: Node was not added to sorting algorithm, already exists"); Node_delete(node); } else { if (node->nodeClass == NODECLASS_REFERENCETYPE) { @@ -423,9 +423,9 @@ void Nodeset_newNodeFinish(Nodeset *nodeset, NL_Node *node) { } } else { if (node->nodeClass == NODECLASS_REFERENCETYPE) { - NodeContainer_add(nodeset->refTypesWithUnknownRefs, node); + NodeContainer_add(&nodeset->refTypesWithUnknownRefs, node); } else { - NodeContainer_add(nodeset->nodesWithUnknownRefs, node); + NodeContainer_add(&nodeset->nodesWithUnknownRefs, node); } } } @@ -453,47 +453,6 @@ void Nodeset_newReferenceFinish(Nodeset *nodeset, NL_Reference *ref, } } -void Nodeset_addDataTypeDefinition(Nodeset *nodeset, NL_Node *node, - int attributeSize, const char **attributes) { - NL_DataTypeNode *dataTypeNode = (NL_DataTypeNode *)node; - NL_DataTypeDefinition *def = DataTypeDefinition_new(dataTypeNode); - def->isUnion = - !strcmp("true", getAttributeValue(nodeset, &dataTypeDefinition_IsUnion, - attributes, attributeSize)); - def->isOptionSet = - !strcmp("true", getAttributeValue(nodeset, &dataTypeDefinition_IsOptionSet, - attributes, attributeSize)); -} - -void Nodeset_addDataTypeField(Nodeset *nodeset, NL_Node *node, - int attributeSize, const char **attributes) { - NL_DataTypeNode *dataTypeNode = (NL_DataTypeNode *)node; - if(dataTypeNode->definition->isOptionSet) - return; - - NL_DataTypeDefinitionField *newField = - DataTypeNode_addDefinitionField(dataTypeNode->definition); - newField->name = getAttributeValue(nodeset, &dataTypeField_Name, attributes, - attributeSize); - - char *value = getAttributeValue(nodeset, &dataTypeField_Value, attributes, - attributeSize); - if (value) { - newField->value = atoi(value); - dataTypeNode->definition->isEnum = - !dataTypeNode->definition->isOptionSet; - } else { - newField->dataType = alias2Id( - nodeset, getAttributeValue(nodeset, &dataTypeField_DataType, - attributes, attributeSize)); - newField->valueRank = atoi(getAttributeValue( - nodeset, &attrValueRank, attributes, attributeSize)); - char *isOptional = getAttributeValue(nodeset, &dataTypeField_IsOptional, - attributes, attributeSize); - newField->isOptional = !strcmp("true", isOptional); - } -} - const NL_BiDirectionalReference * Nodeset_getBiDirectionalRefs(const Nodeset *nodeset) { return nodeset->hasEncodingRefs; @@ -541,7 +500,7 @@ Nodeset_InverseNameFinish(const Nodeset *nodeset, NL_Node *node, char *text) { size_t Nodeset_forEachNode(Nodeset *nodeset, NL_NodeClass nodeClass, void *context, NodesetLoader_forEachNode_Func fn) { - NodeContainer *c = nodeset->nodes[nodeClass]; + NodeContainer *c = &nodeset->nodes[nodeClass]; for(NL_Node **node = c->nodes; node != c->nodes + c->size; node++) { fn(context, *node); } diff --git a/src/Nodeset.h b/src/Nodeset.h index 46a3a70e..a8787056 100644 --- a/src/Nodeset.h +++ b/src/Nodeset.h @@ -8,8 +8,9 @@ #ifndef NODESET_H #define NODESET_H -#include "CharAllocator.h" #include "NodesetLoader/NodesetLoader.h" +#include "CharAllocator.h" +#include "Node.h" #include #include @@ -20,14 +21,13 @@ struct Alias; struct TParserCtx; typedef struct TParserCtx TParserCtx; -struct NodeContainer; struct AliasList; struct SortContext; struct Nodeset { CharArenaAllocator *charArena; struct AliasList *aliasList; - struct NodeContainer *nodes[NL_NODECLASS_COUNT]; + NodeContainer nodes[NL_NODECLASS_COUNT]; NL_FileContext *fc; size_t localNamespaceUrisSize; @@ -35,14 +35,14 @@ struct Nodeset { struct SortContext *sortCtx; NL_BiDirectionalReference *hasEncodingRefs; - NodesetLoader_Logger* logger; - struct NodeContainer *nodesWithUnknownRefs; - struct NodeContainer *refTypesWithUnknownRefs; - NL_ReferenceService* refService; + UA_Logger *logger; + NodeContainer nodesWithUnknownRefs; + NodeContainer refTypesWithUnknownRefs; + NL_ReferenceService * refService; }; Nodeset *Nodeset_new(NL_addNamespaceCallback nsCallback, - NodesetLoader_Logger* logger, + UA_Logger *logger, NL_ReferenceService* refService); void Nodeset_cleanup(Nodeset *nodeset); bool Nodeset_sort(Nodeset *nodeset); diff --git a/src/NodesetLoader.c b/src/NodesetLoader.c index 10920777..2936f579 100644 --- a/src/NodesetLoader.c +++ b/src/NodesetLoader.c @@ -5,7 +5,6 @@ * Copyright 2019 (c) Matthias Konnerth */ -#include "InternalLogger.h" #include "InternalRefService.h" #include "Nodeset.h" #include "Parser.h" @@ -29,8 +28,6 @@ #define NAMESPACEURIS "NamespaceUris" #define NAMESPACEURI "Uri" #define VALUE "Value" -#define EXTENSIONS "Extensions" -#define EXTENSION "Extension" #define INVERSENAME "InverseName" const char *NL_NODECLASS_NAME[NL_NODECLASS_COUNT] = { @@ -39,8 +36,7 @@ const char *NL_NODECLASS_NAME[NL_NODECLASS_COUNT] = { struct NodesetLoader { Nodeset *nodeset; - NodesetLoader_Logger *logger; - bool internalLogger; + UA_Logger *logger; NL_ReferenceService *refService; bool internalRefService; }; @@ -129,8 +125,7 @@ static void OnStartElementNs(void *ctx, const char *localname, pctx->state = PARSER_STATE_ALIAS; } else if (!strcmp(localname, "UANodeSet") || - !strcmp(localname, "Aliases") || - !strcmp(localname, "Extensions")) + !strcmp(localname, "Aliases")) { pctx->state = PARSER_STATE_INIT; } @@ -168,11 +163,7 @@ static void OnStartElementNs(void *ctx, const char *localname, pctx->valueBegin = pctx->ctxt->input->cur - pctx->ctxt->input->base; while(pctx->buf[pctx->valueBegin] != '<') pctx->valueBegin--; - } else if (!strcmp(localname, EXTENSIONS)) { - pctx->state = PARSER_STATE_EXTENSIONS; } else if (!strcmp(localname, "Definition")) { - Nodeset_addDataTypeDefinition(pctx->nodeset, pctx->node, nb_attributes, - attributes); pctx->state = PARSER_STATE_DATATYPE_DEFINITION; } else if (!strcmp(localname, INVERSENAME)) { pctx->state = PARSER_STATE_INVERSENAME; @@ -183,42 +174,12 @@ static void OnStartElementNs(void *ctx, const char *localname, return; } break; - case PARSER_STATE_DATATYPE_DEFINITION: - if (!strcmp(localname, "Field")) { - Nodeset_addDataTypeField(pctx->nodeset, pctx->node, nb_attributes, - attributes); - pctx->state = PARSER_STATE_DATATYPE_DEFINITION_FIELD; - } else { - pctx->unknown_depth++; - return; - } - break; - case PARSER_STATE_DATATYPE_DEFINITION_FIELD: - pctx->unknown_depth++; - return; case PARSER_STATE_VALUE: if(!strcmp(localname, VALUE)) pctx->value_depth++; /* Nested elements */ break; - case PARSER_STATE_EXTENSIONS: - if (!strcmp(localname, EXTENSION)) { - if (pctx->extIf) { - pctx->extensionData = pctx->extIf->newExtension(); - } - pctx->state = PARSER_STATE_EXTENSION; - } else { - pctx->unknown_depth++; - return; - } - break; - case PARSER_STATE_EXTENSION: - if (pctx->extIf) { - pctx->extIf->start(pctx->extensionData, localname, nb_attributes, attributes); - } - break; - case PARSER_STATE_REFERENCES: if (!strcmp(localname, REFERENCE)) { pctx->state = PARSER_STATE_REFERENCE; @@ -229,6 +190,7 @@ static void OnStartElementNs(void *ctx, const char *localname, return; } break; + case PARSER_STATE_DATATYPE_DEFINITION: case PARSER_STATE_DESCRIPTION: case PARSER_STATE_ALIAS: case PARSER_STATE_DISPLAYNAME: @@ -299,23 +261,6 @@ OnEndElementNs(void *ctx, const char *localname, } } break; - case PARSER_STATE_EXTENSION: - if (!strcmp(localname, EXTENSION)) { - if (pctx->extIf) { - pctx->extIf->finish(pctx->extensionData); - pctx->node->extension = pctx->extensionData; - } - pctx->state = PARSER_STATE_EXTENSIONS; - } else { - if (pctx->extIf) { - pctx->extIf->end(pctx->extensionData, localname, - pctx->onCharacters); - } - } - break; - case PARSER_STATE_EXTENSIONS: - pctx->state = PARSER_STATE_NODE; - break; case PARSER_STATE_DESCRIPTION: Nodeset_DescriptionFinish(pctx->nodeset, pctx->node, pctx->onCharacters); @@ -329,9 +274,6 @@ OnEndElementNs(void *ctx, const char *localname, case PARSER_STATE_DATATYPE_DEFINITION: pctx->state = PARSER_STATE_NODE; break; - case PARSER_STATE_DATATYPE_DEFINITION_FIELD: - pctx->state = PARSER_STATE_DATATYPE_DEFINITION; - break; } pctx->onCharacters = NULL; pctx->onCharLength = 0; @@ -352,16 +294,12 @@ static void OnCharacters(void *ctx, const char *ch, int len) { bool NodesetLoader_importFile(NodesetLoader *loader, const NL_FileContext *fileHandler) { if(!fileHandler) { - loader->logger->log(loader->logger->context, - NODESETLOADER_LOGLEVEL_ERROR, - "NodesetLoader: no filehandler - abort"); + UA_LOG_ERROR(loader->logger, UA_LOGCATEGORY_SERVER, "NodesetLoader: no filehandler - abort"); return false; } if(!fileHandler->addNamespace) { - loader->logger->log(loader->logger->context, - NODESETLOADER_LOGLEVEL_ERROR, - "NodesetLoader: fileHandler->addNamespace missing"); + UA_LOG_ERROR(loader->logger, UA_LOGCATEGORY_SERVER, "NodesetLoader: fileHandler->addNamespace missing"); return false; } @@ -376,9 +314,7 @@ bool NodesetLoader_importFile(NodesetLoader *loader, memset(&ctx, 0, sizeof(struct TParserCtx)); if(!f) { - loader->logger->log(loader->logger->context, - NODESETLOADER_LOGLEVEL_ERROR, - "NodesetLoader: file open error"); + UA_LOG_ERROR(loader->logger, UA_LOGCATEGORY_SERVER, "NodesetLoader: file open error"); retStatus = false; goto cleanup; } @@ -386,7 +322,6 @@ bool NodesetLoader_importFile(NodesetLoader *loader, ctx.nodeset = loader->nodeset; ctx.state = PARSER_STATE_INIT; ctx.userContext = fileHandler->userContext; - ctx.extIf = fileHandler->extensionHandling; ctx.nodeset = loader->nodeset; ctx.nodeset->fc = (NL_FileContext*)(uintptr_t)fileHandler; @@ -405,8 +340,7 @@ bool NodesetLoader_importFile(NodesetLoader *loader, } if(Parser_run(&ctx, f, OnStartElementNs, OnEndElementNs, OnCharacters)) { - loader->logger->log(loader->logger->context, - NODESETLOADER_LOGLEVEL_ERROR, "xml parsing error"); + UA_LOG_ERROR(loader->logger, UA_LOGCATEGORY_SERVER, "NodesetLoader: xml parsing error"); retStatus = false; } @@ -427,19 +361,13 @@ bool NodesetLoader_sort(NodesetLoader *loader) { return Nodeset_sort(loader->nodeset); } -NodesetLoader *NodesetLoader_new(NodesetLoader_Logger *logger, +NodesetLoader *NodesetLoader_new(UA_Logger *logger, NL_ReferenceService *refService) { NodesetLoader *loader = (NodesetLoader *)calloc(1, sizeof(NodesetLoader)); if(!loader) return NULL; - if(!logger) { - loader->logger = InternalLogger_new(); - loader->internalLogger = true; - } else { - loader->logger = logger; - } - + loader->logger = logger; if(!refService) { loader->refService = InternalRefService_new(); loader->internalRefService = true; @@ -450,13 +378,8 @@ NodesetLoader *NodesetLoader_new(NodesetLoader_Logger *logger, return loader; } -void NodesetLoader_delete(NodesetLoader *loader) -{ +void NodesetLoader_delete(NodesetLoader *loader) { Nodeset_cleanup(loader->nodeset); - if (loader->internalLogger) - { - free(loader->logger); - } if (loader->internalRefService) { InternalRefService_delete(loader->refService); diff --git a/src/Parser.h b/src/Parser.h index 21cc5b44..33c7eb1c 100644 --- a/src/Parser.h +++ b/src/Parser.h @@ -25,10 +25,7 @@ typedef enum { PARSER_STATE_NAMESPACEURIS, PARSER_STATE_URI, PARSER_STATE_VALUE, - PARSER_STATE_EXTENSION, - PARSER_STATE_EXTENSIONS, PARSER_STATE_DATATYPE_DEFINITION, - PARSER_STATE_DATATYPE_DEFINITION_FIELD } TParserState; struct TParserCtx { @@ -43,7 +40,6 @@ struct TParserCtx { size_t onCharLength; long valueBegin; void *extensionData; - NodesetLoader_ExtensionInterface *extIf; NL_Reference *ref; Nodeset *nodeset; xmlParserCtxtPtr ctxt; diff --git a/src/PrintfLogger.c b/src/PrintfLogger.c deleted file mode 100644 index 6acf9c34..00000000 --- a/src/PrintfLogger.c +++ /dev/null @@ -1,32 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * Copyright 2020 (c) Matthias Konnerth - */ - -#include "InternalLogger.h" -#include -#include -#include - -static const char *logLevel[3] = {"Debug", "Warning", "Error"}; - -static void logStdOut(void *context, enum NodesetLoader_LogLevel level, - const char *message, ...) -{ - va_list vl; - va_start(vl, message); - va_end(vl); - printf("NODESETLOADER: %s : %s\n", logLevel[level], message); -} - -NodesetLoader_Logger *InternalLogger_new(void) -{ - NodesetLoader_Logger *logger = - (NodesetLoader_Logger *)calloc(1, sizeof(NodesetLoader_Logger)); - logger->log = &logStdOut; - return logger; -} - -void InternalLogger_delete(NodesetLoader_Logger *logger) { free(logger); } diff --git a/src/Sort.c b/src/Sort.c index 9ee81c36..30ba2276 100644 --- a/src/Sort.c +++ b/src/Sort.c @@ -8,6 +8,7 @@ #include "Sort.h" #include +#include #include #include #include @@ -348,7 +349,7 @@ bool Sort_addNode(SortContext *ctx, NL_Node *data) { } bool Sort_start(SortContext *ctx, struct Nodeset *nodeset, - Sort_SortedNodeCallback callback, NodesetLoader_Logger *logger) + Sort_SortedNodeCallback callback, UA_Logger *logger) { walk_tree(ctx, ctx->root1, count_items); @@ -382,11 +383,7 @@ bool Sort_start(SortContext *ctx, struct Nodeset *nodeset, } if (ctx->keyCnt > 0) { - if (logger) - { - logger->log(logger->context, NODESETLOADER_LOGLEVEL_ERROR, - "graph contains a loop, abort"); - } + UA_LOG_ERROR(logger, UA_LOGCATEGORY_SERVER, "NodesetLoader: graph contains a loop, abort"); return false; } } diff --git a/src/Sort.h b/src/Sort.h index 047172fd..844de5f9 100644 --- a/src/Sort.h +++ b/src/Sort.h @@ -18,13 +18,12 @@ extern "C" { struct NL_Node; struct Nodeset; struct SortContext; -struct NodesetLoader_Logger; typedef struct SortContext SortContext; SortContext* Sort_init(void); void Sort_cleanup(SortContext * ctx); bool Sort_addNode(SortContext* ctx, struct NL_Node *node); typedef void (*Sort_SortedNodeCallback)(struct Nodeset *nodeset, struct NL_Node *node); -bool Sort_start(SortContext* ctx, struct Nodeset *nodeset, Sort_SortedNodeCallback callback, struct NodesetLoader_Logger* logger); +bool Sort_start(SortContext* ctx, struct Nodeset *nodeset, Sort_SortedNodeCallback callback, struct UA_Logger *logger); #ifdef __cplusplus }