[libdmapsharing] Implement databases_items_xxx in DPAPShare Signed-off-by: W. Michael Petullo <mike flyn org>



commit da4d48a78842aa848c0377e4577b6c970baead4b
Author: W. Michael Petullo <mike flyn org>
Date:   Tue Dec 14 10:07:16 2010 -0600

    Implement databases_items_xxx in DPAPShare
    Signed-off-by: W. Michael Petullo <mike flyn org>

 libdmapsharing/Makefile.am  |    1 +
 libdmapsharing/daap-share.c |   52 ++-------------------------------
 libdmapsharing/dmap-share.h |    1 -
 libdmapsharing/dmap-utils.h |    9 ++++++
 libdmapsharing/dpap-share.c |   66 ++++++++++++++++++++++++++++++++++++++++++-
 5 files changed, 79 insertions(+), 50 deletions(-)
---
diff --git a/libdmapsharing/Makefile.am b/libdmapsharing/Makefile.am
index cdb89a9..5704203 100644
--- a/libdmapsharing/Makefile.am
+++ b/libdmapsharing/Makefile.am
@@ -18,6 +18,7 @@ libdmapsharing_la_SOURCES = \
 	dmap-record-factory.c \
 	dmap-share.c \
 	dmap-structure.c \
+	dmap-utils.c \
 	dpap-connection.c \
 	dpap-record.c \
 	dpap-share.c
diff --git a/libdmapsharing/daap-share.c b/libdmapsharing/daap-share.c
index 903f587..b35a608 100644
--- a/libdmapsharing/daap-share.c
+++ b/libdmapsharing/daap-share.c
@@ -38,6 +38,7 @@
 
 #include <libdmapsharing/dmap.h>
 #include <libdmapsharing/dmap-structure.h>
+#include <libdmapsharing/dmap-utils.h>
 
 #ifdef HAVE_GSTREAMERAPP
 #include <libdmapsharing/g-gst-mp3-input-stream.h>
@@ -93,13 +94,6 @@ enum {
 	PROP_0,
 };
 
-/* Provide two items as user_data to callback. */
-typedef struct ChunkData {
-	SoupServer *server;
-	GInputStream *stream;
-} ChunkData;
-
-
 G_DEFINE_TYPE (DAAPShare, daap_share, TYPE_DMAP_SHARE)
 
 /* FIXME: get rid of this global: */
@@ -400,44 +394,6 @@ static struct DMAPMetaDataMap meta_data_map[] = {
 #define DAAP_SONG_DATA_KIND_NONE 0
 
 static void
-write_next_chunk (SoupMessage *message, ChunkData *cd)
-{
-	gssize read_size;
-	GError *error = NULL;
-	gchar *chunk = g_malloc (DMAP_SHARE_CHUNK_SIZE);
-
-	read_size = g_input_stream_read (cd->stream,
-					 chunk,
-					 DMAP_SHARE_CHUNK_SIZE,
-					 NULL,
-					 &error);
-	if (read_size > 0) {
-		soup_message_body_append (message->response_body,
-					  SOUP_MEMORY_TAKE,
-					  chunk,
-					  read_size);
-	} else {
-		if (error != NULL) {
-			g_warning ("Error reading from input stream: %s",
-				   error->message);
-			g_error_free (error);
-		}
-		g_free (chunk);
-		g_debug ("Wrote 0 bytes, sending message complete.");
-		soup_message_body_complete (message->response_body);
-	}
-	soup_server_unpause_message (cd->server, message);
-}
-
-static void
-chunked_message_finished (SoupMessage *message, ChunkData *cd)
-{
-	g_debug ("Finished sending chunked file.");
-	g_input_stream_close (cd->stream, NULL, NULL);
-	g_free (cd);
-}
-
-static void
 send_chunked_file (SoupServer *server, SoupMessage *message, DAAPRecord *record, guint64 filesize, guint64 offset, const gchar *transcode_mimetype)
 {
 	GInputStream *stream;
@@ -536,9 +492,9 @@ send_chunked_file (SoupServer *server, SoupMessage *message, DAAPRecord *record,
 	soup_message_headers_append (message->response_headers, "Connection", "Close");
 	soup_message_headers_append (message->response_headers, "Content-Type", "application/x-dmap-tagged");
 
-	g_signal_connect (message, "wrote_headers", G_CALLBACK (write_next_chunk), cd);
-	g_signal_connect (message, "wrote_chunk", G_CALLBACK (write_next_chunk), cd);
-	g_signal_connect (message, "finished", G_CALLBACK (chunked_message_finished), cd);
+	g_signal_connect (message, "wrote_headers", G_CALLBACK (dmap_write_next_chunk), cd);
+	g_signal_connect (message, "wrote_chunk", G_CALLBACK (dmap_write_next_chunk), cd);
+	g_signal_connect (message, "finished", G_CALLBACK (dmap_chunked_message_finished), cd);
 	/* NOTE: cd g_free'd by chunked_message_finished(). */
 }
 
diff --git a/libdmapsharing/dmap-share.h b/libdmapsharing/dmap-share.h
index 947150b..a442f1d 100644
--- a/libdmapsharing/dmap-share.h
+++ b/libdmapsharing/dmap-share.h
@@ -91,7 +91,6 @@ G_BEGIN_DECLS
 #define DMAP_SHARE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), \
 				 TYPE_DMAP_SHARE, DMAPShareClass))
 
