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

Browse() public method

public Browse ( OperationContext context, ContinuationPoint &continuationPoint, IList references ) : void
context OperationContext
continuationPoint ContinuationPoint
references IList
return void
        public void Browse(
            OperationContext            context,
            ref ContinuationPoint       continuationPoint,
            IList<ReferenceDescription> references)
        {              
            if (context == null) throw new ArgumentNullException("context");
            if (continuationPoint == null) throw new ArgumentNullException("continuationPoint");
            if (references == null) throw new ArgumentNullException("references");
            
            // check for valid handle.
            ILocalNode source = continuationPoint.NodeToBrowse as ILocalNode;

            if (source == null)
            {
                throw new ServiceResultException(StatusCodes.BadNodeIdUnknown);
            }
            
            // check for view.
            if (!ViewDescription.IsDefault(continuationPoint.View))
            {
                throw new ServiceResultException(StatusCodes.BadViewIdUnknown);
            }

            try
            {
                m_lock.Enter();
                
                // construct list of references.
                uint maxResultsToReturn = continuationPoint.MaxResultsToReturn;

                // get previous enumerator.
                IEnumerator<IReference> enumerator = continuationPoint.Data as IEnumerator<IReference>;
            
                // fetch a snapshot all references for node.
                if (enumerator == null)
                {
                    List<IReference> copy = new List<IReference>(source.References);
                    enumerator = copy.GetEnumerator();
                    enumerator.MoveNext();
                }

                do
                {
                    IReference reference = enumerator.Current;

                    // silently ignore bad values.
                    if (reference == null || NodeId.IsNull(reference.ReferenceTypeId) || NodeId.IsNull(reference.TargetId))
                    {
                        continue;
                    }

                    // apply browse filters.
                    bool include = ApplyBrowseFilters(
                        reference,
                        continuationPoint.BrowseDirection,
                        continuationPoint.ReferenceTypeId,
                        continuationPoint.IncludeSubtypes);

                    if (include)
                    {                 
                        ReferenceDescription description = new ReferenceDescription();
                        
                        description.NodeId = reference.TargetId;
                        description.SetReferenceType(continuationPoint.ResultMask, reference.ReferenceTypeId, !reference.IsInverse);

                        // only fetch the metadata if it is requested.
                        if (continuationPoint.TargetAttributesRequired)
                        {                        
                            // get the metadata for the node.
                            NodeMetadata metadata = GetNodeMetadata(context, GetManagerHandle(reference.TargetId), continuationPoint.ResultMask);

                            // update description with local node metadata.
                            if (metadata != null)
                            {
                                description.SetTargetAttributes(
                                    continuationPoint.ResultMask,
                                    metadata.NodeClass,
                                    metadata.BrowseName,
                                    metadata.DisplayName,
                                    metadata.TypeDefinition);

                                // check node class mask.
                                if (!CheckNodeClassMask(continuationPoint.NodeClassMask, description.NodeClass))
                                {
                                    continue;
                                }
                            }

                            // any target that is not remote must be owned by another node manager.
                            else if (!reference.TargetId.IsAbsolute)
                            {
                                description.Unfiltered = true;
                            }
                        }

                        // add reference to list.
                        references.Add(description);

                        // construct continuation point if max results reached.
                        if (maxResultsToReturn > 0 && references.Count >= maxResultsToReturn)
                        { 
                            continuationPoint.Index = 0;
                            continuationPoint.Data  = enumerator;
                            enumerator.MoveNext();
                            return;
                        }
                    }
                }
                while (enumerator.MoveNext());
                
                // nothing more to browse if it exits from the loop normally.
                continuationPoint.Dispose();
                continuationPoint = null;
            }
            finally
            {
                m_lock.Exit();
            }
        }