Add Streamer and Stream classes.
authorZeeshan Ali (Khattak) <zeeshanak@src.gnome.org>
Sun, 14 Dec 2008 20:21:08 +0000 (20:21 +0000)
committerZeeshan Ali (Khattak) <zeeshanak@src.gnome.org>
Sun, 14 Dec 2008 20:21:08 +0000 (20:21 +0000)
New classes for rygel and plugins to be able to stream data from sources
other than files on disk.

svn path=/trunk/; revision=330

src/rygel/Makefile.am
src/rygel/rygel-stream.vala [new file with mode: 0644]
src/rygel/rygel-streamer.vala [new file with mode: 0644]

index 9edc20f..8d12de5 100644 (file)
@@ -35,6 +35,10 @@ BUILT_SOURCES = rygel-1.0.vapi \
                rygel-plugin.c \
                rygel-plugin-loader.h \
                rygel-plugin-loader.c \
+                rygel-streamer.c \
+                rygel-streamer.h \
+                rygel-stream.c \
+                rygel-stream.h \
                rygel-resource-info.h \
                rygel-resource-info.c \
                rygel-icon-info.h \
@@ -69,6 +73,10 @@ rygel_SOURCES = rygel-1.0.vapi \
                rygel-plugin-loader.h \
                rygel-plugin-loader.c \
                rygel-plugin-loader.vala \
+                rygel-streamer.c \
+                rygel-streamer.h \
+                rygel-stream.c \
+                rygel-stream.h \
                rygel-resource-info.h \
                rygel-resource-info.c \
                rygel-icon-info.h \
@@ -106,6 +114,8 @@ VAPI_FILES = rygel-1.0.vapi
 rygel-1.0.vapi: rygel-content-directory.vala \
                rygel-connection-manager.vala \
                rygel-media-receiver-registrar.vala \
+                rygel-streamer.vala \
+                rygel-stream.vala \
                rygel-resource-info.vala \
                rygel-icon-info.vala \
                rygel-plugin.vala \
diff --git a/src/rygel/rygel-stream.vala b/src/rygel/rygel-stream.vala
new file mode 100644 (file)
index 0000000..f3c56ac
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2008 Nokia Corporation, all rights reserved.
+ *
+ * Author: Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
+ *                               <zeeshan.ali@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ */
+
+public class Rygel.Stream : GLib.Object {
+    public Soup.Server server { get; private set; }
+    private Soup.Message msg;
+
+    public signal void eos ();
+
+    public Stream (Soup.Server server, Soup.Message msg) {
+        this.server = server;
+        this.msg = msg;
+
+        this.msg.response_headers.set_encoding (Soup.Encoding.CHUNKED);
+
+        this.server.request_aborted += on_request_aborted;
+    }
+
+    private void on_request_aborted (Soup.Server        server,
+                                     Soup.Message       msg,
+                                     Soup.ClientContext client) {
+        this.eos ();
+    }
+
+    public void push_data (void *data, size_t length) {
+        this.msg.response_body.append (Soup.MemoryUse.COPY,
+                                       data,
+                                       length);
+
+        this.server.unpause_message (this.msg);
+    }
+
+    public void end () {
+        this.msg.response_body.complete ();
+
+        this.eos ();
+    }
+}
+
diff --git a/src/rygel/rygel-streamer.vala b/src/rygel/rygel-streamer.vala
new file mode 100644 (file)
index 0000000..989163b
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2008 Nokia Corporation, all rights reserved.
+ *
+ * Author: Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
+ *                               <zeeshan.ali@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ */
+
+using Gee;
+
+public class Rygel.Streamer : GUPnP.Context {
+    public const string SERVER_PATH_ROOT = "/RygelStreamer";
+
+    /* Mapping of hosted_paths to mimetypes */
+    private HashMap<string,string> path_hash;
+
+    public signal void stream_available (Rygel.Stream stream,
+                                         string       path);
+
+    public Streamer (string host_ip,
+                     uint   port) {
+        this.host_ip = host_ip;
+        this.port = port;
+
+        this.path_hash = new HashMap<string,string> (str_hash, str_equal);
+
+        this.server.add_handler (SERVER_PATH_ROOT, server_handler);
+    }
+
+    public void add_stream_candidate (string path,
+                                      string mimetype) {
+        this.path_hash.set (path, mimetype);
+    }
+
+    private void server_handler (Soup.Server        server,
+                                 Soup.Message       msg,
+                                 string             server_path,
+                                 HashTable?         query,
+                                 Soup.ClientContext soup_client) {
+        string[] path_tokens = server_path.split (SERVER_PATH_ROOT, 2);
+        if (path_tokens[0] == null || path_tokens[1] == null) {
+            msg.set_status (Soup.KnownStatusCode.NOT_FOUND);
+            return;
+        }
+
+        string stream_path = path_tokens[1];
+        string mimetype = this.path_hash.get (stream_path);
+        if (mimetype == null) {
+            msg.set_status (Soup.KnownStatusCode.NOT_FOUND);
+            return;
+        }
+
+        msg.set_status (Soup.KnownStatusCode.OK);
+        msg.response_headers.append ("Content-Type", mimetype);
+
+        var stream = new Stream (server, msg);
+
+        this.stream_available (stream, stream_path);
+    }
+}
+