/// <summary> /// Exposes the ContentDirectory's Search action (for returning sorted results) as a method of a container. /// </summary> /// <param name="expression">IMediaComparer object that will indicate if a media object is a match</param> /// <param name="sorter">IMediaSorter object that determines the sorting criteria for the results</param> /// <param name="startingIndex">starting index for the search results, 0-based index</param> /// <param name="requestedCount">maximum number of children requested</param> /// <param name="totalMatches">total number of possible matches, sometimes has uint.MaxValue if the total possible is unknown</param> /// <returns></returns> public virtual IList SearchSorted(IMediaComparer expression, IMediaSorter sorter, UInt32 startingIndex, UInt32 requestedCount, out UInt32 totalMatches) { SortedList sorted = null; ArrayList results = null; if (this.m_Listing != null) { sorted = new SortedList(sorter, this.m_Listing.Count); this.SearchCollection(expression, ref sorted); int size = Convert.ToInt32(requestedCount); if (sorted.Count < size) size = sorted.Count; results = new ArrayList(size); int i=0; foreach (IUPnPMedia entry in sorted.Values) { if (i >= startingIndex) { results.Add(entry); } i++; if ((results.Count >= requestedCount) && (requestedCount != 0)) { break; } } totalMatches = Convert.ToUInt32(sorted.Count); } else { results = new ArrayList(0); totalMatches = 0; } return results; }
/// <summary> /// Implements the core logic for a sorted Search. /// </summary> /// <param name="exoression">IMediaComparer object that will indicate if a media object is a match</param> /// <param name="sorted">sorted list of IUPnPMedia objects that make up result set</param> private void SearchCollection(IMediaComparer expression, ref SortedList sorted) { this.m_LockListing.AcquireReaderLock(-1); ArrayList containers = null; if (this.m_Listing != null) { containers = new ArrayList(this.m_Listing.Count); foreach (IUPnPMedia entry in this.m_Listing) { // If the item is a match, add it to the list of results. // if (expression.IsMatch(entry)) { sorted.Add(entry,entry); } if (entry.IsContainer) { containers.Add(entry); } } } this.m_LockListing.ReleaseReaderLock(); if (containers != null) { foreach (MediaContainer container in containers) { container.SearchCollection(expression, ref sorted); } } }
/// <summary> /// Exposes the ContentDirectory's Search action (for returning unsorted results) as a method of a container. /// </summary> /// <param name="expression">IMediaComparer object that will indicate if a media object is a match</param> /// <param name="startingIndex">starting index for the search results, 0-based index</param> /// <param name="requestedCount">maximum number of children requested</param> /// <param name="totalMatches"> /// total number of possible matches, sometimes has uint.MaxValue if the total possible is unknown. /// CHANGED PER DHWG: Returns 0 if total is unknown. /// </param> /// <returns></returns> public virtual IList Search(IMediaComparer expression, UInt32 startingIndex, UInt32 requestedCount, out UInt32 totalMatches) { ArrayList results = new ArrayList(2500); bool searchedSubtree; this.SearchCollection(expression, startingIndex, requestedCount, out searchedSubtree, ref results); if (searchedSubtree) { totalMatches = Convert.ToUInt32(results.Count); } else { //totalMatches = UInt32.MaxValue; totalMatches = 0; } return results; }
/// <summary> /// Implements the core logic for packaging up the results for a Search. /// </summary> /// <param name="expression">IMediaComparer object that will indicate if a media object is a match</param> /// <param name="startingIndex">starting index for the search results, 0-based index</param> /// <param name="requestedCount">maximum number of children requested</param> /// <param name="searchedEntireSubtree">True, if the entire subtree was searched.</param> /// <param name="results">ArrayList of the desired results.</param> private void SearchCollection(IMediaComparer expression, UInt32 startingIndex, UInt32 requestedCount, out bool searchedEntireSubtree, ref ArrayList results) { searchedEntireSubtree = true; if (this.m_Listing != null) { ArrayList containers = new ArrayList(this.m_Listing.Count); this.m_LockListing.AcquireReaderLock(-1); foreach (IUPnPMedia entry in this.m_Listing) { // If the item is a match, add it to the list of results. // if (expression.IsMatch(entry)) { results.Add(entry); } // If we've reached the max number of results, then indicate // that we will not end up searching the entire subtree. // if ((results.Count >= requestedCount) && (requestedCount != 0)) { searchedEntireSubtree = false; break; } if (entry.IsContainer) { containers.Add(entry); } } this.m_LockListing.ReleaseReaderLock(); // If we're still intent on searching the entire subtree, then // recurse through each sub-container. // if (searchedEntireSubtree) { foreach (MediaContainer container in containers) { // After recursing each subtree, check to see if we stopped // searching the entire subtee. If so, then do not continue. if (searchedEntireSubtree) { container.SearchCollection(expression, startingIndex, requestedCount, out searchedEntireSubtree, ref results); } else { break; } } } } }