[rygel] core,plugins: Introducing SearchableContainer



commit 463792da68f7f62d3cbc7b4ac3179d0819652e96
Author: Sunil Mohan Adapa <sunil medhas org>
Date:   Fri Nov 26 01:16:02 2010 +0530

    core,plugins: Introducing SearchableContainer
    
    Move MediaContainer.search (and related methods) to separate interface,
    SearchableContainer. Not every container needs to be searchable and allowing
    search in them only makes searches on top containers slow. Now only the
    container that needs to be searchable implement this new interface.

 src/plugins/external/rygel-external-container.vala |   25 ++--
 .../external/rygel-external-dummy-container.vala   |    6 +
 .../rygel-media-export-db-container.vala           |   25 ++--
 .../rygel-media-export-null-container.vala         |    6 +
 .../rygel-media-export-query-container.vala        |    2 +-
 .../rygel-tracker-category-all-container.vala      |   16 ++-
 .../tracker/rygel-tracker-search-container.vala    |   49 +++---
 src/rygel/Makefile.am                              |    1 +
 src/rygel/rygel-item-creator.vala                  |   20 ++-
 src/rygel/rygel-media-container.vala               |  135 +--------------
 src/rygel/rygel-search.vala                        |    2 +-
 src/rygel/rygel-searchable-container.vala          |  191 ++++++++++++++++++++
 src/rygel/rygel-simple-container.vala              |   16 ++-
 src/rygel/rygel-xbox-hacks.vala                    |   12 +-
 14 files changed, 311 insertions(+), 195 deletions(-)
---
diff --git a/src/plugins/external/rygel-external-container.vala b/src/plugins/external/rygel-external-container.vala
index b661e53..41425e3 100644
--- a/src/plugins/external/rygel-external-container.vala
+++ b/src/plugins/external/rygel-external-container.vala
@@ -29,7 +29,8 @@ using FreeDesktop;
 /**
  * Represents an external container.
  */
