rygel r531 - trunk/src/rygel
- From: zeeshanak svn gnome org
- To: svn-commits-list gnome org
- Subject: rygel r531 - trunk/src/rygel
- Date: Mon, 9 Feb 2009 22:26:56 +0000 (UTC)
Author: zeeshanak
Date: Mon Feb 9 22:26:56 2009
New Revision: 531
URL: http://svn.gnome.org/viewvc/rygel?rev=531&view=rev
Log:
Move 'Browse' handling to a separate class.
Added:
trunk/src/rygel/rygel-browse.vala
Modified:
trunk/src/rygel/Makefile.am
trunk/src/rygel/rygel-content-directory.vala
Modified: trunk/src/rygel/Makefile.am
==============================================================================
--- trunk/src/rygel/Makefile.am (original)
+++ trunk/src/rygel/Makefile.am Mon Feb 9 22:26:56 2009
@@ -32,6 +32,8 @@
rygel-main.c \
rygel-content-directory.h \
rygel-content-directory.c \
+ rygel-browse.h \
+ rygel-browse.c \
rygel-plugin.h \
rygel-plugin.c \
rygel-plugin-loader.h \
@@ -73,6 +75,8 @@
rygel-main.vala \
rygel-content-directory.h \
rygel-content-directory.c \
+ rygel-browse.h \
+ rygel-browse.c \
rygel-plugin.h \
rygel-plugin.c \
rygel-plugin-loader.h \
@@ -130,7 +134,8 @@
rygel-plugin.vala \
rygel-media-object.vala \
rygel-media-container.vala \
- rygel-media-item.vala
+ rygel-media-item.vala \
+ rygel-browse.vala
rygel-1.0.vapi: $(VAPI_SOURCE_FILES)
$(VALAC) -C --library=rygel-1.0 \
Added: trunk/src/rygel/rygel-browse.vala
==============================================================================
--- (empty file)
+++ trunk/src/rygel/rygel-browse.vala Mon Feb 9 22:26:56 2009
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2008 Zeeshan Ali <zeenix gmail com>.
+ * Copyright (C) 2007 OpenedHand Ltd.
+ *
+ * Author: Zeeshan Ali <zeenix gmail com>
+ * Jorn Baayen <jorn openedhand 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 Rygel;
+using GUPnP;
+using Gee;
+
+/**
+ * Browse action implementation.
+ */
+public class Browse: GLib.Object {
+ public const int MAX_REQUESTED_COUNT = 128;
+
+ // In arguments
+ public string object_id;
+ public string browse_flag;
+ public string filter;
+ public uint index; // Starting index
+ public uint requested_count;
+ public string sort_criteria;
+
+ // Out arguments
+ public uint number_returned;
+ public uint total_matches;
+ public uint update_id;
+
+ private unowned ContentDirectory content_dir;
+ private ServiceAction action;
+ private DIDLLiteWriter didl_writer;
+
+ // Signals
+ public signal void completed ();
+
+ public Browse (ContentDirectory content_dir,
+ owned ServiceAction action) {
+ this.content_dir = content_dir;
+ this.action = (owned) action;
+
+ this.didl_writer = new DIDLLiteWriter ();
+ }
+
+ public void start () {
+ /* Start DIDL-Lite fragment */
+ this.didl_writer.start_didl_lite (null, null, true);
+
+ /* Handle incoming arguments */
+ bool metadata = this.parse_args ();
+ if (metadata) {
+ // BrowseMetadata
+ this.handle_metadata_request ();
+ } else {
+ // BrowseDirectChildren
+ this.handle_children_request ();
+ }
+ }
+
+ private void handle_metadata_request () {
+ MediaObject media_object;
+
+ try {
+ media_object = this.content_dir.find_object_by_id (this.object_id);
+
+ media_object.serialize (didl_writer);
+ } catch (Error err) {
+ this.handle_error (err);
+ return;
+ }
+
+ if (media_object is MediaContainer) {
+ this.update_id = ((MediaContainer) media_object).update_id;
+ } else {
+ this.update_id = uint32.MAX;
+ }
+
+ this.number_returned = 1;
+ this.total_matches = 1;
+
+ // Conclude the successful Browse action
+ this.conclude ();
+ }
+
+ private void handle_children_request () {
+ if (this.requested_count == 0)
+ this.requested_count = MAX_REQUESTED_COUNT;
+
+ MediaObject media_object;
+ try {
+ media_object = this.content_dir.find_object_by_id (this.object_id);
+ } catch (Error err) {
+ this.handle_error (err);
+ return;
+ }
+
+ if (!(media_object is MediaContainer)) {
+ this.handle_error (
+ new ContentDirectoryError.NO_SUCH_OBJECT ("No such object"));
+ return;
+ }
+
+ var container = (MediaContainer) media_object;
+ this.total_matches = container.child_count;
+ if (this.requested_count == 0) {
+ // No max count requested, try to fetch all children
+ this.requested_count = this.total_matches;
+ }
+
+ var children = container.get_children (this.index,
+ this.requested_count);
+ if (children == null) {
+ this.handle_error (
+ new ContentDirectoryError.NO_SUCH_OBJECT ("No such object"));
+ return;
+ }
+
+ /* serialize all children */
+ for (int i = 0; i < children.size; i++) {
+ try {
+ children[i].serialize (didl_writer);
+ } catch (Error err) {
+ this.handle_error (err);
+ return;
+ }
+ }
+
+ this.update_id = ((MediaContainer) media_object).update_id;
+ this.number_returned = children.size;
+
+ // Conclude the successful Browse action
+ this.conclude ();
+ }
+
+ private bool parse_args () {
+ this.action.get ("ObjectID", typeof (string), out this.object_id,
+ "BrowseFlag", typeof (string), out this.browse_flag,
+ "Filter", typeof (string), out this.filter,
+ "StartingIndex", typeof (uint), out this.index,
+ "RequestedCount", typeof (uint), out this.requested_count,
+ "SortCriteria", typeof (string), out this.sort_criteria);
+
+ /* BrowseFlag */
+ bool metadata = false;
+ if (this.browse_flag != null &&
+ this.browse_flag == "BrowseDirectChildren") {
+ metadata = false;
+ } else if (this.browse_flag != null &&
+ this.browse_flag == "BrowseMetadata") {
+ metadata = true;
+ } else {
+ this.handle_error (
+ new ContentDirectoryError.INVALID_ARGS ("Invalid Args"));
+ }
+
+ /* ObjectID */
+ if (this.object_id == null) {
+ /* Stupid Xbox */
+ this.action.get ("ContainerID",
+ typeof (string),
+ out this.object_id);
+ }
+
+ if (this.object_id == null) {
+ // Sorry we can't do anything without ObjectID
+ this.handle_error (
+ new ContentDirectoryError.NO_SUCH_OBJECT ("No such object"));
+ }
+
+ return metadata;
+ }
+
+ private void conclude () {
+ /* End DIDL-Lite fragment */
+ this.didl_writer.end_didl_lite ();
+
+ /* Retrieve generated string */
+ string didl = this.didl_writer.get_string ();
+
+ if (this.update_id == uint32.MAX) {
+ this.update_id = this.content_dir.root_container.update_id;
+ }
+
+ /* Set action return arguments */
+ this.action.set ("Result", typeof (string), didl,
+ "NumberReturned", typeof (uint), this.number_returned,
+ "TotalMatches", typeof (uint), this.total_matches,
+ "UpdateID", typeof (uint), this.update_id);
+
+ this.action.return ();
+ this.completed ();
+ }
+
+ private void handle_error (Error error) {
+ if (error is ContentDirectoryError) {
+ warning ("Failed to browse '%s': %s\n",
+ this.object_id,
+ error.message);
+ this.action.return_error (error.code, error.message);
+ } else {
+ warning ("Failed to browse '%s': %s\n",
+ this.object_id,
+ error.message);
+ this.action.return_error (701, error.message);
+ }
+
+ this.completed ();
+ }
+}
+
Modified: trunk/src/rygel/rygel-content-directory.vala
==============================================================================
--- trunk/src/rygel/rygel-content-directory.vala (original)
+++ trunk/src/rygel/rygel-content-directory.vala Mon Feb 9 22:26:56 2009
@@ -33,21 +33,6 @@
INVALID_ARGS = 402
}
-public class BrowseArgs {
- // In arguments
- public string object_id;
- public string browse_flag;
- public string filter;
- public uint index; // Starting index
- public uint requested_count;
- public string sort_criteria;
-
- // Out arguments
- public uint number_returned;
- public uint total_matches;
- public uint update_id;
-}
-
/**
* Basic implementation of UPnP ContentDirectory service version 2. Most often
* plugins will provide a child of this class. The inheriting classes should
@@ -59,17 +44,15 @@
"urn:schemas-upnp-org:service:ContentDirectory:2";
public const string DESCRIPTION_PATH = "xml/ContentDirectory.xml";
- public const int MAX_REQUESTED_COUNT = 128;
-
protected string feature_list;
protected string search_caps;
protected string sort_caps;
protected HTTPServer http_server;
- protected MediaContainer root_container;
+ public MediaContainer root_container;
- DIDLLiteWriter didl_writer;
+ private ArrayList<Browse> browses;
// Public abstract methods derived classes need to implement
public virtual MediaContainer? create_root_container () {
@@ -77,10 +60,11 @@
}
public override void constructed () {
- this.didl_writer = new DIDLLiteWriter ();
this.http_server = new HTTPServer (context, this.get_type ().name ());
this.root_container = this.create_root_container ();
+ this.browses = new ArrayList<Browse> ();
+
this.http_server.item_requested += this.on_item_requested;
this.feature_list =
@@ -121,50 +105,28 @@
this.http_server.destroy ();
}
- /* Browse action implementation */
- protected virtual void browse_cb (ContentDirectory content_dir,
- owned ServiceAction action) {
- bool metadata;
-
- BrowseArgs args = new BrowseArgs ();
-
- /* Start DIDL-Lite fragment */
- this.didl_writer.start_didl_lite (null, null, true);
-
- try {
- /* Handle incoming arguments */
- metadata = this.parse_browse_args (action, args);
+ public MediaObject find_object_by_id (string object_id) throws GLib.Error {
+ if (object_id == this.root_container.id) {
+ return this.root_container;
+ }
- if (metadata) {
- // BrowseMetadata
- this.browse_metadata (args);
- } else {
- // BrowseDirectChildren
- this.browse_direct_children (args);
- }
+ var media_object = this.root_container.find_object_by_id (object_id);
+ if (media_object == null) {
+ throw new ContentDirectoryError.NO_SUCH_OBJECT ("No such object");
+ }
- /* End DIDL-Lite fragment */
- this.didl_writer.end_didl_lite ();
+ return media_object;
+ }
- /* Retrieve generated string */
- string didl = this.didl_writer.get_string ();
+ /* Browse action implementation */
+ protected virtual void browse_cb (ContentDirectory content_dir,
+ owned ServiceAction action) {
+ Browse browse = new Browse (this, action);
- // Conclude the successful Browse action
- conclude_browse (action, didl, args);
- } catch (ContentDirectoryError error) {
- warning ("Failed to browse '%s': %s\n",
- args.object_id,
- error.message);
- action.return_error (error.code, error.message);
- } catch (Error error) {
- warning ("Failed to browse '%s': %s\n",
- args.object_id,
- error.message);
- action.return_error (701, error.message);
- }
+ this.browses.add (browse);
+ browse.completed += this.on_browse_completed;
- /* Reset the parser state */
- this.didl_writer.reset ();
+ browse.start ();
}
/* GetSystemUpdateID action implementation */
@@ -239,130 +201,8 @@
value.set_string (this.feature_list);
}
- private void browse_metadata (BrowseArgs args) throws Error {
- MediaObject media_object = this.find_object_by_id (args.object_id);
-
- media_object.serialize (didl_writer);
-
- if (media_object is MediaContainer) {
- args.update_id = ((MediaContainer) media_object).update_id;
- } else {
- args.update_id = uint32.MAX;
- }
-
- args.number_returned = 1;
- args.total_matches = 1;
- }
-
- private void browse_direct_children (BrowseArgs args) throws Error {
- if (args.requested_count == 0)
- args.requested_count = MAX_REQUESTED_COUNT;
-
- Gee.List<MediaObject> children;
-
- children = this.get_children (args.object_id,
- args.index,
- args.requested_count,
- out args.total_matches,
- out args.update_id);
- /* Iterate through all items */
- for (int i = 0; i < children.size; i++) {
- children[i].serialize (didl_writer);
- }
-
- args.number_returned = children.size;
- }
-
- private bool parse_browse_args (ServiceAction action,
- BrowseArgs args) throws Error {
- action.get ("ObjectID", typeof (string), out args.object_id,
- "BrowseFlag", typeof (string), out args.browse_flag,
- "Filter", typeof (string), out args.filter,
- "StartingIndex", typeof (uint), out args.index,
- "RequestedCount", typeof (uint), out args.requested_count,
- "SortCriteria", typeof (string), out args.sort_criteria);
-
- /* BrowseFlag */
- bool metadata;
- if (args.browse_flag != null &&
- args.browse_flag == "BrowseDirectChildren") {
- metadata = false;
- } else if (args.browse_flag != null &&
- args.browse_flag == "BrowseMetadata") {
- metadata = true;
- } else {
- throw new ContentDirectoryError.INVALID_ARGS ("Invalid Args");
- }
-
- /* ObjectID */
- if (args.object_id == null) {
- /* Stupid Xbox */
- action.get ("ContainerID", typeof (string), out args.object_id);
- }
-
- if (args.object_id == null) {
- // Sorry we can't do anything without ObjectID
- throw new ContentDirectoryError.NO_SUCH_OBJECT ("No such object");
- }
-
- return metadata;
- }
-
- private void conclude_browse (ServiceAction action,
- string didl,
- BrowseArgs args) {
- if (args.update_id == uint32.MAX) {
- args.update_id = this.root_container.update_id;
- }
-
- /* Set action return arguments */
- action.set ("Result", typeof (string), didl,
- "NumberReturned", typeof (uint), args.number_returned,
- "TotalMatches", typeof (uint), args.total_matches,
- "UpdateID", typeof (uint), args.update_id);
-
- action.return ();
- }
-
- private Gee.List<MediaObject> get_children (string container_id,
- uint offset,
- uint max_count,
- out uint child_count,
- out uint update_id)
- throws GLib.Error {
- var media_object = this.find_object_by_id (container_id);
- if (!(media_object is MediaContainer)) {
- throw new ContentDirectoryError.NO_SUCH_OBJECT ("No such object");
- }
-
- var container = (MediaContainer) media_object;
- child_count = container.child_count;
- if (max_count == 0) {
- // No max count requested, try to fetch all children
- max_count = child_count;
- }
-
- var children = container.get_children (offset, max_count);
- if (children == null) {
- throw new ContentDirectoryError.NO_SUCH_OBJECT ("No such object");
- }
-
- update_id = ((MediaContainer) media_object).update_id;
-
- return children;
- }
-
- private MediaObject find_object_by_id (string object_id) throws GLib.Error {
- if (object_id == this.root_container.id) {
- return this.root_container;
- }
-
- var media_object = this.root_container.find_object_by_id (object_id);
- if (media_object == null) {
- throw new ContentDirectoryError.NO_SUCH_OBJECT ("No such object");
- }
-
- return media_object;
+ private void on_browse_completed (Browse browse) {
+ this.browses.remove (browse);
}
private void on_item_requested (HTTPServer http_server,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]