Opc.Ua.Server.CoreNodeManager.Read C# (CSharp) Method

Read() public method

public Read ( OperationContext context, double maxAge, IList nodesToRead, IList values, IList errors ) : void
context OperationContext
maxAge double
nodesToRead IList
values IList
errors IList
return void
        public void Read(
            OperationContext     context,
            double               maxAge,
            IList<ReadValueId>   nodesToRead,
            IList<DataValue>     values,
            IList<ServiceResult> errors)
        {
            if (context == null)     throw new ArgumentNullException("context");
            if (nodesToRead == null) throw new ArgumentNullException("nodesToRead");
            if (values == null)      throw new ArgumentNullException("values");
            if (errors == null)      throw new ArgumentNullException("errors");
                
            #if LEGACY_CORENODEMANAGER
            Dictionary<IReadDataSource,List<RequestHandle>> datasources = new Dictionary<IReadDataSource,List<RequestHandle>>();
            #endif
            
            try
            {
                m_lock.Enter();
                
                for (int ii = 0; ii < nodesToRead.Count; ii++)
                {
                    ReadValueId nodeToRead = nodesToRead[ii];

                    // skip items that have already been processed.
                    if (nodeToRead.Processed)
                    {
                        continue;
                    }
                    
                    // look up the node.
                    ILocalNode node = GetLocalNode(nodeToRead.NodeId) as ILocalNode;

                    if (node == null)
                    {
                        continue;
                    }

                    DataValue value = values[ii] = new DataValue();
                    
                    value.Value           = null;
                    value.ServerTimestamp = DateTime.UtcNow;
                    value.SourceTimestamp = DateTime.MinValue;
                    value.StatusCode      = StatusCodes.BadAttributeIdInvalid;

                    // owned by this node manager.
                    nodeToRead.Processed = true;
                    
                    // read the default value (also verifies that the attribute id is valid for the node).                   
                    ServiceResult error = node.Read(context, nodeToRead.AttributeId, value);

                    if (ServiceResult.IsBad(error))
                    {
                        errors[ii] = error;
                        continue;
                    }                    

                    // always use default value for base attributes.
                    bool useDefault = false;

                    switch (nodeToRead.AttributeId)
                    {
                        case Attributes.NodeId:
                        case Attributes.NodeClass:
                        case Attributes.BrowseName:
                        {
                            useDefault = true;
                            break;
                        }
                    }

                    if (useDefault)
                    {
                        errors[ii] = error;
                        continue;
                    }
                      
                    #if LEGACY_CORENODEMANAGER 
                    // check if an external data source needs to be called.
                    if (CheckSourceHandle(node, typeof(IReadDataSource), ii, datasources))
                    {
                        continue;
                    }

                    // use default value if no datasource found.
                    #endif

                    // apply index range to value attributes.
                    if (nodeToRead.AttributeId == Attributes.Value)
                    {
                        object defaultValue = value.Value;

                        error = nodeToRead.ParsedIndexRange.ApplyRange(ref defaultValue);
                    
                        if (ServiceResult.IsBad(error))
                        {
                            value.Value = null;
                            errors[ii] = error;
                            continue;
                        }
                        
                        // apply data encoding.
                        if (!QualifiedName.IsNull(nodeToRead.DataEncoding))
                        {
                            error = EncodeableObject.ApplyDataEncoding(Server.MessageContext, nodeToRead.DataEncoding, ref defaultValue);
                                
                            if (ServiceResult.IsBad(error))
                            {
                                value.Value = null;
                                errors[ii] = error;
                                continue;
                            }
                        }
                            
                        value.Value = defaultValue;                     
                        
                        // don't replace timestamp if it was set in the NodeSource 
                        if (value.SourceTimestamp == DateTime.MinValue) 
                        { 
                            value.SourceTimestamp = DateTime.UtcNow; 
                        } 
                    }
                }
                
                #if LEGACY_CORENODEMANAGER 
                // check if nothing more to do.
                if (datasources.Count == 0)
                {
                    return;
                }
                #endif
            }   
            finally
            {
                m_lock.Exit();
            }
            
            #if LEGACY_CORENODEMANAGER 
            // call the datasources.
            foreach (KeyValuePair<IReadDataSource,List<RequestHandle>> entry in datasources)
            { 
                try
                {
                    entry.Key.Read(
                        context,
                        maxAge,
                        entry.Value,
                        nodesToRead,
                        values,
                        errors);
                }
                catch (Exception e)
                {
                    ServiceResult error = ServiceResult.Create(e, StatusCodes.BadUnexpectedError, "Unexpected error while calling the IDatasource for the Node.");

                    foreach (RequestHandle handle in entry.Value)
                    {
                        errors[handle.Index] = error;
                    }
                }     
            }
            #endif
        }