Esempio n. 1
0
BiNode * lowestCommonAncestor_BiTree(BiTree root, BiNode * p, BiNode * q)
{
	if(root&&p&&q) {
		if((isNodeInTree(root->left, p) && isNodeInTree(root->right, q)) || (isNodeInTree(root->left, q) && isNodeInTree(root->right, p)) ||(p==root && isNodeInTree(root, q)) || (q==root && isNodeInTree(root, p)))
			return root;
		else if(isNodeInTree(root->left, p) && isNodeInTree(root->left, q)) 
			return lowestCommonAncestor_BiTree(root->left, p ,q);
		else if(isNodeInTree(root->right, p) && isNodeInTree(root->right, q))
			return lowestCommonAncestor_BiTree(root->right, p ,q);
	} else return NULL;
}
Esempio n. 2
0
UA_Boolean
compatibleDataType(UA_Server *server, const UA_NodeId *dataType,
                   const UA_NodeId *constraintDataType) {
    /* Do not allow empty datatypes */
    if(UA_NodeId_isNull(dataType))
       return false;

    /* No constraint (TODO: use variant instead) */
    if(UA_NodeId_isNull(constraintDataType))
        return true;

    /* Variant allows any subtype */
    if(UA_NodeId_equal(constraintDataType, &UA_TYPES[UA_TYPES_VARIANT].typeId))
        return true;

    /* Is the value-type a subtype of the required type? */
    if(isNodeInTree(&server->config.nodestore, dataType, constraintDataType, &subtypeId, 1))
        return true;

    /* If value is a built-in type: The target data type may be a sub type of
     * the built-in type. (e.g. UtcTime is sub-type of DateTime and has a
     * DateTime value). A type is builtin if its NodeId is in Namespace 0 and
     * has a numeric identifier <= 25 (DiagnosticInfo) */
    if(dataType->namespaceIndex == 0 &&
       dataType->identifierType == UA_NODEIDTYPE_NUMERIC &&
       dataType->identifier.numeric <= 25 &&
       isNodeInTree(&server->config.nodestore, constraintDataType,
                    dataType, &subtypeId, 1))
        return true;

    /* Enum allows Int32 (only) */
    if(UA_NodeId_equal(dataType, &UA_TYPES[UA_TYPES_INT32].typeId) &&
       isNodeInTree(&server->config.nodestore, constraintDataType, &enumNodeId, &subtypeId, 1))
        return true;

    return false;
}
Esempio n. 3
0
static UA_StatusCode
satisfySignature(UA_Server *server, const UA_Variant *var, const UA_Argument *arg) {
    if(!UA_NodeId_equal(&var->type->typeId, &arg->dataType)){
        if(!UA_NodeId_equal(&var->type->typeId, &UA_TYPES[UA_TYPES_INT32].typeId))
            return UA_STATUSCODE_BADINVALIDARGUMENT;

        /* enumerations are encoded as int32 -> if provided var is integer, check if arg is an enumeration type */
        UA_NodeId enumerationNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ENUMERATION);
        UA_NodeId hasSubTypeNodeId = UA_NODEID_NUMERIC(0,UA_NS0ID_HASSUBTYPE);
        UA_Boolean found = false;
        UA_StatusCode retval = isNodeInTree(server->nodestore, &arg->dataType, &enumerationNodeId, &hasSubTypeNodeId, 1, 1, &found);
        if(retval != UA_STATUSCODE_GOOD)
            return UA_STATUSCODE_BADINTERNALERROR;
        if(!found)
            return UA_STATUSCODE_BADINVALIDARGUMENT;
    }

    // Note: The namespace compiler will compile nodes with their actual array dimensions
    // Todo: Check if this is standard conform for scalars
    if(arg->arrayDimensionsSize > 0 && var->arrayDimensionsSize > 0)
        if(var->arrayDimensionsSize != arg->arrayDimensionsSize)
            return UA_STATUSCODE_BADINVALIDARGUMENT;

    UA_Int32 *varDims = var->arrayDimensions;
    size_t varDimsSize = var->arrayDimensionsSize;
    UA_Boolean scalar = UA_Variant_isScalar(var);

    /* The dimension 1 is implicit in the array length */
    UA_Int32 fakeDims;
    if(!scalar && !varDims) {
        fakeDims = (UA_Int32)var->arrayLength;
        varDims = &fakeDims;
        varDimsSize = 1;
    }

    /* ValueRank Semantics
     *  n >= 1: the value is an array with the specified number of dimens*ions.
     *  n = 0: the value is an array with one or more dimensions.
     *  n = -1: the value is a scalar.
     *  n = -2: the value can be a scalar or an array with any number of dimensions.
     *  n = -3:  the value can be a scalar or a one dimensional array. */
    switch(arg->valueRank) {
    case -3:
        if(varDimsSize > 1)
            return UA_STATUSCODE_BADINVALIDARGUMENT;
        break;
    case -2:
        break;
    case -1:
        if(!scalar)
            return UA_STATUSCODE_BADINVALIDARGUMENT;
        break;
    case 0:
        if(scalar || !varDims)
            return UA_STATUSCODE_BADINVALIDARGUMENT;
        break;
    default:
        break;
    }

    /* do the array dimensions match? */
    if(arg->arrayDimensionsSize != varDimsSize)
        return UA_STATUSCODE_BADINVALIDARGUMENT;
    for(size_t i = 0; i < varDimsSize; i++) {
        if((UA_Int32)arg->arrayDimensions[i] != varDims[i])
            return UA_STATUSCODE_BADINVALIDARGUMENT;
    }
    return UA_STATUSCODE_GOOD;
}
Esempio n. 4
0
void
Service_Call_single(UA_Server *server, UA_Session *session, const UA_CallMethodRequest *request,
                    UA_CallMethodResult *result) {
    /* Verify method/object relations. Object must have a hasComponent reference to the method node. */
    UA_Boolean found = false;
    UA_NodeId hasComponentNodeId = UA_NODEID_NUMERIC(0,UA_NS0ID_HASCOMPONENT);
    result->statusCode = isNodeInTree(server->nodestore, &request->methodId, &request->objectId,
                                      &hasComponentNodeId, 1, 1, &found);
    if(!found)
        result->statusCode = UA_STATUSCODE_BADMETHODINVALID;
    if(result->statusCode != UA_STATUSCODE_GOOD)
        return;

    /* Get/verify the method node */
    const UA_MethodNode *methodCalled =
        (const UA_MethodNode*)UA_NodeStore_get(server->nodestore, &request->methodId);
    if(!methodCalled) {
        result->statusCode = UA_STATUSCODE_BADMETHODINVALID;
        return;
    }
    if(methodCalled->nodeClass != UA_NODECLASS_METHOD) {
        result->statusCode = UA_STATUSCODE_BADNODECLASSINVALID;
        return;
    }
    if(!methodCalled->executable || !methodCalled->userExecutable || !methodCalled->attachedMethod) {
        result->statusCode = UA_STATUSCODE_BADNOTWRITABLE; // There is no NOTEXECUTABLE?
        return;
    }

    /* Get/verify the object node */
    const UA_ObjectNode *withObject =
        (const UA_ObjectNode*)UA_NodeStore_get(server->nodestore, &request->objectId);
    if(!withObject) {
        result->statusCode = UA_STATUSCODE_BADNODEIDINVALID;
        return;
    }
    if(withObject->nodeClass != UA_NODECLASS_OBJECT && withObject->nodeClass != UA_NODECLASS_OBJECTTYPE) {
        result->statusCode = UA_STATUSCODE_BADNODECLASSINVALID;
        return;
    }

    /* Verify Input Argument count, types and sizes */
    const UA_VariableNode *inputArguments = getArgumentsVariableNode(server, methodCalled, UA_STRING("InputArguments"));
    if(!inputArguments) {
        result->statusCode = UA_STATUSCODE_BADINVALIDARGUMENT;
        return;
    }
    result->statusCode = argConformsToDefinition(server, inputArguments, request->inputArgumentsSize,
                                                 request->inputArguments);
    if(result->statusCode != UA_STATUSCODE_GOOD)
        return;

    /* Allocate the output arguments */
    const UA_VariableNode *outputArguments = getArgumentsVariableNode(server, methodCalled, UA_STRING("OutputArguments"));
    if(!outputArguments) {
        result->statusCode = UA_STATUSCODE_BADINTERNALERROR;
        return;
    }
    result->outputArguments = UA_Array_new(outputArguments->value.variant.value.arrayLength, &UA_TYPES[UA_TYPES_VARIANT]);
    if(!result->outputArguments) {
        result->statusCode = UA_STATUSCODE_BADOUTOFMEMORY;
        return;
    }
    result->outputArgumentsSize = outputArguments->value.variant.value.arrayLength;

    /* Call the method */
    result->statusCode = methodCalled->attachedMethod(methodCalled->methodHandle, withObject->nodeId,
                                                      request->inputArgumentsSize, request->inputArguments,
                                                      result->outputArgumentsSize, result->outputArguments);
    /* TODO: Verify Output Argument count, types and sizes */
}
Esempio n. 5
0
// 11. 求二叉树中两个节点的最低公共祖先节点   //
// 11.1 判断节点是否在子树中,在返回1, 不在返回0
int isNodeInTree(BiTree root, BiNode * p)
{
	if(!root) return 0;
	if(root==p) return 1;
	else return isNodeInTree(root->left, p) || isNodeInTree(root->right, p);
}