How to Parse complex Variant_Array Matrix

Questions regarding the use of the ANSI C SDK for Server or Client development or integration into customer products ...

Moderator: uasdkc

Post Reply
dollefau
Jr. Member
Jr. Member
Posts: 1
Joined: 04 Sep 2018, 17:01

How to Parse complex Variant_Array Matrix

Post by dollefau »

Hello,
i try to parse a nested Variant_Array
the node contains an array with 10 elements
node->Value->Value->Variant_Array[10]

inside this Variant_Array i have another Variant_Array
node->Value->Value->Variant_Array[1]->Variant_Array[7]

Code: Select all

static OpcUa_Void SampleSubscription_DataChange_CB(UaClient_Subscription            *a_pSubscription,
                                                   OpcUa_Int32                       a_noOfMonitoredItems,
                                                   OpcUa_MonitoredItemNotification  *a_pMonitoredItems,
                                                   OpcUa_Int32                       a_noOfDiagnosticInfos,
                                                   OpcUa_DiagnosticInfo             *a_pDiagnosticInfos)
{
int i = a_pMonitoredItems[i].Value.Value.Value.Matrix.NoOfDimensions; //10
for(int j=0;j<i;j++){
//how to access the Array/Matrix Items ?
}
}

User avatar
Support Team
Hero Member
Hero Member
Posts: 2532
Joined: 18 Mar 2011, 15:09

Re: How to Parse complex Variant_Array Matrix

Post by Support Team »

Hello dollefau,

below is a sample on how to iterate over a variant array inside a variant. The sample is not complete and some checks (null pointer etc.) have been omitted for better readability.

Code: Select all

            OpcUa_Variant *pValue = &a_pMonitoredItems[i].Value.Value;

            // check if value contains a variant array
            if (pValue->Datatype == OpcUaType_Variant && pValue->ArrayType == OpcUa_VariantArrayType_Array)
            {
                // iterate over array elements
                for (OpcUa_Int32 i = 0; i < pValue->Value.Array.Length; i++)
                {
                    OpcUa_Variant *pArrayElement = &pValue->Value.Array.Value.VariantArray[i];

                    // the variant can contain anything, so we need to handle all combinations of array and data types:
                    switch (pArrayElement->ArrayType)
                    {
                    case OpcUa_VariantArrayType_Scalar:
                    {
                        switch (pArrayElement->Datatype)
                        {
                        case OpcUaType_Boolean:
                            // pArrayElement->Value.Boolean is set and can be used here
                            break;
                        case OpcUaType_SByte:
                            // pArrayElement->Value.SByte is set and can be used here
                            break;
                            // all data types have to be handled here ...
                        }
                        break;
                    }
                    case OpcUa_VariantArrayType_Array:
                    {
                        switch (pArrayElement->Datatype)
                        {
                        case OpcUaType_Boolean:
                            for (OpcUa_Int32 j = 0; j < pArrayElement->Value.Array.Length; j++)
                            {
                                // pArrayElement->Value.Array.Value.BooleanArray[j] is set and can be used here
                            }
                            break;
                        case OpcUaType_SByte:
                            for (OpcUa_Int32 j = 0; j < pArrayElement->Value.Array.Length; j++)
                            {
                                // pArrayElement->Value.Array.Value.SByteArray[j] is set and can be used here
                            }
                            break;
                            // all data types have to be handled here ...
                        }
                        break;
                    }
                    case OpcUa_VariantArrayType_Matrix:
                    {
                        // for matrix values, pArrayElement->Value.Matrix.Value contains n elements, where n is
                        // all dimensions multiplicated with each other:
                        OpcUa_Int32 numElements = 1;
                        for (OpcUa_Int32 dim = 0; dim < pArrayElement->Value.Matrix.NoOfDimensions; dim++)
                        {
                            numElements = numElements * pArrayElement->Value.Matrix.Dimensions[dim];
                        }
                        switch (pArrayElement->Datatype)
                        {
                        case OpcUaType_Boolean:
                            for (OpcUa_Int32 j = 0; j < numElements; j++)
                            {
                                // pArrayElement->Value.Matrix.Value.BooleanArray[j] is set and can be used here
                            }
                            break;
                        case OpcUaType_SByte:
                            for (OpcUa_Int32 j = 0; j < numElements; j++)
                            {
                                // pArrayElement->Value.Matrix.Value.SByteArray[j] is set and can be used here
                            }
                            break;
                            // all data types have to be handled here ...
                        }
                        break;
                    }
                    default:
                        break;
                    }
                }
            }
            else
            {
                // unexpected datatype or array type
            }
Best regards
Unified Automation Support Team

Post Reply