-#define DMAP_SHARE_CHUNK_SIZE 16384
 #define DMAP_STATUS_OK 200
 
 typedef struct DMAPSharePrivate DMAPSharePrivate;
diff --git a/libdmapsharing/dmap-utils.h b/libdmapsharing/dmap-utils.h
index 6cc8df4..5ec7065 100644
--- a/libdmapsharing/dmap-utils.h
+++ b/libdmapsharing/dmap-utils.h
@@ -21,6 +21,7 @@
 #define __DMAP_UTILS_H__
 
 #include <glib.h>
+#include <libsoup/soup.h>
 
 #include <libdmapsharing/dmap-config.h>
 
@@ -62,6 +63,14 @@ G_BEGIN_DECLS
 
 #endif
 
+typedef struct ChunkData {
+	SoupServer *server;
+	GInputStream *stream;
+} ChunkData;
+
+void dmap_write_next_chunk (SoupMessage *message, ChunkData *cd);
+void dmap_chunked_message_finished (SoupMessage *message, ChunkData *cd);
+
 G_END_DECLS
 
 #endif
diff --git a/libdmapsharing/dpap-share.c b/libdmapsharing/dpap-share.c
index 4fc3135..4aaf25d 100644
--- a/libdmapsharing/dpap-share.c
+++ b/libdmapsharing/dpap-share.c
@@ -44,6 +44,7 @@
 #include <libsoup/soup-server.h>
 
 #include <libdmapsharing/dmap.h>
+#include <libdmapsharing/dmap-utils.h>
 #include <libdmapsharing/dmap-structure.h>
 
 static void dpap_share_set_property  (GObject *object,
@@ -486,6 +487,48 @@ databases_browse_xxx (DMAPShare *share,
 }
 
 static void
+send_chunked_file (SoupServer *server, SoupMessage *message, DPAPRecord *record, guint64 filesize)
+{
+	GInputStream *stream;
+	const char *location;
+	GError *error = NULL;
+	ChunkData *cd = g_new (ChunkData, 1);
+
+	g_object_get (record, "location", &location, NULL);
+
+	cd->server = server;
+
+	stream = G_INPUT_STREAM (dpap_record_read (record, &error));
+
+	if (error != NULL) {
+		g_warning ("Couldn't open %s: %s.", location, error->message);
+		g_error_free (error);
+		soup_message_set_status (message, SOUP_STATUS_INTERNAL_SERVER_ERROR);
+		g_free (cd);
+		return;
+	}
+
+	cd->stream = stream;
+
+	if (cd->stream == NULL) {
+		g_warning ("Could not set up input stream");
+		g_free (cd);
+		return;
+	}
+
+	soup_message_headers_set_encoding (message->response_headers, SOUP_ENCODING_CONTENT_LENGTH);
+	soup_message_headers_set_content_length (message->response_headers, filesize);
+
+	soup_message_headers_append (message->response_headers, "Connection", "Close");
+	soup_message_headers_append (message->response_headers, "Content-Type", "application/x-dmap-tagged");
+
+	g_signal_connect (message, "wrote_headers", G_CALLBACK (dmap_write_next_chunk), cd);
+	g_signal_connect (message, "wrote_chunk", G_CALLBACK (dmap_write_next_chunk), cd);
+	g_signal_connect (message, "finished", G_CALLBACK (dmap_chunked_message_finished), cd);
+	/* NOTE: cd g_free'd by chunked_message_finished(). */
+}
+
+static void
 databases_items_xxx  (DMAPShare *share,
                       SoupServer *server,
                       SoupMessage *msg,
@@ -493,7 +536,28 @@ databases_items_xxx  (DMAPShare *share,
                       GHashTable *query,
                       SoupClientContext *context)
 {
-	g_warning ("Unhandled: %s\n", path);
+	DMAPDb *db;
+	const gchar *rest_of_path;
+	const gchar *id_str;
+	guint id;
+	guint64 filesize;
+	DPAPRecord *record;
+
+	rest_of_path = strchr (path + 1, '/');
+	id_str = rest_of_path + 9;
+	id = strtoul (id_str, NULL, 10);
+
+	g_object_get (share, "db", &db, NULL);
+	record = DPAP_RECORD (dmap_db_lookup_by_id (db, id));
+	g_object_get (record, "large-filesize", &filesize, NULL);
+
+	DMAP_SHARE_GET_CLASS (share)->message_add_standard_headers
+				(share, msg);
+	soup_message_set_status (msg, SOUP_STATUS_OK);
+
+	send_chunked_file (server, msg, record, filesize);
+	
+	g_object_unref (record);
 }
 
 static struct DMAPMetaDataMap *



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