internal static browseFilter GetBrowseFilter(OPCBROWSEFILTER input) { switch (input) { case OPCBROWSEFILTER.OPC_BROWSE_FILTER_ALL: return(browseFilter.all); case OPCBROWSEFILTER.OPC_BROWSE_FILTER_BRANCHES: return(browseFilter.branch); case OPCBROWSEFILTER.OPC_BROWSE_FILTER_ITEMS: return(browseFilter.item); } return(browseFilter.all); }
public void Browse(string szItemID, ref IntPtr pszContinuationPoint, int dwMaxElementsReturned, OPCBROWSEFILTER dwBrowseFilter, string szElementNameFilter, string szVendorFilter, int bReturnAllProperties, int bReturnPropertyValues, int dwPropertyCount, int[] pdwPropertyIDs, out int pbMoreElements, out int pdwCount, out IntPtr ppBrowseElements) { OpcCom.Da.Wrapper.Server server; Monitor.Enter(server = this); try { ItemIdentifier itemID = new ItemIdentifier(szItemID); BrowseFilters filters = new BrowseFilters { MaxElementsReturned = dwMaxElementsReturned, BrowseFilter = OpcCom.Da.Interop.GetBrowseFilter(dwBrowseFilter), ElementNameFilter = szElementNameFilter, VendorFilter = szVendorFilter, ReturnAllProperties = bReturnAllProperties != 0, ReturnPropertyValues = bReturnPropertyValues != 0, PropertyIDs = OpcCom.Da.Interop.GetPropertyIDs(pdwPropertyIDs) }; Opc.Da.BrowsePosition position = null; BrowseElement[] input = null; string key = null; if (pszContinuationPoint != IntPtr.Zero) { key = Marshal.PtrToStringUni(pszContinuationPoint); } if ((key == null) || (key.Length == 0)) { input = this.m_server.Browse(itemID, filters, out position); } else { ContinuationPoint point = (ContinuationPoint)this.m_continuationPoints[key]; if (point != null) { position = point.Position; this.m_continuationPoints.Remove(key); } if (position == null) { throw new ExternalException("E_INVALIDCONTINUATIONPOINT", -1073478653); } Marshal.FreeCoTaskMem(pszContinuationPoint); pszContinuationPoint = IntPtr.Zero; position.MaxElementsReturned = dwMaxElementsReturned; input = this.m_server.BrowseNext(ref position); } this.CleanupContinuationPoints(); if (position != null) { key = Guid.NewGuid().ToString(); this.m_continuationPoints[key] = new ContinuationPoint(position); pszContinuationPoint = Marshal.StringToCoTaskMemUni(key); } if (pszContinuationPoint == IntPtr.Zero) { pszContinuationPoint = Marshal.StringToCoTaskMemUni(string.Empty); } pbMoreElements = 0; pdwCount = 0; ppBrowseElements = IntPtr.Zero; if (input != null) { pdwCount = input.Length; ppBrowseElements = OpcCom.Da.Interop.GetBrowseElements(input, dwPropertyCount > 0); } } catch (Exception exception) { throw CreateException(exception); } finally { Monitor.Exit(server); } }
/// <summary> /// Applies the browse filters to a set of references. /// </summary> private void ApplyFilters( ReferenceDescriptionCollection currentBatch, OPCBROWSEFILTER dwBrowseFilter, string szElementNameFilter, int maxReferencesReturned, IList<BrowseElement> filteredResults, IList<BrowseElement> unprocessedResults) { // apply the filters to each item in the batch. foreach (ReferenceDescription reference in currentBatch) { // check for a valid node. INode target = m_session.NodeCache.FetchNode(reference.NodeId); if (target == null) { continue; } // create the browse element. BrowseElement element = new BrowseElement(); element.Node = target; element.Name = target.BrowseName.Name; element.ItemId = NodeIdToItemId(target.NodeId); // apply the element name filter. if (!String.IsNullOrEmpty(szElementNameFilter)) { if (!ComUtils.Match(element.Name, szElementNameFilter, true)) { continue; } } element.IsItem = IsItem(target); element.HasChildren = HasChildren(target); // apply the browse filter. if (dwBrowseFilter != OPCBROWSEFILTER.OPC_BROWSE_FILTER_ALL) { if (dwBrowseFilter == OPCBROWSEFILTER.OPC_BROWSE_FILTER_ITEMS) { if (!element.IsItem) { continue; } } else { if (!element.HasChildren) { continue; } } } // must save the results to return in a subsequent browse. if (maxReferencesReturned != 0 && filteredResults.Count >= maxReferencesReturned) { unprocessedResults.Add(element); } // can return the results in this browse. else { filteredResults.Add(element); } } }
/// <summary> /// Finds the references that meet the browse criteria. /// </summary> private IList<BrowseElement> Browse( NodeId startId, ref ContinuationPoint cp, int dwMaxElementsReturned, OPCBROWSEFILTER dwBrowseFilter, string szElementNameFilter) { IList<BrowseElement> filteredResults = new List<BrowseElement>(); IList<BrowseElement> unprocessedResults = new List<BrowseElement>(); byte[] continuationPoint = null; while (dwMaxElementsReturned == 0 || filteredResults.Count < dwMaxElementsReturned) { ReferenceDescriptionCollection currentBatch = null; if (cp == null) { currentBatch = Browse(startId, dwMaxElementsReturned, out continuationPoint); if (continuationPoint != null) { cp = new ContinuationPoint(); cp.LastCP = continuationPoint; cp.UnprocessedElements = null; } } else { if (cp.UnprocessedElements != null) { // add any unprocessed results from the previous call. for (int ii = 0; ii < cp.UnprocessedElements.Count; ii++) { if (dwMaxElementsReturned == 0 || filteredResults.Count < dwMaxElementsReturned) { filteredResults.Add(cp.UnprocessedElements[ii]); } else { unprocessedResults.Add(cp.UnprocessedElements[ii]); } } // check if all done. if (unprocessedResults.Count == 0 && cp.LastCP == null) { cp = null; break; } // check for max results. if (unprocessedResults.Count > 0) { cp = new ContinuationPoint(); cp.LastCP = null; cp.UnprocessedElements = unprocessedResults; break; } } // get the next batch. if (cp != null && cp.LastCP != null) { continuationPoint = cp.LastCP; currentBatch = BrowseNext(ref continuationPoint); if (continuationPoint != null) { cp = new ContinuationPoint(); cp.LastCP = continuationPoint; cp.UnprocessedElements = null; } } } // apply the filters. ApplyFilters( currentBatch, dwBrowseFilter, szElementNameFilter, dwMaxElementsReturned, filteredResults, unprocessedResults); // check if all done. if (unprocessedResults.Count == 0 && (cp == null || cp.LastCP == null)) { cp = null; break; } // check for max results. if (unprocessedResults.Count > 0) { cp = new ContinuationPoint(); cp.LastCP = continuationPoint; cp.UnprocessedElements = unprocessedResults; break; } } return filteredResults; }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// #region IOPCBrowse Members /// <summary> /// IOPCBrowse::Browse - Browses a single branch of the address space and returns zero or more OPCBROWSEELEMENT structures. /// </summary> public void Browse( string szItemID, ref System.IntPtr pszContinuationPoint, int dwMaxElementsReturned, OPCBROWSEFILTER dwBrowseFilter, string szElementNameFilter, string szVendorFilter, int bReturnAllProperties, int bReturnPropertyValues, int dwPropertyCount, int[] pdwPropertyIDs, out int pbMoreElements, out int pdwCount, out System.IntPtr ppBrowseElements) { try { NodeId startId = ItemIdToNodeId(szItemID); if (startId == null) { throw new COMException("E_INVALIDITEMID", ResultIds.E_INVALIDITEMID); } // unmarshal continuation point. string continuationPoint = null; if (pszContinuationPoint != IntPtr.Zero) { continuationPoint = Marshal.PtrToStringUni(pszContinuationPoint); } // lookup continuation point. ContinuationPoint cp = null; if (!String.IsNullOrEmpty(continuationPoint)) { // find existing continuation point. lock (m_lock) { for (LinkedListNode<ContinuationPoint> current = m_continuationPoints.First; current != null; current = current.Next) { if (current.Value.Id == continuationPoint) { cp = current.Value; m_continuationPoints.Remove(current); break; } } } // no longer valid. if (cp == null) { throw new COMException("E_INVALIDCONTINUATIONPOINT", ResultIds.E_INVALIDCONTINUATIONPOINT); } } // find references. IList<BrowseElement> elements = Browse( startId, ref cp, dwMaxElementsReturned, dwBrowseFilter, szElementNameFilter); // save continuation point. if (cp != null) { cp.Id = Guid.NewGuid().ToString(); m_continuationPoints.AddLast(cp); pszContinuationPoint = Marshal.StringToCoTaskMemUni(cp.Id); } // return a valid the continution point. if (pszContinuationPoint == IntPtr.Zero) { pszContinuationPoint = Marshal.StringToCoTaskMemUni(String.Empty); } // fetch any properties. if (bReturnAllProperties != 0 || dwPropertyCount > 0) { for (int ii = 0; ii < elements.Count; ii++) { elements[ii].Properties = GetItemProperties( elements[ii].Node, bReturnAllProperties != 0, pdwPropertyIDs, bReturnPropertyValues != 0); } } // marshal return arguments. pbMoreElements = 0; pdwCount = 0; ppBrowseElements = IntPtr.Zero; if (elements != null) { pdwCount = elements.Count; ppBrowseElements = GetBrowseElements(elements); } } catch (Exception e) { throw ComUtils.CreateComException(e); } }
public void Browse(string szItemID, ref IntPtr pszContinuationPoint, int dwMaxElementsReturned, OPCBROWSEFILTER dwBrowseFilter, string szElementNameFilter, string szVendorFilter, int bReturnAllProperties, int bReturnPropertyValues, int dwPropertyCount, int[] pdwPropertyIDs, out int pbMoreElements, out int pdwCount, out IntPtr ppBrowseElements) { lock (this) { try { ItemIdentifier itemID = new ItemIdentifier(szItemID); BrowseFilters browseFilters = new BrowseFilters(); browseFilters.MaxElementsReturned = dwMaxElementsReturned; browseFilters.BrowseFilter = Interop.GetBrowseFilter(dwBrowseFilter); browseFilters.ElementNameFilter = szElementNameFilter; browseFilters.VendorFilter = szVendorFilter; browseFilters.ReturnAllProperties = (bReturnAllProperties != 0); browseFilters.ReturnPropertyValues = (bReturnPropertyValues != 0); browseFilters.PropertyIDs = Interop.GetPropertyIDs(pdwPropertyIDs); Opc.Da.BrowsePosition position = null; BrowseElement[] array = null; string text = null; if (pszContinuationPoint != IntPtr.Zero) { text = Marshal.PtrToStringUni(pszContinuationPoint); } if (text == null || text.Length == 0) { array = m_server.Browse(itemID, browseFilters, out position); } else { ContinuationPoint continuationPoint = (ContinuationPoint)m_continuationPoints[text]; if (continuationPoint != null) { position = continuationPoint.Position; m_continuationPoints.Remove(text); } if (position == null) { throw new ExternalException("E_INVALIDCONTINUATIONPOINT", -1073478653); } Marshal.FreeCoTaskMem(pszContinuationPoint); pszContinuationPoint = IntPtr.Zero; position.MaxElementsReturned = dwMaxElementsReturned; array = m_server.BrowseNext(ref position); } CleanupContinuationPoints(); if (position != null) { text = Guid.NewGuid().ToString(); m_continuationPoints[text] = new ContinuationPoint(position); pszContinuationPoint = Marshal.StringToCoTaskMemUni(text); } if (pszContinuationPoint == IntPtr.Zero) { pszContinuationPoint = Marshal.StringToCoTaskMemUni(string.Empty); } pbMoreElements = 0; pdwCount = 0; ppBrowseElements = IntPtr.Zero; if (array != null) { pdwCount = array.Length; ppBrowseElements = Interop.GetBrowseElements(array, dwPropertyCount > 0); } } catch (Exception e) { throw CreateException(e); } } }