/// <summary> /// Finds the children that match the pattern (updates cache if required). /// </summary> private List <AeBrowseElement> Browse(Session session, AeBrowseElement start, string pattern, bool isArea) { // check cache. List <AeBrowseElement> targets = (isArea)?start.Areas:start.Sources; if (targets == null) { // fetch from server. targets = Browse(session, start, isArea); // update cache. if (isArea) { start.Areas = targets; } else { start.Sources = targets; } } // check if all matched. if (String.IsNullOrEmpty(pattern) || pattern == "*") { return(targets); } // apply filter. List <AeBrowseElement> hits = new List <AeBrowseElement>(); for (int ii = 0; ii < targets.Count; ii++) { if (ComUtils.Match(targets[ii].BrowseText, pattern, false)) { hits.Add(targets[ii]); } } return(hits); }
/// <summary> /// Browses for the children of the specified item. /// </summary> /// <param name="session">The session.</param> /// <param name="itemId">The item id.</param> /// <param name="continuationPoint">The continuation point.</param> /// <param name="maxElementsReturned">The max elements returned.</param> /// <param name="elementFilter">The element filter.</param> /// <param name="nameFilter">The name filter.</param> /// <param name="revisedContinuationPoint">The revised continuation point.</param> /// <returns>The list of elements that meet the criteria.</returns> public List <ComDaBrowseElement> BrowseForElements( Session session, string itemId, string continuationPoint, int maxElementsReturned, int elementFilter, string nameFilter, out string revisedContinuationPoint) { TraceState("BrowseForElements", itemId, continuationPoint, maxElementsReturned, elementFilter, nameFilter); revisedContinuationPoint = String.Empty; // look up continuation point. ContinuationPoint cp = null; if (!String.IsNullOrEmpty(continuationPoint)) { if (!m_continuationPoints.TryGetValue(continuationPoint, out cp)) { throw ComUtils.CreateComException(ResultIds.E_INVALIDCONTINUATIONPOINT); } m_continuationPoints.Remove(continuationPoint); } // get the element queue. Queue <ComDaBrowseElement> elements = null; // get element from continuation point. if (cp != null) { elements = cp.Elements; } // get list from cache. else { elements = m_cache.BrowseForElements(session, itemId); // check if nothing found. if (elements == null) { throw ComUtils.CreateComException(ResultIds.E_UNKNOWNITEMID); } } // apply filters. List <ComDaBrowseElement> hits = new List <ComDaBrowseElement>(); while (elements.Count > 0) { ComDaBrowseElement hit = elements.Dequeue(); // apply name filter. if (!String.IsNullOrEmpty(nameFilter)) { if (!ComUtils.Match(hit.BrowseName, nameFilter, true)) { continue; } } // apply element filter if (elementFilter == (int)OpcRcw.Da.OPCBROWSEFILTER.OPC_BROWSE_FILTER_BRANCHES) { if (!hit.HasChildren) { continue; } } if (elementFilter == (int)OpcRcw.Da.OPCBROWSEFILTER.OPC_BROWSE_FILTER_ITEMS) { if (!hit.IsItem) { continue; } } // check max reached. if (maxElementsReturned > 0 && hits.Count == maxElementsReturned) { elements.Enqueue(hit); cp = new ContinuationPoint(); cp.Id = Guid.NewGuid().ToString(); cp.Elements = elements; m_continuationPoints.Add(cp.Id, cp); revisedContinuationPoint = cp.Id; break; } // add the result. hits.Add(hit); } // return results. return(hits); }
/// <summary> /// Return an IEnumString for a list of Areas as determined by the passed parameters. /// </summary> /// <param name="dwBrowseFilterType"> /// OPC_AREA - returns only areas. /// OPC_SOURCE - returns only sources.</param> /// <param name="szFilterCriteria">A server specific filter string. A pointer to a NULL string indicates no filtering.</param> /// <param name="ppIEnumString">Where to save the returned interface pointer. NULL if the HRESULT is other than S_OK or S_FALSE.</param> public void BrowseOPCAreas( OPCAEBROWSETYPE dwBrowseFilterType, string szFilterCriteria, out OpcRcw.Comn.IEnumString ppIEnumString) { ppIEnumString = null; if (dwBrowseFilterType != OPCAEBROWSETYPE.OPC_AREA && dwBrowseFilterType != OPCAEBROWSETYPE.OPC_SOURCE) { throw ComUtils.CreateComException("BrowseOPCAreas", ResultIds.E_INVALIDARG); } try { lock (m_lock) { // find the current node. INode parent = null; // ensure browse stack has been initialized. if (m_browseStack.Count == 0) { parent = m_session.NodeCache.Find(Objects.Server); m_browseStack.Push(parent); } parent = m_browseStack.Peek(); if (parent == null) { throw ComUtils.CreateComException("BrowseOPCAreas", ResultIds.E_FAIL); } List <string> names = new List <string>(); IList <INode> children; ////// find children. children = m_session.NodeCache.Find(parent.NodeId, ReferenceTypes.HasEventSource, false, true); // This would also include // the HasNotifier reference which is // a subtype of HasEventSource foreach (INode child in children) { // ignore external nodes. if (child.NodeId.IsAbsolute) { continue; } // ignore non-objects/variables. if ((child.NodeClass & (NodeClass.Object | NodeClass.Variable)) == 0) { continue; } // ignore duplicate browse names. if (names.Contains(child.BrowseName.ToString())) { continue; } // For a node to be an area, it has to have the 'HasNotifier' reference and must // allow event notification (the EventNotifier attribute is set to SubscribeToEvents) // For a node to be a source, it should be the target of the HasEventSource reference if (IsValidNode((NodeId)child.NodeId, child.BrowseName.ToString(), dwBrowseFilterType)) { if (String.IsNullOrEmpty(szFilterCriteria)) { names.Add(child.BrowseName.ToString()); } else { // apply filters if (ComUtils.Match(child.BrowseName.ToString(), szFilterCriteria, true)) { names.Add(child.BrowseName.ToString()); } } } } // create enumerator. ppIEnumString = (OpcRcw.Comn.IEnumString) new EnumString(names); } } catch (Exception e) { Utils.Trace(e, "Unexpected error in BrowseOPCAreas"); throw ComUtils.CreateComException(e); } }