/// <summary> /// Returns the set of elements in the address space that meet the specified criteria. /// </summary> public Opc.Da.BrowseElement[] Browse( ItemIdentifier itemID, BrowseFilters filters, ref Opc.Da.BrowsePosition position) { lock (this) { if (m_disposed) throw new ObjectDisposedException("Opc.Da.Cache"); BrowseElement element = m_addressSpace; // find desired element. string browsePath = (itemID != null)?itemID.ItemName:null; if (browsePath != null && browsePath.Length > 0) { element = m_addressSpace.Find(browsePath); if (element == null) { // check if browsing a property item. PropertyID property = Property.VALUE; string rootID = LookupProperty(browsePath, out property); if (rootID != null) { element = m_addressSpace.Find(rootID); } if (element == null) { throw new ResultIDException(ResultID.Da.E_UNKNOWN_ITEM_NAME); } // property items never contain children. return new Opc.Da.BrowseElement[0]; } } // check if no elements exist. if (element.Count == 0) { return new Opc.Da.BrowseElement[0]; } // determine start position. int start = 0; if (position != null) { start = ((BrowsePosition)position).Index; position.Dispose(); position = null; } // process child nodes. ArrayList results = new ArrayList(); for (int ii = start; ii < element.Count; ii++) { BrowseElement child = element.Child(ii); // exclude elements without children. if (filters.BrowseFilter == browseFilter.branch && child.Count == 0) { continue; } // check if an element is an item. CacheItem item = (CacheItem)m_items[child.ItemID]; // exclude elements which are not items. if (filters.BrowseFilter == browseFilter.item && item == null) { continue; } // apply name filter (using the SQL LIKE operator). if (filters.ElementNameFilter != null && filters.ElementNameFilter.Length > 0) { if (!Opc.Convert.Match(child.Name, filters.ElementNameFilter, true)) { continue; } } // add element to list of results. Opc.Da.BrowseElement result = new Opc.Da.BrowseElement(); result.Name = child.Name; result.ItemName = child.ItemID; result.ItemPath = null; result.IsItem = item != null; result.HasChildren = child.Count > 0; result.Properties = null; // add properties to results. if (filters.ReturnAllProperties || filters.PropertyIDs != null) { result.Properties = GetProperties(item, (filters.ReturnAllProperties)?null:filters.PropertyIDs, filters.ReturnPropertyValues); } results.Add(result); // check if max elements exceeded. if (filters.MaxElementsReturned > 0 && results.Count >= filters.MaxElementsReturned) { if (ii+1 < element.Count) { position = new BrowsePosition(itemID, filters); ((BrowsePosition)position).Index = ii+1; } break; } } // return results. return (Opc.Da.BrowseElement[])results.ToArray(typeof(Opc.Da.BrowseElement)); } }