-public class Rygel.External.Container : Rygel.MediaContainer {
+public class Rygel.External.Container : Rygel.MediaContainer,
+                                        Rygel.SearchableContainer {
     public MediaContainerProxy actual_container;
 
     public string host_ip;
@@ -85,19 +86,19 @@ public class Rygel.External.Container : Rygel.MediaContainer {
         return yield this.create_media_objects (children_props, this);
     }
 
-    public override async MediaObjects? search (SearchExpression? expression,
-                                                uint              offset,
-                                                uint              max_count,
-                                                out uint          total_matches,
-                                                Cancellable?      cancellable)
-                                                throws GLib.Error {
+    public async MediaObjects? search (SearchExpression? expression,
+                                       uint              offset,
+                                       uint              max_count,
+                                       out uint          total_matches,
+                                       Cancellable?      cancellable)
+                                       throws GLib.Error {
         if (expression == null || !this.searchable) {
             // Either its wildcard or backend doesn't implement search :(
-            return yield base.search (expression,
-                                      offset,
-                                      max_count,
-                                      out total_matches,
-                                      cancellable);
+            return yield this.simple_search (expression,
+                                             offset,
+                                             max_count,
+                                             out total_matches,
+                                             cancellable);
         }
 
         string[] filter = {};
diff --git a/src/plugins/external/rygel-external-dummy-container.vala b/src/plugins/external/rygel-external-dummy-container.vala
index 40b6095..7ccb6f3 100644
--- a/src/plugins/external/rygel-external-dummy-container.vala
+++ b/src/plugins/external/rygel-external-dummy-container.vala
@@ -44,4 +44,10 @@ internal class Rygel.External.DummyContainer : MediaContainer {
                                                       throws Error {
         return new MediaObjects ();
     }
+
+    public override async MediaObject? find_object (string       id,
+                                                    Cancellable? cancellable)
+                                                    throws Error {
+        return null;
+    }
 }
diff --git a/src/plugins/media-export/rygel-media-export-db-container.vala b/src/plugins/media-export/rygel-media-export-db-container.vala
index 37ca44e..5935186 100644
--- a/src/plugins/media-export/rygel-media-export-db-container.vala
+++ b/src/plugins/media-export/rygel-media-export-db-container.vala
@@ -22,7 +22,8 @@
 using GUPnP;
 using Gee;
 
-public class Rygel.MediaExport.DBContainer : MediaContainer {
+public class Rygel.MediaExport.DBContainer : MediaContainer,
+                                             SearchableContainer {
     protected MediaCache media_db;
 
     public DBContainer (MediaCache media_db, string id, string title) {
@@ -51,12 +52,12 @@ public class Rygel.MediaExport.DBContainer : MediaContainer {
         return this.media_db.get_children (this, offset, max_count);
     }
 
-    public override async MediaObjects? search (SearchExpression? expression,
-                                                uint              offset,
-                                                uint              max_count,
-                                                out uint          total_matches,
-                                                Cancellable?      cancellable)
-                                                throws GLib.Error {
+    public virtual async MediaObjects? search (SearchExpression? expression,
+                                               uint              offset,
+                                               uint              max_count,
+                                               out uint          total_matches,
+                                               Cancellable?      cancellable)
+                                               throws GLib.Error {
         MediaObjects children = null;
 
         try {
@@ -68,11 +69,11 @@ public class Rygel.MediaExport.DBContainer : MediaContainer {
                                          out total_matches);
         } catch (MediaCacheError error) {
             if (error is MediaCacheError.UNSUPPORTED_SEARCH) {
-                children = yield base.search (expression,
-                                              offset,
-                                              max_count,
-                                              out total_matches,
-                                              cancellable);
+                children = yield this.simple_search (expression,
+                                                     offset,
+                                                     max_count,
+                                                     out total_matches,
+                                                     cancellable);
             } else {
                 throw error;
             }
diff --git a/src/plugins/media-export/rygel-media-export-null-container.vala b/src/plugins/media-export/rygel-media-export-null-container.vala
index 1be8b7c..f046959 100644
--- a/src/plugins/media-export/rygel-media-export-null-container.vala
+++ b/src/plugins/media-export/rygel-media-export-null-container.vala
@@ -36,4 +36,10 @@ internal class Rygel.NullContainer : MediaContainer {
                                                       throws Error {
         return new MediaObjects ();
     }
+
+    public override async MediaObject? find_object (string id,
+                                                    Cancellable? cancellable)
+                                                    throws Error {
+        return null;
+    }
 }
diff --git a/src/plugins/media-export/rygel-media-export-query-container.vala b/src/plugins/media-export/rygel-media-export-query-container.vala
index 48c3f38..1bf66f9 100644
--- a/src/plugins/media-export/rygel-media-export-query-container.vala
+++ b/src/plugins/media-export/rygel-media-export-query-container.vala
@@ -100,7 +100,7 @@ internal class Rygel.MediaExport.QueryContainer : DBContainer {
         }
     }
 
-    public override async MediaObjects? search (SearchExpression? expression,
+    public async override MediaObjects? search (SearchExpression? expression,
                                                 uint              offset,
                                                 uint              max_count,
                                                 out uint          total_matches,
diff --git a/src/plugins/tracker/rygel-tracker-category-all-container.vala b/src/plugins/tracker/rygel-tracker-category-all-container.vala
index 9f4c220..952b33e 100644
--- a/src/plugins/tracker/rygel-tracker-category-all-container.vala
+++ b/src/plugins/tracker/rygel-tracker-category-all-container.vala
@@ -28,7 +28,8 @@ using Gee;
  * A search container that contains all the items in a category.
  */
 public class Rygel.Tracker.CategoryAllContainer : SearchContainer,
-                                                  WritableContainer {
+                                                  WritableContainer,
+                                                  SearchableContainer {
     /* class-wide constants */
     private const string TRACKER_SERVICE = "org.freedesktop.Tracker1";
     private const string RESOURCES_PATH = "/org/freedesktop/Tracker1/Resources";
@@ -85,6 +86,19 @@ public class Rygel.Tracker.CategoryAllContainer : SearchContainer,
         yield this.remove_entry_from_store (urn);
     }
 
+    public async MediaObjects? search (SearchExpression? expression,
+                                       uint              offset,
+                                       uint              max_count,
+                                       out uint          total_matches,
+                                       Cancellable?      cancellable)
+                                       throws Error {
+        return yield this.simple_search (expression,
+                                         offset,
+                                         max_count,
+                                         out total_matches,
+                                         cancellable);
+    }
+
     private void on_graph_updated (string  class_name,
                                    Event[] deletes,
                                    Event[] inserts) {
diff --git a/src/plugins/tracker/rygel-tracker-search-container.vala b/src/plugins/tracker/rygel-tracker-search-container.vala
index 7986e6e..1a99589 100644
--- a/src/plugins/tracker/rygel-tracker-search-container.vala
+++ b/src/plugins/tracker/rygel-tracker-search-container.vala
@@ -116,29 +116,21 @@ public class Rygel.Tracker.SearchContainer : Rygel.MediaContainer {
 
         uint total_matches;
 
-        return yield this.search (expression,
-                                  offset,
-                                  max_count,
-                                  out total_matches,
-                                  cancellable);
+        return yield this.execute_query (expression,
+                                         offset,
+                                         max_count,
+                                         out total_matches,
+                                         cancellable);
     }
 
-    public override async MediaObjects? search (SearchExpression? expression,
-                                                uint              offset,
-                                                uint              max_count,
-                                                out uint          total_matches,
-                                                Cancellable?      cancellable)
-                                                throws GLib.Error {
+    public async MediaObjects? execute_query (SearchExpression? expression,
+                                              uint              offset,
+                                              uint              max_count,
+                                              out uint          total_matches,
+                                              Cancellable?      cancellable)
+                                              throws GLib.Error {
         var results = new MediaObjects ();
 
-        if (expression == null || !(expression is RelationalExpression)) {
-            return yield base.search (expression,
-                                      offset,
-                                      max_count,
-                                      out total_matches,
-                                      cancellable);
-        }
-
         var query = this.create_query (expression as RelationalExpression,
                                        (int) offset,
                                        (int) max_count);
@@ -164,8 +156,23 @@ public class Rygel.Tracker.SearchContainer : Rygel.MediaContainer {
     public override async MediaObject? find_object (string       id,
                                                     Cancellable? cancellable)
                                                     throws GLib.Error {
-        if (this.is_our_child (id)) {
-            return yield base.find_object (id, cancellable);
+        if (!this.is_our_child (id)) {
+            return null;
+        }
+
+        var expression = new RelationalExpression ();
+        expression.op = SearchCriteriaOp.EQ;
+        expression.operand1 = "@id";
+        expression.operand2 = id;
+
+        uint total_matches;
+        var results = yield this.execute_query (expression,
+                                                0,
+                                                1,
+                                                out total_matches,
+                                                cancellable);
+        if (results.size > 0) {
+            return results[0];
         } else {
             return null;
         }
diff --git a/src/rygel/Makefile.am b/src/rygel/Makefile.am
index f9f3113..182673e 100644
--- a/src/rygel/Makefile.am
+++ b/src/rygel/Makefile.am
@@ -82,6 +82,7 @@ VAPI_SOURCE_FILES = rygel-configuration.vala \
 		    rygel-media-container.vala \
 		    rygel-simple-container.vala \
 		    rygel-writable-container.vala \
+		    rygel-searchable-container.vala \
 		    rygel-media-item.vala \
 		    rygel-audio-item.vala \
 		    rygel-music-item.vala \
diff --git a/src/rygel/rygel-item-creator.vala b/src/rygel/rygel-item-creator.vala
index 8f7d7e7..081aa09 100644
--- a/src/rygel/rygel-item-creator.vala
+++ b/src/rygel/rygel-item-creator.vala
@@ -166,14 +166,18 @@ internal class Rygel.ItemCreator: GLib.Object, Rygel.StateMachine {
 
             uint total_matches;
 
-            var result = yield this.content_dir.root_container.search
-                                        (expression,
-                                         0,
-                                         1,
-                                         out total_matches,
-                                         this.cancellable);
-            if (result.size > 0) {
-                media_object = result[0];
+            var container = this.content_dir.root_container
+                            as SearchableContainer;
+
+            if (container != null) {
+                var result = yield container.search (expression,
+                                                     0,
+                                                     1,
+                                                     out total_matches,
+                                                     this.cancellable);
+                if (result.size > 0) {
+                    media_object = result[0];
+                }
             }
         } else {
             media_object = yield this.content_dir.root_container.find_object
diff --git a/src/rygel/rygel-media-container.vala b/src/rygel/rygel-media-container.vala
index c2067c8..8246d74 100644
--- a/src/rygel/rygel-media-container.vala
+++ b/src/rygel/rygel-media-container.vala
@@ -111,89 +111,6 @@ public abstract class Rygel.MediaContainer : MediaObject {
                                                       throws Error;
 
     /**
-     * Recursively searches for all media objects the satisfy the given search
-     * expression in this container.
-     *
-     * @param expression the search expression or `null` for wildcard
-     * @param offet zero-based index of the first object to return
-     * @param max_count maximum number of objects to return
-     * @param total_matches sets it to the actual number of objects that satisfy
-     *                      the given search expression. If it is not possible
-     *                      to compute this value (in a timely mannger), it is
-     *                      set to '0'.
-     * @param cancellable optional cancellable for this operation
-     *
-     * return A list of media objects.
-     */
-    public virtual async MediaObjects? search (SearchExpression? expression,
-                                               uint              offset,
-                                               uint              max_count,
-                                               out uint          total_matches,
-                                               Cancellable?      cancellable)
-                                               throws Error {
-        var result = new MediaObjects ();
-
-        var children = yield this.get_children (0,
-                                                this.child_count,
-                                                cancellable);
-
-        // The maximum number of results we need to be able to slice-out
-        // the needed portion from it.
-        uint limit;
-        if (offset > 0 || max_count > 0) {
-            limit = offset + max_count;
-        } else {
-            limit = 0; // No limits on searches
-        }
-
-        // First add relavant children
-        foreach (var child in children) {
-            if (expression == null || expression.satisfied_by (child)) {
-                result.add (child);
-            }
-
-            if (limit > 0 && result.size >= limit) {
-                break;
-            }
-        }
-
-        if (limit == 0 || result.size < limit) {
-            // Then search in the children
-            var child_limit = (limit == 0)? 0: limit - result.size;
-
-            var child_results = yield this.search_in_children (expression,
-                                                               children,
-                                                               child_limit,
-                                                               cancellable);
-            result.add_all (child_results);
-        }
-
-        // See if we need to slice the results
-        if (result.size > 0 && limit > 0) {
-            uint start;
-            uint stop;
-
-            start = offset.clamp (0, result.size - 1);
-
-            if (max_count != 0 && start + max_count <= result.size) {
-                stop = start + max_count;
-            } else {
-                stop = result.size;
-            }
-
-            // Since we limited our search, we don't know how many objects
-            // actually satisfy the give search expression
-            total_matches = 0;
-
-            return result.slice ((int) start, (int) stop) as MediaObjects;
-        } else {
-            total_matches = result.size;
-
-            return result;
-        }
-    }
-
-    /**
      * Recursively searches for media object with the given id in this
      * container.
      *
@@ -203,26 +120,9 @@ public abstract class Rygel.MediaContainer : MediaObject {
      *
      * return the found media object.
      */
-    public virtual async MediaObject? find_object (string       id,
-                                                   Cancellable? cancellable)
-                                                   throws Error {
-        var expression = new RelationalExpression ();
-        expression.op = SearchCriteriaOp.EQ;
-        expression.operand1 = "@id";
-        expression.operand2 = id;
-
-        uint total_matches;
-        var results = yield this.search (expression,
-                                         0,
-                                         1,
-                                         out total_matches,
-                                         cancellable);
-        if (results.size > 0) {
-            return results[0];
-        } else {
-            return null;
-        }
-    }
+    public async abstract MediaObject? find_object (string       id,
+                                                    Cancellable? cancellable)
+                                                    throws Error;
 
     /**
      * Method to be be called each time this container is updated (metadata
@@ -269,35 +169,6 @@ public abstract class Rygel.MediaContainer : MediaObject {
         return didl_container;
     }
 
-    private async MediaObjects search_in_children (SearchExpression expression,
-                                                   MediaObjects     children,
-                                                   uint             limit,
-                                                   Cancellable?     cancellable)
-                                                   throws Error {
-        var result = new MediaObjects ();
-
-        foreach (var child in children) {
-            if (child is MediaContainer) {
-                var container = child as MediaContainer;
-                uint tmp;
-
-                var child_result = yield container.search (expression,
-                                                           0,
-                                                           limit,
-                                                           out tmp,
-                                                           cancellable);
-
-                result.add_all (child_result);
-            }
-
-            if (limit > 0 && result.size >= limit) {
-                break;
-            }
-        }
-
-        return result;
-    }
-
     /**
      * handler for container_updated signal on this container. We only forward
      * it to the parent, hoping someone will get it from the root container
diff --git a/src/rygel/rygel-search.vala b/src/rygel/rygel-search.vala
index 269b3c5..13c898f 100644
--- a/src/rygel/rygel-search.vala
+++ b/src/rygel/rygel-search.vala
@@ -57,7 +57,7 @@ internal class Rygel.Search:  Rygel.MediaQueryAction {
     protected override async MediaObjects fetch_results
                                         (MediaObject media_object)
                                          throws Error {
-        var container = media_object as MediaContainer;
+        var container = media_object as SearchableContainer;
 
         var parser = new Rygel.SearchCriteriaParser (this.search_criteria);
         yield parser.run ();
diff --git a/src/rygel/rygel-searchable-container.vala b/src/rygel/rygel-searchable-container.vala
new file mode 100644
index 0000000..4afcdbe
--- /dev/null
+++ b/src/rygel/rygel-searchable-container.vala
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2008 Zeeshan Ali <zeenix gmail com>.
+ *
+ * Author: Zeeshan Ali <zeenix gmail com>
+ *
+ * This file is part of Rygel.
+ *
+ * Rygel is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Rygel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+using GUPnP;
+
+public interface Rygel.SearchableContainer : MediaContainer {
+    /**
+     * Recursively searches for all media objects that satisfy the given search
+     * expression in this container.
+     *
+     * @param expression the search expression or `null` for wildcard
+     * @param offet zero-based index of the first object to return
+     * @param max_count maximum number of objects to return
+     * @param total_matches sets it to the actual number of objects that satisfy
+     *                      the given search expression. If it is not possible
+     *                      to compute this value (in a timely mannger), it is
+     *                      set to '0'.
+     * @param cancellable optional cancellable for this operation
+     *
+     * return A list of media objects.
+     */
+    public abstract async MediaObjects? search (SearchExpression? expression,
+                                                uint              offset,
+                                                uint              max_count,
+                                                out uint          total_matches,
+                                                Cancellable?      cancellable)
+                                                throws Error;
+
+    /**
+     * Utility method that retrieves all children and recursively searches for
+     * all media objects that satisfy the given search expression in this
+     * container.
+     *
+     * @param expression the search expression or `null` for wildcard
+     * @param offet zero-based index of the first object to return
+     * @param max_count maximum number of objects to return
+     * @param total_matches sets it to the actual number of objects that satisfy
+     *                      the given search expression. If it is not possible
+     *                      to compute this value (in a timely mannger), it is
+     *                      set to '0'.
+     * @param cancellable optional cancellable for this operation
+     *
+     * return A list of media objects.
+     */
+    public async MediaObjects? simple_search (SearchExpression? expression,
+                                              uint              offset,
+                                              uint              max_count,
+                                              out uint          total_matches,
+                                              Cancellable?      cancellable)
+                                              throws Error {
+        var result = new MediaObjects ();
+
+        var children = yield this.get_children (0,
+                                                this.child_count,
+                                                cancellable);
+
+        // The maximum number of results we need to be able to slice-out
+        // the needed portion from it.
+        uint limit;
+        if (offset > 0 || max_count > 0) {
+            limit = offset + max_count;
+        } else {
+            limit = 0; // No limits on searches
+        }
+
+        // First add relavant children
+        foreach (var child in children) {
+            if (expression == null || expression.satisfied_by (child)) {
+                result.add (child);
+            }
+
+            if (limit > 0 && result.size >= limit) {
+                break;
+            }
+        }
+
+        if (limit == 0 || result.size < limit) {
+            // Then search in the children
+            var child_limit = (limit == 0)? 0: limit - result.size;
+
+            var child_results = yield this.search_in_children (expression,
+                                                               children,
+                                                               child_limit,
+                                                               cancellable);
+            result.add_all (child_results);
+        }
+
+        // See if we need to slice the results
+        if (result.size > 0 && limit > 0) {
+            uint start;
+            uint stop;
+
+            start = offset.clamp (0, result.size - 1);
+
+            if (max_count != 0 && start + max_count <= result.size) {
+                stop = start + max_count;
+            } else {
+                stop = result.size;
+            }
+
+            // Since we limited our search, we don't know how many objects
+            // actually satisfy the give search expression
+            total_matches = 0;
+
+            return result.slice ((int) start, (int) stop) as MediaObjects;
+        } else {
+            total_matches = result.size;
+
+            return result;
+        }
+    }
+
+    /**
+     * Recursively searches for media object with the given id in this
+     * container.
+     *
+     * @param id ID of the media object to search for
+     * @param cancellable optional cancellable for this operation
+     * @param callback function to call when result is ready
+     *
+     * return the found media object.
+     */
+    public async MediaObject? find_object (string       id,
+                                           Cancellable? cancellable)
+                                           throws Error {
+        var expression = new RelationalExpression ();
+        expression.op = SearchCriteriaOp.EQ;
+        expression.operand1 = "@id";
+        expression.operand2 = id;
+
+        uint total_matches;
+        var results = yield this.search (expression,
+                                         0,
+                                         1,
+                                         out total_matches,
+                                         cancellable);
+        if (results.size > 0) {
+            return results[0];
+        } else {
+            return null;
+        }
+    }
+
+    private async MediaObjects search_in_children (SearchExpression expression,
+                                                   MediaObjects     children,
+                                                   uint             limit,
+                                                   Cancellable?     cancellable)
+                                                   throws Error {
+        var result = new MediaObjects ();
+
+        foreach (var child in children) {
+            if (child is SearchableContainer) {
+                var container = child as SearchableContainer;
+                uint tmp;
+
+                var child_result = yield container.search (expression,
+                                                           0,
+                                                           limit,
+                                                           out tmp,
+                                                           cancellable);
+
+                result.add_all (child_result);
+            }
+
+            if (limit > 0 && result.size >= limit) {
+                break;
+            }
+        }
+
+        return result;
+    }
+}
diff --git a/src/rygel/rygel-simple-container.vala b/src/rygel/rygel-simple-container.vala
index 18f0542..36fab0d 100644
--- a/src/rygel/rygel-simple-container.vala
+++ b/src/rygel/rygel-simple-container.vala
@@ -29,7 +29,8 @@ using Gee;
  * in memory. In order for it to be of any use, you must add children to
  * children ArrayList field.
  */
-public class Rygel.SimpleContainer : Rygel.MediaContainer {
+public class Rygel.SimpleContainer : Rygel.MediaContainer,
+                                     Rygel.SearchableContainer {
     public MediaObjects children;
 
     public SimpleContainer (string          id,
@@ -94,4 +95,17 @@ public class Rygel.SimpleContainer : Rygel.MediaContainer {
 
         return media_object;
     }
+
+    public async MediaObjects? search (SearchExpression? expression,
+                                       uint              offset,
+                                       uint              max_count,
+                                       out uint          total_matches,
+                                       Cancellable?      cancellable)
+                                       throws Error {
+        return yield this.simple_search (expression,
+                                         offset,
+                                         max_count,
+                                         out total_matches,
+                                         cancellable);
+    }
 }
diff --git a/src/rygel/rygel-xbox-hacks.vala b/src/rygel/rygel-xbox-hacks.vala
index 6462bb6..8ff47c5 100644
--- a/src/rygel/rygel-xbox-hacks.vala
+++ b/src/rygel/rygel-xbox-hacks.vala
@@ -86,12 +86,12 @@ internal class Rygel.XBoxHacks : GLib.Object {
         }
     }
 
-    public async MediaObjects? search (MediaContainer container,
-                                       SearchExpression? expression,
-                                       uint              offset,
-                                       uint              max_count,
-                                       out uint          total_matches,
-                                       Cancellable?      cancellable)
+    public async MediaObjects? search (SearchableContainer container,
+                                       SearchExpression?   expression,
+                                       uint                offset,
+                                       uint                max_count,
+                                       out uint            total_matches,
+                                       Cancellable?        cancellable)
                                        throws Error {
         var results = yield container.search (expression,
                                               offset,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]