[libdmapsharing] Implement DAAPConnection and DPAPConnection, add test program written in Vala Signed-off-by: W. Mich
- From: W. Michael Petullo <wmpetullo src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libdmapsharing] Implement DAAPConnection and DPAPConnection, add test program written in Vala Signed-off-by: W. Mich
- Date: Fri, 10 Dec 2010 17:56:44 +0000 (UTC)
commit 0e7b8dffaebdab601732fb8ab9173d105f49560d
Author: W. Michael Petullo <mike flyn org>
Date: Fri Dec 10 11:55:15 2010 -0600
Implement DAAPConnection and DPAPConnection, add test program written in Vala
Signed-off-by: W. Michael Petullo <mike flyn org>
.gitignore | 2 +
Makefile.am | 1 +
configure.ac | 22 +++
libdmapsharing-2.2.vapi | 331 ++++++++++++++++++++++++++++++++++++++
libdmapsharing/Makefile.am | 4 +
libdmapsharing/daap-connection.c | 195 ++++++++++++++++++++++
libdmapsharing/daap-connection.h | 96 +++++++++++
libdmapsharing/dmap-connection.c | 169 +++++--------------
libdmapsharing/dmap-connection.h | 10 +-
libdmapsharing/dmap-structure.c | 16 --
libdmapsharing/dpap-connection.c | 183 +++++++++++++++++++++
libdmapsharing/dpap-connection.h | 96 +++++++++++
tests/Makefile.am | 39 +++++-
tests/dpapview.ui | 31 ++++
tests/dpapview.vala | 226 ++++++++++++++++++++++++++
tests/test-daap-record.c | 6 +-
tests/test-dmap-client.c | 4 +-
17 files changed, 1282 insertions(+), 149 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 54f0292..7f3ee1e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -53,5 +53,7 @@ tests/.libs/
tests/Makefile
tests/Makefile.in
tests/*.o
+tests/dpapview
tests/test-dmap-client
tests/test-dmap-server
+tests/vala.stamp
diff --git a/Makefile.am b/Makefile.am
index 3a1498e..2148dea 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -17,6 +17,7 @@ pkgconfig_DATA = $(pcfiles)
EXTRA_DIST = \
autogen.sh \
+ libdmapsharing-2.2.vapi \
libdmapsharing.pc.in \
README-Memory
diff --git a/configure.ac b/configure.ac
index 3780215..58a941d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -326,6 +326,28 @@ else
AC_WARN(GStreamer app element not present, transcoding will not be supported.)
fi
+AM_MAINTAINER_MODE
+if test "x$USE_MAINTAINER_MODE" = "xyes" ; then
+ AM_PROG_VALAC([0.10.0])
+ if test "x$VALAC" = "x" ; then
+ AC_MSG_ERROR([Cannot find the "valac" compiler in your PATH])
+ fi
+fi
+
+PKG_CHECK_MODULES(GTK, gtk+-2.0, HAVE_GTK=yes, HAVE_GTK=no)
+if test "x$HAVE_GTK" = "xno"; then
+ AC_MSG_ERROR(you need gtk+-2.0 installed)
+fi
+AC_SUBST(GTK_CFLAGS)
+AC_SUBST(GTK_LIBS)
+
+PKG_CHECK_MODULES(GEE, gee-1.0, HAVE_GEE=yes, HAVE_GEE=no)
+if test "x$HAVE_GEE" = "xno"; then
+ AC_MSG_ERROR(you need gee-1.0 installed)
+fi
+AC_SUBST(GEE_CFLAGS)
+AC_SUBST(GEE_LIBS)
+
AM_CONDITIONAL(USE_GSTREAMERAPP, test x"$HAVE_GSTREAMERAPP" = "xyes")
AC_SUBST(GSTREAMERAPP_CFLAGS)
diff --git a/libdmapsharing-2.2.vapi b/libdmapsharing-2.2.vapi
new file mode 100644
index 0000000..d264112
--- /dev/null
+++ b/libdmapsharing-2.2.vapi
@@ -0,0 +1,331 @@
+/* libdmapsharing-2.2.vapi generated by vapigen, do not modify. */
+
+[CCode (cprefix = "DMAP", lower_case_cprefix = "dmap_")]
+namespace DMAP {
+ [CCode (cheader_filename = "libdmapsharing/dmap.h")]
+ public class Connection : GLib.Object {
+ [CCode (has_construct_function = false)]
+ public Connection (string name, string host, int port, bool password_protected, DMAP.Db db, DMAP.RecordFactory factory);
+ public virtual unowned Soup.Message build_message (string path, bool need_hash, double version, int req_id, bool send_close);
+ public void connect (DMAP.ConnectionCallback callback);
+ public void disconnect (DMAP.ConnectionCallback callback);
+ public bool @get (string path, bool need_hash, DMAP.ResponseHandler handler);
+ public unowned Soup.MessageHeaders get_headers (string uri);
+ public unowned GLib.SList get_playlists ();
+ public bool is_connected ();
+ public void setup ();
+ [NoAccessorMethod]
+ public void* base_uri { get; set; }
+ [NoAccessorMethod]
+ public int database_id { get; set; }
+ [NoAccessorMethod]
+ public void* db { get; construct; }
+ [NoAccessorMethod]
+ public double dmap_version { get; set; }
+ [NoAccessorMethod]
+ public void* factory { get; construct; }
+ [NoAccessorMethod]
+ public string host { owned get; construct; }
+ [NoAccessorMethod]
+ public string name { owned get; construct; }
+ [NoAccessorMethod]
+ public bool password_protected { get; construct; }
+ [NoAccessorMethod]
+ public uint port { get; construct; }
+ [NoAccessorMethod]
+ public int revision_number { get; set; }
+ [NoAccessorMethod]
+ public int session_id { get; set; }
+ public virtual signal unowned string authenticate (string name);
+ public virtual signal void connected ();
+ public virtual signal void connecting (ulong state, float progress);
+ public virtual signal void disconnected ();
+ public virtual signal void operation_done ();
+ }
+ [CCode (cheader_filename = "libdmapsharing/dmap.h")]
+ public class DACPShare : DAAP.Share {
+ [CCode (cname = "dacp_share_new", type = "DACPShare*", has_construct_function = false)]
+ public DACPShare (string library_name, DMAP.DACPPlayer player, DMAP.Db db, DMAP.ContainerDb container_db);
+ [CCode (cname = "dacp_share_pair")]
+ public static void pair (DMAP.DACPShare share, string service_name, char[] passcode);
+ [CCode (cname = "dacp_share_player_updated")]
+ public static void player_updated (DMAP.DACPShare share);
+ [CCode (cname = "dacp_share_start_lookup")]
+ public static void start_lookup (DMAP.DACPShare share);
+ [CCode (cname = "dacp_share_stop_lookup")]
+ public static void stop_lookup (DMAP.DACPShare share);
+ [NoAccessorMethod]
+ public string library_name { owned get; set; }
+ [NoAccessorMethod]
+ public GLib.Object player { owned get; construct; }
+ public virtual signal void add_guid (string guid);
+ public virtual signal bool lookup_guid (string guid);
+ public virtual signal void remote_found (string service_name, string remote_name);
+ public virtual signal void remote_lost (string service_name);
+ public virtual signal void remote_paired (string service_name, bool connected);
+ }
+ [CCode (cheader_filename = "libdmapsharing/dmap.h")]
+ public class DmapMdnsPublisher : GLib.Object {
+ [CCode (cname = "dmap_mdns_publisher_new", type = "DmapMdnsPublisher*", has_construct_function = false)]
+ public DmapMdnsPublisher ();
+ [CCode (cname = "dmap_mdns_publisher_error_quark")]
+ public static GLib.Quark error_quark ();
+ [CCode (cname = "dmap_mdns_publisher_publish")]
+ public static bool publish (DMAP.DmapMdnsPublisher publisher, string name, uint port, string type_of_service, bool password_required, string txt_records) throws GLib.Error;
+ [CCode (cname = "dmap_mdns_publisher_rename_at_port")]
+ public static bool rename_at_port (DMAP.DmapMdnsPublisher publisher, uint port, string name) throws GLib.Error;
+ [CCode (cname = "dmap_mdns_publisher_withdraw")]
+ public static bool withdraw (DMAP.DmapMdnsPublisher publisher, uint port) throws GLib.Error;
+ public virtual signal void name_collision (string name);
+ public virtual signal void published (string name);
+ }
+ [Compact]
+ [CCode (cheader_filename = "libdmapsharing/dmap.h")]
+ public class FilterDefinition {
+ public weak string key;
+ public bool negate;
+ public weak string value;
+ }
+ [CCode (cheader_filename = "libdmapsharing/dmap.h")]
+ public class MdnsBrowser : GLib.Object {
+ [CCode (has_construct_function = false)]
+ public MdnsBrowser (DMAP.MdnsBrowserServiceType type);
+ public static GLib.Quark error_quark ();
+ public DMAP.MdnsBrowserServiceType get_service_type ();
+ public unowned GLib.SList get_services ();
+ public bool start () throws GLib.Error;
+ public bool stop () throws GLib.Error;
+ public virtual signal void service_added (void* service);
+ public virtual signal void service_removed (string service);
+ }
+ [Compact]
+ [CCode (cheader_filename = "libdmapsharing/dmap.h")]
+ public class MdnsBrowserService {
+ public weak string host;
+ public weak string name;
+ public weak string pair;
+ public bool password_protected;
+ public uint port;
+ public weak string service_name;
+ }
+ [Compact]
+ [CCode (cheader_filename = "libdmapsharing/dmap.h")]
+ public class MetaDataMap {
+ }
+ [Compact]
+ [CCode (cheader_filename = "libdmapsharing/dmap.h")]
+ public class Playlist {
+ public int id;
+ public weak string name;
+ public weak GLib.List uris;
+ }
+ [CCode (cheader_filename = "libdmapsharing/dmap.h")]
+ public class Share : GLib.Object {
+ [CCode (has_construct_function = false)]
+ protected Share ();
+ [NoWrapper]
+ public virtual void add_entry_to_mlcl (void* id, DMAP.Record record, void* mb);
+ [NoWrapper]
+ public virtual void content_codes (Soup.Server server, Soup.Message message, string path, GLib.HashTable query, Soup.ClientContext ctx);
+ [NoWrapper]
+ public virtual void ctrl_int (Soup.Server server, Soup.Message message, string path, GLib.HashTable query, Soup.ClientContext ctx);
+ [NoWrapper]
+ public virtual void databases (Soup.Server server, Soup.Message message, string path, GLib.HashTable query, Soup.ClientContext context);
+ [NoWrapper]
+ public virtual void databases_browse_xxx (Soup.Server server, Soup.Message msg, string path, GLib.HashTable query, Soup.ClientContext context);
+ [NoWrapper]
+ public virtual void databases_items_xxx (Soup.Server server, Soup.Message msg, string path, GLib.HashTable query, Soup.ClientContext context);
+ public static void free_filter (GLib.SList filter);
+ [NoWrapper]
+ public virtual uint get_desired_port ();
+ [NoWrapper]
+ public virtual void* get_meta_data_map ();
+ [NoWrapper]
+ public virtual unowned string get_type_of_service ();
+ [NoWrapper]
+ public virtual void login (Soup.Server server, Soup.Message message, string path, GLib.HashTable query, Soup.ClientContext ctx);
+ [NoWrapper]
+ public virtual void logout (Soup.Server server, Soup.Message message, string path, GLib.HashTable query, Soup.ClientContext ctx);
+ [NoWrapper]
+ public virtual void message_add_standard_headers (Soup.Message msg);
+ [NoWrapper]
+ public virtual void name_collision (DMAP.DmapMdnsPublisher publisher, string name);
+ [NoWrapper]
+ public virtual void published (DMAP.DmapMdnsPublisher publisher, string name);
+ [NoWrapper]
+ public virtual void server_info (Soup.Server server, Soup.Message message, string path, GLib.HashTable query, Soup.ClientContext ctx);
+ [NoWrapper]
+ public virtual void update (Soup.Server server, Soup.Message message, string path, GLib.HashTable query, Soup.ClientContext ctx);
+ [NoAccessorMethod]
+ public uint auth_method { get; set; }
+ [NoAccessorMethod]
+ public void* container_db { get; construct; }
+ [NoAccessorMethod]
+ public void* db { get; construct; }
+ [NoAccessorMethod]
+ public string name { owned get; set; }
+ [NoAccessorMethod]
+ public string password { owned get; set; }
+ [NoAccessorMethod]
+ public uint revision_number { get; set; }
+ [NoAccessorMethod]
+ public Soup.Server server { owned get; }
+ [NoAccessorMethod]
+ public string transcode_mimetype { owned get; construct; }
+ [NoAccessorMethod]
+ [CCode (array_length = false, array_null_terminated = true)]
+ public string[] txt_records { owned get; set; }
+ }
+ [Compact]
+ [CCode (cheader_filename = "libdmapsharing/dmap.h")]
+ public class bitwise {
+ }
+ [CCode (cheader_filename = "libdmapsharing/dmap.h")]
+ public interface ContainerDb {
+ public abstract int64 count ();
+ public abstract void @foreach (GLib.HFunc func, void* data);
+ public abstract unowned DMAP.ContainerRecord lookup_by_id (uint id);
+ }
+ [CCode (cheader_filename = "libdmapsharing/dmap.h")]
+ public interface ContainerRecord {
+ public abstract void add_entry (DMAP.Record record, int id);
+ public abstract unowned DMAP.Db get_entries ();
+ public abstract uint64 get_entry_count ();
+ public abstract uint get_id ();
+ }
+ [CCode (cheader_filename = "libdmapsharing/dmap.h")]
+ public interface DACPPlayer {
+ [CCode (cname = "dacp_player_cue_clear")]
+ public abstract void cue_clear (DMAP.DACPPlayer player);
+ [CCode (cname = "dacp_player_cue_play")]
+ public abstract void cue_play (DMAP.DACPPlayer player, GLib.List records, uint index);
+ [CCode (cname = "dacp_player_next_item")]
+ public abstract void next_item (DMAP.DACPPlayer player);
+ [CCode (cname = "dacp_player_now_playing_artwork")]
+ public abstract unowned string now_playing_artwork (DMAP.DACPPlayer player, uint width, uint height);
+ [CCode (cname = "dacp_player_now_playing_record")]
+ public abstract unowned DAAP.Record now_playing_record (DMAP.DACPPlayer player);
+ [CCode (cname = "dacp_player_pause")]
+ public abstract void pause (DMAP.DACPPlayer player);
+ [CCode (cname = "dacp_player_play_pause")]
+ public abstract void play_pause (DMAP.DACPPlayer player);
+ [CCode (cname = "dacp_player_prev_item")]
+ public abstract void prev_item (DMAP.DACPPlayer player);
+ }
+ [CCode (cheader_filename = "libdmapsharing/dmap.h")]
+ public interface Db {
+ public abstract uint add (DMAP.Record record);
+ public abstract uint add_path (string path);
+ public abstract uint add_with_id (DMAP.Record record, uint id);
+ public unowned GLib.HashTable apply_filter (GLib.SList filter_def);
+ public abstract int64 count ();
+ public abstract void @foreach (GLib.HFunc func);
+ public abstract unowned DMAP.Record lookup_by_id (uint id);
+ public abstract uint lookup_id_by_location (string location);
+ }
+ [CCode (cheader_filename = "libdmapsharing/dmap.h")]
+ public interface Record {
+ public abstract unowned DMAP.Record set_from_blob (GLib.ByteArray blob);
+ public abstract unowned GLib.ByteArray to_blob ();
+ }
+ [CCode (cheader_filename = "libdmapsharing/dmap.h")]
+ public interface RecordFactory {
+ public abstract DMAP.Record create (void* user_data);
+ }
+ [CCode (cprefix = "DMAP_", has_type_id = false, cheader_filename = "libdmapsharing/dmap.h")]
+ public enum ConnectionState {
+ GET_INFO,
+ GET_PASSWORD,
+ LOGIN,
+ GET_REVISION_NUMBER,
+ GET_DB_INFO,
+ GET_SONGS,
+ GET_PLAYLISTS,
+ GET_PLAYLIST_ENTRIES,
+ LOGOUT,
+ DONE
+ }
+ [CCode (cprefix = "PLAY_", has_type_id = false, cheader_filename = "libdmapsharing/dmap.h")]
+ public enum DACPPlayState {
+ STOPPED,
+ PAUSED,
+ PLAYING
+ }
+ [CCode (cprefix = "REPEAT_", has_type_id = false, cheader_filename = "libdmapsharing/dmap.h")]
+ public enum DACPRepeatState {
+ NONE,
+ SINGLE,
+ ALL
+ }
+ [CCode (cprefix = "DMAP_MDNS_PUBLISHER_ERROR_", has_type_id = false, cheader_filename = "libdmapsharing/dmap.h")]
+ public enum DmapMdnsPublisherError {
+ NOT_RUNNING,
+ FAILED
+ }
+ [CCode (cprefix = "DMAP_MDNS_BROWSER_ERROR_", has_type_id = false, cheader_filename = "libdmapsharing/dmap.h")]
+ public enum MdnsBrowserError {
+ NOT_RUNNING,
+ FAILED
+ }
+ [CCode (cprefix = "DMAP_MDNS_BROWSER_SERVICE_TYPE_", has_type_id = false, cheader_filename = "libdmapsharing/dmap.h")]
+ public enum MdnsBrowserServiceType {
+ INVALID,
+ DAAP,
+ DPAP,
+ DACP,
+ LAST
+ }
+ [CCode (cprefix = "DMAP_MEDIA_KIND_", has_type_id = false, cheader_filename = "libdmapsharing/dmap.h")]
+ public enum MediaKind {
+ MUSIC,
+ MOVIE
+ }
+ [CCode (cheader_filename = "libdmapsharing/dmap.h")]
+ public delegate bool ConnectionCallback (DMAP.Connection connection, bool result, string reason);
+ [CCode (cheader_filename = "libdmapsharing/dmap.h", has_target = false)]
+ public delegate unowned string RecordGetValueFunc (DMAP.Record record);
+ [CCode (cheader_filename = "libdmapsharing/dmap.h")]
+ public delegate void ResponseHandler (DMAP.Connection connection, uint status, GLib.Node structure);
+ [CCode (cheader_filename = "libdmapsharing/dmap.h")]
+ public const int SHARE_CHUNK_SIZE;
+ [CCode (cheader_filename = "libdmapsharing/dmap.h")]
+ public const int STATUS_OK;
+ [CCode (cheader_filename = "libdmapsharing/dmap.h")]
+ public static void hash_generate (short version_major, uchar[] url, uchar hash_select, uchar[] @out, int request_id);
+}
+namespace DPAP {
+ [CCode (cheader_filename = "libdmapsharing/dmap.h")]
+ public class Share : DMAP.Share {
+ [CCode (cname = "dpap_share_new", type = "DPAPShare*", has_construct_function = false)]
+ public Share (string name, string password, void* db, void* container_db, string transcode_mimetype);
+ }
+ [CCode (cheader_filename = "libdmapsharing/dmap.h")]
+ public interface Record {
+ [CCode (cname = "dpap_record_read")]
+ public abstract unowned GLib.InputStream read (DPAP.Record record) throws GLib.Error;
+ }
+ public class Connection : DMAP.Connection {
+ [CCode (has_construct_function = false)]
+ public Connection (string name, string host, int port, bool password_protected, DMAP.Db db, DMAP.RecordFactory factory);
+ }
+}
+namespace DAAP {
+ [CCode (cheader_filename = "libdmapsharing/dmap.h")]
+ public class Share : DMAP.Share {
+ [CCode (cname = "dpap_share_new", type = "DAAP.Share*", has_construct_function = false)]
+ public Share (string name, string password, void* db, void* container_db, string transcode_mimetype);
+ }
+ [CCode (cheader_filename = "libdmapsharing/dmap.h")]
+ public interface Record {
+ [CCode (cname = "daap_record_cmp_by_album")]
+ public static int cmp_by_album (void* a, void* b, DMAP.Db db);
+ [CCode (cname = "daap_record_itunes_compat")]
+ public abstract bool itunes_compat (DAAP.Record record);
+ [CCode (cname = "daap_record_read")]
+ public abstract unowned GLib.InputStream read (DAAP.Record record) throws GLib.Error;
+ }
+ public class Connection : DMAP.Connection {
+ [CCode (has_construct_function = false)]
+ public Connection (string name, string host, int port, bool password_protected, DMAP.Db db, DMAP.RecordFactory factory);
+ }
+}
diff --git a/libdmapsharing/Makefile.am b/libdmapsharing/Makefile.am
index 6a589d4..cdb89a9 100644
--- a/libdmapsharing/Makefile.am
+++ b/libdmapsharing/Makefile.am
@@ -4,6 +4,7 @@ BUILT_SOURCES = dmap-marshal.c dmap-marshal.h dmap-enums.c dmap-enums.h
libdmapsharing_la_SOURCES = \
$(BUILT_SOURCES) \
+ daap-connection.c \
daap-record.c \
daap-share.c \
dacp-share.c \
@@ -17,6 +18,7 @@ libdmapsharing_la_SOURCES = \
dmap-record-factory.c \
dmap-share.c \
dmap-structure.c \
+ dpap-connection.c \
dpap-record.c \
dpap-share.c
@@ -66,6 +68,7 @@ libdmapsharingincludedir = \
$(includedir)/libdmapsharing- API_VERSION@/libdmapsharing
libdmapsharinginclude_HEADERS = \
+ daap-connection.h \
daap-record.h \
daap-share.h \
dacp-share.h \
@@ -81,6 +84,7 @@ libdmapsharinginclude_HEADERS = \
dmap-record.h \
dmap-record-factory.h \
dmap-share.h \
+ dpap-connection.h \
dpap-record.h \
dpap-share.h
diff --git a/libdmapsharing/daap-connection.c b/libdmapsharing/daap-connection.c
new file mode 100644
index 0000000..84d671a
--- /dev/null
+++ b/libdmapsharing/daap-connection.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2004,2005 Charles Schmidt <cschmidt2 emich edu>
+ * Copyright (C) 2006 INDT
+ * Andre Moreira Magalhaes <andre magalhaes indt org br>
+ *
+ * This library 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.1 of the License, or (at your option) any later version.
+ *
+ * This library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+
+#include <libdmapsharing/daap-connection.h>
+#include <libdmapsharing/dmap-structure.h>
+
+#define DAAP_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_DAAP_CONNECTION, DAAPConnectionPrivate))
+
+/* FIXME:
+struct DAAPConnectionPrivate {
+};
+*/
+
+static DMAPContentCode
+get_protocol_version_cc (DMAPConnection *connection)
+{
+ return DMAP_CC_APRO;
+}
+
+static gchar *
+get_query_metadata (void)
+{
+ return g_strdup ("dmap.itemid,dmap.itemname,daap.songalbum,"
+ "daap.songartist,daap.songgenre,daap.songsize,"
+ "daap.songtime,daap.songtrackcount,daap.songtracknumber,"
+ "daap.songyear,daap.songformat,"
+ "daap.songbitrate,daap.songdiscnumber,daap.songdataurl,"
+ "daap.sortartist,daap.sortalbum");
+}
+
+static DMAPRecord *
+handle_mlcl (DMAPConnection *connection, DMAPRecordFactory *factory, GNode *n, int *item_id)
+{
+ GNode *n2;
+ DMAPRecord *record = NULL;
+ const gchar *title = NULL;
+ const gchar *album = NULL;
+ const gchar *artist = NULL;
+ const gchar *format = NULL;
+ const gchar *genre = NULL;
+ const gchar *streamURI = NULL;
+ const gchar *sort_artist = NULL;
+ const gchar *sort_album = NULL;
+ gint length = 0;
+ gint track_number = 0;
+ gint disc_number = 0;
+ gint year = 0;
+ gint size = 0;
+ gint bitrate = 0;
+
+ for (n2 = n->children; n2; n2 = n2->next) {
+ DMAPStructureItem *meta_item;
+
+ meta_item = n2->data;
+
+ switch (meta_item->content_code) {
+ case DMAP_CC_MIID:
+ *item_id = g_value_get_int (&(meta_item->content));
+ break;
+ case DMAP_CC_MINM:
+ title = g_value_get_string (&(meta_item->content));
+ break;
+ case DMAP_CC_ASAL:
+ album = g_value_get_string (&(meta_item->content));
+ break;
+ case DMAP_CC_ASAR:
+ artist = g_value_get_string (&(meta_item->content));
+ break;
+ case DMAP_CC_ASFM:
+ format = g_value_get_string (&(meta_item->content));
+ break;
+ case DMAP_CC_ASGN:
+ genre = g_value_get_string (&(meta_item->content));
+ break;
+ case DMAP_CC_ASTM:
+ length = g_value_get_int (&(meta_item->content));
+ break;
+ case DMAP_CC_ASTN:
+ track_number = g_value_get_int (&(meta_item->content));
+ break;
+ case DMAP_CC_ASDN:
+ disc_number = g_value_get_int (&(meta_item->content));
+ break;
+ case DMAP_CC_ASYR:
+ year = g_value_get_int (&(meta_item->content));
+ break;
+ case DMAP_CC_ASSZ:
+ size = g_value_get_int (&(meta_item->content));
+ break;
+ case DMAP_CC_ASBR:
+ bitrate = g_value_get_int (&(meta_item->content));
+ break;
+ case DMAP_CC_ASUL:
+ streamURI = g_value_get_string (&(meta_item->content));
+ break;
+ case DMAP_CC_ASSA:
+ sort_artist = g_value_get_string (&(meta_item->content));
+ break;
+ case DMAP_CC_ASSU:
+ sort_album = g_value_get_string (&(meta_item->content));
+ break;
+ default:
+ break;
+ }
+ }
+
+ record = dmap_record_factory_create (factory, NULL);
+ if (record == NULL) {
+ goto _return;
+ }
+ g_object_set (record,
+ "year", year,
+ "track", track_number,
+ "disc", disc_number,
+ "bitrate", bitrate,
+ "duration", length / 1000,
+ "filesize", (guint64) size,
+ "format", format,
+ "title", title,
+ "songalbum", album,
+ "songartist", artist,
+ "songgenre", genre,
+ "sort-artist", sort_artist,
+ "sort-album", sort_album,
+ NULL);
+
+_return:
+ return record;
+}
+
+static void
+daap_connection_class_init (DAAPConnectionClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ DMAPConnectionClass *parent_class = DMAP_CONNECTION_CLASS (object_class);
+
+ parent_class->get_protocol_version_cc = get_protocol_version_cc;
+ parent_class->get_query_metadata = get_query_metadata;
+ parent_class->handle_mlcl = handle_mlcl;
+
+ /* FIXME:
+ g_type_class_add_private (klass, sizeof (DAAPConnectionPrivate));
+ */
+}
+
+DAAPConnection *
+daap_connection_new (const char *name,
+ const char *host,
+ int port,
+ gboolean password_protected,
+ DMAPDb *db,
+ DMAPRecordFactory *factory)
+{
+ DAAPConnection *connection;
+
+ connection = g_object_new (TYPE_DAAP_CONNECTION,
+ "name", name,
+ "password-protected", password_protected,
+ "db", db,
+ "host", host,
+ "port", port,
+ "factory", factory,
+ NULL);
+
+ return connection;
+}
+
+static void
+daap_connection_init (DAAPConnection *connection)
+{
+ /* FIXME:
+ connection->priv = DAAP_CONNECTION_GET_PRIVATE (connection);
+ */
+}
+
+G_DEFINE_TYPE (DAAPConnection, daap_connection, TYPE_DMAP_CONNECTION)
diff --git a/libdmapsharing/daap-connection.h b/libdmapsharing/daap-connection.h
new file mode 100644
index 0000000..a9825be
--- /dev/null
+++ b/libdmapsharing/daap-connection.h
@@ -0,0 +1,96 @@
+/*
+ * This library 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.1 of the License, or (at your option) any later version.
+ *
+ * This library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __DAAP_CONNECTION_H
+#define __DAAP_CONNECTION_H
+
+#include <glib-object.h>
+
+#include <libdmapsharing/dmap-connection.h>
+#include <libdmapsharing/dmap-db.h>
+
+G_BEGIN_DECLS
+
+/**
+ * TYPE_DAAP_CONNECTION:
+ *
+ * The type for #DAAPConnection.
+ */
+#define TYPE_DAAP_CONNECTION (daap_connection_get_type ())
+/**
+ * DAAP_CONNECTION:
+ * @o: Object which is subject to casting.
+ *
+ * Casts a #DAAPConnection or derived pointer into a (DAAPConnection *) pointer.
+ * Depending on the current debugging level, this function may invoke
+ * certain runtime checks to identify invalid casts.
+ */
+#define DAAP_CONNECTION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TYPE_DAAP_CONNECTION, DAAPConnection))
+/**
+ * DAAP_CONNECTION_CLASS:
+ * @k: a valid #DAAPConnectionClass
+ *
+ * Casts a derived #DAAPConnectionClass structure into a #DAAPConnectionClass
+ * structure.
+ */
+#define DAAP_CONNECTION_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), TYPE_DAAP_CONNECTION, DAAPConnectionClass))
+/**
+ * IS_DAAP_CONNECTION:
+ * @o: Instance to check for being a %TYPE_DAAP_CONNECTION.
+ *
+ * Checks whether a valid #GTypeInstance pointer is of type %TYPE_DAAP_CONNECTION.
+ */
+#define IS_DAAP_CONNECTION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TYPE_DAAP_CONNECTION))
+/**
+ * IS_DAAP_CONNECTION_CLASS:
+ * @k: a #DAAPConnectionClass
+ *
+ * Checks whether @k "is a" valid #DAAPConnectionClass structure of type
+ * %DAAP_CONNECTION or derived.
+ */
+#define IS_DAAP_CONNECTION_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), TYPE_DAAP_CONNECTION))
+/**
+ * DAAP_CONNECTION_GET_CLASS:
+ * @o: a #DAAPConnection instance.
+ *
+ * Get the class structure associated to a #DAAPConnection instance.
+ *
+ * Returns: pointer to object class structure.
+ */
+#define DAAP_CONNECTION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TYPE_DAAP_CONNECTION, DAAPConnectionClass))
+
+typedef struct DAAPConnectionPrivate DAAPConnectionPrivate;
+
+typedef struct {
+ DMAPConnectionClass dmap_connection_class;
+} DAAPConnectionClass;
+
+typedef struct {
+ DMAPConnection dmap_connection_instance;
+ DAAPConnectionPrivate *priv;
+} DAAPConnection;
+
+GType daap_connection_get_type (void);
+
+DAAPConnection * daap_connection_new (const char *name,
+ const char *host,
+ int port,
+ gboolean password_protected,
+ DMAPDb *db,
+ DMAPRecordFactory *factory);
+G_END_DECLS
+
+#endif /* __DAAP_CONNECTION_H */
diff --git a/libdmapsharing/dmap-connection.c b/libdmapsharing/dmap-connection.c
index c442305..038f509 100644
--- a/libdmapsharing/dmap-connection.c
+++ b/libdmapsharing/dmap-connection.c
@@ -149,6 +149,10 @@ dmap_connection_class_init (DMAPConnectionClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ klass->get_protocol_version_cc = NULL;
+ klass->get_query_metadata = NULL;
+ klass->handle_mlcl = NULL;
+
object_class->finalize = dmap_connection_finalize;
object_class->dispose = dmap_connection_dispose;
object_class->set_property = dmap_connection_set_property;
@@ -725,7 +729,8 @@ handle_server_info (DMAPConnection *connection,
}
/* get the daap version number */
- item = dmap_structure_find_item (structure, DMAP_CC_APRO);
+ item = dmap_structure_find_item (structure,
+ DMAP_CONNECTION_GET_CLASS(connection)->get_protocol_version_cc (connection));
if (item == NULL) {
dmap_connection_state_done (connection, FALSE);
return;
@@ -917,135 +922,52 @@ handle_song_listing (DMAPConnection *connection,
if (priv->emit_progress_id != 0) {
g_source_remove (priv->emit_progress_id);
}
- connection->priv->emit_progress_id = g_idle_add ((GSourceFunc) emit_progress_idle, connection);
+ priv->emit_progress_id = g_idle_add ((GSourceFunc) emit_progress_idle, connection);
for (i = 0, n = listing_node->children; n; i++, n = n->next) {
- GNode *n2;
- DMAPRecord *record = NULL;
- gchar *uri = NULL;
gint item_id = 0;
- const gchar *title = NULL;
- const gchar *album = NULL;
- const gchar *artist = NULL;
- const gchar *format = NULL;
- const gchar *genre = NULL;
- const gchar *streamURI = NULL;
- const gchar *sort_artist = NULL;
- const gchar *sort_album = NULL;
- gint length = 0;
- gint track_number = 0;
- gint disc_number = 0;
- gint year = 0;
- gint size = 0;
- gint bitrate = 0;
-
- for (n2 = n->children; n2; n2 = n2->next) {
- DMAPStructureItem *meta_item;
-
- meta_item = n2->data;
-
- switch (meta_item->content_code) {
- case DMAP_CC_MIID:
- item_id = g_value_get_int (&(meta_item->content));
- break;
- case DMAP_CC_MINM:
- title = g_value_get_string (&(meta_item->content));
- break;
- case DMAP_CC_ASAL:
- album = g_value_get_string (&(meta_item->content));
- break;
- case DMAP_CC_ASAR:
- artist = g_value_get_string (&(meta_item->content));
- break;
- case DMAP_CC_ASFM:
- format = g_value_get_string (&(meta_item->content));
- break;
- case DMAP_CC_ASGN:
- genre = g_value_get_string (&(meta_item->content));
- break;
- case DMAP_CC_ASTM:
- length = g_value_get_int (&(meta_item->content));
- break;
- case DMAP_CC_ASTN:
- track_number = g_value_get_int (&(meta_item->content));
- break;
- case DMAP_CC_ASDN:
- disc_number = g_value_get_int (&(meta_item->content));
- break;
- case DMAP_CC_ASYR:
- year = g_value_get_int (&(meta_item->content));
- break;
- case DMAP_CC_ASSZ:
- size = g_value_get_int (&(meta_item->content));
- break;
- case DMAP_CC_ASBR:
- bitrate = g_value_get_int (&(meta_item->content));
- break;
- case DMAP_CC_ASUL:
- streamURI = g_value_get_string (&(meta_item->content));
- break;
- case DMAP_CC_ASSA:
- sort_artist = g_value_get_string (&(meta_item->content));
- break;
- case DMAP_CC_ASSU:
- sort_album = g_value_get_string (&(meta_item->content));
- break;
- default:
- break;
+ DMAPRecord *record = DMAP_CONNECTION_GET_CLASS(connection)->handle_mlcl (connection, priv->record_factory, n, &item_id);
+ if (record) {
+ gchar *uri = NULL;
+ gchar *format = NULL;
+
+ g_object_get (record, "format", &format, NULL);
+ if (format == NULL) {
+ format = "Unknown";
}
- }
- /*if (connection->dmap_version == 3.0) {*/
+ /*if (connection->dmap_version == 3.0) {*/
uri = g_strdup_printf ("%s/databases/%d/items/%d.%s?session-id=%u",
- priv->daap_base_uri,
- priv->database_id,
+ connection->priv->daap_base_uri,
+ connection->priv->database_id,
item_id, format,
- priv->session_id);
- /*} else {*/
- /* uri should be
- * "/databases/%d/items/%d.%s?session-id=%u&revision-id=%d";
- * but its not going to work cause the other parts of the code
- * depend on the uri to have the ip address so that the
- * DAAPSource can be found to ++request_id
- * maybe just /dont/ support older itunes. doesn't seem
- * unreasonable to me, honestly
- */
- /*}*/
- record = dmap_record_factory_create (priv->record_factory, NULL);
- if (record == NULL) {
- g_debug ("cannot create record for daap track %s", uri);
- continue;
+ connection->priv->session_id);
+ /*} else {*/
+ /* uri should be
+ * "/databases/%d/items/%d.%s?session-id=%u&revision-id=%d";
+ * but its not going to work cause the other parts of the code
+ * depend on the uri to have the ip address so that the
+ * DAAPSource can be found to ++request_id
+ * maybe just /dont/ support older itunes. doesn't seem
+ * unreasonable to me, honestly
+ */
+ /*}*/
+
+ g_object_set (record, "location", uri, NULL);
+ dmap_db_add (connection->priv->db, record);
+ g_object_unref (record);
+ g_hash_table_insert (connection->priv->item_id_to_uri, GINT_TO_POINTER (item_id), g_strdup (uri));
+ g_free (uri);
+ } else {
+ g_debug ("cannot create record for daap track");
}
- /* FIXME: This is DAAP-specific! */
- g_object_set (record,
- "location", uri,
- "year", year,
- "track", track_number,
- "disc", disc_number,
- "bitrate", bitrate,
- "duration", length / 1000,
- "filesize", (guint64) size,
- "format", format,
- "title", title,
- "songalbum", album,
- "songartist", artist,
- "songgenre", genre,
- "sort-artist", sort_artist,
- "sort-album", sort_album,
- NULL);
- g_hash_table_insert (priv->item_id_to_uri, GINT_TO_POINTER (item_id), g_strdup (uri));
- g_free (uri);
-
- dmap_db_add (priv->db, record);
- g_debug ("Got song: %s", title);
- g_object_unref (record);
if (i % commit_batch == 0) {
- connection->priv->progress = ((float) i / (float) returned_count);
+ priv->progress = ((float) i / (float) returned_count);
if (priv->emit_progress_id != 0) {
g_source_remove (connection->priv->emit_progress_id);
}
- connection->priv->emit_progress_id = g_idle_add ((GSourceFunc) emit_progress_idle, connection);
+ priv->emit_progress_id = g_idle_add ((GSourceFunc) emit_progress_idle, connection);
}
}
@@ -1473,6 +1395,7 @@ static gboolean
dmap_connection_do_something (DMAPConnection *connection)
{
DMAPConnectionPrivate *priv = connection->priv;
+ char *meta;
char *path;
g_debug ("Doing something for state: %d", priv->state);
@@ -1551,22 +1474,20 @@ dmap_connection_do_something (DMAPConnection *connection)
case DMAP_GET_SONGS:
g_debug ("Getting DAAP song listing");
+ meta = DMAP_CONNECTION_GET_CLASS(connection)->get_query_metadata (connection);
path = g_strdup_printf ("/databases/%i/items?session-id=%u&revision-number=%i"
- "&meta=dmap.itemid,dmap.itemname,daap.songalbum,"
- "daap.songartist,daap.songgenre,daap.songsize,"
- "daap.songtime,daap.songtrackcount,daap.songtracknumber,"
- "daap.songyear,daap.songformat,"
- "daap.songbitrate,daap.songdiscnumber,daap.songdataurl,"
- "daap.sortartist,daap.sortalbum",
+ "&meta=%s",
priv->database_id,
priv->session_id,
- priv->revision_number);
+ priv->revision_number,
+ meta);
if (! http_get (connection, path, TRUE, priv->dmap_version, 0, FALSE,
(DMAPResponseHandler) handle_song_listing, NULL, TRUE)) {
g_debug ("Could not get DAAP song listing");
dmap_connection_state_done (connection, FALSE);
}
g_free (path);
+ g_free (meta);
break;
case DMAP_GET_PLAYLISTS:
diff --git a/libdmapsharing/dmap-connection.h b/libdmapsharing/dmap-connection.h
index 0e824aa..3b9d253 100644
--- a/libdmapsharing/dmap-connection.h
+++ b/libdmapsharing/dmap-connection.h
@@ -25,8 +25,9 @@
#include <glib-object.h>
#include <libsoup/soup.h>
-#include "dmap-db.h"
-#include "dmap-record-factory.h"
+#include <libdmapsharing/dmap-structure.h>
+#include <libdmapsharing/dmap-db.h>
+#include <libdmapsharing/dmap-record-factory.h>
G_BEGIN_DECLS
@@ -107,6 +108,11 @@ typedef struct {
typedef struct {
GObjectClass parent;
+ /* Pure virtual methods: */
+ DMAPContentCode (*get_protocol_version_cc) (DMAPConnection *connection);
+ gchar * (*get_query_metadata) (DMAPConnection *connection);
+ DMAPRecord *(*handle_mlcl) (DMAPConnection *connection, DMAPRecordFactory *factory, GNode *mlcl, gint *item_id);
+
SoupMessage * (*build_message)
(DMAPConnection *connection,
const gchar *path,
diff --git a/libdmapsharing/dmap-structure.c b/libdmapsharing/dmap-structure.c
index 47e7f1c..2ea1670 100644
--- a/libdmapsharing/dmap-structure.c
+++ b/libdmapsharing/dmap-structure.c
@@ -379,8 +379,6 @@ dmap_structure_parse_container_buffer (GNode *parent,
GNode *node = NULL;
GType gtype;
- g_debug ("l is %d and buf_length is %d\n", l, buf_length);
-
/* we need at least 8 bytes, 4 of content_code and 4 of size */
if (buf_length - l < 8) {
g_debug ("Malformed response recieved\n");
@@ -406,8 +404,6 @@ dmap_structure_parse_container_buffer (GNode *parent,
}
l += 4;
- g_debug ("content_code = %d, codesize is %d, l is %d\n", cc, codesize, l);
-
item = g_new0 (DMAPStructureItem, 1);
item->content_code = cc;
node = g_node_new (item);
@@ -431,8 +427,6 @@ dmap_structure_parse_container_buffer (GNode *parent,
item->size = 1;
g_value_set_char (&(item->content), c);
- g_debug ("Code: %s, content (%d): \"%c\"\n", dmap_content_code_string (item->content_code), codesize, (gchar)c);
-
break;
}
case DMAP_TYPE_SHORT: {
@@ -444,8 +438,6 @@ dmap_structure_parse_container_buffer (GNode *parent,
item->size = 2;
g_value_set_int (&(item->content),(gint32)s);
- g_debug ("Code: %s, content (%d): %hi\n", dmap_content_code_string (item->content_code), codesize, s);
-
break;
}
case DMAP_TYPE_DATE:
@@ -458,7 +450,6 @@ dmap_structure_parse_container_buffer (GNode *parent,
item->size = 4;
g_value_set_int (&(item->content), i);
- g_debug ("Code: %s, content (%d): %d\n", dmap_content_code_string (item->content_code), codesize, i);
break;
}
case DMAP_TYPE_INT64: {
@@ -470,8 +461,6 @@ dmap_structure_parse_container_buffer (GNode *parent,
item->size = 8;
g_value_set_int64 (&(item->content), i);
- g_debug ("Code: %s, content (%d): %"G_GINT64_FORMAT"\n", dmap_content_code_string (item->content_code), codesize, i);
-
break;
}
case DMAP_TYPE_STRING: {
@@ -479,8 +468,6 @@ dmap_structure_parse_container_buffer (GNode *parent,
item->size = strlen (s);
g_value_set_string (&(item->content), s);
- g_debug ("Code: %s, content (%d): \"%s\"\n", dmap_content_code_string (item->content_code), codesize, s);
-
break;
}
case DMAP_TYPE_POINTER: {
@@ -509,12 +496,9 @@ dmap_structure_parse_container_buffer (GNode *parent,
item->size = 4;
g_value_set_double (&(item->content), v);
- g_debug ("Code: %s, content: %f\n", dmap_content_code_string (item->content_code), v);
-
break;
}
case DMAP_TYPE_CONTAINER: {
- g_debug ("Code: %s, container\n", dmap_content_code_string (item->content_code));
dmap_structure_parse_container_buffer (node,&(buf[l]), codesize);
break;
}
diff --git a/libdmapsharing/dpap-connection.c b/libdmapsharing/dpap-connection.c
new file mode 100644
index 0000000..5a08768
--- /dev/null
+++ b/libdmapsharing/dpap-connection.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2004,2005 Charles Schmidt <cschmidt2 emich edu>
+ * Copyright (C) 2006 INDT
+ * Andre Moreira Magalhaes <andre magalhaes indt org br>
+ *
+ * This library 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.1 of the License, or (at your option) any later version.
+ *
+ * This library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+
+#include <libdmapsharing/dpap-connection.h>
+#include <libdmapsharing/dmap-structure.h>
+
+#define DPAP_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_DPAP_CONNECTION, DPAPConnectionPrivate))
+
+/* FIXME:
+struct DPAPConnectionPrivate {
+};
+*/
+
+static DMAPContentCode
+get_protocol_version_cc (DMAPConnection *connection)
+{
+ return DMAP_CC_PPRO;
+}
+
+static gchar *
+get_query_metadata (void)
+{
+ return g_strdup ("all");
+}
+
+static DMAPRecord *
+handle_mlcl (DMAPConnection *connection, DMAPRecordFactory *factory, GNode *n, int *item_id)
+{
+ GNode *n2;
+ DMAPRecord *record = NULL;
+ const gchar *filename = NULL;
+ const gchar *aspect_ratio = NULL;
+ const gchar *format = NULL;
+ const gchar *comments = NULL;
+ const gchar *thumbnail = NULL;
+ const gchar *ptr = NULL;
+ gint creation_date = 0;
+ gint filesize = 0;
+ gint large_filesize = 0;
+ gint height = 0;
+ gint width = 0;
+ gint rating = 0;
+
+ for (n2 = n->children; n2; n2 = n2->next) {
+ DMAPStructureItem *meta_item;
+
+ meta_item = n2->data;
+
+ switch (meta_item->content_code) {
+ case DMAP_CC_MIID:
+ *item_id = g_value_get_int (&(meta_item->content));
+ break;
+ case DMAP_CC_PIMF:
+ filename = g_value_get_string (&(meta_item->content));
+ break;
+ case DMAP_CC_PASP:
+ aspect_ratio = g_value_get_string (&(meta_item->content));
+ break;
+ case DMAP_CC_PICD:
+ creation_date = g_value_get_int (&(meta_item->content));
+ break;
+ case DMAP_CC_PFMT:
+ format = g_value_get_string (&(meta_item->content));
+ break;
+ case DMAP_CC_PIFS:
+ filesize = g_value_get_int (&(meta_item->content));
+ break;
+ case DMAP_CC_PLSZ:
+ large_filesize = g_value_get_int (&(meta_item->content));
+ break;
+ case DMAP_CC_PHGT:
+ height = g_value_get_int (&(meta_item->content));
+ break;
+ case DMAP_CC_PWTH:
+ width = g_value_get_int (&(meta_item->content));
+ break;
+ case DMAP_CC_PRAT:
+ rating = g_value_get_int (&(meta_item->content));
+ break;
+ case DMAP_CC_PCMT:
+ comments = g_value_get_string (&(meta_item->content));
+ break;
+ case DMAP_CC_PFDT:
+ thumbnail = g_value_get_pointer (&(meta_item->content));
+ break;
+ default:
+ break;
+ }
+ }
+
+ record = dmap_record_factory_create (factory, NULL);
+ if (record == NULL) {
+ goto _return;
+ }
+
+ if (filesize) {
+ ptr = g_new (gchar, filesize);
+ memcpy (ptr, thumbnail, filesize);
+ }
+
+ g_object_set (record,
+ "filename", filename,
+ "aspect-ratio", aspect_ratio,
+ "creation-date", creation_date,
+ "format", format,
+ "filesize", filesize,
+ "large-filesize", large_filesize,
+ "height", height,
+ "width", width,
+ "rating", rating,
+ "comments", comments,
+ "thumbnail", ptr,
+ NULL);
+
+_return:
+ return record;
+}
+
+static void
+dpap_connection_class_init (DPAPConnectionClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ DMAPConnectionClass *parent_class = DMAP_CONNECTION_CLASS (object_class);
+
+ parent_class->get_protocol_version_cc = get_protocol_version_cc;
+ parent_class->get_query_metadata = get_query_metadata;
+ parent_class->handle_mlcl = handle_mlcl;
+
+ /* FIXME:
+ g_type_class_add_private (klass, sizeof (DPAPConnectionPrivate));
+ */
+}
+
+DPAPConnection *
+dpap_connection_new (const char *name,
+ const char *host,
+ int port,
+ gboolean password_protected,
+ DMAPDb *db,
+ DMAPRecordFactory *factory)
+{
+ DPAPConnection *connection;
+
+ connection = g_object_new (TYPE_DPAP_CONNECTION,
+ "name", name,
+ "password-protected", password_protected,
+ "db", db,
+ "host", host,
+ "port", port,
+ "factory", factory,
+ NULL);
+
+ return connection;
+}
+
+static void
+dpap_connection_init (DPAPConnection *connection)
+{
+ /* FIXME:
+ connection->priv = DPAP_CONNECTION_GET_PRIVATE (connection);
+ */
+}
+
+G_DEFINE_TYPE (DPAPConnection, dpap_connection, TYPE_DMAP_CONNECTION)
diff --git a/libdmapsharing/dpap-connection.h b/libdmapsharing/dpap-connection.h
new file mode 100644
index 0000000..d5b8ae0
--- /dev/null
+++ b/libdmapsharing/dpap-connection.h
@@ -0,0 +1,96 @@
+/*
+ * This library 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.1 of the License, or (at your option) any later version.
+ *
+ * This library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __DPAP_CONNECTION_H
+#define __DPAP_CONNECTION_H
+
+#include <glib-object.h>
+
+#include <libdmapsharing/dmap-connection.h>
+#include <libdmapsharing/dmap-db.h>
+
+G_BEGIN_DECLS
+
+/**
+ * TYPE_DPAP_CONNECTION:
+ *
+ * The type for #DPAPConnection.
+ */
+#define TYPE_DPAP_CONNECTION (dpap_connection_get_type ())
+/**
+ * DPAP_CONNECTION:
+ * @o: Object which is subject to casting.
+ *
+ * Casts a #DPAPConnection or derived pointer into a (DPAPConnection *) pointer.
+ * Depending on the current debugging level, this function may invoke
+ * certain runtime checks to identify invalid casts.
+ */
+#define DPAP_CONNECTION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TYPE_DPAP_CONNECTION, DPAPConnection))
+/**
+ * DPAP_CONNECTION_CLASS:
+ * @k: a valid #DPAPConnectionClass
+ *
+ * Casts a derived #DPAPConnectionClass structure into a #DPAPConnectionClass
+ * structure.
+ */
+#define DPAP_CONNECTION_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), TYPE_DPAP_CONNECTION, DPAPConnectionClass))
+/**
+ * IS_DPAP_CONNECTION:
+ * @o: Instance to check for being a %TYPE_DPAP_CONNECTION.
+ *
+ * Checks whether a valid #GTypeInstance pointer is of type %TYPE_DPAP_CONNECTION.
+ */
+#define IS_DPAP_CONNECTION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TYPE_DPAP_CONNECTION))
+/**
+ * IS_DPAP_CONNECTION_CLASS:
+ * @k: a #DPAPConnectionClass
+ *
+ * Checks whether @k "is a" valid #DPAPConnectionClass structure of type
+ * %DPAP_CONNECTION or derived.
+ */
+#define IS_DPAP_CONNECTION_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), TYPE_DPAP_CONNECTION))
+/**
+ * DPAP_CONNECTION_GET_CLASS:
+ * @o: a #DPAPConnection instance.
+ *
+ * Get the class structure associated to a #DPAPConnection instance.
+ *
+ * Returns: pointer to object class structure.
+ */
+#define DPAP_CONNECTION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TYPE_DPAP_CONNECTION, DPAPConnectionClass))
+
+typedef struct DPAPConnectionPrivate DPAPConnectionPrivate;
+
+typedef struct {
+ DMAPConnectionClass dmap_connection_class;
+} DPAPConnectionClass;
+
+typedef struct {
+ DMAPConnection dmap_connection_instance;
+ DPAPConnectionPrivate *priv;
+} DPAPConnection;
+
+GType dpap_connection_get_type (void);
+
+DPAPConnection * dpap_connection_new (const char *name,
+ const char *host,
+ int port,
+ gboolean password_protected,
+ DMAPDb *db,
+ DMAPRecordFactory *factory);
+G_END_DECLS
+
+#endif /* __DPAP_CONNECTION_H */
diff --git a/tests/Makefile.am b/tests/Makefile.am
index acf0ee5..34d6521 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,4 +1,4 @@
-noinst_PROGRAMS = test-dmap-client test-dmap-server
+noinst_PROGRAMS = test-dmap-client test-dmap-server dpapview
test_dmap_client_SOURCES = \
test-dmap-db.c \
@@ -38,6 +38,28 @@ test_dmap_server_LDADD = \
$(IMAGEMAGICK_LIBS) \
$(MDNS_LIBS)
+dpapview_VALASOURCES = \
+ dpapview.vala
+
+dpapview_VALABUILTSOURCES = $(dpapview_VALASOURCES:.vala=.c)
+
+if MAINTAINER_MODE
+PACKAGES = --pkg gee-1.0 --pkg gtk+-2.0 --pkg gstreamer-0.10 --pkg libdmapsharing-2.2 --pkg libsoup-2.4 --pkg glib-2.0
+BUILT_SOURCES = vala.stamp
+
+vala.stamp: $(dpapview_VALASOURCES)
+ $(VALAC) --vapidir=$(srcdir) $(PACKAGES) $^ -C
+ touch $@
+endif
+
+dpapview_SOURCES = \
+ $(dpapview_VALABUILTSOURCES)
+
+dpapview_LDADD = \
+ $(top_builddir)/libdmapsharing/libdmapsharing.la \
+ $(GTK_LIBS) \
+ $(GEE_LIBS)
+
AM_CPPFLAGS = \
-I$(top_srcdir) \
$(GLIB_CFLAGS) \
@@ -48,7 +70,9 @@ AM_CPPFLAGS = \
$(MDNS_CFLAGS)
INCLUDES = \
- $(IMAGEMAGICK_CFLAGS)
+ $(IMAGEMAGICK_CFLAGS) \
+ $(GTK_CFLAGS) \
+ $(GEE_CFLAGS)
noinst_HEADERS = \
test-dmap-container-record.h \
@@ -58,3 +82,14 @@ noinst_HEADERS = \
test-daap-record-factory.h \
test-dpap-record.h \
test-dpap-record-factory.h
+
+EXTRA_DIST = \
+ $(dpapview_VALASOURCES) \
+ $(dpapview_VALABUILTSOURCES)
+
+if MAINTAINER_MODE
+CLEANFILES = \
+ $(BUILT_SOURCES) \
+ $(dpapview_VALABUILTSOURCES)
+endif
+
diff --git a/tests/dpapview.ui b/tests/dpapview.ui
new file mode 100644
index 0000000..0805e4e
--- /dev/null
+++ b/tests/dpapview.ui
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <requires lib="gtk+" version="2.20"/>
+ <!-- interface-naming-policy project-wide -->
+ <object class="GtkWindow" id="window">
+ <signal name="destroy" handler="gtk_main_quit" swapped="no"/>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">automatic</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <child>
+ <object class="GtkIconView" id="iconview">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="model">liststore</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <object class="GtkListStore" id="liststore">
+ <columns>
+ <!-- column-name gdkpixbuf -->
+ <column type="GdkPixbuf"/>
+ <!-- column-name gchararray -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+</interface>
diff --git a/tests/dpapview.vala b/tests/dpapview.vala
new file mode 100644
index 0000000..5695ec5
--- /dev/null
+++ b/tests/dpapview.vala
@@ -0,0 +1,226 @@
+/* FILE: dpapviewer.vala -- View DPAP data
+ * AUTHOR: W. Michael Petullo <mike flyn org>
+ * DATE: 24 November 2010
+ *
+ * Copyright (c) 2010 W. Michael Petullo <new flyn org>
+ * All rights reserved.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+private class ViewerDMAPDb : GLib.Object, DMAP.Db {
+ // A dumb database that stores everything in an array
+
+ private Gee.ArrayList<ViewerDPAPRecord> db = new Gee.ArrayList<ViewerDPAPRecord> ();
+
+ public uint add (DMAP.Record record) {
+ db.add (((ViewerDPAPRecord) record));
+ return db.size;
+ }
+
+ public uint add_path (string path) {
+ GLib.error ("add_path not implemented");
+ }
+
+ public uint add_with_id (DMAP.Record record, uint id) {
+ GLib.error ("add_with_id not implemented");
+ }
+
+ public int64 count () {
+ return db.size;
+ }
+
+ public void @foreach (GLib.HFunc func) {
+ int i;
+ for (i = 0; i < db.size; i++) {
+ func (i.to_pointer (), db[i]);
+ }
+ }
+
+ public unowned DMAP.Record lookup_by_id (uint id) {
+ GLib.error ("lookup_by_id not implemented");
+ }
+
+
+ public uint lookup_id_by_location (string location){
+ GLib.error ("lookup_id_by_location not implemented");
+ }
+}
+
+private class ViewerDPAPRecordFactory : GLib.Object, DMAP.RecordFactory {
+ public DMAP.Record create (void* user_data) {
+ return new ViewerDPAPRecord ();
+ }
+}
+
+private class ViewerDPAPRecord : GLib.Object, DMAP.Record, DPAP.Record {
+ private string _location;
+ private string _filename;
+ private string _aspect_ratio;
+ private string _format;
+ private string _comments;
+ private uchar *_thumbnail;
+ private int _filesize;
+ private int _large_filesize;
+ private int _height;
+ private int _width;
+ private int _rating;
+ private int _creation_date;
+
+ public string location {
+ get { return _location; }
+ set { _location = value; }
+ }
+
+ public string filename {
+ get { return _filename; }
+ set { _filename = value; }
+ }
+
+ public string aspect_ratio {
+ get { return _aspect_ratio; }
+ set { _aspect_ratio = value; }
+ }
+
+ public string format {
+ get { return _format; }
+ set { _format = value; }
+ }
+
+ public uchar *thumbnail {
+ get { return _thumbnail; }
+ set { _thumbnail = value; }
+ }
+
+ public string comments {
+ get { return _comments; }
+ set { _comments = value; }
+ }
+
+ public int filesize {
+ get { return _filesize; }
+ set { _filesize = value; }
+ }
+
+ public int large_filesize {
+ get { return _large_filesize; }
+ set { _large_filesize = value; }
+ }
+
+ public int height {
+ get { return _height; }
+ set { _height = value; }
+ }
+
+ public int width {
+ get { return _width; }
+ set { _width = value; }
+ }
+
+ public int rating {
+ get { return _rating; }
+ set { _rating = value; }
+ }
+
+ public int creation_date {
+ get { return _creation_date; }
+ set { _creation_date = value; }
+ }
+
+ public unowned GLib.InputStream read (DPAP.Record record) throws GLib.Error {
+ GLib.error ("read not implemented");
+ }
+
+ public unowned DMAP.Record set_from_blob (GLib.ByteArray blob) {
+ GLib.error ("set_from_blob not implemented");
+ }
+
+ public unowned GLib.ByteArray to_blob () {
+ GLib.error ("to_blob not implemented");
+ }
+}
+
+private class DPAPViewer {
+ private DMAP.MdnsBrowser browser;
+ private DMAP.Connection connection;
+ private Gtk.ListStore liststore;
+ private ViewerDMAPDb db;
+ private ViewerDPAPRecordFactory factory;
+
+ private bool connected_cb (DMAP.Connection connection, bool result, string? reason) {
+ GLib.debug ("%lld entries\n", db.count ());
+
+ db.foreach ((k, v) => {
+ string path;
+ int fd = GLib.FileUtils.open_tmp ("dpapview.XXXXXX", out path);
+ GLib.FileUtils.set_contents (path, (string) ((ViewerDPAPRecord) v).thumbnail, ((ViewerDPAPRecord) v).filesize);
+ var pixbuf = new Gdk.Pixbuf.from_file (path);
+ GLib.FileUtils.close (fd);
+ GLib.FileUtils.unlink (path);
+
+ Gtk.TreeIter iter;
+ liststore.append (out iter);
+ liststore.set (iter, 0, pixbuf, 1, ((ViewerDPAPRecord) v).filename);
+ });
+
+ return true;
+ }
+
+ private void service_added_cb (void *service) {
+ /* FIXME: fix void * argument, see libdmapsharing TODO: */
+ DMAP.MdnsBrowserService *FIXME = service;
+ /* FIXME: fix int cast: should not be requried: */
+ connection = new DPAP.Connection (FIXME->service_name, FIXME->host, (int) FIXME->port, false, db, factory);
+ connection.connect (connected_cb);
+ }
+
+ public DPAPViewer (Gtk.Builder builder) throws GLib.Error {
+ builder.connect_signals (this);
+
+ Gtk.Widget widget = builder.get_object ("window") as Gtk.Widget;
+ Gtk.IconView iconview = builder.get_object ("iconview") as Gtk.IconView;
+ liststore = builder.get_object ("liststore") as Gtk.ListStore;
+ db = new ViewerDMAPDb ();
+ factory = new ViewerDPAPRecordFactory ();
+
+ iconview.set_pixbuf_column (0);
+ iconview.set_text_column (1);
+
+ widget.show_all ();
+
+ browser = new DMAP.MdnsBrowser (DMAP.MdnsBrowserServiceType.DPAP);
+ browser.service_added.connect (service_added_cb);
+ browser.start ();
+ }
+}
+
+int main (string[] args) {
+ Gtk.init (ref args);
+
+ try {
+ var builder = new Gtk.Builder ();
+ builder.add_from_file ("dpapview.ui");
+
+ var dpapviewer = new DPAPViewer (builder);
+
+ Gtk.main ();
+
+ } catch (GLib.Error e) {
+ stderr.printf ("Error: %s\n", e.message);
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/tests/test-daap-record.c b/tests/test-daap-record.c
index 01fc448..6111933 100644
--- a/tests/test-daap-record.c
+++ b/tests/test-daap-record.c
@@ -259,9 +259,9 @@ test_daap_record_class_init (TestDAAPRecordClass *klass)
static void
test_daap_record_daap_iface_init (gpointer iface, gpointer data)
{
- DAAPRecordInterface *daap_record = iface;
+ DAAPRecordIface *daap_record = iface;
- g_assert (G_TYPE_FROM_INTERFACE (daap_record) == TYPE_DAAP_RECORD);
+ g_assert (G_TYPE_FROM_INTERFACE (daap_record) == DAAP_TYPE_RECORD);
daap_record->read = test_daap_record_read;
}
@@ -275,7 +275,7 @@ test_daap_record_dmap_iface_init (gpointer iface, gpointer data)
}
G_DEFINE_TYPE_WITH_CODE (TestDAAPRecord, test_daap_record, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (TYPE_DAAP_RECORD, test_daap_record_daap_iface_init)
+ G_IMPLEMENT_INTERFACE (DAAP_TYPE_RECORD, test_daap_record_daap_iface_init)
G_IMPLEMENT_INTERFACE (DMAP_TYPE_RECORD, test_daap_record_dmap_iface_init))
static void
diff --git a/tests/test-dmap-client.c b/tests/test-dmap-client.c
index 1d33086..aa07e8f 100644
--- a/tests/test-dmap-client.c
+++ b/tests/test-dmap-client.c
@@ -87,13 +87,13 @@ service_added_cb (DMAPMdnsBrowser *browser,
if (factory == NULL) {
g_error ("Error creating record factory");
}
- conn = DMAP_CONNECTION (dmap_connection_new (service->name, service->host, service->port, FALSE, db, factory));
+ conn = DMAP_CONNECTION (daap_connection_new (service->name, service->host, service->port, FALSE, db, factory));
} else {
factory = DMAP_RECORD_FACTORY (test_dpap_record_factory_new ());
if (factory == NULL) {
g_error ("Error creating record factory");
}
- conn = DMAP_CONNECTION (dmap_connection_new (service->name, service->host, service->port, FALSE, db, factory));
+ conn = DMAP_CONNECTION (dpap_connection_new (service->name, service->host, service->port, FALSE, db, factory));
}
dmap_connection_connect (DMAP_CONNECTION (conn), (DMAPConnectionCallback) connected_cb, db);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]