diff options
author | Mark Ryan <mark.d.ryan@intel.com> | 2012-09-14 17:06:27 +0200 |
---|---|---|
committer | Mark Ryan <mark.d.ryan@intel.com> | 2012-09-14 17:06:27 +0200 |
commit | a4715d2e8aa44865a0b11fd0ac27ae7049cf5170 (patch) | |
tree | 44ad3fdd902545b93cb2ada1b643016accc0d0bb /libgupnp-av | |
download | GUPnP-AV-a4715d2e8aa44865a0b11fd0ac27ae7049cf5170.tar.gz GUPnP-AV-a4715d2e8aa44865a0b11fd0ac27ae7049cf5170.tar.bz2 GUPnP-AV-a4715d2e8aa44865a0b11fd0ac27ae7049cf5170.zip |
Initial submission of GUPnP-AV to Tizen IVIsubmit/trunk/20120924.173142accepted/trunk/20120924.1713471.0_branch1.0
Diffstat (limited to 'libgupnp-av')
40 files changed, 11412 insertions, 0 deletions
diff --git a/libgupnp-av/Makefile.am b/libgupnp-av/Makefile.am new file mode 100644 index 0000000..40475ed --- /dev/null +++ b/libgupnp-av/Makefile.am @@ -0,0 +1,114 @@ +# Version format current:revision:age +# If the library source code has changed at all since the last update, then +# increment revision (‘c:r:a’ becomes ‘c:r+1:a’). +# If any interfaces have been added, removed, or changed since the last update, +# increment current, and set revision to 0. +# If any interfaces have been added since the last public release, then +# increment age. +# If any interfaces have been removed since the last public release, then set +# age to 0. +LTVERSION = 2:0:0 + +AM_CFLAGS = $(LIBGUPNP_CFLAGS) -I$(top_srcdir) + +libgupnp_av_incdir = $(includedir)/gupnp-av-1.0/libgupnp-av + +lib_LTLIBRARIES = libgupnp-av-1.0.la + +libgupnp_av_inc_HEADERS = gupnp-didl-lite-object.h \ + gupnp-didl-lite-item.h \ + gupnp-didl-lite-container.h \ + gupnp-didl-lite-parser.h \ + gupnp-didl-lite-resource.h \ + gupnp-didl-lite-descriptor.h \ + gupnp-didl-lite-contributor.h \ + gupnp-didl-lite-writer.h \ + gupnp-protocol-info.h \ + gupnp-search-criteria-parser.h \ + gupnp-last-change-parser.h \ + gupnp-dlna.h \ + gupnp-av-error.h \ + gupnp-av.h + + +gupnp-av-marshal.c: gupnp-av-marshal.list + $(AM_V_GEN) \ + $(GLIB_GENMARSHAL) --prefix=gupnp_av_marshal $(srcdir)/gupnp-av-marshal.list --header --body > gupnp-av-marshal.c + +gupnp-av-marshal.h: gupnp-av-marshal.list + $(AM_V_GEN) \ + $(GLIB_GENMARSHAL) --prefix=gupnp_av_marshal $(srcdir)/gupnp-av-marshal.list --header > gupnp-av-marshal.h + +BUILT_SOURCES = gupnp-av-marshal.c gupnp-av-marshal.h + +libgupnp_av_1_0_la_LDFLAGS = -version-info $(LTVERSION) -no-undefined + +libgupnp_av_1_0_la_SOURCES = gupnp-didl-lite-object.c \ + gupnp-didl-lite-object-private.h \ + gupnp-didl-lite-item.c \ + gupnp-didl-lite-container.c \ + gupnp-didl-lite-parser.c \ + gupnp-didl-lite-resource.c \ + gupnp-didl-lite-resource-private.h \ + gupnp-didl-lite-descriptor.c \ + gupnp-didl-lite-descriptor-private.h \ + gupnp-didl-lite-contributor.c \ + gupnp-didl-lite-contributor-private.h \ + gupnp-didl-lite-writer.c \ + gupnp-protocol-info.c \ + gupnp-search-criteria-parser.c \ + gupnp-last-change-parser.c \ + gupnp-dlna.c \ + gupnp-av-error.c \ + xml-util.c \ + xml-util.h \ + gvalue-util.c \ + gvalue-util.h \ + $(BUILT_SOURCES) + +libgupnp_av_1_0_la_LIBADD = $(LIBGUPNP_LIBS) + +EXTRA_DIST = gupnp-av-marshal.list + +-include $(INTROSPECTION_MAKEFILE) +INTROSPECTION_GIRS = +INTROSPECTION_SCANNER_ARGS = --warn-all --add-include-path=$(srcdir) +INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir) + +if HAVE_INTROSPECTION +introspection_sources = \ + $(addprefix $(top_srcdir)/libgupnp-av/, \ + $(libgupnp_av_inc_HEADERS)) \ + $(top_srcdir)/libgupnp-av/gupnp-didl-lite-object.c \ + $(top_srcdir)/libgupnp-av/gupnp-didl-lite-item.c \ + $(top_srcdir)/libgupnp-av/gupnp-didl-lite-container.c \ + $(top_srcdir)/libgupnp-av/gupnp-didl-lite-parser.c \ + $(top_srcdir)/libgupnp-av/gupnp-didl-lite-resource.c \ + $(top_srcdir)/libgupnp-av/gupnp-didl-lite-descriptor.c \ + $(top_srcdir)/libgupnp-av/gupnp-didl-lite-contributor.c \ + $(top_srcdir)/libgupnp-av/gupnp-didl-lite-writer.c \ + $(top_srcdir)/libgupnp-av/gupnp-protocol-info.c \ + $(top_srcdir)/libgupnp-av/gupnp-search-criteria-parser.c \ + $(top_srcdir)/libgupnp-av/gupnp-last-change-parser.c \ + $(top_srcdir)/libgupnp-av/gupnp-dlna.c \ + $(top_srcdir)/libgupnp-av/gupnp-av-error.c + +GUPnPAV-1.0.gir: libgupnp-av-1.0.la +GUPnPAV_1_0_gir_INCLUDES = GObject-2.0 GSSDP-1.0 Soup-2.4 libxml2-2.0 GUPnP-1.0 +GUPnPAV_1_0_gir_CFLAGS = $(AM_CFLAGS) +GUPnPAV_1_0_gir_LIBS = libgupnp-av-1.0.la +GUPnPAV_1_0_gir_SCANNERFLAGS = --identifier-prefix=GUPnP --symbol-prefix=gupnp --pkg-export=gupnp-av-1.0 +GUPnPAV_1_0_gir_FILES = $(introspection_sources) +INTROSPECTION_GIRS += GUPnPAV-1.0.gir + +girdir = $(INTROSPECTION_GIRDIR) +gir_DATA = $(INTROSPECTION_GIRS) + +typelibdir = $(INTROSPECTION_TYPELIBDIR) +typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib) +endif + +CLEANFILES = $(BUILT_SOURCES) $(gir_DATA) $(typelib_DATA) +DISTCLEANFILES = $(BUILT_SOURCES) +MAINTAINERCLEANFILES = Makefile.in $(BUILT_SOURCES) + diff --git a/libgupnp-av/Makefile.in b/libgupnp-av/Makefile.in new file mode 100644 index 0000000..4b8de7c --- /dev/null +++ b/libgupnp-av/Makefile.in @@ -0,0 +1,765 @@ +# Makefile.in generated by automake 1.11.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@HAVE_INTROSPECTION_TRUE@am__append_1 = GUPnPAV-1.0.gir +subdir = libgupnp-av +DIST_COMMON = $(libgupnp_av_inc_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/gtk-doc.m4 \ + $(top_srcdir)/m4/introspection.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(girdir)" \ + "$(DESTDIR)$(typelibdir)" "$(DESTDIR)$(libgupnp_av_incdir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +am__DEPENDENCIES_1 = +libgupnp_av_1_0_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am__objects_1 = gupnp-av-marshal.lo +am_libgupnp_av_1_0_la_OBJECTS = gupnp-didl-lite-object.lo \ + gupnp-didl-lite-item.lo gupnp-didl-lite-container.lo \ + gupnp-didl-lite-parser.lo gupnp-didl-lite-resource.lo \ + gupnp-didl-lite-descriptor.lo gupnp-didl-lite-contributor.lo \ + gupnp-didl-lite-writer.lo gupnp-protocol-info.lo \ + gupnp-search-criteria-parser.lo gupnp-last-change-parser.lo \ + gupnp-dlna.lo gupnp-av-error.lo xml-util.lo gvalue-util.lo \ + $(am__objects_1) +libgupnp_av_1_0_la_OBJECTS = $(am_libgupnp_av_1_0_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +libgupnp_av_1_0_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(libgupnp_av_1_0_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = $(libgupnp_av_1_0_la_SOURCES) +DIST_SOURCES = $(libgupnp_av_1_0_la_SOURCES) +DATA = $(gir_DATA) $(typelib_DATA) +HEADERS = $(libgupnp_av_inc_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GREP = @GREP@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ +GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +HTML_DIR = @HTML_DIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ +INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ +INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ +INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ +INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ +INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBGUPNP_CFLAGS = @LIBGUPNP_CFLAGS@ +LIBGUPNP_LIBS = @LIBGUPNP_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ + +# Version format current:revision:age +# If the library source code has changed at all since the last update, then +# increment revision (‘c:r:a’ becomes ‘c:r+1:a’). +# If any interfaces have been added, removed, or changed since the last update, +# increment current, and set revision to 0. +# If any interfaces have been added since the last public release, then +# increment age. +# If any interfaces have been removed since the last public release, then set +# age to 0. +LTVERSION = 2:0:0 +AM_CFLAGS = $(LIBGUPNP_CFLAGS) -I$(top_srcdir) +libgupnp_av_incdir = $(includedir)/gupnp-av-1.0/libgupnp-av +lib_LTLIBRARIES = libgupnp-av-1.0.la +libgupnp_av_inc_HEADERS = gupnp-didl-lite-object.h \ + gupnp-didl-lite-item.h \ + gupnp-didl-lite-container.h \ + gupnp-didl-lite-parser.h \ + gupnp-didl-lite-resource.h \ + gupnp-didl-lite-descriptor.h \ + gupnp-didl-lite-contributor.h \ + gupnp-didl-lite-writer.h \ + gupnp-protocol-info.h \ + gupnp-search-criteria-parser.h \ + gupnp-last-change-parser.h \ + gupnp-dlna.h \ + gupnp-av-error.h \ + gupnp-av.h + +BUILT_SOURCES = gupnp-av-marshal.c gupnp-av-marshal.h +libgupnp_av_1_0_la_LDFLAGS = -version-info $(LTVERSION) -no-undefined +libgupnp_av_1_0_la_SOURCES = gupnp-didl-lite-object.c \ + gupnp-didl-lite-object-private.h \ + gupnp-didl-lite-item.c \ + gupnp-didl-lite-container.c \ + gupnp-didl-lite-parser.c \ + gupnp-didl-lite-resource.c \ + gupnp-didl-lite-resource-private.h \ + gupnp-didl-lite-descriptor.c \ + gupnp-didl-lite-descriptor-private.h \ + gupnp-didl-lite-contributor.c \ + gupnp-didl-lite-contributor-private.h \ + gupnp-didl-lite-writer.c \ + gupnp-protocol-info.c \ + gupnp-search-criteria-parser.c \ + gupnp-last-change-parser.c \ + gupnp-dlna.c \ + gupnp-av-error.c \ + xml-util.c \ + xml-util.h \ + gvalue-util.c \ + gvalue-util.h \ + $(BUILT_SOURCES) + +libgupnp_av_1_0_la_LIBADD = $(LIBGUPNP_LIBS) +EXTRA_DIST = gupnp-av-marshal.list +INTROSPECTION_GIRS = $(am__append_1) +INTROSPECTION_SCANNER_ARGS = --warn-all --add-include-path=$(srcdir) +INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir) +@HAVE_INTROSPECTION_TRUE@introspection_sources = \ +@HAVE_INTROSPECTION_TRUE@ $(addprefix $(top_srcdir)/libgupnp-av/, \ +@HAVE_INTROSPECTION_TRUE@ $(libgupnp_av_inc_HEADERS)) \ +@HAVE_INTROSPECTION_TRUE@ $(top_srcdir)/libgupnp-av/gupnp-didl-lite-object.c \ +@HAVE_INTROSPECTION_TRUE@ $(top_srcdir)/libgupnp-av/gupnp-didl-lite-item.c \ +@HAVE_INTROSPECTION_TRUE@ $(top_srcdir)/libgupnp-av/gupnp-didl-lite-container.c \ +@HAVE_INTROSPECTION_TRUE@ $(top_srcdir)/libgupnp-av/gupnp-didl-lite-parser.c \ +@HAVE_INTROSPECTION_TRUE@ $(top_srcdir)/libgupnp-av/gupnp-didl-lite-resource.c \ +@HAVE_INTROSPECTION_TRUE@ $(top_srcdir)/libgupnp-av/gupnp-didl-lite-descriptor.c \ +@HAVE_INTROSPECTION_TRUE@ $(top_srcdir)/libgupnp-av/gupnp-didl-lite-contributor.c \ +@HAVE_INTROSPECTION_TRUE@ $(top_srcdir)/libgupnp-av/gupnp-didl-lite-writer.c \ +@HAVE_INTROSPECTION_TRUE@ $(top_srcdir)/libgupnp-av/gupnp-protocol-info.c \ +@HAVE_INTROSPECTION_TRUE@ $(top_srcdir)/libgupnp-av/gupnp-search-criteria-parser.c \ +@HAVE_INTROSPECTION_TRUE@ $(top_srcdir)/libgupnp-av/gupnp-last-change-parser.c \ +@HAVE_INTROSPECTION_TRUE@ $(top_srcdir)/libgupnp-av/gupnp-dlna.c \ +@HAVE_INTROSPECTION_TRUE@ $(top_srcdir)/libgupnp-av/gupnp-av-error.c + +@HAVE_INTROSPECTION_TRUE@GUPnPAV_1_0_gir_INCLUDES = GObject-2.0 GSSDP-1.0 Soup-2.4 libxml2-2.0 GUPnP-1.0 +@HAVE_INTROSPECTION_TRUE@GUPnPAV_1_0_gir_CFLAGS = $(AM_CFLAGS) +@HAVE_INTROSPECTION_TRUE@GUPnPAV_1_0_gir_LIBS = libgupnp-av-1.0.la +@HAVE_INTROSPECTION_TRUE@GUPnPAV_1_0_gir_SCANNERFLAGS = --identifier-prefix=GUPnP --symbol-prefix=gupnp --pkg-export=gupnp-av-1.0 +@HAVE_INTROSPECTION_TRUE@GUPnPAV_1_0_gir_FILES = $(introspection_sources) +@HAVE_INTROSPECTION_TRUE@girdir = $(INTROSPECTION_GIRDIR) +@HAVE_INTROSPECTION_TRUE@gir_DATA = $(INTROSPECTION_GIRS) +@HAVE_INTROSPECTION_TRUE@typelibdir = $(INTROSPECTION_TYPELIBDIR) +@HAVE_INTROSPECTION_TRUE@typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib) +CLEANFILES = $(BUILT_SOURCES) $(gir_DATA) $(typelib_DATA) +DISTCLEANFILES = $(BUILT_SOURCES) +MAINTAINERCLEANFILES = Makefile.in $(BUILT_SOURCES) +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libgupnp-av/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu libgupnp-av/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libgupnp-av-1.0.la: $(libgupnp_av_1_0_la_OBJECTS) $(libgupnp_av_1_0_la_DEPENDENCIES) $(EXTRA_libgupnp_av_1_0_la_DEPENDENCIES) + $(AM_V_CCLD)$(libgupnp_av_1_0_la_LINK) -rpath $(libdir) $(libgupnp_av_1_0_la_OBJECTS) $(libgupnp_av_1_0_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gupnp-av-error.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gupnp-av-marshal.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gupnp-didl-lite-container.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gupnp-didl-lite-contributor.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gupnp-didl-lite-descriptor.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gupnp-didl-lite-item.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gupnp-didl-lite-object.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gupnp-didl-lite-parser.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gupnp-didl-lite-resource.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gupnp-didl-lite-writer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gupnp-dlna.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gupnp-last-change-parser.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gupnp-protocol-info.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gupnp-search-criteria-parser.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gvalue-util.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml-util.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-girDATA: $(gir_DATA) + @$(NORMAL_INSTALL) + test -z "$(girdir)" || $(MKDIR_P) "$(DESTDIR)$(girdir)" + @list='$(gir_DATA)'; test -n "$(girdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(girdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(girdir)" || exit $$?; \ + done + +uninstall-girDATA: + @$(NORMAL_UNINSTALL) + @list='$(gir_DATA)'; test -n "$(girdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(girdir)'; $(am__uninstall_files_from_dir) +install-typelibDATA: $(typelib_DATA) + @$(NORMAL_INSTALL) + test -z "$(typelibdir)" || $(MKDIR_P) "$(DESTDIR)$(typelibdir)" + @list='$(typelib_DATA)'; test -n "$(typelibdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(typelibdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(typelibdir)" || exit $$?; \ + done + +uninstall-typelibDATA: + @$(NORMAL_UNINSTALL) + @list='$(typelib_DATA)'; test -n "$(typelibdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(typelibdir)'; $(am__uninstall_files_from_dir) +install-libgupnp_av_incHEADERS: $(libgupnp_av_inc_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(libgupnp_av_incdir)" || $(MKDIR_P) "$(DESTDIR)$(libgupnp_av_incdir)" + @list='$(libgupnp_av_inc_HEADERS)'; test -n "$(libgupnp_av_incdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libgupnp_av_incdir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(libgupnp_av_incdir)" || exit $$?; \ + done + +uninstall-libgupnp_av_incHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(libgupnp_av_inc_HEADERS)'; test -n "$(libgupnp_av_incdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(libgupnp_av_incdir)'; $(am__uninstall_files_from_dir) + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(girdir)" "$(DESTDIR)$(typelibdir)" "$(DESTDIR)$(libgupnp_av_incdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-girDATA install-libgupnp_av_incHEADERS \ + install-typelibDATA + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-girDATA uninstall-libLTLIBRARIES \ + uninstall-libgupnp_av_incHEADERS uninstall-typelibDATA + +.MAKE: all check install install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-girDATA \ + install-html install-html-am install-info install-info-am \ + install-libLTLIBRARIES install-libgupnp_av_incHEADERS \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip install-typelibDATA installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-girDATA \ + uninstall-libLTLIBRARIES uninstall-libgupnp_av_incHEADERS \ + uninstall-typelibDATA + + +gupnp-av-marshal.c: gupnp-av-marshal.list + $(AM_V_GEN) \ + $(GLIB_GENMARSHAL) --prefix=gupnp_av_marshal $(srcdir)/gupnp-av-marshal.list --header --body > gupnp-av-marshal.c + +gupnp-av-marshal.h: gupnp-av-marshal.list + $(AM_V_GEN) \ + $(GLIB_GENMARSHAL) --prefix=gupnp_av_marshal $(srcdir)/gupnp-av-marshal.list --header > gupnp-av-marshal.h + +-include $(INTROSPECTION_MAKEFILE) + +@HAVE_INTROSPECTION_TRUE@GUPnPAV-1.0.gir: libgupnp-av-1.0.la + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libgupnp-av/gupnp-av-error.c b/libgupnp-av/gupnp-av-error.c new file mode 100644 index 0000000..d205997 --- /dev/null +++ b/libgupnp-av/gupnp-av-error.c @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2009, Nokia Corporation. + * Copyright (C) 2006, 2007 OpenedHand Ltd. + * + * Authors: Zeeshan Ali (Khattak) <zeeshanak@gnome.org> + * <zeeshan.ali@nokia.com> + * Jorn Baayen <jorn@openedhand.com> + * + * 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. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "gupnp-av-error.h" + +/** + * SECTION:gupnp-av-error + * @short_description: Error domains and codes. + */ + +/** + * GUPNP_PROTOCOL_ERROR: + * + * The #GQuark uniquely used by GUPnP AV protocol related errors. + * + * Returns: a #GQuark uniquely used by GUPnP AV protocol related errors. + **/ +GQuark +gupnp_protocol_error_quark (void) +{ + static GQuark quark = 0; + + if (!quark) + quark = g_quark_from_static_string ("gupnp-protocol-error"); + + return quark; +} diff --git a/libgupnp-av/gupnp-av-error.h b/libgupnp-av/gupnp-av-error.h new file mode 100644 index 0000000..20b0477 --- /dev/null +++ b/libgupnp-av/gupnp-av-error.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2009, Nokia Corporation. + * Copyright (C) 2006, 2007 OpenedHand Ltd. + * + * Authors: Zeeshan Ali (Khattak) <zeeshanak@gnome.org> + * <zeeshan.ali@nokia.com> + * Jorn Baayen <jorn@openedhand.com> + * + * 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. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __GUPNP_AV_ERROR_H__ +#define __GUPNP_AV_ERROR_H__ + +#include <glib.h> + +G_BEGIN_DECLS + +GQuark +gupnp_protocol_error_quark (void) G_GNUC_CONST; + +#define GUPNP_PROTOCOL_ERROR (gupnp_protocol_error_quark ()) + +/** + * GUPnPProtocolError: + * @GUPNP_PROTOCOL_ERROR_INVALID_SYNTAX: Invalid syntax. + * @GUPNP_PROTOCOL_ERROR_OTHER: Unknown/unhandled protocol related errors. + * + * #GError codes used for errors in the #GUPNP_PROTOCOL_ERROR domain, upon any + * protocol related errors. + */ +typedef enum { + GUPNP_PROTOCOL_ERROR_INVALID_SYNTAX, + GUPNP_PROTOCOL_ERROR_OTHER +} GUPnPProtocolError; + +G_END_DECLS + +#endif /* __GUPNP_AV_ERROR_H__ */ diff --git a/libgupnp-av/gupnp-av-marshal.c b/libgupnp-av/gupnp-av-marshal.c new file mode 100644 index 0000000..dcc0a24 --- /dev/null +++ b/libgupnp-av/gupnp-av-marshal.c @@ -0,0 +1,110 @@ + +#ifndef __gupnp_av_marshal_MARSHAL_H__ +#define __gupnp_av_marshal_MARSHAL_H__ + +#include <glib-object.h> + +G_BEGIN_DECLS + +#ifdef G_ENABLE_DEBUG +#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) +#define g_marshal_value_peek_char(v) g_value_get_schar (v) +#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) +#define g_marshal_value_peek_int(v) g_value_get_int (v) +#define g_marshal_value_peek_uint(v) g_value_get_uint (v) +#define g_marshal_value_peek_long(v) g_value_get_long (v) +#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) +#define g_marshal_value_peek_int64(v) g_value_get_int64 (v) +#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) +#define g_marshal_value_peek_enum(v) g_value_get_enum (v) +#define g_marshal_value_peek_flags(v) g_value_get_flags (v) +#define g_marshal_value_peek_float(v) g_value_get_float (v) +#define g_marshal_value_peek_double(v) g_value_get_double (v) +#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) +#define g_marshal_value_peek_param(v) g_value_get_param (v) +#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) +#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) +#define g_marshal_value_peek_object(v) g_value_get_object (v) +#define g_marshal_value_peek_variant(v) g_value_get_variant (v) +#else /* !G_ENABLE_DEBUG */ +/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. + * Do not access GValues directly in your code. Instead, use the + * g_value_get_*() functions + */ +#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int +#define g_marshal_value_peek_char(v) (v)->data[0].v_int +#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint +#define g_marshal_value_peek_int(v) (v)->data[0].v_int +#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint +#define g_marshal_value_peek_long(v) (v)->data[0].v_long +#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong +#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 +#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 +#define g_marshal_value_peek_enum(v) (v)->data[0].v_long +#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong +#define g_marshal_value_peek_float(v) (v)->data[0].v_float +#define g_marshal_value_peek_double(v) (v)->data[0].v_double +#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer +#endif /* !G_ENABLE_DEBUG */ + + +/* BOOLEAN:STRING,UINT,STRING,POINTER (./gupnp-av-marshal.list:1) */ +extern void gupnp_av_marshal_BOOLEAN__STRING_UINT_STRING_POINTER (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +void +gupnp_av_marshal_BOOLEAN__STRING_UINT_STRING_POINTER (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__STRING_UINT_STRING_POINTER) (gpointer data1, + gpointer arg_1, + guint arg_2, + gpointer arg_3, + gpointer arg_4, + gpointer data2); + register GMarshalFunc_BOOLEAN__STRING_UINT_STRING_POINTER callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 5); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__STRING_UINT_STRING_POINTER) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_string (param_values + 1), + g_marshal_value_peek_uint (param_values + 2), + g_marshal_value_peek_string (param_values + 3), + g_marshal_value_peek_pointer (param_values + 4), + data2); + + g_value_set_boolean (return_value, v_return); +} + +G_END_DECLS + +#endif /* __gupnp_av_marshal_MARSHAL_H__ */ + diff --git a/libgupnp-av/gupnp-av-marshal.h b/libgupnp-av/gupnp-av-marshal.h new file mode 100644 index 0000000..fc9c825 --- /dev/null +++ b/libgupnp-av/gupnp-av-marshal.h @@ -0,0 +1,20 @@ + +#ifndef __gupnp_av_marshal_MARSHAL_H__ +#define __gupnp_av_marshal_MARSHAL_H__ + +#include <glib-object.h> + +G_BEGIN_DECLS + +/* BOOLEAN:STRING,UINT,STRING,POINTER (./gupnp-av-marshal.list:1) */ +extern void gupnp_av_marshal_BOOLEAN__STRING_UINT_STRING_POINTER (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +G_END_DECLS + +#endif /* __gupnp_av_marshal_MARSHAL_H__ */ + diff --git a/libgupnp-av/gupnp-av-marshal.list b/libgupnp-av/gupnp-av-marshal.list new file mode 100644 index 0000000..e66081d --- /dev/null +++ b/libgupnp-av/gupnp-av-marshal.list @@ -0,0 +1 @@ +BOOLEAN:STRING,UINT,STRING,POINTER diff --git a/libgupnp-av/gupnp-av.h b/libgupnp-av/gupnp-av.h new file mode 100644 index 0000000..63ee485 --- /dev/null +++ b/libgupnp-av/gupnp-av.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2007 Zeeshan Ali (Khattak) <zeeshanak@gnome.org> + * Copyright (C) 2006, 2007, 2008 OpenedHand Ltd. + * + * Author: Zeeshan Ali Khattak <zeenix@gstreamer.net> + * Jorn Baayen <jorn@openedhand.com> + * + * 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. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "gupnp-didl-lite-object.h" +#include "gupnp-didl-lite-container.h" +#include "gupnp-didl-lite-item.h" +#include "gupnp-didl-lite-parser.h" +#include "gupnp-didl-lite-resource.h" +#include "gupnp-didl-lite-descriptor.h" +#include "gupnp-didl-lite-writer.h" +#include "gupnp-protocol-info.h" +#include "gupnp-search-criteria-parser.h" +#include "gupnp-last-change-parser.h" +#include "gupnp-dlna.h" + diff --git a/libgupnp-av/gupnp-didl-lite-container.c b/libgupnp-av/gupnp-didl-lite-container.c new file mode 100644 index 0000000..1a0abf4 --- /dev/null +++ b/libgupnp-av/gupnp-didl-lite-container.c @@ -0,0 +1,575 @@ +/* + * Copyright (C) 2009 Nokia Corporation. + * + * Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com> + * <zeeshanak@gnome.org> + * + * 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. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +/** + * SECTION:gupnp-didl-lite-container + * @short_description: DIDL-Lite Container + * + * #GUPnPDIDLLiteContainer respresents a DIDL-Lite container element. + */ + +#include <string.h> + +#include "gupnp-didl-lite-container.h" +#include "xml-util.h" + +G_DEFINE_TYPE (GUPnPDIDLLiteContainer, + gupnp_didl_lite_container, + GUPNP_TYPE_DIDL_LITE_OBJECT); + +enum { + PROP_0, + PROP_SEARCHABLE, + PROP_CHILD_COUNT, + PROP_STORAGE_USED +}; + +static void +gupnp_didl_lite_container_init (GUPnPDIDLLiteContainer *container) +{ + /* Nothing to initialize, yay! */ +} + +static void +gupnp_didl_lite_container_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + GUPnPDIDLLiteContainer *container; + + container = GUPNP_DIDL_LITE_CONTAINER (object); + + switch (property_id) { + case PROP_SEARCHABLE: + g_value_set_boolean + (value, + gupnp_didl_lite_container_get_searchable (container)); + break; + case PROP_CHILD_COUNT: + g_value_set_int + (value, + gupnp_didl_lite_container_get_child_count (container)); + break; + case PROP_STORAGE_USED: + g_value_set_long + (value, + gupnp_didl_lite_container_get_storage_used (container)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gupnp_didl_lite_container_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) + +{ + GUPnPDIDLLiteContainer *container; + + container = GUPNP_DIDL_LITE_CONTAINER (object); + + switch (property_id) { + case PROP_SEARCHABLE: + gupnp_didl_lite_container_set_searchable + (container, + g_value_get_boolean (value)); + break; + case PROP_CHILD_COUNT: + gupnp_didl_lite_container_set_child_count + (container, + g_value_get_int (value)); + break; + case PROP_STORAGE_USED: + gupnp_didl_lite_container_set_storage_used + (container, + g_value_get_int64 (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gupnp_didl_lite_container_class_init (GUPnPDIDLLiteContainerClass *klass) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = gupnp_didl_lite_container_get_property; + object_class->set_property = gupnp_didl_lite_container_set_property; + + /** + * GUPnPDIDLLiteContainer:searchable: + * + * Whether this container is searchable. + **/ + g_object_class_install_property + (object_class, + PROP_SEARCHABLE, + g_param_spec_boolean ("searchable", + "Searchable", + "Whether this container is searchable.", + FALSE, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteContainer:child-count: + * + * The child count of this container. + **/ + g_object_class_install_property + (object_class, + PROP_CHILD_COUNT, + g_param_spec_int ("child-count", + "ChildCount", + "The child count of this container.", + 0, + G_MAXINT, + 0, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteContainer:storage-used: + * + * The number of bytes used by all child items of this container. + **/ + g_object_class_install_property + (object_class, + PROP_STORAGE_USED, + g_param_spec_int64 ("storage-used", + "Storage Used", + "The Number of bytes used by all child " + "items of this container.", + -1, + G_MAXINT64, + -1, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); +} + +/** + * gupnp_didl_lite_container_get_searchable: + * @container: #GUPnPDIDLLiteContainer + * + * Checks whether @container is searchable. + * + * Return value: #TRUE if @container is searchable. + **/ +gboolean +gupnp_didl_lite_container_get_searchable (GUPnPDIDLLiteContainer *container) +{ + xmlNode *xml_node; + + g_return_val_if_fail (container != NULL, FALSE); + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_CONTAINER (container), FALSE); + + xml_node = gupnp_didl_lite_object_get_xml_node + (GUPNP_DIDL_LITE_OBJECT (container)); + + return xml_util_get_boolean_attribute (xml_node, "searchable"); +} + +/** + * gupnp_didl_lite_container_get_child_count: + * @container: #GUPnPDIDLLiteContainer + * + * Get the child count of the @container. If the child count is unknown, -1 is + * returned. + * + * Return value: The child count of the @container, or -1 if it is unknown. + **/ +gint +gupnp_didl_lite_container_get_child_count (GUPnPDIDLLiteContainer *container) +{ + xmlNode *xml_node; + + g_return_val_if_fail (container != NULL, 0); + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_CONTAINER (container), 0); + + xml_node = gupnp_didl_lite_object_get_xml_node + (GUPNP_DIDL_LITE_OBJECT (container)); + + return xml_util_get_int_attribute (xml_node, "childCount", -1); +} + +/** + * gupnp_didl_lite_container_get_create_classes: + * @container: #GUPnPDIDLLiteContainer + * + * Gets the list of create classes of the @object. + * + * Returns: (element-type utf8) (transfer full): The list of create classes + * belonging to @object, or %NULL. + * #g_list_free the returned list after usage and #g_free each string in it. + **/ +GList * +gupnp_didl_lite_container_get_create_classes (GUPnPDIDLLiteContainer *container) +{ + GList *classes = NULL; + GList *ret = NULL; + GList *l; + + g_return_val_if_fail (container != NULL, NULL); + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_CONTAINER (container), NULL); + + classes = gupnp_didl_lite_object_get_properties ( + GUPNP_DIDL_LITE_OBJECT (container), + "createClass"); + + for (l = classes; l; l = l->next) { + char *create_class; + xmlNode *node; + + node = (xmlNode *) l->data; + if (node->children != NULL) { + create_class = g_strdup ((const char *) node->children->content); + + ret = g_list_append (ret, create_class); + } + } + + g_list_free (classes); + + return ret; +} + +/** + * gupnp_didl_lite_container_get_search_classes: + * @container: #GUPnPDIDLLiteContainer + * + * Gets the list of search classes of the @object. + * + * Return value: (element-type utf8) (transfer full): The list of search classes + * belonging to @object, or %NULL. #g_list_free the returned list after usage + * and #g_free each string in it. + **/ +GList * +gupnp_didl_lite_container_get_search_classes (GUPnPDIDLLiteContainer *container) +{ + GList *classes = NULL; + GList *ret = NULL; + GList *l; + + g_return_val_if_fail (container != NULL, NULL); + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_CONTAINER (container), NULL); + + classes = gupnp_didl_lite_object_get_properties ( + GUPNP_DIDL_LITE_OBJECT (container), + "searchClass"); + + for (l = classes; l; l = l->next) { + char *search_class; + xmlNode *node; + + node = (xmlNode *) l->data; + if (node->children != NULL) { + search_class = g_strdup ((const char *) node->children->content); + + ret = g_list_append (ret, search_class); + } + } + + g_list_free (classes); + + return ret; +} + +/** + * gupnp_didl_lite_container_get_storage_used: + * @container: #GUPnPDIDLLiteContainer + * + * Get the number of bytes used by all child items of the @container. + * If storage used is unknown, -1 is returned. + * + * Return value: The number of bytes used by all children of the @container, + * or -1 if it is unknown. + **/ +gint64 +gupnp_didl_lite_container_get_storage_used (GUPnPDIDLLiteContainer *container) +{ + GList *storage = NULL; + xmlNode *xml_node; + const char *str; + + g_return_val_if_fail (container != NULL, 0); + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_CONTAINER (container), 0); + + storage = gupnp_didl_lite_object_get_properties ( + GUPNP_DIDL_LITE_OBJECT (container), + "storageUsed"); + if (storage == NULL) + return -1; + + /* only return value from first node */ + xml_node = (xmlNode *) storage->data; + + g_list_free (storage); + + str = (const char *) xml_node->content; + + return g_ascii_strtoll (str, NULL, 10); +} +/** + * gupnp_didl_lite_container_set_searchable: + * @container: #GUPnPDIDLLiteContainer + * @searchable: The searchibility + * + * (Un)set the searchibility of @container. + **/ +void +gupnp_didl_lite_container_set_searchable (GUPnPDIDLLiteContainer *container, + gboolean searchable) +{ + xmlNode *xml_node; + const char *str; + + g_return_if_fail (container != NULL); + g_return_if_fail (GUPNP_IS_DIDL_LITE_CONTAINER (container)); + + xml_node = gupnp_didl_lite_object_get_xml_node + (GUPNP_DIDL_LITE_OBJECT (container)); + + if (searchable) + str = "1"; + else + str = "0"; + xmlSetProp (xml_node, + (unsigned char *) "searchable", + (unsigned char *) str); + + g_object_notify (G_OBJECT (container), "searchable"); +} + +/** + * gupnp_didl_lite_container_set_child_count: + * @container: #GUPnPDIDLLiteContainer + * @child_count: The child count + * + * Set the child count of the @container. + **/ +void +gupnp_didl_lite_container_set_child_count (GUPnPDIDLLiteContainer *container, + gint child_count) +{ + xmlNode *xml_node; + char *str; + + g_return_if_fail (container != NULL); + g_return_if_fail (GUPNP_IS_DIDL_LITE_CONTAINER (container)); + + xml_node = gupnp_didl_lite_object_get_xml_node + (GUPNP_DIDL_LITE_OBJECT (container)); + + str = g_strdup_printf ("%d", child_count); + xmlSetProp (xml_node, + (unsigned char *) "childCount", + (unsigned char *) str); + g_free (str); + + g_object_notify (G_OBJECT (container), "child-count"); +} + +/** + * gupnp_didl_lite_container_add_create_class: + * @container: #GUPnPDIDLLiteContainer + * @create_class: The createClass to add. + * + * Add a new create class to the @object. includeDerived defaults to "0". + * + * Return value: None. + **/ +void +gupnp_didl_lite_container_add_create_class ( + GUPnPDIDLLiteContainer *container, + const char *create_class) +{ + gupnp_didl_lite_container_add_create_class_full (container, + create_class, + FALSE); +} + +/** + * gupnp_didl_lite_container_add_create_class_full: + * @container: #GUPnPDIDLLiteContainer + * @create_class: The createClass to add. + * @include_derived: Whether object with dervied classes may be created in + * this container or not. + * + * Add a new create class to the @object. + * + * Return value: None. + **/ +void +gupnp_didl_lite_container_add_create_class_full ( + GUPnPDIDLLiteContainer *container, + const char *create_class, + gboolean include_derived) +{ + xmlNode *container_node, *new_node; + xmlNs *namespace; + const char *str; + + g_return_if_fail (container != NULL); + g_return_if_fail (GUPNP_IS_DIDL_LITE_CONTAINER (container)); + + container_node = gupnp_didl_lite_object_get_xml_node + (GUPNP_DIDL_LITE_OBJECT (container)); + namespace = gupnp_didl_lite_object_get_upnp_namespace + (GUPNP_DIDL_LITE_OBJECT (container)); + + new_node = xmlNewChild (container_node, + namespace, + (unsigned char *) "createClass", + (unsigned char *) create_class); + if (include_derived) + str = "1"; + else + str = "0"; + + xmlSetProp (new_node, + (unsigned char *) "includeDerived", + (unsigned char *) str); +} + +/** + * gupnp_didl_lite_container_add_search_class: + * @container: #GUPnPDIDLLiteContainer + * @search_class: The searchClass to add. + * + * Add a new search class to the @object. + * + * Return value: None. + **/ +void +gupnp_didl_lite_container_add_search_class ( + GUPnPDIDLLiteContainer *container, + const char *search_class) +{ + gupnp_didl_lite_container_add_search_class_full (container, + search_class, + TRUE); +} + +/** + * gupnp_didl_lite_container_add_search_class_full: + * @container: #GUPnPDIDLLiteContainer + * @search_class: The searchClass to add. + * @include_derived: includeDerived attribute of the DIDL + * + * Add a new search class to the @object. + * + * Return value: None. + **/ +void +gupnp_didl_lite_container_add_search_class_full ( + GUPnPDIDLLiteContainer *container, + const char *search_class, + gboolean include_derived) +{ + xmlNode *xml_node; + xmlNode *new_xml_node; + xmlNs *namespace; + const char *str; + + g_return_if_fail (container != NULL); + g_return_if_fail (GUPNP_IS_DIDL_LITE_CONTAINER (container)); + + xml_node = gupnp_didl_lite_object_get_xml_node + (GUPNP_DIDL_LITE_OBJECT (container)); + namespace = gupnp_didl_lite_object_get_upnp_namespace + (GUPNP_DIDL_LITE_OBJECT (container)); + + new_xml_node = xmlNewChild (xml_node, + namespace, + (unsigned char *) "searchClass", + (unsigned char *) search_class); + + if (include_derived) + str = "1"; + else + str = "0"; + + xmlSetProp (new_xml_node, + (unsigned char*) "includeDerived", + (unsigned char*) str); +} + +/** + * gupnp_didl_lite_container_set_storage_used: + * @container: #GUPnPDIDLLiteContainer + * @storage_used: The number of bytes used by all child items of the + * @container or -1 if unknown. + * + * Set the number of bytes used by all child items of the @container. + **/ +void +gupnp_didl_lite_container_set_storage_used ( + GUPnPDIDLLiteContainer *container, + gint64 storage_used) +{ + GList *storage = NULL; + xmlNode *xml_node; + xmlNs *namespace; + char *str; + + g_return_if_fail (container != NULL); + g_return_if_fail (GUPNP_IS_DIDL_LITE_CONTAINER (container)); + + xml_node = gupnp_didl_lite_object_get_xml_node + (GUPNP_DIDL_LITE_OBJECT (container)); + + namespace = gupnp_didl_lite_object_get_upnp_namespace + (GUPNP_DIDL_LITE_OBJECT (container)); + + str = g_strdup_printf ("%"G_GINT64_FORMAT, storage_used); + + storage = gupnp_didl_lite_object_get_properties ( + GUPNP_DIDL_LITE_OBJECT (container), + "storageUsed"); + if (storage == NULL) + xmlNewChild (xml_node, + namespace, + (unsigned char *) "storageUsed", + (unsigned char *) str); + else + xmlNodeSetContent ((xmlNode *) storage->data, + (unsigned char *) str); + + g_free (str); + + g_object_notify (G_OBJECT (container), "storage-used"); +} diff --git a/libgupnp-av/gupnp-didl-lite-container.h b/libgupnp-av/gupnp-didl-lite-container.h new file mode 100644 index 0000000..e1af1cd --- /dev/null +++ b/libgupnp-av/gupnp-didl-lite-container.h @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2009 Nokia Corporation. + * + * Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com> + * <zeeshanak@gnome.org> + * + * 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. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __GUPNP_DIDL_LITE_CONTAINER_H__ +#define __GUPNP_DIDL_LITE_CONTAINER_H__ + +#include <glib-object.h> +#include "gupnp-didl-lite-object.h" + +G_BEGIN_DECLS + +GType +gupnp_didl_lite_container_get_type (void) G_GNUC_CONST; + +#define GUPNP_TYPE_DIDL_LITE_CONTAINER \ + (gupnp_didl_lite_container_get_type ()) +#define GUPNP_DIDL_LITE_CONTAINER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + GUPNP_TYPE_DIDL_LITE_CONTAINER, \ + GUPnPDIDLLiteContainer)) +#define GUPNP_DIDL_LITE_CONTAINER_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_CAST ((obj), \ + GUPNP_TYPE_DIDL_LITE_CONTAINER, \ + GUPnPDIDLLiteContainerClass)) +#define GUPNP_IS_DIDL_LITE_CONTAINER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + GUPNP_TYPE_DIDL_LITE_CONTAINER)) +#define GUPNP_IS_DIDL_LITE_CONTAINER_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE ((obj), \ + GUPNP_TYPE_DIDL_LITE_CONTAINER)) +#define GUPNP_DIDL_LITE_CONTAINER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + GUPNP_TYPE_DIDL_LITE_CONTAINER, \ + GUPnPDIDLLiteContainerClass)) + +typedef struct { + GUPnPDIDLLiteObject parent; +} GUPnPDIDLLiteContainer; + +typedef struct { + GUPnPDIDLLiteObjectClass parent_class; + + /* future padding */ + void (* _gupnp_reserved1) (void); + void (* _gupnp_reserved2) (void); + void (* _gupnp_reserved3) (void); + void (* _gupnp_reserved4) (void); +} GUPnPDIDLLiteContainerClass; + +gboolean +gupnp_didl_lite_container_get_searchable + (GUPnPDIDLLiteContainer *container); + +gint +gupnp_didl_lite_container_get_child_count + (GUPnPDIDLLiteContainer *container); + +GList * +gupnp_didl_lite_container_get_create_classes + (GUPnPDIDLLiteContainer *container); + +GList * +gupnp_didl_lite_container_get_search_classes + (GUPnPDIDLLiteContainer *container); + +void +gupnp_didl_lite_container_set_searchable + (GUPnPDIDLLiteContainer *container, + gboolean searchable); + +void +gupnp_didl_lite_container_set_child_count + (GUPnPDIDLLiteContainer *container, + gint child_count); + +void +gupnp_didl_lite_container_add_create_class + (GUPnPDIDLLiteContainer *container, + const char *create_class); + +void +gupnp_didl_lite_container_add_create_class_full + (GUPnPDIDLLiteContainer *container, + const char *create_class, + gboolean include_derived); + +void +gupnp_didl_lite_container_add_search_class + (GUPnPDIDLLiteContainer *container, + const char *search_class); +void +gupnp_didl_lite_container_add_search_class_full + (GUPnPDIDLLiteContainer *container, + const char *search_class, + gboolean include_derived); + +gint64 +gupnp_didl_lite_container_get_storage_used + (GUPnPDIDLLiteContainer *container); + +void +gupnp_didl_lite_container_set_storage_used + (GUPnPDIDLLiteContainer *container, + gint64 storage_used); +G_END_DECLS + +#endif /* __GUPNP_DIDL_LITE_CONTAINER_H__ */ diff --git a/libgupnp-av/gupnp-didl-lite-contributor-private.h b/libgupnp-av/gupnp-didl-lite-contributor-private.h new file mode 100644 index 0000000..0bb6451 --- /dev/null +++ b/libgupnp-av/gupnp-didl-lite-contributor-private.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2009 Nokia Corporation. + * + * Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com> + * <zeeshanak@gnome.org> + * + * 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. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __GUPNP_DIDL_LITE_CONTRIBUTOR_PRIVATE_H__ +#define __GUPNP_DIDL_LITE_CONTRIBUTOR_PRIVATE_H__ + +#include <glib-object.h> +#include <libxml/tree.h> + +#include "gupnp-didl-lite-contributor.h" + +G_BEGIN_DECLS + +GUPnPDIDLLiteContributor * +gupnp_didl_lite_contributor_new_from_xml (xmlNode *xml_node, + GUPnPXMLDoc *xml_doc); + +G_END_DECLS + +#endif /* __GUPNP_DIDL_LITE_CONTRIBUTOR_PRIVATE_H__ */ diff --git a/libgupnp-av/gupnp-didl-lite-contributor.c b/libgupnp-av/gupnp-didl-lite-contributor.c new file mode 100644 index 0000000..11f453e --- /dev/null +++ b/libgupnp-av/gupnp-didl-lite-contributor.c @@ -0,0 +1,360 @@ +/* + * Copyright (C) 2009 Nokia Corporation. + * + * Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com> + * <zeeshanak@gnome.org> + * + * 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. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +/** + * SECTION:gupnp-didl-lite-contributor + * @short_description: DIDL-Lite Contributor + * + * #GUPnPDIDLLiteContributor respresents a contributor (artist, author, actor, + * producer, director, producer and contributor) property in a DIDL-Lite object. + */ + +#include <libgupnp/gupnp.h> + +#include "gupnp-didl-lite-contributor.h" +#include "xml-util.h" + +G_DEFINE_TYPE (GUPnPDIDLLiteContributor, + gupnp_didl_lite_contributor, + G_TYPE_OBJECT); + +struct _GUPnPDIDLLiteContributorPrivate { + xmlNode *xml_node; + GUPnPXMLDoc *xml_doc; +}; + +enum { + PROP_0, + PROP_XML_NODE, + PROP_XML_DOC, + PROP_ROLE, + PROP_NAME +}; + +static void +gupnp_didl_lite_contributor_init (GUPnPDIDLLiteContributor *contributor) +{ + contributor->priv = G_TYPE_INSTANCE_GET_PRIVATE + (contributor, + GUPNP_TYPE_DIDL_LITE_CONTRIBUTOR, + GUPnPDIDLLiteContributorPrivate); +} + +static void +gupnp_didl_lite_contributor_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + GUPnPDIDLLiteContributor *contributor; + + contributor = GUPNP_DIDL_LITE_CONTRIBUTOR (object); + + switch (property_id) { + case PROP_XML_NODE: + g_value_set_pointer + (value, + gupnp_didl_lite_contributor_get_xml_node + (contributor)); + break; + case PROP_ROLE: + g_value_set_string + (value, + gupnp_didl_lite_contributor_get_role (contributor)); + break; + case PROP_NAME: + g_value_set_string + (value, + gupnp_didl_lite_contributor_get_name (contributor)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gupnp_didl_lite_contributor_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) + +{ + GUPnPDIDLLiteContributor *contributor; + + contributor = GUPNP_DIDL_LITE_CONTRIBUTOR (object); + + switch (property_id) { + case PROP_XML_NODE: + contributor->priv->xml_node = g_value_get_pointer (value); + break; + case PROP_XML_DOC: + contributor->priv->xml_doc = g_value_dup_object (value); + break; + case PROP_ROLE: + gupnp_didl_lite_contributor_set_role + (contributor, + g_value_get_string (value)); + break; + case PROP_NAME: + gupnp_didl_lite_contributor_set_name + (contributor, + g_value_get_string (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gupnp_didl_lite_contributor_dispose (GObject *object) +{ + GObjectClass *object_class; + GUPnPDIDLLiteContributorPrivate *priv; + + priv = GUPNP_DIDL_LITE_CONTRIBUTOR (object)->priv; + + if (priv->xml_doc) { + g_object_unref (priv->xml_doc); + priv->xml_doc = NULL; + } + + object_class = G_OBJECT_CLASS + (gupnp_didl_lite_contributor_parent_class); + object_class->dispose (object); +} + +static void +gupnp_didl_lite_contributor_class_init (GUPnPDIDLLiteContributorClass *klass) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = gupnp_didl_lite_contributor_get_property; + object_class->set_property = gupnp_didl_lite_contributor_set_property; + object_class->dispose = gupnp_didl_lite_contributor_dispose; + + g_type_class_add_private (klass, + sizeof (GUPnPDIDLLiteContributorPrivate)); + + /** + * GUPnPDIDLLiteContributor:xml-node: + * + * The pointer to object node in XML document. + **/ + g_object_class_install_property + (object_class, + PROP_XML_NODE, + g_param_spec_pointer ("xml-node", + "XMLNode", + "The pointer to contributor node in XML" + " document.", + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteContributor:xml-doc: + * + * The reference to XML document containing this object. + * + * Internal property. + * + * Stability: Private + **/ + g_object_class_install_property + (object_class, + PROP_XML_DOC, + g_param_spec_object ("xml-doc", + "XMLDoc", + "The reference to XML document" + " containing this contributor.", + GUPNP_TYPE_XML_DOC, + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteContributor:role: + * + * The role of this contributor. + **/ + g_object_class_install_property + (object_class, + PROP_ROLE, + g_param_spec_string ("role", + "Role", + "The role of this contributor.", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteContributor:name: + * + * The name of this contributor. + **/ + g_object_class_install_property + (object_class, + PROP_NAME, + g_param_spec_string ("name", + "Name", + "The name of this contributor.", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); +} + +/** + * gupnp_didl_lite_contributor_get_role: + * @contributor: #GUPnPDIDLLiteContributor + * + * Get the role of the @contributor. + * + * Return value: The role of the @contributor, or %NULL. + **/ +const char * +gupnp_didl_lite_contributor_get_role (GUPnPDIDLLiteContributor *contributor) +{ + g_return_val_if_fail (contributor != NULL, NULL); + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_CONTRIBUTOR (contributor), + NULL); + + return xml_util_get_attribute_content (contributor->priv->xml_node, + "role"); +} + +/** + * gupnp_didl_lite_contributor_get_name: + * @contributor: A #GUPnPDIDLLiteContributor + * + * Get the name of the @contributor. + * + * Return value: The name of the @contributor or %NULL. + **/ +const char * +gupnp_didl_lite_contributor_get_name (GUPnPDIDLLiteContributor *contributor) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_CONTRIBUTOR (contributor), + NULL); + + return (const char *) contributor->priv->xml_node->children->content; +} + +/** + * gupnp_didl_lite_contributor_set_role: + * @contributor: #GUPnPDIDLLiteContributor + * @role: The role of the @contributor + * + * Set the role of the @contributor to @role. + * + * Return value: None. + **/ +void +gupnp_didl_lite_contributor_set_role (GUPnPDIDLLiteContributor *contributor, + const char *role) +{ + g_return_if_fail (contributor != NULL); + g_return_if_fail (GUPNP_IS_DIDL_LITE_CONTRIBUTOR (contributor)); + + xmlSetProp (contributor->priv->xml_node, + (unsigned char *) "role", + (unsigned char *) role); + + g_object_notify (G_OBJECT (contributor), "role"); +} + +/** + * gupnp_didl_lite_contributor_set_name: + * @contributor: A #GUPnPDIDLLiteContributor + * @name: The name of the contributor + * + * Set the name of the @contributor to @name. + * + * Return value: None. + **/ +void +gupnp_didl_lite_contributor_set_name (GUPnPDIDLLiteContributor *contributor, + const char *name) +{ + xmlChar *escaped; + + g_return_if_fail (GUPNP_IS_DIDL_LITE_CONTRIBUTOR (contributor)); + g_return_if_fail (name != NULL); + + escaped = xmlEncodeSpecialChars (contributor->priv->xml_doc->doc, + (const unsigned char *) name); + xmlNodeSetContent (contributor->priv->xml_node, escaped); + xmlFree (escaped); + + g_object_notify (G_OBJECT (contributor), "name"); +} + +/** + * gupnp_didl_lite_contributor_new_from_xml: + * @xml_node: The pointer to relevant node in XML document + * @xml_doc: The reference to containing XML document + * + * Creates a new #GUPnPDIDLLiteContributor for the @xml_node. + * + * Return value: A new #GUPnPDIDLLiteContributor object. Unref after usage. + **/ +GUPnPDIDLLiteContributor * +gupnp_didl_lite_contributor_new_from_xml (xmlNode *xml_node, + GUPnPXMLDoc *xml_doc) +{ + GUPnPDIDLLiteContributor *contributor; + + return g_object_new (GUPNP_TYPE_DIDL_LITE_CONTRIBUTOR, + "xml-node", xml_node, + "xml-doc", xml_doc, + NULL); + + return contributor; +} + +/** + * gupnp_didl_lite_contributor_get_xml_node: + * @contributor: The #GUPnPDIDLLiteContributor + * + * Get the pointer to relevant node in XML document. + * + * Returns: (transfer none): The pointer to relevant node in XML document. + **/ +xmlNode * +gupnp_didl_lite_contributor_get_xml_node (GUPnPDIDLLiteContributor *contributor) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_CONTRIBUTOR (contributor), + NULL); + + return contributor->priv->xml_node; +} diff --git a/libgupnp-av/gupnp-didl-lite-contributor.h b/libgupnp-av/gupnp-didl-lite-contributor.h new file mode 100644 index 0000000..dbedae7 --- /dev/null +++ b/libgupnp-av/gupnp-didl-lite-contributor.h @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2009 Nokia Corporation. + * + * Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com> + * <zeeshanak@gnome.org> + * + * 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. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __GUPNP_DIDL_LITE_CONTRIBUTOR_H__ +#define __GUPNP_DIDL_LITE_CONTRIBUTOR_H__ + +#include <glib-object.h> +#include <libxml/tree.h> + +G_BEGIN_DECLS + +GType +gupnp_didl_lite_contributor_get_type (void) G_GNUC_CONST; + +#define GUPNP_TYPE_DIDL_LITE_CONTRIBUTOR \ + (gupnp_didl_lite_contributor_get_type ()) +#define GUPNP_DIDL_LITE_CONTRIBUTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + GUPNP_TYPE_DIDL_LITE_CONTRIBUTOR, \ + GUPnPDIDLLiteContributor)) +#define GUPNP_DIDL_LITE_CONTRIBUTOR_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_CAST ((obj), \ + GUPNP_TYPE_DIDL_LITE_CONTRIBUTOR, \ + GUPnPDIDLLiteContributorClass)) +#define GUPNP_IS_DIDL_LITE_CONTRIBUTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + GUPNP_TYPE_DIDL_LITE_CONTRIBUTOR)) +#define GUPNP_IS_DIDL_LITE_CONTRIBUTOR_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE ((obj), \ + GUPNP_TYPE_DIDL_LITE_CONTRIBUTOR)) +#define GUPNP_DIDL_LITE_CONTRIBUTOR_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + GUPNP_TYPE_DIDL_LITE_CONTRIBUTOR, \ + GUPnPDIDLLiteContributorClass)) + +typedef struct _GUPnPDIDLLiteContributorPrivate GUPnPDIDLLiteContributorPrivate; + +typedef struct { + GObject parent; + + GUPnPDIDLLiteContributorPrivate *priv; +} GUPnPDIDLLiteContributor; + +typedef struct { + GObjectClass parent_class; + + /* future padding */ + void (* _gupnp_reserved1) (void); + void (* _gupnp_reserved2) (void); + void (* _gupnp_reserved3) (void); + void (* _gupnp_reserved4) (void); +} GUPnPDIDLLiteContributorClass; + +const char * +gupnp_didl_lite_contributor_get_role (GUPnPDIDLLiteContributor *contributor); + +const char * +gupnp_didl_lite_contributor_get_name (GUPnPDIDLLiteContributor *contributor); + +void +gupnp_didl_lite_contributor_set_role (GUPnPDIDLLiteContributor *contributor, + const char *role); + +void +gupnp_didl_lite_contributor_set_name (GUPnPDIDLLiteContributor *contributor, + const char *name); + +xmlNode * +gupnp_didl_lite_contributor_get_xml_node + (GUPnPDIDLLiteContributor *contributor); + +G_END_DECLS + +#endif /* __GUPNP_DIDL_LITE_CONTRIBUTOR_H__ */ diff --git a/libgupnp-av/gupnp-didl-lite-descriptor-private.h b/libgupnp-av/gupnp-didl-lite-descriptor-private.h new file mode 100644 index 0000000..1ed983c --- /dev/null +++ b/libgupnp-av/gupnp-didl-lite-descriptor-private.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2009 Nokia Corporation. + * + * Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com> + * <zeeshanak@gnome.org> + * + * 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. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __GUPNP_DIDL_LITE_DESCRIPTOR_PRIVATE_H__ +#define __GUPNP_DIDL_LITE_DESCRIPTOR_PRIVATE_H__ + +#include <stdarg.h> +#include <glib-object.h> +#include <libxml/tree.h> +#include <libgupnp/gupnp.h> + +G_BEGIN_DECLS + +GUPnPDIDLLiteDescriptor * +gupnp_didl_lite_descriptor_new_from_xml (xmlNode *xml_node, + GUPnPXMLDoc *xml_doc); + +G_END_DECLS + +#endif /* __GUPNP_DIDL_LITE_DESCRIPTOR_PRIVATE_H__ */ diff --git a/libgupnp-av/gupnp-didl-lite-descriptor.c b/libgupnp-av/gupnp-didl-lite-descriptor.c new file mode 100644 index 0000000..c9b4581 --- /dev/null +++ b/libgupnp-av/gupnp-didl-lite-descriptor.c @@ -0,0 +1,506 @@ +/* + * Copyright (C) 2009 Nokia Corporation. + * + * Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com> + * <zeeshanak@gnome.org> + * + * 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. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +/** + * SECTION:gupnp-didl-lite-descriptor + * @short_description: DIDL-Lite Descriptor + * + * #GUPnPDIDLLiteDescriptor respresent a DIDL-Lite descriptor (desc) element. + */ + +#include <string.h> + +#include "gupnp-didl-lite-descriptor.h" +#include "xml-util.h" + +G_DEFINE_TYPE (GUPnPDIDLLiteDescriptor, + gupnp_didl_lite_descriptor, + G_TYPE_OBJECT); + +struct _GUPnPDIDLLiteDescriptorPrivate { + xmlNode *xml_node; + GUPnPXMLDoc *xml_doc; +}; + +enum { + PROP_0, + PROP_XML_NODE, + PROP_XML_DOC, + + PROP_ID, + PROP_METADATA_TYPE, + PROP_NAME_SPACE, + PROP_CONTENT +}; + +static void +gupnp_didl_lite_descriptor_init (GUPnPDIDLLiteDescriptor *descriptor) +{ + descriptor->priv = G_TYPE_INSTANCE_GET_PRIVATE + (descriptor, + GUPNP_TYPE_DIDL_LITE_DESCRIPTOR, + GUPnPDIDLLiteDescriptorPrivate); +} + +static void +gupnp_didl_lite_descriptor_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + GUPnPDIDLLiteDescriptor *descriptor; + + descriptor = GUPNP_DIDL_LITE_DESCRIPTOR (object); + + switch (property_id) { + case PROP_XML_NODE: + descriptor->priv->xml_node = g_value_get_pointer (value); + break; + case PROP_XML_DOC: + descriptor->priv->xml_doc = g_value_dup_object (value); + break; + case PROP_ID: + gupnp_didl_lite_descriptor_set_id + (descriptor, + g_value_get_string (value)); + break; + case PROP_METADATA_TYPE: + gupnp_didl_lite_descriptor_set_metadata_type + (descriptor, + g_value_get_string (value)); + break; + case PROP_NAME_SPACE: + gupnp_didl_lite_descriptor_set_name_space + (descriptor, + g_value_get_string (value)); + break; + case PROP_CONTENT: + gupnp_didl_lite_descriptor_set_content + (descriptor, + g_value_get_string (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gupnp_didl_lite_descriptor_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + GUPnPDIDLLiteDescriptor *descriptor; + + descriptor = GUPNP_DIDL_LITE_DESCRIPTOR (object); + + switch (property_id) { + case PROP_XML_NODE: + g_value_set_pointer + (value, + gupnp_didl_lite_descriptor_get_xml_node (descriptor)); + break; + case PROP_ID: + g_value_set_string + (value, + gupnp_didl_lite_descriptor_get_id (descriptor)); + break; + case PROP_METADATA_TYPE: + g_value_set_string + (value, + gupnp_didl_lite_descriptor_get_metadata_type + (descriptor)); + break; + case PROP_NAME_SPACE: + g_value_set_string + (value, + gupnp_didl_lite_descriptor_get_name_space + (descriptor)); + break; + case PROP_CONTENT: + g_value_set_string + (value, + gupnp_didl_lite_descriptor_get_content (descriptor)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gupnp_didl_lite_descriptor_dispose (GObject *object) +{ + GObjectClass *object_class; + GUPnPDIDLLiteDescriptorPrivate *priv; + + priv = GUPNP_DIDL_LITE_DESCRIPTOR (object)->priv; + + if (priv->xml_doc) { + g_object_unref (priv->xml_doc); + priv->xml_doc = NULL; + } + + object_class = G_OBJECT_CLASS (gupnp_didl_lite_descriptor_parent_class); + object_class->dispose (object); +} + +static void +gupnp_didl_lite_descriptor_class_init (GUPnPDIDLLiteDescriptorClass *klass) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (klass); + + object_class->set_property = gupnp_didl_lite_descriptor_set_property; + object_class->get_property = gupnp_didl_lite_descriptor_get_property; + object_class->dispose = gupnp_didl_lite_descriptor_dispose; + + g_type_class_add_private (klass, + sizeof (GUPnPDIDLLiteDescriptorPrivate)); + + /** + * GUPnPDIDLLiteDescriptor:xml-node: + * + * The pointer to desc node in XML document. + **/ + g_object_class_install_property + (object_class, + PROP_XML_NODE, + g_param_spec_pointer ("xml-node", + "XMLNode", + "The pointer to desc node in XML" + " document.", + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteDescriptor:xml-doc: + * + * The reference to XML document containing this object. + * + * Internal property. + * + * Stability: Private + **/ + g_object_class_install_property + (object_class, + PROP_XML_DOC, + g_param_spec_object ("xml-doc", + "XMLDoc", + "The reference to XML document" + " containing this object.", + GUPNP_TYPE_XML_DOC, + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteDescriptor:name-space: + * + * The name space associated with this descriptor. + **/ + g_object_class_install_property + (object_class, + PROP_NAME_SPACE, + g_param_spec_string ("name-space", + "NameSpace", + "The name space associated with this" + " descriptor", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteDescriptor:id: + * + * The ID of this descriptor. + **/ + g_object_class_install_property + (object_class, + PROP_ID, + g_param_spec_string ("id", + "ID", + "The ID of this descriptor", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteDescriptor:metadata-type: + * + * The type of this descriptor. + **/ + g_object_class_install_property + (object_class, + PROP_METADATA_TYPE, + g_param_spec_string ("metadata-type", + "MetadataType", + "The metadata type of this descriptor", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteDescriptor:content: + * + * The content of this descriptor. + **/ + g_object_class_install_property + (object_class, + PROP_CONTENT, + g_param_spec_string ("content", + "Content", + "The content of this descriptor", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); +} + +/** + * gupnp_didl_lite_descriptor_new: + * + * Return value: A new #GUPnPDIDLLiteDescriptor object. Unref after usage. + **/ +GUPnPDIDLLiteDescriptor * +gupnp_didl_lite_descriptor_new (void) +{ + return g_object_new (GUPNP_TYPE_DIDL_LITE_DESCRIPTOR, + NULL); +} + +/** + * gupnp_didl_lite_descriptor_new_from_xml: + * @xml_node: The pointer to 'desc' node in XML document + * @xml_doc: The reference to XML document containing this descriptor + * + * Creates a new #GUPnPDIDLLiteDescriptor for the @xml_node. + * + * Return value: A new #GUPnPDIDLLiteDescriptor object. Unref after usage. + **/ +GUPnPDIDLLiteDescriptor * +gupnp_didl_lite_descriptor_new_from_xml (xmlNode *xml_node, + GUPnPXMLDoc *xml_doc) +{ + GUPnPDIDLLiteDescriptor *descriptor; + + return g_object_new (GUPNP_TYPE_DIDL_LITE_DESCRIPTOR, + "xml-node", xml_node, + "xml-doc", xml_doc, + NULL); + + return descriptor; +} + +/** + * gupnp_didl_lite_descriptor_get_xml_node: + * @descriptor: The #GUPnPDIDLLiteDescriptor + * + * Get the pointer to desc node in XML document. + * + * Returns: (transfer none): The pointer to desc node in XML document. + **/ +xmlNode * +gupnp_didl_lite_descriptor_get_xml_node (GUPnPDIDLLiteDescriptor *descriptor) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_DESCRIPTOR (descriptor), NULL); + + return descriptor->priv->xml_node; +} + +/** + * gupnp_didl_lite_descriptor_get_content: + * @descriptor: A #GUPnPDIDLLiteDescriptor + * + * Get the content of the @descriptor. + * + * Return value: The content of the @descriptor or %NULL. + **/ +const char * +gupnp_didl_lite_descriptor_get_content (GUPnPDIDLLiteDescriptor *descriptor) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_DESCRIPTOR (descriptor), NULL); + + return (const char *) descriptor->priv->xml_node->children; +} + +/** + * gupnp_didl_lite_descriptor_get_id: + * @descriptor: A #GUPnPDIDLLiteDescriptor + * + * Get the ID of the @descriptor. + * + * Return value: The ID string or %NULL. + **/ +const char * +gupnp_didl_lite_descriptor_get_id (GUPnPDIDLLiteDescriptor *descriptor) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_DESCRIPTOR (descriptor), NULL); + + return xml_util_get_attribute_content (descriptor->priv->xml_node, + "id"); +} + +/** + * gupnp_didl_lite_descriptor_get_metadata_type: + * @descriptor: A #GUPnPDIDLLiteDescriptor + * + * Get the metadata type of the @descriptor. + * + * Return value: The type as string or %NULL. + **/ +const char * +gupnp_didl_lite_descriptor_get_metadata_type + (GUPnPDIDLLiteDescriptor *descriptor) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_DESCRIPTOR (descriptor), NULL); + + return xml_util_get_attribute_content (descriptor->priv->xml_node, + "type"); +} + +/** + * gupnp_didl_lite_descriptor_get_name_space: + * @descriptor: A #GUPnPDIDLLiteDescriptor + * + * Get the name space associated with the @descriptor. + * + * Return value: The name space or %NULL. + **/ +const char * +gupnp_didl_lite_descriptor_get_name_space (GUPnPDIDLLiteDescriptor *descriptor) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_DESCRIPTOR (descriptor), NULL); + + return xml_util_get_attribute_content (descriptor->priv->xml_node, + "nameSpace"); +} + +/** + * gupnp_didl_lite_descriptor_set_content: + * @descriptor: A #GUPnPDIDLLiteDescriptor + * @content: The content as string + * + * Set the content of the @descriptor. + * + * Return value: None. + **/ +void +gupnp_didl_lite_descriptor_set_content (GUPnPDIDLLiteDescriptor *descriptor, + const char *content) +{ + xmlChar *escaped; + + g_return_if_fail (GUPNP_IS_DIDL_LITE_DESCRIPTOR (descriptor)); + g_return_if_fail (content != NULL); + + escaped = xmlEncodeSpecialChars (descriptor->priv->xml_doc->doc, + (const unsigned char *) content); + xmlNodeSetContent (descriptor->priv->xml_node, escaped); + xmlFree (escaped); + + g_object_notify (G_OBJECT (descriptor), "content"); +} + +/** + * gupnp_didl_lite_descriptor_set_id: + * @descriptor: A #GUPnPDIDLLiteDescriptor + * @id: The ID as string + * + * Set the ID of the @descriptor. + * + * Return value: None. + **/ +void +gupnp_didl_lite_descriptor_set_id (GUPnPDIDLLiteDescriptor *descriptor, + const char *id) +{ + g_return_if_fail (GUPNP_IS_DIDL_LITE_DESCRIPTOR (descriptor)); + g_return_if_fail (id != NULL); + + xmlSetProp (descriptor->priv->xml_node, + (unsigned char *) "id", + (const unsigned char *) id); + + g_object_notify (G_OBJECT (descriptor), "id"); +} + +/** + * gupnp_didl_lite_descriptor_set_metadata_type: + * @descriptor: A #GUPnPDIDLLiteDescriptor + * @type: The metadata type as string + * + * Set the metadata type of the @descriptor. + * + * Return value: None. + **/ +void +gupnp_didl_lite_descriptor_set_metadata_type + (GUPnPDIDLLiteDescriptor *descriptor, + const char *type) +{ + g_return_if_fail (GUPNP_IS_DIDL_LITE_DESCRIPTOR (descriptor)); + g_return_if_fail (type != NULL); + + xmlSetProp (descriptor->priv->xml_node, + (unsigned char *) "type", + (const unsigned char *) type); + + g_object_notify (G_OBJECT (descriptor), "metadata-type"); +} + +/** + * gupnp_didl_lite_descriptor_set_name_space: + * @descriptor: A #GUPnPDIDLLiteDescriptor + * @name_space: The name space URI as string + * + * Set the name space associated with the @descriptor. + * + * Return value: None. + **/ +void +gupnp_didl_lite_descriptor_set_name_space (GUPnPDIDLLiteDescriptor *descriptor, + const char *name_space) +{ + g_return_if_fail (GUPNP_IS_DIDL_LITE_DESCRIPTOR (descriptor)); + g_return_if_fail (name_space != NULL); + + xmlSetProp (descriptor->priv->xml_node, + (unsigned char *) "nameSpace", + (const unsigned char *) name_space); + + g_object_notify (G_OBJECT (descriptor), "name-space"); +} diff --git a/libgupnp-av/gupnp-didl-lite-descriptor.h b/libgupnp-av/gupnp-didl-lite-descriptor.h new file mode 100644 index 0000000..2b685d6 --- /dev/null +++ b/libgupnp-av/gupnp-didl-lite-descriptor.h @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2009 Nokia Corporation. + * + * Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com> + * <zeeshanak@gnome.org> + * + * 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. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __GUPNP_DIDL_LITE_DESCRIPTOR_H__ +#define __GUPNP_DIDL_LITE_DESCRIPTOR_H__ + +#include <stdarg.h> +#include <glib-object.h> +#include <libxml/tree.h> +#include <libgupnp/gupnp.h> + +G_BEGIN_DECLS + +GType +gupnp_didl_lite_descriptor_get_type (void) G_GNUC_CONST; + +#define GUPNP_TYPE_DIDL_LITE_DESCRIPTOR \ + (gupnp_didl_lite_descriptor_get_type ()) +#define GUPNP_DIDL_LITE_DESCRIPTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + GUPNP_TYPE_DIDL_LITE_DESCRIPTOR, \ + GUPnPDIDLLiteDescriptor)) +#define GUPNP_DIDL_LITE_DESCRIPTOR_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_CAST ((obj), \ + GUPNP_TYPE_DIDL_LITE_DESCRIPTOR, \ + GUPnPDIDLLiteDescriptorClass)) +#define GUPNP_IS_DIDL_LITE_DESCRIPTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + GUPNP_TYPE_DIDL_LITE_DESCRIPTOR)) +#define GUPNP_IS_DIDL_LITE_DESCRIPTOR_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE ((obj), \ + GUPNP_TYPE_DIDL_LITE_DESCRIPTOR)) +#define GUPNP_DIDL_LITE_DESCRIPTOR_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + GUPNP_TYPE_DIDL_LITE_DESCRIPTOR, \ + GUPnPDIDLLiteDescriptorClass)) + +typedef struct _GUPnPDIDLLiteDescriptorPrivate GUPnPDIDLLiteDescriptorPrivate; + +typedef struct { + GObject parent; + + GUPnPDIDLLiteDescriptorPrivate *priv; +} GUPnPDIDLLiteDescriptor; + +typedef struct { + GObjectClass parent_class; + + /* future padding */ + void (* _gupnp_reserved1) (void); + void (* _gupnp_reserved2) (void); + void (* _gupnp_reserved3) (void); + void (* _gupnp_reserved4) (void); +} GUPnPDIDLLiteDescriptorClass; + +xmlNode * +gupnp_didl_lite_descriptor_get_xml_node (GUPnPDIDLLiteDescriptor *descriptor); + +const char * +gupnp_didl_lite_descriptor_get_content (GUPnPDIDLLiteDescriptor *descriptor); + +const char * +gupnp_didl_lite_descriptor_get_id (GUPnPDIDLLiteDescriptor *descriptor); + +const char * +gupnp_didl_lite_descriptor_get_metadata_type + (GUPnPDIDLLiteDescriptor *descriptor); + +const char * +gupnp_didl_lite_descriptor_get_name_space + (GUPnPDIDLLiteDescriptor *descriptor); + +void +gupnp_didl_lite_descriptor_set_content (GUPnPDIDLLiteDescriptor *descriptor, + const char *content); + +void +gupnp_didl_lite_descriptor_set_id (GUPnPDIDLLiteDescriptor *descriptor, + const char *id); + +void +gupnp_didl_lite_descriptor_set_metadata_type + (GUPnPDIDLLiteDescriptor *descriptor, + const char *type); + +void +gupnp_didl_lite_descriptor_set_name_space + (GUPnPDIDLLiteDescriptor *descriptor, + const char *name_space); + +G_END_DECLS + +#endif /* __GUPNP_DIDL_LITE_DESCRIPTOR_H__ */ diff --git a/libgupnp-av/gupnp-didl-lite-item.c b/libgupnp-av/gupnp-didl-lite-item.c new file mode 100644 index 0000000..9e5d34c --- /dev/null +++ b/libgupnp-av/gupnp-didl-lite-item.c @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2009 Nokia Corporation. + * + * Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com> + * <zeeshanak@gnome.org> + * + * 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. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +/** + * SECTION:gupnp-didl-lite-item + * @short_description: DIDL-Lite Item + * + * #GUPnPDIDLLiteItem respresents a DIDL-Lite item element. + */ + +#include <string.h> + +#include "gupnp-didl-lite-item.h" +#include "xml-util.h" + +G_DEFINE_TYPE (GUPnPDIDLLiteItem, + gupnp_didl_lite_item, + GUPNP_TYPE_DIDL_LITE_OBJECT); + +enum { + PROP_0, + PROP_REF_ID +}; + +static void +gupnp_didl_lite_item_init (GUPnPDIDLLiteItem *item) +{ + /* Nothing to initialize, yay! */ +} + +static void +gupnp_didl_lite_item_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + GUPnPDIDLLiteItem *item; + + item = GUPNP_DIDL_LITE_ITEM (object); + + switch (property_id) { + case PROP_REF_ID: + g_value_set_string + (value, + gupnp_didl_lite_item_get_ref_id (item)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gupnp_didl_lite_item_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) + +{ + GUPnPDIDLLiteItem *item; + + item = GUPNP_DIDL_LITE_ITEM (object); + + switch (property_id) { + case PROP_REF_ID: + gupnp_didl_lite_item_set_ref_id (item, + g_value_get_string (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gupnp_didl_lite_item_class_init (GUPnPDIDLLiteItemClass *klass) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = gupnp_didl_lite_item_get_property; + object_class->set_property = gupnp_didl_lite_item_set_property; + + /** + * GUPnPDIDLLiteItem:ref-id: + * + * The ref ID of this item. + **/ + g_object_class_install_property + (object_class, + PROP_REF_ID, + g_param_spec_string ("ref-id", + "RefID", + "The ref ID of this item.", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); +} + +/** + * gupnp_didl_lite_item_get_ref_id: + * @item: #GUPnPDIDLLiteItem + * + * Get the ref ID of the @item. + * + * Return value: The ref ID of the @item, or %NULL. + **/ +const char * +gupnp_didl_lite_item_get_ref_id (GUPnPDIDLLiteItem *item) +{ + xmlNode *xml_node; + + g_return_val_if_fail (item != NULL, 0); + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_ITEM (item), NULL); + + xml_node = gupnp_didl_lite_object_get_xml_node + (GUPNP_DIDL_LITE_OBJECT (item)); + + return xml_util_get_attribute_content (xml_node, "refID"); +} + +/** + * gupnp_didl_lite_item_set_ref_id: + * @item: #GUPnPDIDLLiteItem + * @ref_id: The ref ID + * + * Set the ref ID of the @item. + **/ +void +gupnp_didl_lite_item_set_ref_id (GUPnPDIDLLiteItem *item, + const char *ref_id) +{ + xmlNode *xml_node; + + g_return_if_fail (item != NULL); + g_return_if_fail (GUPNP_IS_DIDL_LITE_ITEM (item)); + + xml_node = gupnp_didl_lite_object_get_xml_node + (GUPNP_DIDL_LITE_OBJECT (item)); + + xmlSetProp (xml_node, + (unsigned char *) "refID", + (unsigned char *) ref_id); + + g_object_notify (G_OBJECT (item), "ref-id"); +} diff --git a/libgupnp-av/gupnp-didl-lite-item.h b/libgupnp-av/gupnp-didl-lite-item.h new file mode 100644 index 0000000..1719729 --- /dev/null +++ b/libgupnp-av/gupnp-didl-lite-item.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2009 Nokia Corporation. + * + * Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com> + * <zeeshanak@gnome.org> + * + * 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. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __GUPNP_DIDL_LITE_ITEM_H__ +#define __GUPNP_DIDL_LITE_ITEM_H__ + +#include <glib-object.h> +#include "gupnp-didl-lite-object.h" + +G_BEGIN_DECLS + +GType +gupnp_didl_lite_item_get_type (void) G_GNUC_CONST; + +#define GUPNP_TYPE_DIDL_LITE_ITEM \ + (gupnp_didl_lite_item_get_type ()) +#define GUPNP_DIDL_LITE_ITEM(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + GUPNP_TYPE_DIDL_LITE_ITEM, \ + GUPnPDIDLLiteItem)) +#define GUPNP_DIDL_LITE_ITEM_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_CAST ((obj), \ + GUPNP_TYPE_DIDL_LITE_ITEM, \ + GUPnPDIDLLiteItemClass)) +#define GUPNP_IS_DIDL_LITE_ITEM(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + GUPNP_TYPE_DIDL_LITE_ITEM)) +#define GUPNP_IS_DIDL_LITE_ITEM_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE ((obj), \ + GUPNP_TYPE_DIDL_LITE_ITEM)) +#define GUPNP_DIDL_LITE_ITEM_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + GUPNP_TYPE_DIDL_LITE_ITEM, \ + GUPnPDIDLLiteItemClass)) + +typedef struct { + GUPnPDIDLLiteObject parent; +} GUPnPDIDLLiteItem; + +typedef struct { + GUPnPDIDLLiteObjectClass parent_class; + + /* future padding */ + void (* _gupnp_reserved1) (void); + void (* _gupnp_reserved2) (void); + void (* _gupnp_reserved3) (void); + void (* _gupnp_reserved4) (void); +} GUPnPDIDLLiteItemClass; + +const char * +gupnp_didl_lite_item_get_ref_id (GUPnPDIDLLiteItem *item); + +void +gupnp_didl_lite_item_set_ref_id (GUPnPDIDLLiteItem *item, + const char *ref_id); + +G_END_DECLS + +#endif /* __GUPNP_DIDL_LITE_ITEM_H__ */ diff --git a/libgupnp-av/gupnp-didl-lite-object-private.h b/libgupnp-av/gupnp-didl-lite-object-private.h new file mode 100644 index 0000000..780e495 --- /dev/null +++ b/libgupnp-av/gupnp-didl-lite-object-private.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2009 Nokia Corporation. + * + * Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com> + * <zeeshanak@gnome.org> + * + * 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. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __GUPNP_DIDL_LITE_OBJECT_PRIVATE_H__ +#define __GUPNP_DIDL_LITE_OBJECT_PRIVATE_H__ + +#include <glib-object.h> +#include <libxml/tree.h> + +G_BEGIN_DECLS + +G_GNUC_INTERNAL GUPnPDIDLLiteObject * +gupnp_didl_lite_object_new_from_xml (xmlNode *xml_node, + GUPnPXMLDoc *xml_doc, + xmlNs *upnp_ns, + xmlNs *dc_ns, + xmlNs *dlna_ns); + +G_END_DECLS + +#endif /* __GUPNP_DIDL_LITE_OBJECT_PRIVATE_H__ */ diff --git a/libgupnp-av/gupnp-didl-lite-object.c b/libgupnp-av/gupnp-didl-lite-object.c new file mode 100644 index 0000000..5c916a6 --- /dev/null +++ b/libgupnp-av/gupnp-didl-lite-object.c @@ -0,0 +1,1966 @@ +/* + * Copyright (C) 2009 Nokia Corporation. + * + * Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com> + * <zeeshanak@gnome.org> + * + * 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. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +/** + * SECTION:gupnp-didl-lite-object + * @short_description: DIDL-Lite Object + * + * #GUPnPDIDLLiteObject respresent a DIDL-Lite object element. + */ + +#include <string.h> +#include <libgupnp/gupnp.h> + +#include "gupnp-didl-lite-object.h" +#include "gupnp-didl-lite-object-private.h" +#include "gupnp-didl-lite-resource-private.h" +#include "gupnp-didl-lite-descriptor-private.h" +#include "gupnp-didl-lite-container.h" +#include "gupnp-didl-lite-item.h" +#include "gupnp-didl-lite-contributor-private.h" +#include "xml-util.h" + +G_DEFINE_ABSTRACT_TYPE (GUPnPDIDLLiteObject, + gupnp_didl_lite_object, + G_TYPE_OBJECT); + +struct _GUPnPDIDLLiteObjectPrivate { + xmlNode *xml_node; + GUPnPXMLDoc *xml_doc; + + xmlNs *upnp_ns; + xmlNs *dc_ns; + xmlNs *dlna_ns; +}; + +enum { + PROP_0, + PROP_XML_NODE, + PROP_XML_DOC, + PROP_UPNP_NAMESPACE, + PROP_DC_NAMESPACE, + PROP_DLNA_NAMESPACE, + PROP_ID, + PROP_PARENT_ID, + PROP_RESTRICTED, + PROP_TITLE, + PROP_UPNP_CLASS, + PROP_CREATOR, + PROP_ARTIST, + PROP_AUTHOR, + PROP_GENRE, + PROP_WRITE_STATUS, + PROP_ALBUM, + PROP_ALBUM_ART, + PROP_DESCRIPTION, + PROP_DATE, + PROP_TRACK_NUMBER, + PROP_DLNA_MANAGED, +}; + +static int +is_non_transcoded_resource (GUPnPDIDLLiteResource *resource) +{ + GUPnPProtocolInfo *info; + + info = gupnp_didl_lite_resource_get_protocol_info (resource); + if (G_UNLIKELY (info == NULL)) + return -1; + + return gupnp_protocol_info_get_dlna_conversion (info) & + GUPNP_DLNA_CONVERSION_TRANSCODED; +} + +static void +gupnp_didl_lite_object_init (GUPnPDIDLLiteObject *object) +{ + object->priv = G_TYPE_INSTANCE_GET_PRIVATE + (object, + GUPNP_TYPE_DIDL_LITE_OBJECT, + GUPnPDIDLLiteObjectPrivate); +} + +static void +gupnp_didl_lite_object_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) + +{ + GUPnPDIDLLiteObject *didl_object; + + didl_object = GUPNP_DIDL_LITE_OBJECT (object); + + switch (property_id) { + case PROP_XML_NODE: + didl_object->priv->xml_node = g_value_get_pointer (value); + break; + case PROP_XML_DOC: + didl_object->priv->xml_doc = g_value_dup_object (value); + break; + case PROP_UPNP_NAMESPACE: + didl_object->priv->upnp_ns = g_value_get_pointer (value); + break; + case PROP_DC_NAMESPACE: + didl_object->priv->dc_ns = g_value_get_pointer (value); + break; + case PROP_DLNA_NAMESPACE: + didl_object->priv->dlna_ns = g_value_get_pointer (value); + break; + case PROP_ID: + gupnp_didl_lite_object_set_id (didl_object, + g_value_get_string (value)); + break; + case PROP_PARENT_ID: + gupnp_didl_lite_object_set_parent_id + (didl_object, + g_value_get_string (value)); + break; + case PROP_RESTRICTED: + gupnp_didl_lite_object_set_restricted + (didl_object, + g_value_get_boolean (value)); + break; + case PROP_TITLE: + gupnp_didl_lite_object_set_title + (didl_object, + g_value_get_string (value)); + break; + case PROP_UPNP_CLASS: + gupnp_didl_lite_object_set_upnp_class + (didl_object, + g_value_get_string (value)); + break; + case PROP_CREATOR: + gupnp_didl_lite_object_set_creator + (didl_object, + g_value_get_string (value)); + break; + case PROP_ARTIST: + gupnp_didl_lite_object_set_artist + (didl_object, + g_value_get_string (value)); + break; + case PROP_AUTHOR: + gupnp_didl_lite_object_set_author + (didl_object, + g_value_get_string (value)); + break; + case PROP_GENRE: + gupnp_didl_lite_object_set_genre + (didl_object, + g_value_get_string (value)); + break; + case PROP_WRITE_STATUS: + gupnp_didl_lite_object_set_write_status + (didl_object, + g_value_get_string (value)); + break; + case PROP_ALBUM: + gupnp_didl_lite_object_set_album + (didl_object, + g_value_get_string (value)); + break; + case PROP_ALBUM_ART: + gupnp_didl_lite_object_set_album_art + (didl_object, + g_value_get_string (value)); + break; + case PROP_DESCRIPTION: + gupnp_didl_lite_object_set_description + (didl_object, + g_value_get_string (value)); + break; + case PROP_DATE: + gupnp_didl_lite_object_set_date + (didl_object, + g_value_get_string (value)); + break; + case PROP_TRACK_NUMBER: + gupnp_didl_lite_object_set_track_number + (didl_object, + g_value_get_int (value)); + break; + case PROP_DLNA_MANAGED: + gupnp_didl_lite_object_set_dlna_managed + (didl_object, + g_value_get_flags (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gupnp_didl_lite_object_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + GUPnPDIDLLiteObject *didl_object; + + didl_object = GUPNP_DIDL_LITE_OBJECT (object); + + switch (property_id) { + case PROP_XML_NODE: + g_value_set_pointer + (value, + gupnp_didl_lite_object_get_xml_node (didl_object)); + break; + case PROP_UPNP_NAMESPACE: + g_value_set_pointer + (value, + gupnp_didl_lite_object_get_upnp_namespace + (didl_object)); + break; + case PROP_DC_NAMESPACE: + g_value_set_pointer + (value, + gupnp_didl_lite_object_get_dc_namespace + (didl_object)); + break; + case PROP_DLNA_NAMESPACE: + g_value_set_pointer + (value, + gupnp_didl_lite_object_get_dlna_namespace + (didl_object)); + break; + case PROP_ID: + g_value_set_string + (value, + gupnp_didl_lite_object_get_id (didl_object)); + break; + case PROP_PARENT_ID: + g_value_set_string + (value, + gupnp_didl_lite_object_get_parent_id (didl_object)); + break; + case PROP_RESTRICTED: + g_value_set_boolean + (value, + gupnp_didl_lite_object_get_restricted (didl_object)); + break; + case PROP_TITLE: + g_value_set_string + (value, + gupnp_didl_lite_object_get_title (didl_object)); + break; + case PROP_UPNP_CLASS: + g_value_set_string + (value, + gupnp_didl_lite_object_get_upnp_class (didl_object)); + break; + case PROP_CREATOR: + g_value_set_string + (value, + gupnp_didl_lite_object_get_creator (didl_object)); + break; + case PROP_ARTIST: + g_value_set_string + (value, + gupnp_didl_lite_object_get_artist (didl_object)); + break; + case PROP_AUTHOR: + g_value_set_string + (value, + gupnp_didl_lite_object_get_author (didl_object)); + break; + case PROP_GENRE: + g_value_set_string + (value, + gupnp_didl_lite_object_get_genre (didl_object)); + break; + case PROP_WRITE_STATUS: + g_value_set_string + (value, + gupnp_didl_lite_object_get_write_status (didl_object)); + break; + case PROP_ALBUM: + g_value_set_string + (value, + gupnp_didl_lite_object_get_album (didl_object)); + break; + case PROP_ALBUM_ART: + g_value_set_string + (value, + gupnp_didl_lite_object_get_album_art (didl_object)); + break; + case PROP_DESCRIPTION: + g_value_set_string + (value, + gupnp_didl_lite_object_get_description (didl_object)); + break; + case PROP_DATE: + g_value_set_string + (value, + gupnp_didl_lite_object_get_date (didl_object)); + break; + case PROP_TRACK_NUMBER: + g_value_set_int + (value, + gupnp_didl_lite_object_get_track_number (didl_object)); + break; + case PROP_DLNA_MANAGED: + g_value_set_flags + (value, + gupnp_didl_lite_object_get_dlna_managed (didl_object)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gupnp_didl_lite_object_dispose (GObject *object) +{ + GObjectClass *object_class; + GUPnPDIDLLiteObjectPrivate *priv; + + priv = GUPNP_DIDL_LITE_OBJECT (object)->priv; + + if (priv->xml_doc) { + g_object_unref (priv->xml_doc); + priv->xml_doc = NULL; + } + + object_class = G_OBJECT_CLASS (gupnp_didl_lite_object_parent_class); + object_class->dispose (object); +} + +static void +gupnp_didl_lite_object_class_init (GUPnPDIDLLiteObjectClass *klass) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (klass); + + object_class->set_property = gupnp_didl_lite_object_set_property; + object_class->get_property = gupnp_didl_lite_object_get_property; + object_class->dispose = gupnp_didl_lite_object_dispose; + + g_type_class_add_private (klass, sizeof (GUPnPDIDLLiteObjectPrivate)); + + /** + * GUPnPDIDLLiteObject:xml-node: + * + * The pointer to object node in XML document. + **/ + g_object_class_install_property + (object_class, + PROP_XML_NODE, + g_param_spec_pointer ("xml-node", + "XMLNode", + "The pointer to object node in XML" + " document.", + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteObject:xml-doc: + * + * The reference to XML document containing this object. + * + * Internal property. + * + * Stability: Private + **/ + g_object_class_install_property + (object_class, + PROP_XML_DOC, + g_param_spec_object ("xml-doc", + "XMLDoc", + "The reference to XML document" + " containing this object.", + GUPNP_TYPE_XML_DOC, + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteObject:upnp-namespace: + * + * Pointer to the UPnP namespace registered with the XML document + * containing this object. + * + **/ + g_object_class_install_property + (object_class, + PROP_UPNP_NAMESPACE, + g_param_spec_pointer ("upnp-namespace", + "XML namespace", + "Pointer to the UPnP XML namespace " + "registered with the XML document " + "containing this object.", + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteObject:dc-namespace: + * + * Pointer to the DublinCore namespace registered with the XML document + * containing this object. + * + **/ + g_object_class_install_property + (object_class, + PROP_DC_NAMESPACE, + g_param_spec_pointer ("dc-namespace", + "XML namespace", + "Pointer to the Dublin Core XML " + "namespace registered with the XML " + "document containing this object.", + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteObject:dlna-namespace: + * + * Pointer to the DLNA metadata namespace registered with the XML + * document containing this object. + * + **/ + g_object_class_install_property + (object_class, + PROP_DLNA_NAMESPACE, + g_param_spec_pointer ("dlna-namespace", + "XML namespace", + "Pointer to the DLNA metadata namespace " + "registered with the XML document " + "containing this object.", + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteObject:id: + * + * The ID of this object. + **/ + g_object_class_install_property + (object_class, + PROP_ID, + g_param_spec_string ("id", + "ID", + "The ID of this object.", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteObject:parent-id: + * + * The ID of the parent container of this object. + **/ + g_object_class_install_property + (object_class, + PROP_PARENT_ID, + g_param_spec_string ("parent-id", + "ParentID", + "The ID of the parent container of" + " this object.", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteObject:restricted: + * + * Whether this object is restricted. + **/ + g_object_class_install_property + (object_class, + PROP_RESTRICTED, + g_param_spec_boolean ("restricted", + "Restricted", + "Whether this object is restricted.", + FALSE, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteObject:title: + * + * The title of this object. + **/ + g_object_class_install_property + (object_class, + PROP_TITLE, + g_param_spec_string ("title", + "Title", + "The title of this object.", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteObject:upnp-class: + * + * The UPnP class of this object. + **/ + g_object_class_install_property + (object_class, + PROP_UPNP_CLASS, + g_param_spec_string ("upnp-class", + "UPnPClassName", + "The UPnP class of this object.", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteObject:creator: + * + * The creator of this object. + * + * Deprecated: 0.5.3: Use #gupnp_didl_lite_object_get_creators and + * #gupnp_didl_lite_object_add_creator instead since unlike this + * property, they are capable of dealing with multiple creator nodes. + **/ + g_object_class_install_property + (object_class, + PROP_CREATOR, + g_param_spec_string ("creator", + "Creator", + "The creator of this object.", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteObject:artist: + * + * The artist of this object. + * + * Deprecated: 0.5.3: Use #gupnp_didl_lite_object_get_artists and + * #gupnp_didl_lite_object_add_artist instead since unlike this + * property, they are capable of dealing with multiple artist nodes. + **/ + g_object_class_install_property + (object_class, + PROP_ARTIST, + g_param_spec_string ("artist", + "Artist", + "The artist of this object.", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteObject:author: + * + * The author of this object. + * + * Deprecated: 0.5.3: Use #gupnp_didl_lite_object_get_authors and + * #gupnp_didl_lite_object_add_author instead since unlike this + * property, they are capable of dealing with multiple author nodes. + **/ + g_object_class_install_property + (object_class, + PROP_AUTHOR, + g_param_spec_string ("author", + "Author", + "The author of this object.", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteObject:genre: + * + * The genre of this object. + **/ + g_object_class_install_property + (object_class, + PROP_GENRE, + g_param_spec_string ("genre", + "Genre", + "The genre of this object.", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteObject:write-status: + * + * The write status of this object. + **/ + g_object_class_install_property + (object_class, + PROP_WRITE_STATUS, + g_param_spec_string ("write-status", + "WriteStatus", + "The write status of this object.", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteObject:album: + * + * The album of this object. + **/ + g_object_class_install_property + (object_class, + PROP_ALBUM, + g_param_spec_string ("album", + "Album", + "The album of this object.", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteObject:album-art: + * + * The URI to album art of this object. + **/ + g_object_class_install_property + (object_class, + PROP_ALBUM_ART, + g_param_spec_string ("album-art", + "AlbumArt", + "The URI to album art of this object.", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteObject:description: + * + * The description of this object. + **/ + g_object_class_install_property + (object_class, + PROP_DESCRIPTION, + g_param_spec_string ("description", + "Description", + "The description of this object.", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteObject:date: + * + * The date of this object. + **/ + g_object_class_install_property + (object_class, + PROP_DATE, + g_param_spec_string ("date", + "Date", + "The date of this object.", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteObject:track-number: + * + * The original track number of this object. + **/ + g_object_class_install_property + (object_class, + PROP_TRACK_NUMBER, + g_param_spec_int ("track-number", + "TrackNumber", + "The original track number of this object.", + -1, G_MAXINT, -1, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteObject:dlna-managed: + * + * The 'dlna:dlnaManaged' attribute. + **/ + g_object_class_install_property + (object_class, + PROP_DLNA_MANAGED, + g_param_spec_flags ("dlna-managed", + "DLNAManaged", + "The 'dlna:dlnaManaged' attribute", + GUPNP_TYPE_OCM_FLAGS, + GUPNP_OCM_FLAGS_NONE, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); +} + +static gboolean +is_resource_compatible (GUPnPDIDLLiteResource *resource, + const char *sink_protocol_info) +{ + gboolean ret = FALSE; + char **protocols, **it; + + protocols = g_strsplit (sink_protocol_info, ",", 0); + + + for (it = protocols; *it != NULL && !ret; it++) { + GUPnPProtocolInfo *info; + GUPnPProtocolInfo *res_info; + + info = gupnp_protocol_info_new_from_string (*it, NULL); + if (info == NULL) + continue; + + res_info = gupnp_didl_lite_resource_get_protocol_info + (resource); + ret = gupnp_protocol_info_is_compatible (info, res_info); + + g_object_unref (info); + } + + g_strfreev (protocols); + + return ret; +} + +static GList * +get_contributor_list_by_name (GUPnPDIDLLiteObject *object, + const char *name) +{ + GList *contributors = NULL; + GList *ret = NULL; + GList *l; + + contributors = gupnp_didl_lite_object_get_properties (object, name); + + for (l = contributors; l; l = l->next) { + GUPnPDIDLLiteContributor *contributor; + xmlNode *contributor_node; + + contributor_node = (xmlNode *) l->data; + if (!contributor_node->children) + continue; + + contributor = gupnp_didl_lite_contributor_new_from_xml + (contributor_node, + object->priv->xml_doc); + + ret = g_list_append (ret, contributor); + } + + g_list_free (contributors); + + return ret; +} + +/** + * gupnp_didl_lite_object_new_from_xml: + * @xml_node: The pointer to 'res' node in XML document + * @xml_doc: The reference to XML document containing this object + * @upnp_ns: The pointer to 'upnp' namespace in XML document + * @dc_ns: The pointer to 'dc' namespace in XML document + * @dlna_ns: The pointer to 'dlna' namespace in XML document + * + * Creates a new #GUPnPDIDLLiteObject for the @xml_node. + * + * Return value: A new #GUPnPDIDLLiteObject object. Unref after usage. + **/ +GUPnPDIDLLiteObject * +gupnp_didl_lite_object_new_from_xml (xmlNode *xml_node, + GUPnPXMLDoc *xml_doc, + xmlNs *upnp_ns, + xmlNs *dc_ns, + xmlNs *dlna_ns) +{ + g_return_val_if_fail (xml_node != NULL, NULL); + g_return_val_if_fail (xml_node->name != NULL, NULL); + g_return_val_if_fail (upnp_ns != NULL, NULL); + g_return_val_if_fail (dc_ns != NULL, NULL); + g_return_val_if_fail (dlna_ns != NULL, NULL); + + if (g_ascii_strcasecmp ((char *) xml_node->name, "container") == 0) + return g_object_new (GUPNP_TYPE_DIDL_LITE_CONTAINER, + "xml-node", xml_node, + "xml-doc", xml_doc, + "upnp-namespace", upnp_ns, + "dc-namespace", dc_ns, + "dlna-namespace", dlna_ns, + NULL); + else if (g_ascii_strcasecmp ((char *) xml_node->name, "item") == 0) + return g_object_new (GUPNP_TYPE_DIDL_LITE_ITEM, + "xml-node", xml_node, + "xml-doc", xml_doc, + "upnp-namespace", upnp_ns, + "dc-namespace", dc_ns, + "dlna-namespace", dlna_ns, + NULL); + else + return NULL; +} + +/** + * gupnp_didl_lite_object_get_xml_node: + * @object: The #GUPnPDIDLLiteObject + * + * Get the pointer to object node in XML document. + * + * Returns: (transfer none): The pointer to object node in XML document. + **/ +xmlNode * +gupnp_didl_lite_object_get_xml_node (GUPnPDIDLLiteObject *object) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL); + + return object->priv->xml_node; +} + +/** + * gupnp_didl_lite_object_get_upnp_namespace: + * @object: The #GUPnPDIDLLiteObject + * + * Get the pointer to the UPnP namespace registered with the XML document. + * + * Returns: (transfer none): The pointer to UPnP namespace in XML document. + **/ +xmlNsPtr +gupnp_didl_lite_object_get_upnp_namespace (GUPnPDIDLLiteObject *object) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL); + + return object->priv->upnp_ns; +} + +/** + * gupnp_didl_lite_object_get_dc_namespace: + * @object: The #GUPnPDIDLLiteObject + * + * Get the pointer to the DublinCore namespace registered with the XML document + * containing this object. + * + * Returns: (transfer none): The pointer to DublinCore namespace in XML document. + **/ +xmlNsPtr +gupnp_didl_lite_object_get_dc_namespace (GUPnPDIDLLiteObject *object) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL); + + return object->priv->dc_ns; +} + +/** + * gupnp_didl_lite_object_get_upnp_class: + * @object: The #GUPnPDIDLLiteObject + * + * Get the UPnP class of the @object. + * + * Return value: The class of @object, or %NULL. + **/ +const char * +gupnp_didl_lite_object_get_upnp_class (GUPnPDIDLLiteObject *object) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL); + + return xml_util_get_child_element_content (object->priv->xml_node, + "class"); +} + +/** + * gupnp_didl_lite_object_get_dlna_namespace: + * @object: The #GUPnPDIDLLiteObject + * + * Get the pointer to the DLNA metadata namespace registered with the XML + * document containing this object. + * + * Returns: (transfer none): The pointer to DLNA namespace in XML document. + **/ +xmlNsPtr +gupnp_didl_lite_object_get_dlna_namespace (GUPnPDIDLLiteObject *object) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL); + + return object->priv->dlna_ns; +} + +/** + * gupnp_didl_lite_object_get_id: + * @object: #GUPnPDIDLLiteObject + * + * Get the ID of the @object. + * + * Return value: The ID of the @object, or %NULL. + **/ +const char * +gupnp_didl_lite_object_get_id (GUPnPDIDLLiteObject *object) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL); + + return xml_util_get_attribute_content (object->priv->xml_node, "id"); +} + +/** + * gupnp_didl_lite_object_get_parent_id: + * @object: #GUPnPDIDLLiteObject + * + * Get the ID of the parent of the @object. + * + * Return value: The ID of parent of the @object, or %NULL. + **/ +const char * +gupnp_didl_lite_object_get_parent_id (GUPnPDIDLLiteObject *object) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL); + + return xml_util_get_attribute_content (object->priv->xml_node, + "parentID"); +} + +/** + * gupnp_didl_lite_object_get_properties: + * @object: #GUPnPDIDLLiteObject + * @name: name of the properties + * + * Use this function to retreive property nodes by name. + * + * Return value: (element-type xmlNode*) (transfer container): The list of + * property nodes by the name @property_name belonging to @object, or %NULL. + * #g_list_free the returned list after usage but do not modify the contents. + **/ +GList * +gupnp_didl_lite_object_get_properties (GUPnPDIDLLiteObject *object, + const char *name) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL); + g_return_val_if_fail (name != NULL, NULL); + + return xml_util_get_child_elements_by_name (object->priv->xml_node, + name); +} + +/** + * gupnp_didl_lite_object_get_restricted: + * @object: #GUPnPDIDLLiteObject + * + * Whether the @object is restricted or not. + * + * Return value: #TRUE if @object is restricted. + **/ +gboolean +gupnp_didl_lite_object_get_restricted (GUPnPDIDLLiteObject *object) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), FALSE); + + return xml_util_get_boolean_attribute (object->priv->xml_node, + "restricted"); +} + +/** + * gupnp_didl_lite_object_get_title: + * @object: #GUPnPDIDLLiteObject + * + * Get the title of the @object. + * + * Return value: The title of the @object, or %NULL. + **/ +const char * +gupnp_didl_lite_object_get_title (GUPnPDIDLLiteObject *object) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL); + + return xml_util_get_child_element_content (object->priv->xml_node, + "title"); +} + +/** + * gupnp_didl_lite_object_get_creator: + * @object: #GUPnPDIDLLiteObject + * + * Get the creator of the @object. + * + * Return value: The creator of the @object, or %NULL. + * + * Deprecated: 0.5.3: Use #gupnp_didl_lite_object_get_creators instead. + **/ +const char * +gupnp_didl_lite_object_get_creator (GUPnPDIDLLiteObject *object) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL); + + return xml_util_get_child_element_content (object->priv->xml_node, + "creator"); +} + +/** + * gupnp_didl_lite_object_get_creators: + * @object: #GUPnPDIDLLiteObject + * + * Get the creators of the @object. + * + * Returns: (element-type GUPnPDIDLLiteContributor*) (transfer full): The list + * of creators belonging to @object, or %NULL. + * #g_list_free the returned list after usage and unref each object in it. + **/ +GList * +gupnp_didl_lite_object_get_creators (GUPnPDIDLLiteObject *object) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL); + + return get_contributor_list_by_name (object, "creator"); +} + +/** + * gupnp_didl_lite_object_get_artist: + * @object: #GUPnPDIDLLiteObject + * + * Get the artist of the @object. If role is not %NULL, it is set to the role + * of the artist if available. + * + * Return value: The artist of the @object, or %NULL. + * + * Deprecated: 0.5.3: Use #gupnp_didl_lite_object_get_artists instead. + **/ +const char * +gupnp_didl_lite_object_get_artist (GUPnPDIDLLiteObject *object) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL); + + return xml_util_get_child_element_content (object->priv->xml_node, + "artist"); +} + +/** + * gupnp_didl_lite_object_get_artists: + * @object: #GUPnPDIDLLiteObject + * + * Get the artists of the @object. + * + * Returns: (element-type GUPnPDIDLLiteContributor*) (transfer full): The list + * of artists belonging to @object, or %NULL. + * #g_list_free the returned list after usage and unref each object in it. + **/ +GList * +gupnp_didl_lite_object_get_artists (GUPnPDIDLLiteObject *object) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL); + + return get_contributor_list_by_name (object, "artist"); +} + +/** + * gupnp_didl_lite_object_get_author: + * @object: #GUPnPDIDLLiteObject + * + * Get the author of the @object. + * + * Return value: The author of the @object, or %NULL. + * + * Deprecated: 0.5.3: Use #gupnp_didl_lite_object_get_authors instead. + **/ +const char * +gupnp_didl_lite_object_get_author (GUPnPDIDLLiteObject *object) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL); + + return xml_util_get_child_element_content (object->priv->xml_node, + "author"); +} + +/** + * gupnp_didl_lite_object_get_authors: + * @object: #GUPnPDIDLLiteObject + * + * Get the authors of the @object. + * + * Returns: (element-type GUPnPDIDLLiteContributor*) (transfer full): The list + * of authors belonging to @object, or %NULL. + * #g_list_free the returned list after usage and unref each object in it. + **/ +GList * +gupnp_didl_lite_object_get_authors (GUPnPDIDLLiteObject *object) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL); + + return get_contributor_list_by_name (object, "author"); +} + +/** + * gupnp_didl_lite_object_get_descriptors: + * @object: #GUPnPDIDLLiteObject + * + * Get the descriptors of the @object. + * + * Returns: (element-type GUPnPDIDLLiteDescriptor*) (transfer full): The list of + * descriptors belonging to @object, or %NULL. + * #g_list_free the returned list after usage and unref each object in it. + **/ +GList * +gupnp_didl_lite_object_get_descriptors (GUPnPDIDLLiteObject *object) +{ + GList *descriptors = NULL; + GList *ret = NULL; + GList *l; + + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL); + + descriptors = gupnp_didl_lite_object_get_properties (object, "desc"); + + for (l = descriptors; l; l = l->next) { + GUPnPDIDLLiteDescriptor *descriptor; + xmlNode *descriptor_node; + + descriptor_node = (xmlNode *) l->data; + + descriptor = gupnp_didl_lite_descriptor_new_from_xml + (descriptor_node, + object->priv->xml_doc); + + ret = g_list_append (ret, descriptor); + } + + g_list_free (descriptors); + + return ret; +} + +/** + * gupnp_didl_lite_object_get_genre: + * @object: #GUPnPDIDLLiteObject + * + * Get the genre of the @object. + * + * Return value: The genre of the @object, or %NULL. + **/ +const char * +gupnp_didl_lite_object_get_genre (GUPnPDIDLLiteObject *object) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL); + + return xml_util_get_child_element_content (object->priv->xml_node, + "genre"); +} + +/** + * gupnp_didl_lite_object_get_write_status: + * @object: #GUPnPDIDLLiteObject + * + * Get the write status of the @object. + * + * Return value: The write status of the @object, or %NULL. + **/ +const char * +gupnp_didl_lite_object_get_write_status (GUPnPDIDLLiteObject *object) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL); + + return xml_util_get_child_element_content (object->priv->xml_node, + "writeStatus"); +} + +/** + * gupnp_didl_lite_object_get_album: + * @object: #GUPnPDIDLLiteObject + * + * Get the album of the @object. + * + * Return value: The album of the @object, or %NULL. + **/ +const char * +gupnp_didl_lite_object_get_album (GUPnPDIDLLiteObject *object) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL); + + return xml_util_get_child_element_content (object->priv->xml_node, + "album"); +} + +/** + * gupnp_didl_lite_object_get_album_art: + * @object: #GUPnPDIDLLiteObject + * + * Get the URI to album art of the @object. + * + * Return value: The URI to album art of the @object, or %NULL. + **/ +const char * +gupnp_didl_lite_object_get_album_art (GUPnPDIDLLiteObject *object) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL); + + return xml_util_get_child_element_content (object->priv->xml_node, + "albumArtURI"); +} + +/** + * gupnp_didl_lite_object_get_description: + * @object: #GUPnPDIDLLiteObject + * + * Get the description of the @object. + * + * Return value: The description of the @object, or %NULL. + **/ +const char * +gupnp_didl_lite_object_get_description (GUPnPDIDLLiteObject *object) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL); + + return xml_util_get_child_element_content (object->priv->xml_node, + "description"); +} + +/** + * gupnp_didl_lite_object_get_date: + * @object: #GUPnPDIDLLiteObject + * + * Get the date of the @object. + * + * Return value: The date of the @object, or %NULL. + **/ +const char * +gupnp_didl_lite_object_get_date (GUPnPDIDLLiteObject *object) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL); + + return xml_util_get_child_element_content (object->priv->xml_node, + "date"); +} + +/** + * gupnp_didl_lite_object_get_track_number: + * @object: #GUPnPDIDLLiteObject + * + * Get the original track number of the @object. + * + * Return value: The original track number of the @object, or -1. + **/ +int +gupnp_didl_lite_object_get_track_number (GUPnPDIDLLiteObject *object) +{ + const char *str; + + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), -1); + + str = xml_util_get_child_element_content (object->priv->xml_node, + "originalTrackNumber"); + if (str == NULL) + return -1; + + return atoi (str); +} + +/** + * gupnp_didl_lite_object_get_dlna_managed: + * @object: #GUPnPDIDLLiteObject + * + * Get the 'dlna:dlnaManaged' attribute of the @object. + * + * Return value: The 'dlna:dlnaManaged' attribute of the @object. + **/ +GUPnPOCMFlags +gupnp_didl_lite_object_get_dlna_managed (GUPnPDIDLLiteObject *object) +{ + const char *str; + GUPnPOCMFlags dlna_managed; + + g_return_val_if_fail (object != NULL, GUPNP_OCM_FLAGS_NONE); + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), + GUPNP_OCM_FLAGS_NONE); + + str = xml_util_get_attribute_content (object->priv->xml_node, + "dlnaManaged"); + if (str == NULL) + return GUPNP_OCM_FLAGS_NONE; + + sscanf (str, "%08x", &dlna_managed); + + return dlna_managed; +} + +/** + * gupnp_didl_lite_object_get_resources: + * @object: #GUPnPDIDLLiteObject + * + * Use this function to retreive resources from the @object. + * + * Return value: (element-type GUPnPDIDLLiteResource*) (transfer full): The list + * of resources belonging to @object, or %NULL. #g_list_free the + * returned list after usage and unref each resource in it. + **/ +GList * +gupnp_didl_lite_object_get_resources (GUPnPDIDLLiteObject *object) +{ + GList *resources = NULL; + GList *res = NULL; + GList *ret = NULL; + + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL); + + resources = gupnp_didl_lite_object_get_properties (object, "res"); + + for (res = resources; res; res = res->next) { + GUPnPDIDLLiteResource *resource; + xmlNode *res_node; + + res_node = (xmlNode *) res->data; + + /* Create a resource struct out of DIDLLite XML */ + resource = gupnp_didl_lite_resource_new_from_xml + (res_node, + object->priv->xml_doc); + + ret = g_list_append (ret, resource); + } + + g_list_free (resources); + + return ret; +} + +/** + * gupnp_didl_lite_object_get_compat_resource: + * @object: #GUPnPDIDLLiteObject + * @sink_protocol_info: The SinkProtocolInfo string from MediaRenderer + * @lenient: Enable lenient mode + * + * Use this function to get a resource from the @object that is compatible with + * any of the protocols specified in the @sink_protocol_info. The value of + * @sink_protocol_info will typically be acquired from 'Sink' argument of + * 'GetProtocolInfo' action or 'SinkProtocolInfo' state-variable of a + * ConnectionManager service. + * + * If @lenient is #TRUE, the first resource in the list is returned instead of + * %NULL if none of resources and protocols are found to be compatible. + * + * Returns: (transfer full): The resource belonging to @object that is comaptible with + * any of the protocols specified in @sink_protocol_info, or %NULL. Unref after + * usage. + **/ +GUPnPDIDLLiteResource * +gupnp_didl_lite_object_get_compat_resource + (GUPnPDIDLLiteObject *object, + const char *sink_protocol_info, + gboolean lenient) +{ + GUPnPDIDLLiteResource *resource = NULL; + GList *resources = NULL; + GList *compat_resources = NULL; + GList *res; + + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL); + g_return_val_if_fail (sink_protocol_info != NULL, NULL); + + resources = gupnp_didl_lite_object_get_resources (object); + if (resources == NULL) + return NULL; + + for (res = resources; + res != NULL; + res = res->next) { + resource = (GUPnPDIDLLiteResource *) res->data; + + if (is_resource_compatible (resource, sink_protocol_info)) + compat_resources = g_list_append (compat_resources, + resource); + } + + resource = NULL; + + if (compat_resources != NULL) { + /* Try to find non-transcoded resource */ + res = g_list_find_custom (compat_resources, + NULL, + (GCompareFunc) + is_non_transcoded_resource); + + if (res != NULL) + resource = (GUPnPDIDLLiteResource *) res->data; + else + /* Just use the first compatible resource */ + resource = (GUPnPDIDLLiteResource *) + compat_resources->data; + + } else if (lenient) + /* Just use the first resource */ + resource = (GUPnPDIDLLiteResource *) resources->data; + + /* Unref all resources except for the one we just took */ + for (res = resources; res; res = res->next) + if (res->data != resource) + g_object_unref (res->data); + g_list_free (resources); + g_list_free (compat_resources); + + return resource; +} + +/** + * gupnp_didl_lite_object_set_upnp_class: + * @object: The #GUPnPDIDLLiteObject + * @upnp_class: The UPnP class as string. + * + * Set the UPnP class of the @object to @upnp_class. + **/ +void +gupnp_didl_lite_object_set_upnp_class (GUPnPDIDLLiteObject *object, + const char *upnp_class) +{ + g_return_if_fail (object != NULL); + g_return_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object)); + + xml_util_set_child (object->priv->xml_node, + object->priv->upnp_ns, + object->priv->xml_doc->doc, + "class", + upnp_class); + + g_object_notify (G_OBJECT (object), "upnp-class"); +} + +/** + * gupnp_didl_lite_object_set_id: + * @object: #GUPnPDIDLLiteObject + * @id: The ID + * + * Set the ID of the @object to @id. + **/ +void +gupnp_didl_lite_object_set_id (GUPnPDIDLLiteObject *object, + const char *id) +{ + g_return_if_fail (object != NULL); + g_return_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object)); + + xmlSetProp (object->priv->xml_node, + (unsigned char *) "id", + (unsigned char *) id); + + g_object_notify (G_OBJECT (object), "id"); +} + +/** + * gupnp_didl_lite_object_set_parent_id: + * @object: #GUPnPDIDLLiteObject + * @parent_id: The parent ID + * + * Set the ID of the parent of the @object to @parent_id. + **/ +void +gupnp_didl_lite_object_set_parent_id (GUPnPDIDLLiteObject *object, + const char *parent_id) +{ + g_return_if_fail (object != NULL); + g_return_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object)); + + xmlSetProp (object->priv->xml_node, + (unsigned char *) "parentID", + (unsigned char *) parent_id); + + g_object_notify (G_OBJECT (object), "parent-id"); +} + +/** + * gupnp_didl_lite_object_set_restricted: + * @object: #GUPnPDIDLLiteObject + * @restricted: The restricted status + * + * Set the restricted status of @object to @restricted. + **/ +void +gupnp_didl_lite_object_set_restricted (GUPnPDIDLLiteObject *object, + gboolean restricted) +{ + const char *str; + + g_return_if_fail (object != NULL); + g_return_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object)); + + if (restricted) + str = "1"; + else + str = "0"; + xmlSetProp (object->priv->xml_node, + (unsigned char *) "restricted", + (unsigned char *) str); + + g_object_notify (G_OBJECT (object), "restricted"); +} + +/** + * gupnp_didl_lite_object_set_title: + * @object: #GUPnPDIDLLiteObject + * @title: The title + * + * Set the title of the @object to @title. + **/ +void +gupnp_didl_lite_object_set_title (GUPnPDIDLLiteObject *object, + const char *title) +{ + g_return_if_fail (object != NULL); + g_return_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object)); + + xml_util_set_child (object->priv->xml_node, + object->priv->dc_ns, + object->priv->xml_doc->doc, + "title", + title); + + g_object_notify (G_OBJECT (object), "title"); +} + +/** + * gupnp_didl_lite_object_set_creator: + * @object: #GUPnPDIDLLiteObject + * @creator: The creator + * + * Set the creator of the @object to @creator. + * + * Deprecated: 0.5.3: Use #gupnp_didl_lite_object_add_creator instead. + **/ +void +gupnp_didl_lite_object_set_creator (GUPnPDIDLLiteObject *object, + const char *creator) +{ + g_return_if_fail (object != NULL); + g_return_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object)); + + xml_util_set_child (object->priv->xml_node, + object->priv->dc_ns, + object->priv->xml_doc->doc, + "creator", + creator); + + g_object_notify (G_OBJECT (object), "creator"); +} + +/** + * gupnp_didl_lite_object_add_creator: + * @object: The #GUPnPDIDLLiteObject + * + * Add a new creator node to the @object and return the associated + * #GUPnPDIDLLiteContributor object. + * + * Returns: (transfer full): A new #GUPnPDIDLLiteContributor object. Unref after usage. + **/ +GUPnPDIDLLiteContributor * +gupnp_didl_lite_object_add_creator (GUPnPDIDLLiteObject *object) +{ + xmlNode *res_node; + + g_return_val_if_fail (object != NULL, NULL); + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL); + + res_node = xmlNewChild (object->priv->xml_node, + object->priv->dc_ns, + (unsigned char *) "creator", + NULL); + + return gupnp_didl_lite_contributor_new_from_xml (res_node, + object->priv->xml_doc); +} + + +/** + * gupnp_didl_lite_object_set_artist: + * @object: The #GUPnPDIDLLiteObject + * @artist: The Artist + * + * Set the Artist of the @object to @artist. + * + * Deprecated: 0.5.3: Use #gupnp_didl_lite_object_add_artist instead. + **/ +void +gupnp_didl_lite_object_set_artist (GUPnPDIDLLiteObject *object, + const char *artist) +{ + g_return_if_fail (object != NULL); + g_return_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object)); + + xml_util_set_child (object->priv->xml_node, + object->priv->upnp_ns, + object->priv->xml_doc->doc, + "artist", + artist); + + g_object_notify (G_OBJECT (object), "artist"); +} + +/** + * gupnp_didl_lite_object_add_artist: + * @object: The #GUPnPDIDLLiteObject + * + * Add a new Artist node to the @object and return the associated + * #GUPnPDIDLLiteContributor object. + * + * Returns: (transfer full): A new #GUPnPDIDLLiteContributor object. Unref after usage. + **/ +GUPnPDIDLLiteContributor * +gupnp_didl_lite_object_add_artist (GUPnPDIDLLiteObject *object) +{ + xmlNode *res_node; + + g_return_val_if_fail (object != NULL, NULL); + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL); + + res_node = xmlNewChild (object->priv->xml_node, + object->priv->upnp_ns, + (unsigned char *) "artist", + NULL); + + return gupnp_didl_lite_contributor_new_from_xml (res_node, + object->priv->xml_doc); +} + +/** + * gupnp_didl_lite_object_set_author: + * @object: The #GUPnPDIDLLiteObject + * @author: The Author + * + * Set the Author of the @object to @author. + * + * Deprecated: 0.5.3: Use #gupnp_didl_lite_object_add_author instead. + **/ +void +gupnp_didl_lite_object_set_author (GUPnPDIDLLiteObject *object, + const char *author) +{ + g_return_if_fail (object != NULL); + g_return_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object)); + + xml_util_set_child (object->priv->xml_node, + object->priv->upnp_ns, + object->priv->xml_doc->doc, + "author", + author); + + g_object_notify (G_OBJECT (object), "author"); +} + +/** + * gupnp_didl_lite_object_add_author: + * @object: The #GUPnPDIDLLiteObject + * + * Add a new author node to the @object and return the associated + * #GUPnPDIDLLiteContributor object. + * + * Returns: (transfer full): A new #GUPnPDIDLLiteContributor object. Unref after usage. + **/ +GUPnPDIDLLiteContributor * +gupnp_didl_lite_object_add_author (GUPnPDIDLLiteObject *object) +{ + xmlNode *res_node; + + g_return_val_if_fail (object != NULL, NULL); + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL); + + res_node = xmlNewChild (object->priv->xml_node, + object->priv->upnp_ns, + (unsigned char *) "author", + NULL); + + return gupnp_didl_lite_contributor_new_from_xml (res_node, + object->priv->xml_doc); +} + +/** + * gupnp_didl_lite_object_set_genre: + * @object: The #GUPnPDIDLLiteObject + * @genre: The Genre + * + * Set the genre of the @object to @genre. + **/ +void +gupnp_didl_lite_object_set_genre (GUPnPDIDLLiteObject *object, + const char *genre) +{ + g_return_if_fail (object != NULL); + g_return_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object)); + + xml_util_set_child (object->priv->xml_node, + object->priv->upnp_ns, + object->priv->xml_doc->doc, + "genre", + genre); + + g_object_notify (G_OBJECT (object), "genre"); +} + +/** + * gupnp_didl_lite_object_set_write_status: + * @object: #GUPnPDIDLLiteObject + * @write_status: The write status string + * + * Set the write status of the @object to @write_status. + **/ +void +gupnp_didl_lite_object_set_write_status (GUPnPDIDLLiteObject *object, + const char *write_status) +{ + g_return_if_fail (object != NULL); + g_return_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object)); + + xml_util_set_child (object->priv->xml_node, + object->priv->dc_ns, + object->priv->xml_doc->doc, + "writeStatus", + write_status); + + g_object_notify (G_OBJECT (object), "write-status"); +} + +/** + * gupnp_didl_lite_object_set_album: + * @object: #GUPnPDIDLLiteObject + * @album: The album string + * + * Set the album of the @object to @album. + **/ +void +gupnp_didl_lite_object_set_album (GUPnPDIDLLiteObject *object, + const char *album) +{ + g_return_if_fail (object != NULL); + g_return_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object)); + + xml_util_set_child (object->priv->xml_node, + object->priv->upnp_ns, + object->priv->xml_doc->doc, + "album", + album); + + g_object_notify (G_OBJECT (object), "album"); +} + +/** + * gupnp_didl_lite_object_set_album_art: + * @object: #GUPnPDIDLLiteObject + * @album_art: The URI of album art + * + * Set the URI to album art of the @object to @album_art. + **/ +void +gupnp_didl_lite_object_set_album_art (GUPnPDIDLLiteObject *object, + const char *album_art) +{ + xmlNode *node; + + g_return_if_fail (object != NULL); + g_return_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object)); + + node = xml_util_set_child (object->priv->xml_node, + object->priv->upnp_ns, + object->priv->xml_doc->doc, + "albumArtURI", + album_art); + xmlSetNsProp (node, + object->priv->dlna_ns, + (const unsigned char *) "profileID", + (const unsigned char *) "JPEG_TN"); + + g_object_notify (G_OBJECT (object), "album-art"); +} + +/** + * gupnp_didl_lite_object_set_description: + * @object: #GUPnPDIDLLiteObject + * @description: The description string + * + * Set the description of the @object to @description. + **/ +void +gupnp_didl_lite_object_set_description (GUPnPDIDLLiteObject *object, + const char *description) +{ + g_return_if_fail (object != NULL); + g_return_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object)); + + xml_util_set_child (object->priv->xml_node, + object->priv->dc_ns, + object->priv->xml_doc->doc, + "description", + description); + + g_object_notify (G_OBJECT (object), "description"); +} + +/** + * gupnp_didl_lite_object_set_date: + * @object: #GUPnPDIDLLiteObject + * @date: The date string + * + * Set the date of the @object to @date. + **/ +void +gupnp_didl_lite_object_set_date (GUPnPDIDLLiteObject *object, + const char *date) +{ + g_return_if_fail (object != NULL); + g_return_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object)); + + xml_util_set_child (object->priv->xml_node, + object->priv->dc_ns, + object->priv->xml_doc->doc, + "date", + date); + + g_object_notify (G_OBJECT (object), "date"); +} + +/** + * gupnp_didl_lite_object_set_track_number: + * @object: #GUPnPDIDLLiteObject + * @track_number: The original track number + * + * Set the original track number of the @object to @track_number. + **/ +void +gupnp_didl_lite_object_set_track_number (GUPnPDIDLLiteObject *object, + int track_number) +{ + char *str; + + g_return_if_fail (object != NULL); + g_return_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object)); + + str = g_strdup_printf ("%d", track_number); + xml_util_set_child (object->priv->xml_node, + object->priv->upnp_ns, + object->priv->xml_doc->doc, + "originalTrackNumber", + str); + g_free (str); + + g_object_notify (G_OBJECT (object), "track-number"); +} + +/** + * gupnp_didl_lite_object_set_dlna_managed: + * @object: #GUPnPDIDLLiteObject + * @dlna_managed: The #GUPnPOCMFlags. + * + * Set the 'dlna:dlnaManaged' attribute of the @object to @dlna_managed. + **/ +void +gupnp_didl_lite_object_set_dlna_managed (GUPnPDIDLLiteObject *object, + GUPnPOCMFlags dlna_managed) +{ + char *str; + + g_return_if_fail (object != NULL); + g_return_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object)); + + str = g_strdup_printf ("%08x", dlna_managed); + xmlSetNsProp (object->priv->xml_node, + object->priv->dlna_ns, + (const unsigned char *) "dlnaManaged", + (const unsigned char *) str); + g_free (str); + + g_object_notify (G_OBJECT (object), "dlna-managed"); +} + +/** + * gupnp_didl_lite_object_add_resource: + * @object: A #GUPnPDIDLLiteObject + * + * Creates a new resource, attaches it to @object and returns it. + * + * Returns: (transfer full): A new #GUPnPDIDLLiteResource object. Unref after usage. + **/ +GUPnPDIDLLiteResource * +gupnp_didl_lite_object_add_resource (GUPnPDIDLLiteObject *object) +{ + xmlNode *res_node; + + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL); + + res_node = xmlNewChild (object->priv->xml_node, + NULL, + (unsigned char *) "res", + NULL); + + return gupnp_didl_lite_resource_new_from_xml (res_node, + object->priv->xml_doc); +} + +/** + * gupnp_didl_lite_object_add_descriptor: + * @object: A #GUPnPDIDLLiteObject + * + * Creates a new descriptor, attaches it to @object and returns it. + * + * Returns: (transfer full): A new #GUPnPDIDLLiteDescriptor object. Unref after usage. + **/ +GUPnPDIDLLiteDescriptor * +gupnp_didl_lite_object_add_descriptor (GUPnPDIDLLiteObject *object) +{ + xmlNode *desc_node; + + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_OBJECT (object), NULL); + + desc_node = xmlNewChild (object->priv->xml_node, + NULL, + (unsigned char *) "desc", + NULL); + + return gupnp_didl_lite_descriptor_new_from_xml (desc_node, + object->priv->xml_doc); +} + diff --git a/libgupnp-av/gupnp-didl-lite-object.h b/libgupnp-av/gupnp-didl-lite-object.h new file mode 100644 index 0000000..722e833 --- /dev/null +++ b/libgupnp-av/gupnp-didl-lite-object.h @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2009 Nokia Corporation. + * Copyright (C) 2007, 2008 OpenedHand Ltd. + * + * Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com> + * <zeeshanak@gnome.org> + * Jorn Baayen <jorn@openedhand.com> + * + * 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. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __GUPNP_DIDL_LITE_OBJECT_H__ +#define __GUPNP_DIDL_LITE_OBJECT_H__ + +#include <stdarg.h> +#include <glib-object.h> +#include <libxml/tree.h> + +#include "gupnp-didl-lite-resource.h" +#include "gupnp-didl-lite-descriptor.h" +#include "gupnp-didl-lite-contributor.h" + +G_BEGIN_DECLS + +GType +gupnp_didl_lite_object_get_type (void) G_GNUC_CONST; + +#define GUPNP_TYPE_DIDL_LITE_OBJECT \ + (gupnp_didl_lite_object_get_type ()) +#define GUPNP_DIDL_LITE_OBJECT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + GUPNP_TYPE_DIDL_LITE_OBJECT, \ + GUPnPDIDLLiteObject)) +#define GUPNP_DIDL_LITE_OBJECT_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_CAST ((obj), \ + GUPNP_TYPE_DIDL_LITE_OBJECT, \ + GUPnPDIDLLiteObjectClass)) +#define GUPNP_IS_DIDL_LITE_OBJECT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + GUPNP_TYPE_DIDL_LITE_OBJECT)) +#define GUPNP_IS_DIDL_LITE_OBJECT_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE ((obj), \ + GUPNP_TYPE_DIDL_LITE_OBJECT)) +#define GUPNP_DIDL_LITE_OBJECT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + GUPNP_TYPE_DIDL_LITE_OBJECT, \ + GUPnPDIDLLiteObjectClass)) + +typedef struct _GUPnPDIDLLiteObjectPrivate GUPnPDIDLLiteObjectPrivate; + +typedef struct { + GObject parent; + + GUPnPDIDLLiteObjectPrivate *priv; +} GUPnPDIDLLiteObject; + +typedef struct { + GObjectClass parent_class; + + /* future padding */ + void (* _gupnp_reserved1) (void); + void (* _gupnp_reserved2) (void); + void (* _gupnp_reserved3) (void); + void (* _gupnp_reserved4) (void); +} GUPnPDIDLLiteObjectClass; + +xmlNode * +gupnp_didl_lite_object_get_xml_node (GUPnPDIDLLiteObject *object); + +xmlNsPtr +gupnp_didl_lite_object_get_upnp_namespace + (GUPnPDIDLLiteObject *object); + +xmlNsPtr +gupnp_didl_lite_object_get_dc_namespace (GUPnPDIDLLiteObject *object); + +xmlNsPtr +gupnp_didl_lite_object_get_dlna_namespace + (GUPnPDIDLLiteObject *object); + +const char * +gupnp_didl_lite_object_get_upnp_class (GUPnPDIDLLiteObject *object); + +const char * +gupnp_didl_lite_object_get_id (GUPnPDIDLLiteObject *object); + +const char * +gupnp_didl_lite_object_get_parent_id (GUPnPDIDLLiteObject *object); + +GList * +gupnp_didl_lite_object_get_properties (GUPnPDIDLLiteObject *object, + const char *name); + +gboolean +gupnp_didl_lite_object_get_restricted (GUPnPDIDLLiteObject *object); + +const char * +gupnp_didl_lite_object_get_title (GUPnPDIDLLiteObject *object); + +#ifndef GUPNP_DISABLE_DEPRECATED +const char * +gupnp_didl_lite_object_get_creator (GUPnPDIDLLiteObject *object); + +const char * +gupnp_didl_lite_object_get_artist (GUPnPDIDLLiteObject *object); + +const char * +gupnp_didl_lite_object_get_author (GUPnPDIDLLiteObject *object); + +#endif /* GUPNP_DISABLE_DEPRECATED */ + +GList * +gupnp_didl_lite_object_get_creators (GUPnPDIDLLiteObject *object); + +GList * +gupnp_didl_lite_object_get_artists (GUPnPDIDLLiteObject *object); + +GList * +gupnp_didl_lite_object_get_authors (GUPnPDIDLLiteObject *object); + +GList * +gupnp_didl_lite_object_get_descriptors (GUPnPDIDLLiteObject *object); + +const char * +gupnp_didl_lite_object_get_genre (GUPnPDIDLLiteObject *object); + +const char * +gupnp_didl_lite_object_get_write_status (GUPnPDIDLLiteObject *object); + +const char * +gupnp_didl_lite_object_get_album (GUPnPDIDLLiteObject *object); + +const char * +gupnp_didl_lite_object_get_album_art (GUPnPDIDLLiteObject *object); + +const char * +gupnp_didl_lite_object_get_description (GUPnPDIDLLiteObject *object); + +const char * +gupnp_didl_lite_object_get_date (GUPnPDIDLLiteObject *object); + +int +gupnp_didl_lite_object_get_track_number (GUPnPDIDLLiteObject *object); + +GUPnPOCMFlags +gupnp_didl_lite_object_get_dlna_managed (GUPnPDIDLLiteObject *object); + +GList * +gupnp_didl_lite_object_get_resources (GUPnPDIDLLiteObject *object); + +GUPnPDIDLLiteResource * +gupnp_didl_lite_object_get_compat_resource + (GUPnPDIDLLiteObject *object, + const char + *sink_protocol_info, + gboolean lenient); + +GUPnPDIDLLiteResource * +gupnp_didl_lite_object_add_resource (GUPnPDIDLLiteObject *object); + +GUPnPDIDLLiteDescriptor * +gupnp_didl_lite_object_add_descriptor (GUPnPDIDLLiteObject *object); + +void +gupnp_didl_lite_object_set_upnp_class (GUPnPDIDLLiteObject *object, + const char *upnp_class); + +void +gupnp_didl_lite_object_set_id (GUPnPDIDLLiteObject *object, + const char *id); + +void +gupnp_didl_lite_object_set_parent_id (GUPnPDIDLLiteObject *object, + const char *parent_id); + +void +gupnp_didl_lite_object_set_restricted (GUPnPDIDLLiteObject *object, + gboolean restricted); + +void +gupnp_didl_lite_object_set_title (GUPnPDIDLLiteObject *object, + const char *title); + +#ifndef GUPNP_DISABLE_DEPRECATED +void +gupnp_didl_lite_object_set_creator (GUPnPDIDLLiteObject *object, + const char *creator); + +void +gupnp_didl_lite_object_set_artist (GUPnPDIDLLiteObject *object, + const char *artist); + +void +gupnp_didl_lite_object_set_author (GUPnPDIDLLiteObject *object, + const char *author); + +#endif /* GUPNP_DISABLE_DEPRECATED */ + +GUPnPDIDLLiteContributor * +gupnp_didl_lite_object_add_creator (GUPnPDIDLLiteObject *object); + +GUPnPDIDLLiteContributor * +gupnp_didl_lite_object_add_artist (GUPnPDIDLLiteObject *object); + +GUPnPDIDLLiteContributor * +gupnp_didl_lite_object_add_author (GUPnPDIDLLiteObject *object); + +void +gupnp_didl_lite_object_set_genre (GUPnPDIDLLiteObject *object, + const char *genre); + +void +gupnp_didl_lite_object_set_write_status (GUPnPDIDLLiteObject *object, + const char *write_status); + +void +gupnp_didl_lite_object_set_album (GUPnPDIDLLiteObject *object, + const char *album); + +void +gupnp_didl_lite_object_set_album_art (GUPnPDIDLLiteObject *object, + const char *album_art); + +void +gupnp_didl_lite_object_set_description (GUPnPDIDLLiteObject *object, + const char *description); + +void +gupnp_didl_lite_object_set_date (GUPnPDIDLLiteObject *object, + const char *date); + +void +gupnp_didl_lite_object_set_track_number (GUPnPDIDLLiteObject *object, + int track_number); + +void +gupnp_didl_lite_object_set_dlna_managed (GUPnPDIDLLiteObject *object, + GUPnPOCMFlags dlna_managed); + +G_END_DECLS + +#endif /* __GUPNP_DIDL_LITE_OBJECT_H__ */ diff --git a/libgupnp-av/gupnp-didl-lite-parser.c b/libgupnp-av/gupnp-didl-lite-parser.c new file mode 100644 index 0000000..8b1088d --- /dev/null +++ b/libgupnp-av/gupnp-didl-lite-parser.c @@ -0,0 +1,334 @@ +/* + * Copyright (C) 2007 Zeeshan Ali (Khattak) <zeeshanak@gnome.org> + * + * Authors: Zeeshan Ali (Khattak) <zeeshanak@gnome.org> + * + * 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. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +/** + * SECTION:gupnp-didl-lite-parser + * @short_description: A/V DIDL-Lite XML parser + * + * #GUPnPDIDLLiteParser parses DIDL-Lite XML strings. + * + */ + +#include <string.h> +#include <ctype.h> +#include "gupnp-av.h" +#include "gupnp-didl-lite-object-private.h" +#include "xml-util.h" + +G_DEFINE_TYPE (GUPnPDIDLLiteParser, + gupnp_didl_lite_parser, + G_TYPE_OBJECT); + +enum { + OBJECT_AVAILABLE, + ITEM_AVAILABLE, + CONTAINER_AVAILABLE, + SIGNAL_LAST +}; + +static guint signals[SIGNAL_LAST]; + +static gboolean +verify_didl_attributes (xmlNode *node) +{ + const char *content; + + content = xml_util_get_child_element_content (node, "date"); + if (content) { + /* try to roughly verify the passed date with ^\d{4}-\d{2}-\d{2} */ + char *ptr = (char *) content; + int state = 0; + while (*ptr) { + if (state == 4 || state == 7) { + if (*ptr != '-') + return FALSE; + } else { + if (!isdigit (*ptr)) + return FALSE; + } + + ptr++; + state++; + if (state == 10) + break; + } + } + + return xml_util_verify_attribute_is_boolean (node, "restricted"); +} + +static void +gupnp_didl_lite_parser_init (GUPnPDIDLLiteParser *parser) +{ +} + +static void +gupnp_didl_lite_parser_dispose (GObject *object) +{ + GObjectClass *gobject_class; + + gobject_class = G_OBJECT_CLASS (gupnp_didl_lite_parser_parent_class); + gobject_class->dispose (object); +} + +static void +gupnp_didl_lite_parser_class_init (GUPnPDIDLLiteParserClass *klass) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = gupnp_didl_lite_parser_dispose; + + /** + * GUPnPDIDLLiteParser::object-available: + * @parser: The #GUPnPDIDLLiteParser that received the signal + * @object: The now available #GUPnPDIDLLiteObject + * + * The ::object-available signal is emitted each time an object is + * found in the DIDL-Lite XML being parsed. + **/ + signals[OBJECT_AVAILABLE] = + g_signal_new ("object-available", + GUPNP_TYPE_DIDL_LITE_PARSER, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GUPnPDIDLLiteParserClass, + object_available), + NULL, + NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, + GUPNP_TYPE_DIDL_LITE_OBJECT); + + /** + * GUPnPDIDLLiteParser::item-available: + * @parser: The #GUPnPDIDLLiteParser that received the signal + * @item: The now available #GUPnPDIDLLiteItem + * + * The ::item-available signal is emitted each time an item is found in + * the DIDL-Lite XML being parsed. + **/ + signals[ITEM_AVAILABLE] = + g_signal_new ("item-available", + GUPNP_TYPE_DIDL_LITE_PARSER, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GUPnPDIDLLiteParserClass, + item_available), + NULL, + NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, + GUPNP_TYPE_DIDL_LITE_ITEM); + + /** + * GUPnPDIDLLiteParser::container-available: + * @parser: The #GUPnPDIDLLiteParser that received the signal + * @container: The now available #GUPnPDIDLLiteContainer + * + * The ::container-available signal is emitted each time a container is + * found in the DIDL-Lite XML being parsed. + **/ + signals[CONTAINER_AVAILABLE] = + g_signal_new ("container-available", + GUPNP_TYPE_DIDL_LITE_PARSER, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GUPnPDIDLLiteParserClass, + container_available), + NULL, + NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, + GUPNP_TYPE_DIDL_LITE_CONTAINER); +} + +/** + * gupnp_didl_lite_parser_new: + * + * Return value: A new #GUPnPDIDLLiteParser object. + **/ +GUPnPDIDLLiteParser * +gupnp_didl_lite_parser_new (void) +{ + return g_object_new (GUPNP_TYPE_DIDL_LITE_PARSER, NULL); +} + +/** + * gupnp_didl_lite_parser_parse_didl: + * @parser: A #GUPnPDIDLLiteParser + * @didl: The DIDL-Lite XML string to be parsed + * @error: The location where to store any error, or NULL + * + * Parses DIDL-Lite XML string @didl, emitting the ::object-available, + * ::item-available and ::container-available signals appropriately during the + * process. + * + * Return value: TRUE on success. + **/ +gboolean +gupnp_didl_lite_parser_parse_didl (GUPnPDIDLLiteParser *parser, + const char *didl, + GError **error) +{ + xmlDoc *doc; + xmlNode *element; + xmlNode *node; + xmlNs **ns_list; + xmlNs *upnp_ns = NULL; + xmlNs *dc_ns = NULL; + xmlNs *dlna_ns = NULL; + GUPnPXMLDoc *xml_doc; + + doc = xmlRecoverMemory (didl, strlen (didl)); + if (doc == NULL) { + g_set_error (error, + GUPNP_XML_ERROR, + GUPNP_XML_ERROR_PARSE, + "Could not parse DIDL-Lite XML:\n%s", didl); + + return FALSE; + } + + /* Get a pointer to root element */ + element = xml_util_get_element ((xmlNode *) doc, + "DIDL-Lite", + NULL); + if (element == NULL) { + g_set_error (error, + GUPNP_XML_ERROR, + GUPNP_XML_ERROR_NO_NODE, + "No 'DIDL-Lite' node in the DIDL-Lite XML:\n%s", + didl); + xmlFreeDoc (doc); + + return FALSE; + } + + if (element->children == NULL) { + g_set_error (error, + GUPNP_XML_ERROR, + GUPNP_XML_ERROR_EMPTY_NODE, + "Empty 'DIDL-Lite' node in the DIDL-Lite XML:\n%s", + didl); + xmlFreeDoc (doc); + + return FALSE; + } + + /* Lookup UPnP and DC namespaces */ + ns_list = xmlGetNsList (doc, + xmlDocGetRootElement (doc)); + + if (ns_list) { + short i; + + for (i = 0; ns_list[i] != NULL; i++) { + const char *prefix = (const char *) ns_list[i]->prefix; + + if (prefix == NULL) + continue; + + if (! upnp_ns && + g_ascii_strcasecmp (prefix, "upnp") == 0) + upnp_ns = ns_list[i]; + else if (! dc_ns && + g_ascii_strcasecmp (prefix, "dc") == 0) + dc_ns = ns_list[i]; + else if (! dlna_ns && + g_ascii_strcasecmp (prefix, "dlna") == 0) + dlna_ns = ns_list[i]; + } + + xmlFree (ns_list); + } + + /* Create UPnP and DC namespaces if they don't exist */ + if (! upnp_ns) + upnp_ns = xmlNewNs (xmlDocGetRootElement (doc), + (unsigned char *) + "urn:schemas-upnp-org:metadata-1-0/upnp/", + (unsigned char *) + GUPNP_DIDL_LITE_WRITER_NAMESPACE_UPNP); + if (! dc_ns) + dc_ns = xmlNewNs (xmlDocGetRootElement (doc), + (unsigned char *) + "http://purl.org/dc/elements/1.1/", + (unsigned char *) + GUPNP_DIDL_LITE_WRITER_NAMESPACE_DC); + if (! dlna_ns) + dlna_ns = xmlNewNs (xmlDocGetRootElement (doc), + (unsigned char *) + "urn:schemas-dlna-org:metadata-2-0/", + (unsigned char *) + GUPNP_DIDL_LITE_WRITER_NAMESPACE_DLNA); + + xml_doc = gupnp_xml_doc_new (doc); + + for (element = element->children; element; element = element->next) { + GUPnPDIDLLiteObject *object; + + object = gupnp_didl_lite_object_new_from_xml (element, xml_doc, + upnp_ns, dc_ns, + dlna_ns); + + if (object == NULL) + continue; + + if (GUPNP_IS_DIDL_LITE_CONTAINER (object)) + g_signal_emit (parser, + signals[CONTAINER_AVAILABLE], + 0, + object); + else if (GUPNP_IS_DIDL_LITE_ITEM (object)) { + node = gupnp_didl_lite_object_get_xml_node(object); + if (!verify_didl_attributes(node)) { + g_object_unref (object); + g_object_unref (xml_doc); + g_set_error (error, + GUPNP_XML_ERROR, + GUPNP_XML_ERROR_INVALID_ATTRIBUTE, + "Could not parse DIDL-Lite XML:\n%s", + didl); + + return FALSE; + } + + g_signal_emit (parser, + signals[ITEM_AVAILABLE], + 0, + object); + } + + g_signal_emit (parser, + signals[OBJECT_AVAILABLE], + 0, + object); + + g_object_unref (object); + } + + g_object_unref (xml_doc); + + return TRUE; +} + diff --git a/libgupnp-av/gupnp-didl-lite-parser.h b/libgupnp-av/gupnp-didl-lite-parser.h new file mode 100644 index 0000000..f7b3c4e --- /dev/null +++ b/libgupnp-av/gupnp-didl-lite-parser.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2007 Zeeshan Ali (Khattak) <zeeshanak@gnome.org> + * + * Authors: Zeeshan Ali (Khattak) <zeeshanak@gnome.org> + * + * 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. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __GUPNP_DIDL_LITE_PARSER_H__ +#define __GUPNP_DIDL_LITE_PARSER_H__ + +#include <libgupnp/gupnp.h> +#include "gupnp-didl-lite-container.h" +#include "gupnp-didl-lite-item.h" + +G_BEGIN_DECLS + +GType +gupnp_didl_lite_parser_get_type (void) G_GNUC_CONST; + +#define GUPNP_TYPE_DIDL_LITE_PARSER \ + (gupnp_didl_lite_parser_get_type ()) +#define GUPNP_DIDL_LITE_PARSER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + GUPNP_TYPE_DIDL_LITE_PARSER, \ + GUPnPDIDLLiteParser)) +#define GUPNP_DIDL_LITE_PARSER_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_CAST ((obj), \ + GUPNP_TYPE_DIDL_LITE_PARSER, \ + GUPnPDIDLLiteParserClass)) +#define GUPNP_IS_DIDL_LITE_PARSER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + GUPNP_TYPE_DIDL_LITE_PARSER)) +#define GUPNP_IS_DIDL_LITE_PARSER_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE ((obj), \ + GUPNP_TYPE_DIDL_LITE_PARSER)) +#define GUPNP_DIDL_LITE_PARSER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + GUPNP_TYPE_DIDL_LITE_PARSER, \ + GUPnPDIDLLiteParserClass)) + +typedef struct { + GObject parent; + + gpointer gupnp_reserved; +} GUPnPDIDLLiteParser; + +typedef struct { + GObjectClass parent_class; + + /* signals */ + void (* object_available) (GUPnPDIDLLiteParser *parser, + GUPnPDIDLLiteObject *object); + void (* item_available) (GUPnPDIDLLiteParser *parser, + GUPnPDIDLLiteItem *item); + void (* container_available) (GUPnPDIDLLiteParser *parser, + GUPnPDIDLLiteContainer *container); + + /* future padding */ + void (* _gupnp_reserved1) (void); + void (* _gupnp_reserved2) (void); + void (* _gupnp_reserved3) (void); + void (* _gupnp_reserved4) (void); + void (* _gupnp_reserved5) (void); +} GUPnPDIDLLiteParserClass; + +GUPnPDIDLLiteParser * +gupnp_didl_lite_parser_new (void); + +gboolean +gupnp_didl_lite_parser_parse_didl (GUPnPDIDLLiteParser *parser, + const char *didl, + GError **error); + +G_END_DECLS + +#endif /* __GUPNP_DIDL_LITE_PARSER_H__ */ diff --git a/libgupnp-av/gupnp-didl-lite-resource-private.h b/libgupnp-av/gupnp-didl-lite-resource-private.h new file mode 100644 index 0000000..eff4518 --- /dev/null +++ b/libgupnp-av/gupnp-didl-lite-resource-private.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2009 Nokia Corporation. + * + * Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com> + * <zeeshanak@gnome.org> + * + * 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. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __GUPNP_DIDL_LITE_RESOURCE_PRIVATE_H__ +#define __GUPNP_DIDL_LITE_RESOURCE_PRIVATE_H__ + +#include <stdarg.h> +#include <glib-object.h> +#include <libxml/tree.h> + +G_BEGIN_DECLS + +GUPnPDIDLLiteResource * +gupnp_didl_lite_resource_new_from_xml (xmlNode *xml_node, + GUPnPXMLDoc *xml_doc); + +G_END_DECLS + +#endif /* __GUPNP_DIDL_LITE_RESOURCE_PRIVATE_H__ */ diff --git a/libgupnp-av/gupnp-didl-lite-resource.c b/libgupnp-av/gupnp-didl-lite-resource.c new file mode 100644 index 0000000..240b070 --- /dev/null +++ b/libgupnp-av/gupnp-didl-lite-resource.c @@ -0,0 +1,1419 @@ +/* + * Copyright (C) 2009 Nokia Corporation. + * Copyright (C) 2007, 2008 OpenedHand Ltd. + * + * Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com> + * <zeeshanak@gnome.org> + * Jorn Baayen <jorn@openedhand.com> + * + * 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. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +/** + * SECTION:gupnp-didl-lite-resource + * @short_description: DIDL-Lite Resource + * + * #GUPnPDIDLLiteResource respresent a DIDL-Lite resource (res) element. + */ + +#include <string.h> + +#include "gupnp-didl-lite-resource.h" +#include "xml-util.h" + +#define SEC_PER_MIN 60 +#define SEC_PER_HOUR 3600 + +G_DEFINE_TYPE (GUPnPDIDLLiteResource, + gupnp_didl_lite_resource, + G_TYPE_OBJECT); + +struct _GUPnPDIDLLiteResourcePrivate { + xmlNode *xml_node; + GUPnPXMLDoc *xml_doc; + + GUPnPProtocolInfo *protocol_info; +}; + +enum { + PROP_0, + PROP_XML_NODE, + PROP_XML_DOC, + + PROP_URI, + PROP_IMPORT_URI, + + PROP_PROTOCOL_INFO, + + PROP_SIZE, + PROP_SIZE64, + PROP_DURATION, + PROP_BITRATE, + PROP_SAMPLE_FREQ, + PROP_BITS_PER_SAMPLE, + PROP_PROTECTION, + + PROP_AUDIO_CHANNELS, + + PROP_WIDTH, + PROP_HEIGHT, + PROP_COLOR_DEPTH +}; + +static void +get_resolution_info (GUPnPDIDLLiteResource *resource, + int *width, + int *height) +{ + const char *resolution; + char **tokens; + + resolution = xml_util_get_attribute_content (resource->priv->xml_node, + "resolution"); + if (resolution == NULL) + return; + + tokens = g_strsplit (resolution, "x", -1); + if (tokens == NULL || tokens[0] == NULL || tokens[1] == NULL) { + g_warning ("Failed to resolution string '%s'\n", resolution); + + goto return_point; + } + + if (width) + *width = atoi (tokens[0]); + if (height) + *height = atoi (tokens[1]); + +return_point: + g_strfreev (tokens); +} + +static long +seconds_from_time (const char *time_str) +{ + char **tokens; + gdouble seconds = -1; + + if (time_str == NULL) + return -1; + + tokens = g_strsplit (time_str, ":", -1); + if (tokens[0] == NULL || + tokens[1] == NULL || + tokens[2] == NULL) + goto return_point; + + seconds = g_strtod (tokens[2], NULL); + seconds += g_strtod (tokens[1], NULL) * SEC_PER_MIN; + seconds += g_strtod (tokens[0], NULL) * SEC_PER_HOUR; + +return_point: + g_strfreev (tokens); + + return (long) seconds; +} + +static void +on_protocol_info_changed (GUPnPProtocolInfo *info, + GParamSpec *pspec, + gpointer user_data) +{ + GUPnPDIDLLiteResource *resource = GUPNP_DIDL_LITE_RESOURCE (user_data); + + gupnp_didl_lite_resource_set_protocol_info (resource, info); +} + +static void +gupnp_didl_lite_resource_init (GUPnPDIDLLiteResource *resource) +{ + resource->priv = G_TYPE_INSTANCE_GET_PRIVATE + (resource, + GUPNP_TYPE_DIDL_LITE_RESOURCE, + GUPnPDIDLLiteResourcePrivate); +} + +static void +gupnp_didl_lite_resource_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + GUPnPDIDLLiteResource *resource; + + resource = GUPNP_DIDL_LITE_RESOURCE (object); + + switch (property_id) { + case PROP_XML_NODE: + resource->priv->xml_node = g_value_get_pointer (value); + break; + case PROP_XML_DOC: + resource->priv->xml_doc = g_value_dup_object (value); + break; + case PROP_URI: + gupnp_didl_lite_resource_set_uri (resource, + g_value_get_string (value)); + break; + case PROP_IMPORT_URI: + gupnp_didl_lite_resource_set_import_uri + (resource, + g_value_get_string (value)); + break; + case PROP_PROTOCOL_INFO: + gupnp_didl_lite_resource_set_protocol_info + (resource, + g_value_get_object (value)); + break; + case PROP_SIZE: + gupnp_didl_lite_resource_set_size (resource, + g_value_get_long (value)); + break; + case PROP_SIZE64: + gupnp_didl_lite_resource_set_size64 (resource, + g_value_get_int64 (value)); + break; + case PROP_DURATION: + gupnp_didl_lite_resource_set_duration + (resource, + g_value_get_long (value)); + break; + case PROP_BITRATE: + gupnp_didl_lite_resource_set_bitrate (resource, + g_value_get_int (value)); + break; + case PROP_SAMPLE_FREQ: + gupnp_didl_lite_resource_set_sample_freq + (resource, + g_value_get_int (value)); + break; + case PROP_BITS_PER_SAMPLE: + gupnp_didl_lite_resource_set_bits_per_sample + (resource, + g_value_get_int (value)); + break; + case PROP_PROTECTION: + gupnp_didl_lite_resource_set_protection + (resource, + g_value_get_string (value)); + break; + case PROP_AUDIO_CHANNELS: + gupnp_didl_lite_resource_set_audio_channels + (resource, + g_value_get_int (value)); + break; + case PROP_WIDTH: + gupnp_didl_lite_resource_set_width (resource, + g_value_get_int (value)); + break; + case PROP_HEIGHT: + gupnp_didl_lite_resource_set_height (resource, + g_value_get_int (value)); + break; + case PROP_COLOR_DEPTH: + gupnp_didl_lite_resource_set_color_depth + (resource, + g_value_get_int (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gupnp_didl_lite_resource_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + GUPnPDIDLLiteResource *resource; + + resource = GUPNP_DIDL_LITE_RESOURCE (object); + + switch (property_id) { + case PROP_XML_NODE: + g_value_set_pointer + (value, + gupnp_didl_lite_resource_get_xml_node (resource)); + break; + case PROP_URI: + g_value_set_string + (value, + gupnp_didl_lite_resource_get_uri (resource)); + break; + case PROP_IMPORT_URI: + g_value_set_string + (value, + gupnp_didl_lite_resource_get_import_uri (resource)); + break; + case PROP_PROTOCOL_INFO: + g_value_set_object + (value, + gupnp_didl_lite_resource_get_protocol_info (resource)); + break; + case PROP_SIZE: + g_value_set_long (value, + gupnp_didl_lite_resource_get_size (resource)); + break; + case PROP_SIZE64: + g_value_set_int64 (value, + gupnp_didl_lite_resource_get_size64 (resource)); + break; + case PROP_DURATION: + g_value_set_long + (value, + gupnp_didl_lite_resource_get_duration (resource)); + break; + case PROP_BITRATE: + g_value_set_int + (value, + gupnp_didl_lite_resource_get_bitrate (resource)); + break; + case PROP_BITS_PER_SAMPLE: + g_value_set_int + (value, + gupnp_didl_lite_resource_get_bits_per_sample + (resource)); + break; + case PROP_SAMPLE_FREQ: + g_value_set_int + (value, + gupnp_didl_lite_resource_get_sample_freq (resource)); + break; + case PROP_PROTECTION: + g_value_set_string + (value, + gupnp_didl_lite_resource_get_protection (resource)); + break; + case PROP_AUDIO_CHANNELS: + g_value_set_int + (value, + gupnp_didl_lite_resource_get_audio_channels + (resource)); + break; + case PROP_WIDTH: + g_value_set_int (value, + gupnp_didl_lite_resource_get_width (resource)); + break; + case PROP_HEIGHT: + g_value_set_int + (value, + gupnp_didl_lite_resource_get_height (resource)); + break; + case PROP_COLOR_DEPTH: + g_value_set_int + (value, + gupnp_didl_lite_resource_get_color_depth (resource)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gupnp_didl_lite_resource_dispose (GObject *object) +{ + GObjectClass *object_class; + GUPnPDIDLLiteResourcePrivate *priv; + + priv = GUPNP_DIDL_LITE_RESOURCE (object)->priv; + + if (priv->xml_doc) { + g_object_unref (priv->xml_doc); + priv->xml_doc = NULL; + } + + if (priv->protocol_info != NULL) { + g_object_unref (priv->protocol_info); + priv->protocol_info = NULL; + } + + object_class = G_OBJECT_CLASS (gupnp_didl_lite_resource_parent_class); + object_class->dispose (object); +} + +static void +gupnp_didl_lite_resource_class_init (GUPnPDIDLLiteResourceClass *klass) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (klass); + + object_class->set_property = gupnp_didl_lite_resource_set_property; + object_class->get_property = gupnp_didl_lite_resource_get_property; + object_class->dispose = gupnp_didl_lite_resource_dispose; + + g_type_class_add_private (klass, sizeof (GUPnPDIDLLiteResourcePrivate)); + + /** + * GUPnPDIDLLiteResource:xml-node: + * + * The pointer to res node in XML document. + **/ + g_object_class_install_property + (object_class, + PROP_XML_NODE, + g_param_spec_pointer ("xml-node", + "XMLNode", + "The pointer to res node in XML" + " document.", + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteResource:xml-doc: + * + * The reference to XML document containing this object. + * + * Internal property. + * + * Stability: Private + **/ + g_object_class_install_property + (object_class, + PROP_XML_DOC, + g_param_spec_object ("xml-doc", + "XMLDoc", + "The reference to XML document" + " containing this object.", + GUPNP_TYPE_XML_DOC, + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteResource:uri: + * + * The URI associated with this resource. + **/ + g_object_class_install_property + (object_class, + PROP_URI, + g_param_spec_string ("uri", + "URI", + "The URI associated with this resource", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteResource:import-uri: + * + * The Import URI associated with this resource. + **/ + g_object_class_install_property + (object_class, + PROP_IMPORT_URI, + g_param_spec_string ("import-uri", + "ImportURI", + "The import URI associated with this" + " resource", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteResource:protocol-info: + * + * The protocol info associated with this resource. + **/ + g_object_class_install_property + (object_class, + PROP_PROTOCOL_INFO, + g_param_spec_object ("protocol-info", + "ProtocolInfo", + "The protocol info associated with this" + " resource", + GUPNP_TYPE_PROTOCOL_INFO, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteResource:size: + * + * The size (in bytes) of this resource. + **/ + g_object_class_install_property + (object_class, + PROP_SIZE, + g_param_spec_long ("size", + "Size", + "The size (in bytes) of this resource.", + -1, + G_MAXLONG, + -1, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteResource:size64: + * + * The size (in bytes) of this resource. + **/ + g_object_class_install_property + (object_class, + PROP_SIZE64, + g_param_spec_int64 ("size64", + "Size64", + "The size (in bytes) of this resource.", + -1, + G_MAXINT64, + -1, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteResource:duration: + * + * The duration (in seconds) of this resource. + **/ + g_object_class_install_property + (object_class, + PROP_DURATION, + g_param_spec_long ("duration", + "Duration", + "The duration (in seconds) of this" + " resource.", + -1, + G_MAXLONG, + -1, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteResource:bitrate: + * + * The bitrate of this resource. + **/ + g_object_class_install_property + (object_class, + PROP_BITRATE, + g_param_spec_int ("bitrate", + "Bitrate", + "The bitrate of this resource.", + -1, + G_MAXINT, + -1, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteResource:sample-freq: + * + * The sample frequency of this resource. + **/ + g_object_class_install_property + (object_class, + PROP_SAMPLE_FREQ, + g_param_spec_int ("sample-freq", + "SampleFrequency", + "The sample frequency of this resource.", + -1, + G_MAXINT, + -1, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteResource:bits-per-sample: + * + * The sample size of this resource. + **/ + g_object_class_install_property + (object_class, + PROP_BITS_PER_SAMPLE, + g_param_spec_int ("bits-per-sample", + "BitsPerSample", + "The sample size of this resource.", + -1, + G_MAXINT, + -1, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteResource:protection: + * + * The protection system used for this resource. + **/ + g_object_class_install_property + (object_class, + PROP_PROTECTION, + g_param_spec_string ("protection", + "Protection", + "The protection system used by this" + " resource.", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteResource:audio-channels: + * + * The number of audio channels in this resource. + **/ + g_object_class_install_property + (object_class, + PROP_AUDIO_CHANNELS, + g_param_spec_int ("audio-channels", + "AudioChannels", + "The number of audio channels in this" + " resource.", + -1, + G_MAXINT, + -1, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteResource:width: + * + * The width of this image/video resource. + **/ + g_object_class_install_property + (object_class, + PROP_WIDTH, + g_param_spec_int ("width", + "Width", + "The width of this image/video resource.", + -1, + G_MAXINT, + -1, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteResource:height: + * + * The height of this image/video resource. + **/ + g_object_class_install_property + (object_class, + PROP_HEIGHT, + g_param_spec_int ("height", + "Height", + "The height of this image/video resource.", + -1, + G_MAXINT, + -1, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteResource:color-depth: + * + * The color-depth of this image/video resource. + **/ + g_object_class_install_property + (object_class, + PROP_COLOR_DEPTH, + g_param_spec_int ("color-depth", + "ColorDepth", + "The color-depth of this image/video" + " resource.", + -1, + G_MAXINT, + -1, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); +} + +/** + * gupnp_didl_lite_resource_new_from_xml: + * @xml_node: The pointer to 'res' node in XML document + * @xml_doc: The reference to XML document containing this resource + * + * Creates a new #GUPnPDIDLLiteResource for the @xml_node. + * + * Return value: A new #GUPnPDIDLLiteResource object. Unref after usage. + **/ +GUPnPDIDLLiteResource * +gupnp_didl_lite_resource_new_from_xml (xmlNode *xml_node, + GUPnPXMLDoc *xml_doc) +{ + GUPnPDIDLLiteResource *resource; + + return g_object_new (GUPNP_TYPE_DIDL_LITE_RESOURCE, + "xml-node", xml_node, + "xml-doc", xml_doc, + NULL); + + return resource; +} + +/** + * gupnp_didl_lite_resource_get_xml_node: + * @resource: The #GUPnPDIDLLiteResource + * + * Get the pointer to res node in XML document. + * + * Returns: (transfer none): The pointer to res node in XML document. + **/ +xmlNode * +gupnp_didl_lite_resource_get_xml_node (GUPnPDIDLLiteResource *resource) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), NULL); + + return resource->priv->xml_node; +} + +/** + * gupnp_didl_lite_resource_get_uri: + * @resource: A #GUPnPDIDLLiteResource + * + * Get the URI associated with the @resource. + * + * Return value: The of URI the @resource or %NULL. + **/ +const char * +gupnp_didl_lite_resource_get_uri (GUPnPDIDLLiteResource *resource) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), NULL); + + if (G_UNLIKELY (resource->priv->xml_node->children == NULL)) + return NULL; + + return (const char *) resource->priv->xml_node->children->content; +} + +/** + * gupnp_didl_lite_resource_get_import_uri: + * @resource: A #GUPnPDIDLLiteResource + * + * Get the import URI associated with the @resource. + * + * Return value: The import URI or %NULL. + **/ +const char * +gupnp_didl_lite_resource_get_import_uri (GUPnPDIDLLiteResource *resource) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), NULL); + + return xml_util_get_attribute_content (resource->priv->xml_node, + "importUri"); +} + +/** + * gupnp_didl_lite_resource_get_protocol_info: + * @resource: A #GUPnPDIDLLiteResource + * + * Get the protocol info associated with the @resource. + * + * Returns: (transfer none): The protocol info associated with the @resource or %NULL. The + * returned object must not be unrefed. + **/ +GUPnPProtocolInfo * +gupnp_didl_lite_resource_get_protocol_info (GUPnPDIDLLiteResource *resource) +{ + GUPnPProtocolInfo *info; + const char *protocol_info; + GError *error; + + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), NULL); + + if (resource->priv->protocol_info != NULL) + return resource->priv->protocol_info; + + protocol_info = xml_util_get_attribute_content + (resource->priv->xml_node, + "protocolInfo"); + g_return_val_if_fail (protocol_info != NULL, NULL); + + error = NULL; + info = gupnp_protocol_info_new_from_string (protocol_info, &error); + if (info == NULL) { + g_warning ("Error parsing protocolInfo '%s': %s", + protocol_info, + error->message); + + g_error_free (error); + } + + resource->priv->protocol_info = info; + + return info; +} + +/** + * gupnp_didl_lite_resource_get_size: + * @resource: A #GUPnPDIDLLiteResource + * + * Get the size (in bytes) of the @resource. + * + * Return value: The size (in bytes) of the @resource or -1. + **/ +long +gupnp_didl_lite_resource_get_size (GUPnPDIDLLiteResource *resource) +{ + return (long) gupnp_didl_lite_resource_get_size64 (resource); +} + +/** + * gupnp_didl_lite_resource_get_size64: + * @resource: A #GUPnPDIDLLiteResource + * + * Get the size (in bytes) of the @resource. + * + * Return value: The size (in bytes) of the @resource or -1. + **/ +gint64 +gupnp_didl_lite_resource_get_size64 (GUPnPDIDLLiteResource *resource) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), -1); + + return xml_util_get_int64_attribute (resource->priv->xml_node, + "size", + -1); +} + + +/** + * gupnp_didl_lite_resource_get_duration: + * @resource: A #GUPnPDIDLLiteResource + * + * Get the duration (in seconds) of the @resource. + * + * Return value: The duration (in seconds) of the @resource or -1. + **/ +long +gupnp_didl_lite_resource_get_duration (GUPnPDIDLLiteResource *resource) +{ + const char *duration_str; + long duration; + + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), -1); + + duration_str = xml_util_get_attribute_content (resource->priv->xml_node, + "duration"); + duration = seconds_from_time (duration_str); + + return duration; +} + +/** + * gupnp_didl_lite_resource_get_bitrate: + * @resource: A #GUPnPDIDLLiteResource + * + * Get the bitrate (in bytes per second) of the @resource. + * + * Return value: The bitrate (in bytes per second) of the @resource or -1. + **/ +int +gupnp_didl_lite_resource_get_bitrate (GUPnPDIDLLiteResource *resource) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), -1); + + return xml_util_get_long_attribute (resource->priv->xml_node, + "bitrate", + -1); +} + +/** + * gupnp_didl_lite_resource_get_sample_freq: + * @resource: A #GUPnPDIDLLiteResource + * + * Get the sample frequency of the @resource. + * + * Return value: The sample frequency of the @resource or -1. + **/ +int +gupnp_didl_lite_resource_get_sample_freq (GUPnPDIDLLiteResource *resource) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), -1); + + return xml_util_get_long_attribute (resource->priv->xml_node, + "sampleFrequency", + -1); +} + +/** + * gupnp_didl_lite_resource_get_bits_per_sample: + * @resource: A #GUPnPDIDLLiteResource + * + * Get the sample size of the @resource. + * + * Return value: The number of bits per sample of the @resource or -1. + **/ +int +gupnp_didl_lite_resource_get_bits_per_sample (GUPnPDIDLLiteResource *resource) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), -1); + + return xml_util_get_long_attribute (resource->priv->xml_node, + "bitsPerSample", + -1); +} + +/** + * gupnp_didl_lite_resource_get_protection: + * @resource: A #GUPnPDIDLLiteResource + * + * Get the protection system used by the @resource. + * + * Return value: The protection system in use by the @resource or %NULL. + **/ +const char * +gupnp_didl_lite_resource_get_protection (GUPnPDIDLLiteResource *resource) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), NULL); + + return xml_util_get_attribute_content (resource->priv->xml_node, + "protection"); +} + +/** + * gupnp_didl_lite_resource_get_audio_channels: + * @resource: A #GUPnPDIDLLiteResource + * + * Get the number of audio channels in the @resource. + * + * Return value: The number of audio channels in the @resource or -1. + **/ +int +gupnp_didl_lite_resource_get_audio_channels (GUPnPDIDLLiteResource *resource) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), -1); + + return xml_util_get_long_attribute (resource->priv->xml_node, + "nrAudioChannels", + -1); +} + +/** + * gupnp_didl_lite_resource_get_width: + * @resource: A #GUPnPDIDLLiteResource + * + * Get the width of this image/video resource. + * + * Return value: The width of this image/video resource or -1. + **/ +int +gupnp_didl_lite_resource_get_width (GUPnPDIDLLiteResource *resource) +{ + int width = -1; + + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), -1); + + get_resolution_info (resource, &width, NULL); + + return width; +} + +/** + * gupnp_didl_lite_resource_get_height: + * @resource: A #GUPnPDIDLLiteResource + * + * Get the height of this image/video resource. + * + * Return value: The height of the @resource or -1. + **/ +int +gupnp_didl_lite_resource_get_height (GUPnPDIDLLiteResource *resource) +{ + int height = -1; + + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), -1); + + get_resolution_info (resource, NULL, &height); + + return height; +} + +/** + * gupnp_didl_lite_resource_get_color_depth: + * @resource: A #GUPnPDIDLLiteResource + * + * Get the color-depth of this image/video resource. + * + * Return value: The color depth of the @resource or -1. + **/ +int +gupnp_didl_lite_resource_get_color_depth (GUPnPDIDLLiteResource *resource) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource), -1); + + return xml_util_get_long_attribute (resource->priv->xml_node, + "colorDepth", + -1); +} + +/** + * gupnp_didl_lite_resource_set_uri: + * @resource: A #GUPnPDIDLLiteResource + * @uri: The URI as string + * + * Set the URI associated with the @resource. + * + * Return value: None. + **/ +void +gupnp_didl_lite_resource_set_uri (GUPnPDIDLLiteResource *resource, + const char *uri) +{ + xmlChar *escaped; + + g_return_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource)); + g_return_if_fail (uri != NULL); + + escaped = xmlEncodeSpecialChars (resource->priv->xml_doc->doc, + (const unsigned char *) uri); + xmlNodeSetContent (resource->priv->xml_node, escaped); + xmlFree (escaped); + + g_object_notify (G_OBJECT (resource), "uri"); +} + +/** + * gupnp_didl_lite_resource_set_import_uri: + * @resource: A #GUPnPDIDLLiteResource + * @import_uri: The URI as string + * + * Set the import URI associated with the @resource. + * + * Return value: None. + **/ +void +gupnp_didl_lite_resource_set_import_uri (GUPnPDIDLLiteResource *resource, + const char *import_uri) +{ + g_return_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource)); + + xmlSetProp (resource->priv->xml_node, + (unsigned char *) "importUri", + (unsigned char *) import_uri); + + g_object_notify (G_OBJECT (resource), "import-uri"); +} + +/** + * gupnp_didl_lite_resource_set_protocol_info: + * @resource: A #GUPnPDIDLLiteResource + * @info: The protocol string + * + * Set the protocol info associated with the @resource. + * + * Return value: None. + **/ +void +gupnp_didl_lite_resource_set_protocol_info (GUPnPDIDLLiteResource *resource, + GUPnPProtocolInfo *info) +{ + char *str; + + g_return_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource)); + g_return_if_fail (GUPNP_IS_PROTOCOL_INFO (info)); + + str = gupnp_protocol_info_to_string (info); + xmlSetProp (resource->priv->xml_node, + (unsigned char *) "protocolInfo", + (unsigned char *) str); + g_free (str); + + /* Get a ref first in case it's the same object that we already have */ + g_object_ref (info); + if (resource->priv->protocol_info != NULL) + g_object_unref (resource->priv->protocol_info); + resource->priv->protocol_info = info; + + /* We need to listen to changes to properties so we update the + * corresponding xml property. + */ + g_signal_handlers_disconnect_by_func (info, + on_protocol_info_changed, + resource); + g_signal_connect (info, + "notify", + G_CALLBACK (on_protocol_info_changed), + resource); + + g_object_notify (G_OBJECT (resource), "protocol-info"); +} + +/** + * gupnp_didl_lite_resource_set_size: + * @resource: A #GUPnPDIDLLiteResource + * @size: The size (in bytes) + * + * Set the size (in bytes) of the @resource. Passing a negative number will + * unset this property. + * + * Return value: None. + **/ +void +gupnp_didl_lite_resource_set_size (GUPnPDIDLLiteResource *resource, + long size) +{ + gupnp_didl_lite_resource_set_size64 (resource, size); +} + +/** + * gupnp_didl_lite_resource_set_size64: + * @resource: A #GUPnPDIDLLiteResource + * @size: The size (in bytes) + * + * Set the size (in bytes) of the @resource. Passing a negative number will + * unset this property. + * + * Return value: None. + **/ +void +gupnp_didl_lite_resource_set_size64 (GUPnPDIDLLiteResource *resource, + gint64 size) +{ + g_return_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource)); + + if (size < 0) + xmlUnsetProp (resource->priv->xml_node, + (unsigned char *) "size"); + else { + char *str; + + str = g_strdup_printf ("%" G_GINT64_FORMAT, size); + xmlSetProp (resource->priv->xml_node, + (unsigned char *) "size", + (unsigned char *) str); + g_free (str); + } + + g_object_notify (G_OBJECT (resource), "size64"); + g_object_notify (G_OBJECT (resource), "size"); +} + + +/** + * gupnp_didl_lite_resource_set_duration: + * @resource: A #GUPnPDIDLLiteResource + * @duration: The duration (in seconds) + * + * Set the duration (in seconds) of the @resource. Passing a negative number + * will unset this property. + * + * Return value: None. + **/ +void +gupnp_didl_lite_resource_set_duration (GUPnPDIDLLiteResource *resource, + long duration) +{ + g_return_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource)); + + if (duration < 0) + xmlUnsetProp (resource->priv->xml_node, + (unsigned char *) "duration"); + else { + char *str; + + str = g_strdup_printf ("%ld:%.2ld:%.2ld.000", + duration / (60 * 60), + (duration / 60) % 60, + duration % 60); + xmlSetProp (resource->priv->xml_node, + (unsigned char *) "duration", + (unsigned char *) str); + g_free (str); + } + + g_object_notify (G_OBJECT (resource), "duration"); +} + +/** + * gupnp_didl_lite_resource_set_bitrate: + * @resource: A #GUPnPDIDLLiteResource + * @bitrate: The bitrate + * + * Set the bitrate (in bytes per second) of the @resource. Passing a negative + * number will unset this property. + * + * Return value: None. + **/ +void +gupnp_didl_lite_resource_set_bitrate (GUPnPDIDLLiteResource *resource, + int bitrate) +{ + g_return_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource)); + + if (bitrate < 0) + xmlUnsetProp (resource->priv->xml_node, + (unsigned char *) "bitrate"); + else { + char *str; + + str = g_strdup_printf ("%d", bitrate); + xmlSetProp (resource->priv->xml_node, + (unsigned char *) "bitrate", + (unsigned char *) str); + g_free (str); + } + + g_object_notify (G_OBJECT (resource), "bitrate"); +} + +/** + * gupnp_didl_lite_resource_set_sample_freq: + * @resource: A #GUPnPDIDLLiteResource + * @sample_freq: The sample frequency + * + * Set the sample frequency of the @resource. Passing a negative number will + * unset this property. + * + * Return value: None. + **/ +void +gupnp_didl_lite_resource_set_sample_freq (GUPnPDIDLLiteResource *resource, + int sample_freq) +{ + g_return_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource)); + + if (sample_freq < 0) + xmlUnsetProp (resource->priv->xml_node, + (unsigned char *) "sampleFrequency"); + else { + char *str; + + str = g_strdup_printf ("%d", sample_freq); + xmlSetProp (resource->priv->xml_node, + (unsigned char *) "sampleFrequency", + (unsigned char *) str); + g_free (str); + } + + g_object_notify (G_OBJECT (resource), "sample-freq"); +} + +/** + * gupnp_didl_lite_resource_set_bits_per_sample: + * @resource: A #GUPnPDIDLLiteResource + * @sample_size: The number of bits per sample + * + * Set the sample size of the @resource. Passing a negative number will unset + * this property. + * + * Return value: None. + **/ +void +gupnp_didl_lite_resource_set_bits_per_sample + (GUPnPDIDLLiteResource *resource, + int sample_size) +{ + g_return_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource)); + + if (sample_size < 0) + xmlUnsetProp (resource->priv->xml_node, + (unsigned char *) "bitsPerSample"); + else { + char *str; + + str = g_strdup_printf ("%d", sample_size); + xmlSetProp (resource->priv->xml_node, + (unsigned char *) "bitsPerSample", + (unsigned char *) str); + g_free (str); + } + + g_object_notify (G_OBJECT (resource), "bits-per-sample"); +} + +/** + * gupnp_didl_lite_resource_set_protection: + * @resource: A #GUPnPDIDLLiteResource + * @protection: The protection system identifier as string + * + * Set the protection system used by the @resource. Passing a negative number + * will unset this property. + * + * Return value: None. + **/ +void +gupnp_didl_lite_resource_set_protection (GUPnPDIDLLiteResource *resource, + const char *protection) +{ + g_return_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource)); + + xmlSetProp (resource->priv->xml_node, + (unsigned char *) "protection", + (unsigned char *) protection); + + g_object_notify (G_OBJECT (resource), "protection"); +} + +/** + * gupnp_didl_lite_resource_set_audio_channels: + * @resource: A #GUPnPDIDLLiteResource + * @n_channels: The number of channels + * + * Set the number of audio channels in the @resource. Passing a negative number + * will unset this property. + * + * Return value: The number of audio channels in the @resource or -1. + **/ +void +gupnp_didl_lite_resource_set_audio_channels (GUPnPDIDLLiteResource *resource, + int n_channels) +{ + g_return_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource)); + + if (n_channels < 0) + xmlUnsetProp (resource->priv->xml_node, + (unsigned char *) "nrAudioChannels"); + else { + char *str; + + str = g_strdup_printf ("%d", n_channels); + xmlSetProp (resource->priv->xml_node, + (unsigned char *) "nrAudioChannels", + (unsigned char *) str); + g_free (str); + } + + g_object_notify (G_OBJECT (resource), "audio-channels"); +} + +/** + * gupnp_didl_lite_resource_set_width: + * @resource: A #GUPnPDIDLLiteResource + * @width: The width + * + * Set the width of this image/video resource. Setting both width and height to + * a negative number will unset the resolution property. + * + * Return value: None. + **/ +void +gupnp_didl_lite_resource_set_width (GUPnPDIDLLiteResource *resource, + int width) +{ + char *resolution; + int height = -1; + + g_return_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource)); + + get_resolution_info (resource, NULL, &height); + + if (width < 0 && height < 0) + xmlUnsetProp (resource->priv->xml_node, + (unsigned char *) "resolution"); + else { + resolution = g_strdup_printf ("%dx%d", width, height); + xmlSetProp (resource->priv->xml_node, + (unsigned char *) "resolution", + (unsigned char *) resolution); + g_free (resolution); + } + + g_object_notify (G_OBJECT (resource), "width"); +} + +/** + * gupnp_didl_lite_resource_set_height: + * @resource: A #GUPnPDIDLLiteResource + * @height: The height + * + * Set the height of this image/video resource. Setting both width and height to + * a negative number will unset the resolution property. + * + * Return value: None. + **/ +void +gupnp_didl_lite_resource_set_height (GUPnPDIDLLiteResource *resource, + int height) +{ + int width = -1; + + g_return_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource)); + + get_resolution_info (resource, &width, NULL); + + if (width < 0 && height < 0) + xmlUnsetProp (resource->priv->xml_node, + (unsigned char *) "resolution"); + else { + char *resolution; + + resolution = g_strdup_printf ("%dx%d", width, height); + xmlSetProp (resource->priv->xml_node, + (unsigned char *) "resolution", + (unsigned char *) resolution); + g_free (resolution); + } + + g_object_notify (G_OBJECT (resource), "height"); +} + +/** + * gupnp_didl_lite_resource_set_color_depth: + * @resource: A #GUPnPDIDLLiteResource + * @color_depth: The color-depth + * + * Set the color-depth of this image/video resource. Passing a negative number + * will unset this property. + * + * Return value: None. + **/ +void +gupnp_didl_lite_resource_set_color_depth (GUPnPDIDLLiteResource *resource, + int color_depth) +{ + g_return_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource)); + + if (color_depth < 0) + xmlUnsetProp (resource->priv->xml_node, + (unsigned char *) "colorDepth"); + else { + char *str; + + str = g_strdup_printf ("%d", color_depth); + xmlSetProp (resource->priv->xml_node, + (unsigned char *) "colorDepth", + (unsigned char *) str); + g_free (str); + } + + g_object_notify (G_OBJECT (resource), "color-depth"); +} + diff --git a/libgupnp-av/gupnp-didl-lite-resource.h b/libgupnp-av/gupnp-didl-lite-resource.h new file mode 100644 index 0000000..1f3b8f3 --- /dev/null +++ b/libgupnp-av/gupnp-didl-lite-resource.h @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2009 Nokia Corporation. + * Copyright (C) 2007, 2008 OpenedHand Ltd. + * + * Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com> + * <zeeshanak@gnome.org> + * Jorn Baayen <jorn@openedhand.com> + * + * 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. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __GUPNP_DIDL_LITE_RESOURCE_H__ +#define __GUPNP_DIDL_LITE_RESOURCE_H__ + +#include <stdarg.h> +#include <glib-object.h> +#include <glib.h> +#include <libxml/tree.h> +#include <libgupnp/gupnp.h> + +#include "gupnp-dlna.h" +#include "gupnp-protocol-info.h" + +G_BEGIN_DECLS + +GType +gupnp_didl_lite_resource_get_type (void) G_GNUC_CONST; + +#define GUPNP_TYPE_DIDL_LITE_RESOURCE \ + (gupnp_didl_lite_resource_get_type ()) +#define GUPNP_DIDL_LITE_RESOURCE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + GUPNP_TYPE_DIDL_LITE_RESOURCE, \ + GUPnPDIDLLiteResource)) +#define GUPNP_DIDL_LITE_RESOURCE_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_CAST ((obj), \ + GUPNP_TYPE_DIDL_LITE_RESOURCE, \ + GUPnPDIDLLiteResourceClass)) +#define GUPNP_IS_DIDL_LITE_RESOURCE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + GUPNP_TYPE_DIDL_LITE_RESOURCE)) +#define GUPNP_IS_DIDL_LITE_RESOURCE_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE ((obj), \ + GUPNP_TYPE_DIDL_LITE_RESOURCE)) +#define GUPNP_DIDL_LITE_RESOURCE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + GUPNP_TYPE_DIDL_LITE_RESOURCE, \ + GUPnPDIDLLiteResourceClass)) + +typedef struct _GUPnPDIDLLiteResourcePrivate GUPnPDIDLLiteResourcePrivate; + +typedef struct { + GObject parent; + + GUPnPDIDLLiteResourcePrivate *priv; +} GUPnPDIDLLiteResource; + +typedef struct { + GObjectClass parent_class; + + /* future padding */ + void (* _gupnp_reserved1) (void); + void (* _gupnp_reserved2) (void); + void (* _gupnp_reserved3) (void); + void (* _gupnp_reserved4) (void); +} GUPnPDIDLLiteResourceClass; + +void +gupnp_didl_lite_resource_set_uri (GUPnPDIDLLiteResource *resource, + const char *uri); + +void +gupnp_didl_lite_resource_set_import_uri (GUPnPDIDLLiteResource *resource, + const char *import_uri); + +void +gupnp_didl_lite_resource_set_protocol_info + (GUPnPDIDLLiteResource *resource, + GUPnPProtocolInfo *info); + +void +gupnp_didl_lite_resource_set_size (GUPnPDIDLLiteResource *resource, + long size); + +void +gupnp_didl_lite_resource_set_size64 (GUPnPDIDLLiteResource *resource, + gint64 size); + +void +gupnp_didl_lite_resource_set_duration (GUPnPDIDLLiteResource *resource, + long duration); + +void +gupnp_didl_lite_resource_set_bitrate (GUPnPDIDLLiteResource *resource, + int bitrate); + +void +gupnp_didl_lite_resource_set_sample_freq + (GUPnPDIDLLiteResource *resource, + int sample_freq); + +void +gupnp_didl_lite_resource_set_bits_per_sample + (GUPnPDIDLLiteResource *resource, + int sample_size); + +void +gupnp_didl_lite_resource_set_protection (GUPnPDIDLLiteResource *resource, + const char *protection); + +void +gupnp_didl_lite_resource_set_audio_channels + (GUPnPDIDLLiteResource *resource, + int n_channels); + +void +gupnp_didl_lite_resource_set_width (GUPnPDIDLLiteResource *resource, + int width); + +void +gupnp_didl_lite_resource_set_height (GUPnPDIDLLiteResource *resource, + int height); + +void +gupnp_didl_lite_resource_set_color_depth + (GUPnPDIDLLiteResource *resource, + int color_depth); + +xmlNode * +gupnp_didl_lite_resource_get_xml_node (GUPnPDIDLLiteResource *resource); + +const char * +gupnp_didl_lite_resource_get_uri (GUPnPDIDLLiteResource *resource); + +const char * +gupnp_didl_lite_resource_get_import_uri (GUPnPDIDLLiteResource *resource); + +GUPnPProtocolInfo * +gupnp_didl_lite_resource_get_protocol_info + (GUPnPDIDLLiteResource *resource); + +long +gupnp_didl_lite_resource_get_size (GUPnPDIDLLiteResource *resource); + +gint64 +gupnp_didl_lite_resource_get_size64 (GUPnPDIDLLiteResource *resource); + +long +gupnp_didl_lite_resource_get_duration (GUPnPDIDLLiteResource *resource); + +int +gupnp_didl_lite_resource_get_bitrate (GUPnPDIDLLiteResource *resource); + +int +gupnp_didl_lite_resource_get_sample_freq + (GUPnPDIDLLiteResource *resource); + +int +gupnp_didl_lite_resource_get_bits_per_sample + (GUPnPDIDLLiteResource *resource); + +const char * +gupnp_didl_lite_resource_get_protection (GUPnPDIDLLiteResource *resource); + +int +gupnp_didl_lite_resource_get_audio_channels + (GUPnPDIDLLiteResource *resource); + +int +gupnp_didl_lite_resource_get_width (GUPnPDIDLLiteResource *resource); + +int +gupnp_didl_lite_resource_get_height (GUPnPDIDLLiteResource *resource); + +int +gupnp_didl_lite_resource_get_color_depth + (GUPnPDIDLLiteResource *resource); + +G_END_DECLS + +#endif /* __GUPNP_DIDL_LITE_RESOURCE_H__ */ diff --git a/libgupnp-av/gupnp-didl-lite-writer.c b/libgupnp-av/gupnp-didl-lite-writer.c new file mode 100644 index 0000000..baec6fc --- /dev/null +++ b/libgupnp-av/gupnp-didl-lite-writer.c @@ -0,0 +1,640 @@ +/* + * Copyright (C) 2007, 2008 OpenedHand Ltd. + * + * Authors: Jorn Baayen <jorn@openedhand.com> + * + * 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. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +/** + * SECTION:gupnp-didl-lite-writer + * @short_description: DIDL-Lite fragment writer + * + * #GUPnPDIDLLiteWriter is a helper class for writing DIDL-Lite fragments. + */ + +#include <string.h> + +#include "gupnp-didl-lite-writer.h" +#include "gupnp-didl-lite-object.h" +#include "gupnp-didl-lite-object-private.h" +#include "gupnp-didl-lite-descriptor-private.h" + +#include "xml-util.h" + +G_DEFINE_TYPE (GUPnPDIDLLiteWriter, + gupnp_didl_lite_writer, + G_TYPE_OBJECT); + +struct _GUPnPDIDLLiteWriterPrivate { + xmlNode *xml_node; + GUPnPXMLDoc *xml_doc; + + xmlNs *upnp_ns; + xmlNs *dc_ns; + xmlNs *dlna_ns; + + char *language; +}; + +enum { + PROP_0, + PROP_XML_NODE, + PROP_LANGUAGE, +}; + +static int +compare_prop (const char *a, xmlAttr *attr) +{ + const char *p; + char *parent_name; + char *attr_name; + int ret = -1; + + if (attr->ns != NULL) + attr_name = g_strjoin (":", attr->ns->prefix, attr->name, NULL); + else + attr_name = g_strdup ((const char *) attr->name); + + if (attr->parent->ns != NULL) + parent_name = g_strjoin (":", + attr->parent->ns->prefix, + attr->parent->name, + NULL); + else + parent_name = g_strdup ((const char *) attr->parent->name); + + p = strstr (a, "@"); + if (p) + if (p == a) + /* Top-level property */ + ret = strcmp (a + 1, attr_name); + else + ret = strncmp (a, parent_name, p - a) || + strcmp (p + 1, attr_name); + else + ret = strcmp (a, attr_name); + + g_free (attr_name); + g_free (parent_name); + + return ret; +} + +static gboolean +is_attribute_forbidden (xmlAttr *attr, + GList *allowed) +{ + return g_list_find_custom (allowed, + attr, + (GCompareFunc) compare_prop) == NULL; +} + +static int +compare_node_name (const char *a, const char *b) +{ + const char *p; + int len; + + if (a[0] == '@') + /* Filer is for top-level property */ + return -1; + + p = strstr (a, "@"); + if (p != NULL) + /* Compare only the string before '@' */ + len = p - a; + else + len = strlen (a); + + return strncmp (a, b, len); +} + +static gboolean +is_node_forbidden (xmlNode *node, + GList *allowed, + const char *ns) +{ + char *name; + gboolean ret; + + if (ns != NULL) + name = g_strjoin (":", ns, node->name, NULL); + else + name = g_strdup ((const char *) node->name); + + ret = g_list_find_custom (allowed, + name, + (GCompareFunc) compare_node_name) == NULL; + + g_free (name); + + return ret; +} + +static gboolean +is_container_standard_prop (const char *name, + const char *namespace, + const char *upnp_class) +{ + return g_strcmp0 (upnp_class, "object.container.storageFolder") == 0 && + g_strcmp0 (namespace, "upnp") == 0 && + strcmp (name, "storageUsed") == 0; +} + +static gboolean +is_standard_prop (const char *name, + const char *namespace, + const char *parent_name) +{ + return strcmp (name, "id") == 0 || + strcmp (name, "parentID") == 0 || + strcmp (name, "restricted") == 0 || + (g_strcmp0 (namespace, "dc") == 0 && + strcmp (name, "title") == 0) || + (g_strcmp0 (namespace, "upnp") == 0 && + strcmp (name, "class") == 0) || + (g_strcmp0 (parent_name, "res") == 0 && + strcmp (name, "protocolInfo") == 0); +} + +static void +filter_attributes (xmlNode *node, + GList *allowed, + GUPnPDIDLLiteWriter *writer) +{ + xmlAttr *attr; + GList *forbidden = NULL; + GList *l; + + /* Find forbidden properties */ + for (attr = node->properties; attr != NULL; attr = attr->next) + if (!is_standard_prop ((const char *) attr->name, + NULL, + (const char *) attr->parent->name) && + is_attribute_forbidden (attr, allowed)) + forbidden = g_list_append (forbidden, attr); + + /* Now unset forbidden properties */ + for (l = forbidden; l != NULL; l = l->next) + xmlRemoveProp ((xmlAttr *) l->data); + + g_list_free (forbidden); +} + +static void +filter_node (xmlNode *node, + GList *allowed, + GUPnPDIDLLiteWriter *writer) +{ + xmlNode *child; + GList *forbidden = NULL; + GList *l; + gboolean is_container; + const char *container_class = NULL; + + filter_attributes (node, allowed, writer); + + if (strcmp ((const char *) node->name, "container") == 0) { + is_container = TRUE; + container_class = xml_util_get_child_element_content (node, + "class"); + } + + forbidden = NULL; + for (child = node->children; child != NULL; child = child->next) { + const char *ns = NULL; + + if (xmlNodeIsText (child)) + continue; + + if (child->ns != NULL) + ns = (const char *) child->ns->prefix; + + if (!(is_container && is_container_standard_prop + ((const char *) child->name, + ns, + container_class)) && + !is_standard_prop ((const char *) child->name, + ns, + (const char *) node->name) && + is_node_forbidden (child, allowed, ns)) + forbidden = g_list_append (forbidden, child); + } + + /* Now remove the forbidden nodes */ + for (l = forbidden; l != NULL; l = l->next) { + xmlNode *n; + + n = (xmlNode *) l->data; + + xmlUnlinkNode (n); + xmlFreeNode (n); + } + + g_list_free (forbidden); + + /* Recurse */ + for (child = node->children; child != NULL; child = child->next) + if (!xmlNodeIsText (child)) + filter_node (child, allowed, writer); +} + +static void +gupnp_didl_lite_writer_init (GUPnPDIDLLiteWriter *writer) +{ + writer->priv = G_TYPE_INSTANCE_GET_PRIVATE (writer, + GUPNP_TYPE_DIDL_LITE_WRITER, + GUPnPDIDLLiteWriterPrivate); +} + +static void +gupnp_didl_lite_writer_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) + +{ + GUPnPDIDLLiteWriter *writer; + + writer = GUPNP_DIDL_LITE_WRITER (object); + + switch (property_id) { + case PROP_LANGUAGE: + writer->priv->language = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gupnp_didl_lite_writer_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + GUPnPDIDLLiteWriter *writer; + + writer = GUPNP_DIDL_LITE_WRITER (object); + + switch (property_id) { + case PROP_XML_NODE: + g_value_set_pointer + (value, gupnp_didl_lite_writer_get_xml_node (writer)); + break; + case PROP_LANGUAGE: + g_value_set_string + (value, gupnp_didl_lite_writer_get_language (writer)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gupnp_didl_lite_writer_constructed (GObject *object) +{ + GObjectClass *object_class; + GUPnPDIDLLiteWriterPrivate *priv; + xmlDoc *doc; + + priv = GUPNP_DIDL_LITE_WRITER (object)->priv; + + doc = xmlNewDoc ((unsigned char *) "1.0"); + priv->xml_doc = gupnp_xml_doc_new (doc); + + priv->xml_node = xmlNewDocNode (priv->xml_doc->doc, + NULL, + (unsigned char *) "DIDL-Lite", + NULL); + xmlDocSetRootElement (priv->xml_doc->doc, priv->xml_node); + priv->dc_ns = xmlNewNs (priv->xml_node, + (unsigned char *) + "http://purl.org/dc/elements/1.1/", + (unsigned char *) + GUPNP_DIDL_LITE_WRITER_NAMESPACE_DC); + priv->upnp_ns = xmlNewNs (priv->xml_node, + (unsigned char *) + "urn:schemas-upnp-org:metadata-1-0/upnp/", + (unsigned char *) + GUPNP_DIDL_LITE_WRITER_NAMESPACE_UPNP); + priv->dlna_ns = xmlNewNs (priv->xml_node, + (unsigned char *) + "urn:schemas-dlna-org:metadata-1-0/", + (unsigned char *) + GUPNP_DIDL_LITE_WRITER_NAMESPACE_DLNA); + xmlNewNs (priv->xml_node, + (unsigned char *) + "urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/", + NULL); + + if (priv->language) + xmlSetProp (priv->xml_node, + (unsigned char *) "lang", + (unsigned char *) priv->language); + + object_class = G_OBJECT_CLASS (gupnp_didl_lite_writer_parent_class); + if (object_class->constructed != NULL) + object_class->constructed (object); +} + +static void +gupnp_didl_lite_writer_dispose (GObject *object) +{ + GObjectClass *object_class; + GUPnPDIDLLiteWriterPrivate *priv; + + priv = GUPNP_DIDL_LITE_WRITER (object)->priv; + + if (priv->xml_doc) { + g_object_unref (priv->xml_doc); + priv->xml_doc = NULL; + } + + object_class = G_OBJECT_CLASS (gupnp_didl_lite_writer_parent_class); + object_class->dispose (object); +} + +static void +gupnp_didl_lite_writer_finalize (GObject *object) +{ + GObjectClass *object_class; + GUPnPDIDLLiteWriterPrivate *priv; + + priv = GUPNP_DIDL_LITE_WRITER (object)->priv; + + if (priv->language) + g_free (priv->language); + + object_class = G_OBJECT_CLASS (gupnp_didl_lite_writer_parent_class); + object_class->finalize (object); +} + +static void +gupnp_didl_lite_writer_class_init (GUPnPDIDLLiteWriterClass *klass) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (klass); + + object_class->set_property = gupnp_didl_lite_writer_set_property; + object_class->get_property = gupnp_didl_lite_writer_get_property; + object_class->constructed = gupnp_didl_lite_writer_constructed; + object_class->dispose = gupnp_didl_lite_writer_dispose; + object_class->finalize = gupnp_didl_lite_writer_finalize; + + g_type_class_add_private (klass, sizeof (GUPnPDIDLLiteWriterPrivate)); + + /** + * GUPnPDIDLLiteWriter:xml-node: + * + * The pointer to root node in XML document. + **/ + g_object_class_install_property + (object_class, + PROP_XML_NODE, + g_param_spec_pointer ("xml-node", + "XMLNode", + "The pointer to root node in XML" + " document.", + G_PARAM_READABLE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPDIDLLiteWriter:language: + * + * The language the DIDL-Lite fragment is in. + * + **/ + g_object_class_install_property + (object_class, + PROP_LANGUAGE, + g_param_spec_string ("language", + "Language", + "The language the DIDL-Lite fragment" + " is in.", + NULL, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); +} + +/** + * gupnp_didl_lite_writer_new: + * @language: The language the DIDL-Lite fragment is in, or NULL + * + * Return value: A new #GUPnPDIDLLiteWriter object. + **/ +GUPnPDIDLLiteWriter * +gupnp_didl_lite_writer_new (const char *language) +{ + return g_object_new (GUPNP_TYPE_DIDL_LITE_WRITER, + "language", language, + NULL); +} + +/** + * gupnp_didl_lite_writer_add_item: + * @writer: A #GUPnPDIDLLiteWriter + * + * Creates a new item, attaches it to @writer and returns it. + * + * Returns: (transfer full): A new #GUPnPDIDLLiteItem object. Unref after usage. + **/ +GUPnPDIDLLiteItem * +gupnp_didl_lite_writer_add_item (GUPnPDIDLLiteWriter *writer) +{ + xmlNode *item_node; + GUPnPDIDLLiteObject *object; + + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_WRITER (writer), NULL); + + item_node = xmlNewChild (writer->priv->xml_node, + NULL, + (unsigned char *) "item", + NULL); + + object = gupnp_didl_lite_object_new_from_xml (item_node, + writer->priv->xml_doc, + writer->priv->upnp_ns, + writer->priv->dc_ns, + writer->priv->dlna_ns); + return GUPNP_DIDL_LITE_ITEM (object); +} + +/** + * gupnp_didl_lite_writer_add_container: + * @writer: A #GUPnPDIDLLiteWriter + * + * Creates a new container, attaches it to @writer and returns it. + * + * Returns: (transfer full): A new #GUPnPDIDLLiteContainer object. Unref after usage. + **/ +GUPnPDIDLLiteContainer * +gupnp_didl_lite_writer_add_container (GUPnPDIDLLiteWriter *writer) +{ + xmlNode *container_node; + GUPnPDIDLLiteObject *object; + + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_WRITER (writer), NULL); + + container_node = xmlNewChild (writer->priv->xml_node, + NULL, + (unsigned char *) "container", + NULL); + + object = gupnp_didl_lite_object_new_from_xml (container_node, + writer->priv->xml_doc, + writer->priv->upnp_ns, + writer->priv->dc_ns, + writer->priv->dlna_ns); + return GUPNP_DIDL_LITE_CONTAINER (object); +} + +/** + * gupnp_didl_lite_writer_add_descriptor: + * @writer: A #GUPnPDIDLLiteWriter + * + * Creates a new descriptor, attaches it to @object and returns it. + * + * Returns: (transfer full): A new #GUPnPDIDLLiteDescriptor object. Unref after usage. + **/ +GUPnPDIDLLiteDescriptor * +gupnp_didl_lite_writer_add_descriptor (GUPnPDIDLLiteWriter *writer) +{ + xmlNode *desc_node; + + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_WRITER (writer), NULL); + + desc_node = xmlNewChild (writer->priv->xml_node, + NULL, + (unsigned char *) "desc", + NULL); + + return gupnp_didl_lite_descriptor_new_from_xml (desc_node, + writer->priv->xml_doc); +} + +/** + * gupnp_didl_lite_writer_get_string: + * @writer: A #GUPnPDIDLLiteWriter + * + * Creates a string representation of the DIDL-Lite XML document. + * + * Return value: The DIDL-Lite XML string, or %NULL. #g_free after usage. + **/ +char * +gupnp_didl_lite_writer_get_string (GUPnPDIDLLiteWriter *writer) +{ + xmlBuffer *buffer; + char *ret; + + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_WRITER (writer), NULL); + + buffer = xmlBufferCreate (); + xmlNodeDump (buffer, + writer->priv->xml_doc->doc, + writer->priv->xml_node, + 0, + 0); + ret = g_strndup ((char *) xmlBufferContent (buffer), + xmlBufferLength (buffer)); + xmlBufferFree (buffer); + + return ret; +} + +/** + * gupnp_didl_lite_writer_get_xml_node: + * @writer: The #GUPnPDIDLLiteWriter + * + * Get the pointer to root node in XML document. + * + * Returns: (transfer none): The pointer to root node in XML document. + **/ +xmlNode * +gupnp_didl_lite_writer_get_xml_node (GUPnPDIDLLiteWriter *writer) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_WRITER (writer), NULL); + + return writer->priv->xml_node; +} + +/** + * gupnp_didl_lite_writer_get_language: + * @writer: #GUPnPDIDLLiteWriter + * + * Get the language the DIDL-Lite fragment is in. + * + * Returns: (transfer none): The language of the @writer, or %NULL. + **/ +const char * +gupnp_didl_lite_writer_get_language (GUPnPDIDLLiteWriter *writer) +{ + g_return_val_if_fail (GUPNP_IS_DIDL_LITE_WRITER (writer), NULL); + + return writer->priv->language; +} + +/** + * gupnp_didl_lite_writer_filter: + * @writer: A #GUPnPDIDLLiteWriter + * @filter: A filter string + * + * Clears the DIDL-Lite XML document of the properties not specified in the + * @filter. The passed filter string would typically come from the 'Filter' + * argument of Browse or Search actions from a ContentDirectory control point. + * Please refer to Section 2.3.15 of UPnP AV ContentDirectory version 3 + * specification for details on this string. + * + * Return value: None. + **/ +void +gupnp_didl_lite_writer_filter (GUPnPDIDLLiteWriter *writer, + const char *filter) +{ + char **tokens; + GList *allowed = NULL; + unsigned short i; + xmlNode *node; + + g_return_if_fail (GUPNP_IS_DIDL_LITE_WRITER (writer)); + g_return_if_fail (filter != NULL); + + if (filter[0] == '*') + return; /* Wildcard */ + + tokens = g_strsplit (filter, ",", -1); + g_return_if_fail (tokens != NULL); + + for (i = 0; tokens[i] != NULL; i++) + allowed = g_list_append (allowed, tokens[i]); + + for (node = writer->priv->xml_node->children; + node != NULL; + node = node->next) + filter_node (node, allowed, writer); + + g_list_free (allowed); + g_strfreev (tokens); +} diff --git a/libgupnp-av/gupnp-didl-lite-writer.h b/libgupnp-av/gupnp-didl-lite-writer.h new file mode 100644 index 0000000..33da37f --- /dev/null +++ b/libgupnp-av/gupnp-didl-lite-writer.h @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2007, 2008 OpenedHand Ltd. + * + * Authors: Jorn Baayen <jorn@openedhand.com> + * + * 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. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __GUPNP_DIDL_LITE_WRITER_H__ +#define __GUPNP_DIDL_LITE_WRITER_H__ + + +#include <stdarg.h> +#include <glib-object.h> +#include <libsoup/soup-uri.h> + +#include "gupnp-dlna.h" +#include "gupnp-didl-lite-item.h" +#include "gupnp-didl-lite-container.h" +#include "gupnp-didl-lite-resource.h" +#include "gupnp-didl-lite-descriptor.h" + +G_BEGIN_DECLS + +GType +gupnp_didl_lite_writer_get_type (void) G_GNUC_CONST; + +#define GUPNP_TYPE_DIDL_LITE_WRITER \ + (gupnp_didl_lite_writer_get_type ()) +#define GUPNP_DIDL_LITE_WRITER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + GUPNP_TYPE_DIDL_LITE_WRITER, \ + GUPnPDIDLLiteWriter)) +#define GUPNP_DIDL_LITE_WRITER_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_CAST ((obj), \ + GUPNP_TYPE_DIDL_LITE_WRITER, \ + GUPnPDIDLLiteWriterClass)) +#define GUPNP_IS_DIDL_LITE_WRITER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + GUPNP_TYPE_DIDL_LITE_WRITER)) +#define GUPNP_IS_DIDL_LITE_WRITER_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE ((obj), \ + GUPNP_TYPE_DIDL_LITE_WRITER)) +#define GUPNP_DIDL_LITE_WRITER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + GUPNP_TYPE_DIDL_LITE_WRITER, \ + GUPnPDIDLLiteWriterClass)) + +typedef struct _GUPnPDIDLLiteWriterPrivate GUPnPDIDLLiteWriterPrivate; + +typedef struct { + GObject parent; + + GUPnPDIDLLiteWriterPrivate *priv; +} GUPnPDIDLLiteWriter; + +typedef struct { + GObjectClass parent_class; + + /* future padding */ + void (* _gupnp_reserved1) (void); + void (* _gupnp_reserved2) (void); + void (* _gupnp_reserved3) (void); + void (* _gupnp_reserved4) (void); +} GUPnPDIDLLiteWriterClass; + +#define GUPNP_DIDL_LITE_WRITER_NAMESPACE_DC "dc" +#define GUPNP_DIDL_LITE_WRITER_NAMESPACE_UPNP "upnp" +#define GUPNP_DIDL_LITE_WRITER_NAMESPACE_DLNA "dlna" + +GUPnPDIDLLiteWriter * +gupnp_didl_lite_writer_new (const char *language); + +GUPnPDIDLLiteItem * +gupnp_didl_lite_writer_add_item (GUPnPDIDLLiteWriter *writer); + +GUPnPDIDLLiteContainer * +gupnp_didl_lite_writer_add_container (GUPnPDIDLLiteWriter *writer); + +GUPnPDIDLLiteDescriptor * +gupnp_didl_lite_writer_add_descriptor (GUPnPDIDLLiteWriter *writer); + +xmlNode * +gupnp_didl_lite_writer_get_xml_node (GUPnPDIDLLiteWriter *writer); + +char * +gupnp_didl_lite_writer_get_string (GUPnPDIDLLiteWriter *writer); + +const char * +gupnp_didl_lite_writer_get_language (GUPnPDIDLLiteWriter *writer); + +void +gupnp_didl_lite_writer_filter (GUPnPDIDLLiteWriter *writer, + const char *filter); + +G_END_DECLS + +#endif /* __GUPNP_DIDL_LITE_WRITER_H__ */ diff --git a/libgupnp-av/gupnp-dlna.c b/libgupnp-av/gupnp-dlna.c new file mode 100644 index 0000000..97ff080 --- /dev/null +++ b/libgupnp-av/gupnp-dlna.c @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2009 Nokia Corporation. + * + * Authors: Zeeshan Ali <zeeshanak@gnome.org> + * <zeeshan.ali@nokia.com> + * + * 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. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "gupnp-dlna.h" + +GType +gupnp_dlna_conversion_get_type (void) +{ + static GType type = 0; + + if (type == 0) { + static const GFlagsValue values[] = { + { GUPNP_DLNA_CONVERSION_NONE, + "GUPNP_DLNA_CONVERSION_NONE", + "none" }, + { GUPNP_DLNA_CONVERSION_TRANSCODED, + "GUPNP_DLNA_CONVERSION_TRANSCODED", + "transcoded" }, + { 0, NULL, NULL } + }; + + type = g_flags_register_static + (g_intern_static_string ("GUPnPDLNAConversion"), + values); + } + + return type; +} + +GType +gupnp_dlna_operation_get_type (void) +{ + static GType type = 0; + + if (type == 0) { + static const GFlagsValue values[] = { + { GUPNP_DLNA_OPERATION_NONE, + "GUPNP_DLNA_OPERATION_NONE", + "none" }, + { GUPNP_DLNA_OPERATION_RANGE, + "GUPNP_DLNA_OPERATION_RANGE", + "range" }, + { GUPNP_DLNA_OPERATION_TIMESEEK, + "GUPNP_DLNA_OPERATION_TIMESEEK", + "timeseek" }, + { 0, NULL, NULL } + }; + + type = g_flags_register_static + (g_intern_static_string ("GUPnPDLNAOperation"), + values); + } + + return type; +} + +GType +gupnp_dlna_flags_get_type (void) +{ + static GType type = 0; + + if (type == 0) { + static const GFlagsValue values[] = { + { GUPNP_DLNA_FLAGS_NONE, + "GUPNP_DLNA_FLAGS_NONE", + "none" }, + { GUPNP_DLNA_FLAGS_SENDER_PACED, + "GUPNP_DLNA_FLAGS_SENDER_PACED", + "sender-paced" }, + { GUPNP_DLNA_FLAGS_TIME_BASED_SEEK, + "GUPNP_DLNA_FLAGS_TIME_BASED_SEEK", + "time-based-seek" }, + { GUPNP_DLNA_FLAGS_BYTE_BASED_SEEK, + "GUPNP_DLNA_FLAGS_BYTE_BASED_SEEK", + "byte-based-seek" }, + { GUPNP_DLNA_FLAGS_PLAY_CONTAINER, + "GUPNP_DLNA_FLAGS_PLAY_CONTAINER", + "play-container" }, + { GUPNP_DLNA_FLAGS_S0_INCREASE, + "GUPNP_DLNA_FLAGS_S0_INCREASE", + "s0-increase" }, + { GUPNP_DLNA_FLAGS_SN_INCREASE, + "GUPNP_DLNA_FLAGS_SN_INCREASE", + "sn-increase" }, + { GUPNP_DLNA_FLAGS_RTSP_PAUSE, + "GUPNP_DLNA_FLAGS_RTSP_PAUSE", + "rtsp-pause" }, + { GUPNP_DLNA_FLAGS_STREAMING_TRANSFER_MODE, + "GUPNP_DLNA_FLAGS_STREAMING_TRANSFER_MODE", + "streaming-transfer-mode" }, + { GUPNP_DLNA_FLAGS_INTERACTIVE_TRANSFER_MODE, + "GUPNP_DLNA_FLAGS_INTERACTIVE_TRANSFER_MODE", + "interactive-transfer-mode" }, + { GUPNP_DLNA_FLAGS_BACKGROUND_TRANSFER_MODE, + "GUPNP_DLNA_FLAGS_BACKGROUND_TRANSFER_MODE", + "background-transfer-mode" }, + { GUPNP_DLNA_FLAGS_CONNECTION_STALL, + "GUPNP_DLNA_FLAGS_CONNECTION_STALL", + "connection-stall" }, + { GUPNP_DLNA_FLAGS_DLNA_V15, + "GUPNP_DLNA_FLAGS_DLNA_V15", + "dlna-v15" }, + { 0, NULL, NULL } + }; + + type = g_flags_register_static + (g_intern_static_string ("GUPnPDLNAFlags"), + values); + } + + return type; +} + +GType +gupnp_ocm_flags_get_type (void) +{ + static GType type = 0; + + if (type == 0) { + static const GFlagsValue values[] = { + { GUPNP_OCM_FLAGS_NONE, + "GUPNP_OCM_FLAGS_NONE", + "none" }, + { GUPNP_OCM_FLAGS_UPLOAD, + "GUPNP_OCM_FLAGS_UPLOAD", + "upload" }, + { GUPNP_OCM_FLAGS_CREATE_CONTAINER, + "GUPNP_OCM_FLAGS_CREATE_CONTAINER", + "create-container" }, + { GUPNP_OCM_FLAGS_DESTROYABLE, + "GUPNP_OCM_FLAGS_DESTROYABLE", + "destroyable" }, + { GUPNP_OCM_FLAGS_UPLOAD_DESTROYABLE, + "GUPNP_OCM_FLAGS_UPLOAD_DESTROYABLE", + "upload-destroyable" }, + { GUPNP_OCM_FLAGS_CHANGE_METADATA, + "GUPNP_OCM_FLAGS_CHANGE_METADATA", + "change-metadata" }, + { 0, NULL, NULL } + }; + + type = g_flags_register_static + (g_intern_static_string ("GUPnPOCMFlags"), + values); + } + + return type; +} diff --git a/libgupnp-av/gupnp-dlna.h b/libgupnp-av/gupnp-dlna.h new file mode 100644 index 0000000..c0beb20 --- /dev/null +++ b/libgupnp-av/gupnp-dlna.h @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2007, 2008 OpenedHand Ltd. + * + * Authors: Jorn Baayen <jorn@openedhand.com> + * + * 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. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __GUPNP_DLNA_H__ +#define __GUPNP_DLNA_H__ + +#include <glib-object.h> + +G_BEGIN_DECLS + +GType +gupnp_dlna_conversion_get_type (void) G_GNUC_CONST; + +#define GUPNP_TYPE_DLNA_CONVERSION (gupnp_dlna_conversion_get_type ()) + +/** + * GUPnPDLNAConversion: + * @GUPNP_DLNA_CONVERSION_NONE: Content is in original source format + * @GUPNP_DLNA_CONVERSION_TRANSCODED: Content is transcoded + * + * The DLNA conversion flags for a resource. + * + **/ +typedef enum { + GUPNP_DLNA_CONVERSION_NONE = 0, + GUPNP_DLNA_CONVERSION_TRANSCODED = 1 +} GUPnPDLNAConversion; + +GType +gupnp_dlna_operation_get_type (void) G_GNUC_CONST; + +#define GUPNP_TYPE_DLNA_OPERATION (gupnp_dlna_operation_get_type ()) + +/** + * GUPnPDLNAOperation: + * @GUPNP_DLNA_OPERATION_NONE: Resource does not support seeking of any type + * @GUPNP_DLNA_OPERATION_RANGE: Resource supports byte-seek + * @GUPNP_DLNA_OPERATION_TIMESEEK: Resource supports time-seek + * + * The seek operations supported by a resource. + * + **/ +typedef enum { + GUPNP_DLNA_OPERATION_NONE = 0x00, + GUPNP_DLNA_OPERATION_RANGE = 0x01, + GUPNP_DLNA_OPERATION_TIMESEEK = 0x10 +} GUPnPDLNAOperation; + +GType +gupnp_dlna_flags_get_type (void) G_GNUC_CONST; + +#define GUPNP_TYPE_DLNA_FLAGS (gupnp_dlna_flags_get_type ()) + +/** + * GUPnPDLNAFlags: + * @GUPNP_DLNA_FLAGS_NONE: No flags + * @GUPNP_DLNA_FLAGS_SENDER_PACED: Content source is the clock source during + * transport + * @GUPNP_DLNA_FLAGS_TIME_BASED_SEEK: Limited Operation: time-seek supported + * @GUPNP_DLNA_FLAGS_BYTE_BASED_SEEK: Limited Operation: byte-seek supported + * @GUPNP_DLNA_FLAGS_PLAY_CONTAINER: Resource supports 'Container Playback' + * @GUPNP_DLNA_FLAGS_S0_INCREASE: Content does not have a fixed beginning + * @GUPNP_DLNA_FLAGS_SN_INCREASE: Content does not have a fixed end + * @GUPNP_DLNA_FLAGS_RTSP_PAUSE: RTSP resource supports pausing of media + * transfer + * @GUPNP_DLNA_FLAGS_STREAMING_TRANSFER_MODE: Streaming transfer mode supported + * @GUPNP_DLNA_FLAGS_INTERACTIVE_TRANSFER_MODE: Interactive transfer mode + * supported + * @GUPNP_DLNA_FLAGS_BACKGROUND_TRANSFER_MODE: Background transfer mode + * supported + * @GUPNP_DLNA_FLAGS_CONNECTION_STALL: No content transfer when paused. + * @GUPNP_DLNA_FLAGS_DLNA_V15: DLNAv1.5 version flag + * + * The miscellaneous operations supported by a resource. For details on these + * flags please refer to section 7.3.37.2 of DLNA Networked Device + * Interoperability Guidelines Volume 1, October 2006. + * + **/ +typedef enum { + GUPNP_DLNA_FLAGS_NONE = 0, + GUPNP_DLNA_FLAGS_SENDER_PACED = (1 << 31), + GUPNP_DLNA_FLAGS_TIME_BASED_SEEK = (1 << 30), + GUPNP_DLNA_FLAGS_BYTE_BASED_SEEK = (1 << 29), + GUPNP_DLNA_FLAGS_PLAY_CONTAINER = (1 << 28), + GUPNP_DLNA_FLAGS_S0_INCREASE = (1 << 27), + GUPNP_DLNA_FLAGS_SN_INCREASE = (1 << 26), + GUPNP_DLNA_FLAGS_RTSP_PAUSE = (1 << 25), + GUPNP_DLNA_FLAGS_STREAMING_TRANSFER_MODE = (1 << 24), + GUPNP_DLNA_FLAGS_INTERACTIVE_TRANSFER_MODE = (1 << 23), + GUPNP_DLNA_FLAGS_BACKGROUND_TRANSFER_MODE = (1 << 22), + GUPNP_DLNA_FLAGS_CONNECTION_STALL = (1 << 21), + GUPNP_DLNA_FLAGS_DLNA_V15 = (1 << 20) +} GUPnPDLNAFlags; + +/** + * GUPnPOCMFlags: + * @GUPNP_OCM_FLAGS_NONE: No flags + * @GUPNP_OCM_FLAGS_UPLOAD: Indicates support for content upload. + * @GUPNP_OCM_FLAGS_CREATE_CONTAINER: Indicates support for creation of child + * container. + * @GUPNP_OCM_FLAGS_DESTROYABLE: This object is destroyable. + * @GUPNP_OCM_FLAGS_UPLOAD_DESTROYABLE: Indicates support for upload of + * destroyable content. + * @GUPNP_OCM_FLAGS_CHANGE_METADATA: Indicates support for changing metadata. + * + * The DLNA OCM flags supported by a DIDL-Lite Object. For details on these + * flags please refer to section 7.3.118.4 of DLNA Networked Device + * Interoperability Guidelines Volume 1, October 2006. + * + **/ +typedef enum { + GUPNP_OCM_FLAGS_NONE = 0x0, + GUPNP_OCM_FLAGS_UPLOAD = 0x01, + GUPNP_OCM_FLAGS_CREATE_CONTAINER = 0x02, + GUPNP_OCM_FLAGS_DESTROYABLE = 0x04, + GUPNP_OCM_FLAGS_UPLOAD_DESTROYABLE = 0x08, + GUPNP_OCM_FLAGS_CHANGE_METADATA = 0x10 +} GUPnPOCMFlags; + +GType +gupnp_ocm_flags_get_type (void) G_GNUC_CONST; + +#define GUPNP_TYPE_OCM_FLAGS (gupnp_ocm_flags_get_type ()) + +G_END_DECLS + +#endif /* __GUPNP_DLNA_H__ */ diff --git a/libgupnp-av/gupnp-last-change-parser.c b/libgupnp-av/gupnp-last-change-parser.c new file mode 100644 index 0000000..43aabe7 --- /dev/null +++ b/libgupnp-av/gupnp-last-change-parser.c @@ -0,0 +1,252 @@ +/* + * Copyright (C) 2007 Zeeshan Ali (Khattak) <zeeshanak@gnome.org> + * Copyright (C) 2007 OpenedHand Ltd + * + * Authors: Zeeshan Ali (Khattak) <zeeshanak@gnome.org> + * Jorn Baayen <jorn@openedhand.com> + * + * 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. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +/** + * SECTION:gupnp-last-change-parser + * @short_description: A/V LastChange event XML parser + * + * #GUPnPLastChangeParser parses XML strings from LastChange events that are + * generated by AVTransport and RenderingControl services. + * + */ + + +#include <gobject/gvaluecollector.h> + +#include "gupnp-last-change-parser.h" +#include "gvalue-util.h" +#include "xml-util.h" + +G_DEFINE_TYPE (GUPnPLastChangeParser, + gupnp_last_change_parser, + G_TYPE_OBJECT); + +static void +gupnp_last_change_parser_init (GUPnPLastChangeParser *parser) +{ +} + +static void +gupnp_last_change_parser_dispose (GObject *object) +{ + GObjectClass *gobject_class; + + gobject_class = G_OBJECT_CLASS (gupnp_last_change_parser_parent_class); + gobject_class->dispose (object); +} + +static void +gupnp_last_change_parser_class_init (GUPnPLastChangeParserClass *klass) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = gupnp_last_change_parser_dispose; +} + +/* Reads a value of state variable @variable_name to an initialised GValue pair + * from the InstanceID node of a LastChange xml doc */ +static gboolean +read_state_variable (const char *variable_name, + GValue *value, + xmlNode *instance_node) +{ + xmlNode *variable_node; + const char *val_str; + + variable_node = xml_util_get_element (instance_node, + "InstanceID", + variable_name, + NULL); + if (!variable_node) + return FALSE; + + val_str = xml_util_get_attribute_content (variable_node, "val"); + if (!val_str) { + g_warning ("No value provided for variable \"%s\" in " + "LastChange event", + variable_name); + + return FALSE; + } + + gvalue_util_set_value_from_string (value, val_str); + + return TRUE; +} + +static xmlNode * +get_instance_node (xmlDoc *doc, + guint instance_id) +{ + xmlNode *node; + + for (node = doc->children; + node; + node = node->next) { + guint id; + + id = xml_util_get_uint_attribute (node, "val", 0); + if (id == instance_id) + break; + } + + return node; +} + +/** + * gupnp_last_change_parser_new: + * + * Return value: A new #GUPnPLastChangeParser + **/ +GUPnPLastChangeParser * +gupnp_last_change_parser_new (void) +{ + return g_object_new (GUPNP_TYPE_LAST_CHANGE_PARSER, + NULL); +} + +/** + * gupnp_last_change_parser_parse_last_change_valist: + * @parser: A #GUPnPLastChangeParser + * @instance_id: The ID of the AV instance caller is interested in + * @last_change_xml: The xml from the "LastChange" event to parse + * @error: The location where to store any error, or NULL + * @var_args: A va_list of tuples of state variable name, state variable type, + * and state variable value location, terminated with NULL. The state variable + * values should be freed after use + * + * See gupnp_last_change_parser_parse_last_change(); this version takes a + * va_list for use by language bindings. + * + * Return value: TRUE on success. + **/ +gboolean +gupnp_last_change_parser_parse_last_change_valist + (GUPnPLastChangeParser *parser, + guint instance_id, + const char *last_change_xml, + GError **error, + va_list var_args) +{ + const char *variable_name; + xmlDoc *doc; + xmlNode *instance_node; + + g_return_val_if_fail (last_change_xml, FALSE); + + doc = xmlParseDoc ((const xmlChar *) last_change_xml); + if (doc == NULL) { + g_set_error (error, + GUPNP_XML_ERROR, + GUPNP_XML_ERROR_PARSE, + "Could not parse LastChange xml"); + + return FALSE; + } + + instance_node = get_instance_node (doc, instance_id); + if (instance_node == NULL) { + /* This is not an error since the caller of this function + * doesn't (need to) know if the instance of his interest is + * part of the LastChange event received. + */ + xmlFreeDoc (doc); + + return FALSE; + } + + /* Variables */ + variable_name = va_arg (var_args, const char *); + while (variable_name) { + GType variable_type; + GValue value = { 0, }; + char *copy_error = NULL; + + variable_type = va_arg (var_args, GType); + + g_value_init (&value, variable_type); + + if (read_state_variable (variable_name, + &value, + instance_node)) { + G_VALUE_LCOPY (&value, var_args, 0, ©_error); + } else { + va_arg (var_args, gpointer); + } + + g_value_unset (&value); + + if (copy_error) { + g_warning ("Error copying value: %s", copy_error); + + g_free (copy_error); + } + + variable_name = va_arg (var_args, const char *); + } + + /* Cleanup */ + xmlFreeDoc (doc); + + return TRUE; +} + +/** + * gupnp_last_change_parser_parse_last_change: + * @parser: A #GUPnPLastChangeParser + * @instance_id: The ID of the AV instance caller is interested in + * @last_change_xml: The xml from the "LastChange" event to parse + * @error: The location where to store any error, or NULL + * @Varargs: tuples of state variable name, state variable type, and state + * variable value location, terminated with NULL. The state variable values + * should be freed after use. + * + * Parses the xml fragment from a LastChange event. + * + * Return value: TRUE on success. + **/ +gboolean +gupnp_last_change_parser_parse_last_change + (GUPnPLastChangeParser *parser, + guint instance_id, + const char *last_change_xml, + GError **error, + ...) +{ + va_list var_args; + gboolean ret; + + va_start (var_args, error); + ret = gupnp_last_change_parser_parse_last_change_valist + (parser, + instance_id, + last_change_xml, + error, + var_args); + va_end (var_args); + + return ret; +} + diff --git a/libgupnp-av/gupnp-last-change-parser.h b/libgupnp-av/gupnp-last-change-parser.h new file mode 100644 index 0000000..de82ebc --- /dev/null +++ b/libgupnp-av/gupnp-last-change-parser.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2007 Zeeshan Ali (Khattak) <zeeshanak@gnome.org> + * Copyright (C) 2007 OpenedHand Ltd + * + * Authors: Zeeshan Ali Khattak <zeenix@gstreamer.net> + * Jorn Baayen <jorn@openedhand.com> + * + * 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. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __GUPNP_LAST_CHANGE_PARSER_H__ +#define __GUPNP_LAST_CHANGE_PARSER_H__ + +#include <libgupnp/gupnp.h> + +G_BEGIN_DECLS + +GType +gupnp_last_change_parser_get_type (void) G_GNUC_CONST; + +#define GUPNP_TYPE_LAST_CHANGE_PARSER \ + (gupnp_last_change_parser_get_type ()) +#define GUPNP_LAST_CHANGE_PARSER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + GUPNP_TYPE_LAST_CHANGE_PARSER, \ + GUPnPLastChangeParser)) +#define GUPNP_LAST_CHANGE_PARSER_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_CAST ((obj), \ + GUPNP_TYPE_LAST_CHANGE_PARSER, \ + GUPnPLastChangeParserClass)) +#define GUPNP_IS_LAST_CHANGE_PARSER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + GUPNP_TYPE_LAST_CHANGE_PARSER)) +#define GUPNP_IS_LAST_CHANGE_PARSER_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE ((obj), \ + GUPNP_TYPE_LAST_CHANGE_PARSER)) +#define GUPNP_LAST_CHANGE_PARSER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + GUPNP_TYPE_LAST_CHANGE_PARSER, \ + GUPnPLastChangeParserClass)) + +typedef struct { + GObject parent; +} GUPnPLastChangeParser; + +typedef struct { + GObjectClass parent_class; + + /* future padding */ + void (* _gupnp_reserved1) (void); + void (* _gupnp_reserved2) (void); + void (* _gupnp_reserved3) (void); + void (* _gupnp_reserved4) (void); +} GUPnPLastChangeParserClass; + +GUPnPLastChangeParser * +gupnp_last_change_parser_new (void); + +gboolean +gupnp_last_change_parser_parse_last_change_valist + (GUPnPLastChangeParser *parser, + guint instance_id, + const char *last_change_xml, + GError **error, + va_list var_args); + +gboolean +gupnp_last_change_parser_parse_last_change + (GUPnPLastChangeParser *parser, + guint instance_id, + const char *last_change_xml, + GError **error, + ...) G_GNUC_NULL_TERMINATED; + +G_END_DECLS + +#endif /* __GUPNP_LAST_CHANGE_PARSER_H__ */ + diff --git a/libgupnp-av/gupnp-protocol-info.c b/libgupnp-av/gupnp-protocol-info.c new file mode 100644 index 0000000..73975c7 --- /dev/null +++ b/libgupnp-av/gupnp-protocol-info.c @@ -0,0 +1,1029 @@ +/* + * Copyright (C) 2009 Nokia Corporation. + * Copyright (C) 2007, 2008 OpenedHand Ltd. + * + * Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com> + * <zeeshanak@gnome.org> + * Jorn Baayen <jorn@openedhand.com> + * + * 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. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +/** + * SECTION:gupnp-protocol-info + * @short_description: UPnP AV ProtocolInfo + * + * #GUPnPProtocolInfo provides a convenient API to deal with ProtocolInfo + * strings used in UPnP AV specifications. + */ + +#include <string.h> +#include <stdlib.h> +#include <libgupnp/gupnp.h> +#include "gupnp-protocol-info.h" +#include "gupnp-av-error.h" + +G_DEFINE_TYPE (GUPnPProtocolInfo, + gupnp_protocol_info, + G_TYPE_OBJECT); + +struct _GUPnPProtocolInfoPrivate { + char *protocol; + char *network; + char *mime_type; + char *dlna_profile; + char **play_speeds; + + GUPnPDLNAConversion dlna_conversion; + GUPnPDLNAOperation dlna_operation; + GUPnPDLNAFlags dlna_flags; +}; + +enum { + PROP_0, + PROP_PROTOCOL, + PROP_NETWORK, + PROP_MIME_TYPE, + PROP_DLNA_PROFILE, + PROP_PLAY_SPEEDS, + + PROP_DLNA_CONVERSION, + PROP_DLNA_OPERATION, + PROP_DLNA_FLAGS +}; + +static void +parse_additional_info (const char *additional_info, + GUPnPProtocolInfo *info) +{ + GUPnPProtocolInfoPrivate *priv; + char **tokens = NULL; + short i; + + priv = info->priv; + + if (strcmp (additional_info, "*") == 0) + return; + + tokens = g_strsplit (additional_info, ";", -1); + if (tokens == NULL) { + g_warning ("Invalid additional info in DIDL-Lite info: %s", + additional_info); + + return; + } + + for (i = 0; tokens[i]; i++) { + char *p; + + p = g_strstr_len (tokens[i], + strlen (tokens[i]), + "DLNA.ORG_PN="); + if (p != NULL) { + p += 12; /* end of "DLNA.ORG_PN=" */ + gupnp_protocol_info_set_dlna_profile (info, p); + + continue; + } + + p = g_strstr_len (tokens[i], + strlen (tokens[i]), + "DLNA.ORG_PS="); + if (p != NULL) { + char **play_speeds; + + p += 12; /* end of "DLNA.ORG_PS=" */ + + play_speeds = g_strsplit (p, ",", -1); + gupnp_protocol_info_set_play_speeds + (info, + (const char **) play_speeds); + g_strfreev (play_speeds); + + continue; + } + + p = g_strstr_len (tokens[i], + strlen (tokens[i]), + "DLNA.ORG_CI="); + if (p != NULL) { + p += 12; /* end of "DLNA.ORG_CI=" */ + + gupnp_protocol_info_set_dlna_conversion (info, + atoi (p)); + + continue; + } + + p = g_strstr_len (tokens[i], + strlen (tokens[i]), + "DLNA.ORG_OP="); + if (p != NULL) { + p += 12; /* end of "DLNA.ORG_OP=" */ + + gupnp_protocol_info_set_dlna_operation + (info, + strtoul (p, NULL, 16)); + + continue; + } + + p = g_strstr_len (tokens[i], + strlen (tokens[i]), + "DLNA.ORG_FLAGS="); + if (p != NULL) { + p += 15; /* end of "DLNA.ORG_FLAGS=" */ + if (strlen (p) > 8) + p[8] = '\0'; + gupnp_protocol_info_set_dlna_flags + (info, + strtoul (p, NULL, 16)); + + continue; + } + } + + g_strfreev (tokens); +} + +static gboolean +is_transport_compat (GUPnPProtocolInfo *info1, + GUPnPProtocolInfo *info2) +{ + const char *protocol1; + const char *protocol2; + + protocol1 = gupnp_protocol_info_get_protocol (info1); + protocol2 = gupnp_protocol_info_get_protocol (info2); + + if (protocol1[0] != '*' && + protocol2[0] != '*' && + g_ascii_strcasecmp (protocol1, protocol2) != 0) + return FALSE; + else if (g_ascii_strcasecmp ("internal", protocol1) == 0 && + strcmp (gupnp_protocol_info_get_network (info1), + gupnp_protocol_info_get_network (info2)) != 0) + /* Host must be the same in case of INTERNAL protocol */ + return FALSE; + else + return TRUE; +} + +static gboolean +is_content_format_compat (GUPnPProtocolInfo *info1, + GUPnPProtocolInfo *info2) +{ + const char *mime_type1; + const char *mime_type2; + + mime_type1 = gupnp_protocol_info_get_mime_type (info1); + mime_type2 = gupnp_protocol_info_get_mime_type (info2); + + if (mime_type1 [0] != '*' && + mime_type2 [0] != '*' && + g_ascii_strcasecmp (mime_type1, mime_type2) != 0 && + /* Handle special case for LPCM: It is the only content type that + * make use of mime-type parameters that we know of. + * + * Example: audio/L16;rate=44100;channels=2 + */ + !((g_ascii_strcasecmp (mime_type1, "audio/L16") == 0 && + g_ascii_strncasecmp (mime_type2, "audio/L16", 9) == 0) || + (g_ascii_strcasecmp (mime_type2, "audio/L16") == 0 && + g_ascii_strncasecmp (mime_type1, "audio/L16", 9) == 0))) + return FALSE; + else + return TRUE; +} + +static gboolean +is_additional_info_compat (GUPnPProtocolInfo *info1, + GUPnPProtocolInfo *info2) +{ + const char *profile1; + const char *profile2; + + profile1 = gupnp_protocol_info_get_dlna_profile (info1); + profile2 = gupnp_protocol_info_get_dlna_profile (info2); + + if (profile1 == NULL || + profile2 == NULL || + profile1 [0] == '*' || + profile2 [0] == '*' || + g_ascii_strcasecmp (profile1, profile2) == 0) + return TRUE; + else + return FALSE; +} + +static void +add_dlna_info (GString *str, + GUPnPProtocolInfo *info) +{ + const char *dlna_profile; + const char **speeds; + GUPnPDLNAConversion conversion; + GUPnPDLNAOperation operation; + GUPnPDLNAFlags flags; + + dlna_profile = gupnp_protocol_info_get_dlna_profile (info); + if (dlna_profile == NULL) { + g_string_append_printf (str, ":"); + } else { + g_string_append_printf (str, ":DLNA.ORG_PN=%s;", dlna_profile); + } + + operation = gupnp_protocol_info_get_dlna_operation (info); + if (operation != GUPNP_DLNA_OPERATION_NONE && + /* the OP parameter is only allowed for the "http-get" + * and "rtsp-rtp-udp" protocols + */ + (strcmp (gupnp_protocol_info_get_protocol (info), + "http-get") == 0 || + strcmp (gupnp_protocol_info_get_protocol (info), + "rtsp-rtp-udp") == 0)) + g_string_append_printf (str, "DLNA.ORG_OP=%.2x;", operation); + + /* Specify PS parameter if list of play speeds is provided */ + speeds = gupnp_protocol_info_get_play_speeds (info); + if (speeds != NULL) { + int i; + + g_string_append_printf (str, "DLNA.ORG_PS=;"); + + for (i = 0; speeds[i]; i++) { + g_string_append (str, speeds[i]); + + if (speeds[i + 1]) + g_string_append_c (str, ','); + } + } + + conversion = gupnp_protocol_info_get_dlna_conversion (info); + /* omit the CI parameter for non-converted content */ + if (conversion != GUPNP_DLNA_CONVERSION_NONE) + g_string_append_printf (str, "DLNA.ORG_CI=%d;", conversion); + + flags = gupnp_protocol_info_get_dlna_flags (info); + /* Omit the FLAGS parameter if no or DLNA profile are set */ + if (flags != GUPNP_DLNA_FLAGS_NONE && dlna_profile != NULL) { + g_string_append_printf (str, "DLNA.ORG_FLAGS=%.8x", flags); + /* append 24 reserved hex-digits */ + g_string_append_printf (str, + "0000" "0000" "0000" + "0000" "0000" "0000"); + } + + /* if nothing of the above was set, use the "match all" rule */ + switch (str->str[str->len - 1]) { + case ':': + g_string_append_c (str, '*'); + break; + case ';': + g_string_erase (str, str->len - 1, 1); + break; + default: + break; + } +} + +static void +gupnp_protocol_info_init (GUPnPProtocolInfo *info) +{ + info->priv = G_TYPE_INSTANCE_GET_PRIVATE + (info, + GUPNP_TYPE_PROTOCOL_INFO, + GUPnPProtocolInfoPrivate); + + info->priv->dlna_conversion = GUPNP_DLNA_CONVERSION_NONE; + info->priv->dlna_operation = GUPNP_DLNA_OPERATION_NONE; + info->priv->dlna_flags = GUPNP_DLNA_FLAGS_NONE; +} + +static void +gupnp_protocol_info_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + GUPnPProtocolInfo *info; + + info = GUPNP_PROTOCOL_INFO (object); + + switch (property_id) { + case PROP_PROTOCOL: + gupnp_protocol_info_set_protocol (info, + g_value_get_string (value)); + break; + case PROP_NETWORK: + gupnp_protocol_info_set_network (info, + g_value_get_string (value)); + break; + case PROP_MIME_TYPE: + gupnp_protocol_info_set_mime_type (info, + g_value_get_string (value)); + break; + case PROP_DLNA_PROFILE: + gupnp_protocol_info_set_dlna_profile + (info, + g_value_get_string (value)); + break; + case PROP_PLAY_SPEEDS: + gupnp_protocol_info_set_play_speeds (info, + g_value_get_boxed (value)); + break; + case PROP_DLNA_CONVERSION: + gupnp_protocol_info_set_dlna_conversion + (info, + g_value_get_flags (value)); + break; + case PROP_DLNA_OPERATION: + gupnp_protocol_info_set_dlna_operation + (info, + g_value_get_flags (value)); + break; + case PROP_DLNA_FLAGS: + gupnp_protocol_info_set_dlna_flags + (info, + g_value_get_flags (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gupnp_protocol_info_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + GUPnPProtocolInfo *info; + + info = GUPNP_PROTOCOL_INFO (object); + + switch (property_id) { + case PROP_PROTOCOL: + g_value_set_string (value, + gupnp_protocol_info_get_protocol (info)); + break; + case PROP_NETWORK: + g_value_set_string (value, + gupnp_protocol_info_get_network (info)); + break; + case PROP_MIME_TYPE: + g_value_set_string (value, + gupnp_protocol_info_get_mime_type (info)); + break; + case PROP_DLNA_PROFILE: + g_value_set_string + (value, + gupnp_protocol_info_get_dlna_profile (info)); + break; + case PROP_PLAY_SPEEDS: + g_value_set_boxed (value, + gupnp_protocol_info_get_play_speeds (info)); + break; + case PROP_DLNA_CONVERSION: + g_value_set_flags + (value, + gupnp_protocol_info_get_dlna_conversion + (info)); + break; + case PROP_DLNA_OPERATION: + g_value_set_flags + (value, + gupnp_protocol_info_get_dlna_operation (info)); + break; + case PROP_DLNA_FLAGS: + g_value_set_flags (value, + gupnp_protocol_info_get_dlna_flags (info)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gupnp_protocol_info_finalize (GObject *object) +{ + GObjectClass *object_class; + GUPnPProtocolInfoPrivate *priv; + + priv = GUPNP_PROTOCOL_INFO (object)->priv; + + if (priv->protocol) + g_free (priv->protocol); + if (priv->network) + g_free (priv->network); + if (priv->mime_type) + g_free (priv->mime_type); + if (priv->dlna_profile) + g_free (priv->dlna_profile); + if (priv->play_speeds) + g_strfreev (priv->play_speeds); + + object_class = G_OBJECT_CLASS (gupnp_protocol_info_parent_class); + object_class->finalize (object); +} + +static void +gupnp_protocol_info_class_init (GUPnPProtocolInfoClass *klass) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (klass); + + object_class->set_property = gupnp_protocol_info_set_property; + object_class->get_property = gupnp_protocol_info_get_property; + object_class->finalize = gupnp_protocol_info_finalize; + + g_type_class_add_private (klass, sizeof (GUPnPProtocolInfoPrivate)); + + /** + * GUPnPProtocolInfo:protocol: + * + * The protocol of this info. + **/ + g_object_class_install_property + (object_class, + PROP_PROTOCOL, + g_param_spec_string ("protocol", + "Protocol", + "The protocol of this info.", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPProtocolInfo:network: + * + * The network this info is associated with. + **/ + g_object_class_install_property + (object_class, + PROP_NETWORK, + g_param_spec_string ("network", + "Network", + "The network this info is associated" + " with.", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPProtocolInfo:mime-type: + * + * The MIME-type of this info. + **/ + g_object_class_install_property + (object_class, + PROP_MIME_TYPE, + g_param_spec_string ("mime-type", + "MIMEType", + "The MIME-type of this info.", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPProtocolInfo:dlna-profile: + * + * The DLNA profile of this info. + **/ + g_object_class_install_property + (object_class, + PROP_DLNA_PROFILE, + g_param_spec_string ("dlna-profile", + "DLNAProfile", + "The DLNA profile of this info.", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPProtocolInfo:play-speeds: + * + * The allowed play speeds on this info in the form of array of + * strings. + **/ + g_object_class_install_property + (object_class, + PROP_PLAY_SPEEDS, + g_param_spec_boxed ("play-speeds", + "PlaySpeeds", + "The allowed play speeds on this" + " info in the form of array of" + " strings.", + G_TYPE_STRV, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPProtocolInfo:dlna-conversion: + * + * The DLNA conversion flags. + **/ + g_object_class_install_property + (object_class, + PROP_DLNA_CONVERSION, + g_param_spec_flags ("dlna-conversion", + "DLNAConversion", + "The DLNA conversion flags.", + GUPNP_TYPE_DLNA_CONVERSION, + GUPNP_DLNA_CONVERSION_NONE, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPProtocolInfo:dlna-operation: + * + * The DLNA operation flags. + **/ + g_object_class_install_property + (object_class, + PROP_DLNA_OPERATION, + g_param_spec_flags ("dlna-operation", + "DLNAOperation", + "The DLNA operation flags.", + GUPNP_TYPE_DLNA_OPERATION, + GUPNP_DLNA_OPERATION_NONE, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * GUPnPProtocolInfo:dlna-flags: + * + * Various generic DLNA flags. + **/ + g_object_class_install_property + (object_class, + PROP_DLNA_FLAGS, + g_param_spec_flags ("dlna-flags", + "DLNAFlags", + "Various generic DLNA flags.", + GUPNP_TYPE_DLNA_FLAGS, + GUPNP_DLNA_FLAGS_NONE, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); +} + +/** + * gupnp_protocol_info_new: + * + * Return value: A new #GUPnPProtocolInfo object. Unref after usage. + **/ +GUPnPProtocolInfo * +gupnp_protocol_info_new () +{ + return g_object_new (GUPNP_TYPE_PROTOCOL_INFO, + NULL); +} + +/** + * gupnp_protocol_info_new_from_string: + * @protocol_info: The protocol info string + * @error: The location where to store any error, or NULL + * + * Parses the @protocol_info string and creates a new #GUPnPProtocolInfo object + * as a result. + * + * Return value: A new #GUPnPProtocolInfo object. Unref after usage. + **/ +GUPnPProtocolInfo * +gupnp_protocol_info_new_from_string (const char *protocol_info, + GError **error) +{ + GUPnPProtocolInfo *info; + char **tokens; + + g_return_val_if_fail (protocol_info != NULL, NULL); + + tokens = g_strsplit (protocol_info, ":", 4); + if (tokens[0] == NULL || + tokens[1] == NULL || + tokens[2] == NULL || + tokens[3] == NULL) { + g_set_error (error, + GUPNP_PROTOCOL_ERROR, + GUPNP_PROTOCOL_ERROR_INVALID_SYNTAX, + "Failed to parse protocolInfo string: \n%s", + protocol_info); + + g_strfreev (tokens); + + return NULL; + } + + info = gupnp_protocol_info_new (); + + gupnp_protocol_info_set_protocol (info, tokens[0]); + gupnp_protocol_info_set_network (info, tokens[1]); + gupnp_protocol_info_set_mime_type (info, tokens[2]); + + parse_additional_info (tokens[3], info); + + g_strfreev (tokens); + + return info; +} + +/** + * gupnp_protocol_info_to_string: + * @info: The #GUPnPProtocolInfo + * + * Provides the string representation of @info. + * + * Return value: String representation of @info. #g_free after usage. + **/ +char * +gupnp_protocol_info_to_string (GUPnPProtocolInfo *info) +{ + GString *str; + const char *protocol; + const char *mime_type; + const char *network; + + g_return_val_if_fail (GUPNP_IS_PROTOCOL_INFO (info), NULL); + + protocol = gupnp_protocol_info_get_protocol (info); + mime_type = gupnp_protocol_info_get_mime_type (info); + network = gupnp_protocol_info_get_network (info); + + g_return_val_if_fail (protocol != NULL, NULL); + g_return_val_if_fail (mime_type != NULL, NULL); + + str = g_string_new (""); + + g_string_append (str, protocol); + g_string_append_c (str, ':'); + if (network != NULL) + g_string_append (str, network); + else + g_string_append_c (str, '*'); + g_string_append_c (str, ':'); + g_string_append (str, mime_type); + + add_dlna_info (str, info); + + return g_string_free (str, FALSE); +} + +/** + * gupnp_protocol_info_get_protocol: + * @info: A #GUPnPProtocolInfo + * + * Get the protocol of this info. + * + * Return value: The protocol of this info or %NULL. This string should not + * be freed. + **/ +const char * +gupnp_protocol_info_get_protocol (GUPnPProtocolInfo *info) +{ + g_return_val_if_fail (GUPNP_IS_PROTOCOL_INFO (info), NULL); + + return info->priv->protocol; +} + +/** + * gupnp_protocol_info_get_network: + * @info: A #GUPnPProtocolInfo + * + * Get the network this info is associated with. + * + * Return value: The network string or %NULL. This string should not be freed. + **/ +const char * +gupnp_protocol_info_get_network (GUPnPProtocolInfo *info) +{ + g_return_val_if_fail (GUPNP_IS_PROTOCOL_INFO (info), NULL); + + return info->priv->network; +} + +/** + * gupnp_protocol_info_get_mime_type: + * @info: A #GUPnPProtocolInfo + * + * Get the MIME-type of this info. + * + * Return value: The MIME-type of this info or %NULL. This string should not + * be freed. + **/ +const char * +gupnp_protocol_info_get_mime_type (GUPnPProtocolInfo *info) +{ + g_return_val_if_fail (GUPNP_IS_PROTOCOL_INFO (info), NULL); + + return info->priv->mime_type; +} + +/** + * gupnp_protocol_info_get_dlna_profile: + * @info: A #GUPnPProtocolInfo + * + * Get the DLNA profile of this info. + * + * Return value: The DLNA profile of this info or %NULL. This string should + * not be freed. + **/ +const char * +gupnp_protocol_info_get_dlna_profile (GUPnPProtocolInfo *info) +{ + g_return_val_if_fail (GUPNP_IS_PROTOCOL_INFO (info), NULL); + + return info->priv->dlna_profile; +} + +/** + * gupnp_protocol_info_get_play_speeds: + * @info: A #GUPnPProtocolInfo + * + * Get the allowed play speeds on this info in the form of array of strings. + * + * Returns: (transfer none): The allowed play speeds as array of strings or %NULL. This + * return array and it's content must not be modified or freed. + **/ +const char ** +gupnp_protocol_info_get_play_speeds (GUPnPProtocolInfo *info) +{ + g_return_val_if_fail (GUPNP_IS_PROTOCOL_INFO (info), NULL); + + return (const char **) info->priv->play_speeds; +} + +/** + * gupnp_protocol_info_get_dlna_conversion: + * @info: A #GUPnPProtocolInfo + * + * Get the DLNA conversion flags. + * + * Return value: The DLNA conversion flags. + **/ +GUPnPDLNAConversion +gupnp_protocol_info_get_dlna_conversion (GUPnPProtocolInfo *info) +{ + g_return_val_if_fail (GUPNP_IS_PROTOCOL_INFO (info), + GUPNP_DLNA_CONVERSION_NONE); + + return info->priv->dlna_conversion; +} + +/** + * gupnp_protocol_info_get_dlna_operation: + * @info: A #GUPnPProtocolInfo + * + * Get the DLNA operation flags. + * + * Return value: The DLNA operation flags. + **/ +GUPnPDLNAOperation +gupnp_protocol_info_get_dlna_operation (GUPnPProtocolInfo *info) +{ + g_return_val_if_fail (GUPNP_IS_PROTOCOL_INFO (info), + GUPNP_DLNA_OPERATION_NONE); + + return info->priv->dlna_operation; +} + +/** + * gupnp_protocol_info_get_dlna_flags: + * @info: A #GUPnPProtocolInfo + * + * Get the gereric DLNA flags. + * + * Return value: The generic DLNA flags. + **/ +GUPnPDLNAFlags +gupnp_protocol_info_get_dlna_flags (GUPnPProtocolInfo *info) +{ + g_return_val_if_fail (GUPNP_IS_PROTOCOL_INFO (info), + GUPNP_DLNA_FLAGS_NONE); + + return info->priv->dlna_flags; +} + +/** + * gupnp_protocol_info_set_protocol: + * @info: A #GUPnPProtocolInfo + * @protocol: The protocol string + * + * Set the protocol of this info. + * + * Return value: None. + **/ +void +gupnp_protocol_info_set_protocol (GUPnPProtocolInfo *info, + const char *protocol) +{ + g_return_if_fail (GUPNP_IS_PROTOCOL_INFO (info)); + + if (info->priv->protocol) + g_free (info->priv->protocol); + info->priv->protocol = g_strdup (protocol); + + g_object_notify (G_OBJECT (info), "protocol"); +} + +/** + * gupnp_protocol_info_set_network: + * @info: A #GUPnPProtocolInfo + * @network: The network string + * + * Set the network this info is associated with. + * + * Return value: None. + **/ +void +gupnp_protocol_info_set_network (GUPnPProtocolInfo *info, + const char *network) +{ + g_return_if_fail (GUPNP_IS_PROTOCOL_INFO (info)); + + if (info->priv->network) + g_free (info->priv->network); + info->priv->network = g_strdup (network); + + g_object_notify (G_OBJECT (info), "network"); +} + +/** + * gupnp_protocol_info_set_mime_type: + * @info: A #GUPnPProtocolInfo + * @mime_type: The MIME-type string + * + * Set the MIME-type of this info. + * + * Return value: None. + **/ +void +gupnp_protocol_info_set_mime_type (GUPnPProtocolInfo *info, + const char *mime_type) +{ + g_return_if_fail (GUPNP_IS_PROTOCOL_INFO (info)); + + if (info->priv->mime_type) + g_free (info->priv->mime_type); + info->priv->mime_type = g_strdup (mime_type); + + g_object_notify (G_OBJECT (info), "mime-type"); +} + +/** + * gupnp_protocol_info_set_dlna_profile: + * @info: A #GUPnPProtocolInfo + * @profile: The DLNA profile string + * + * Set the DLNA profile of this info. + * + * Return value: None. + **/ +void +gupnp_protocol_info_set_dlna_profile (GUPnPProtocolInfo *info, + const char *profile) +{ + g_return_if_fail (GUPNP_IS_PROTOCOL_INFO (info)); + + if (info->priv->dlna_profile) + g_free (info->priv->dlna_profile); + info->priv->dlna_profile = g_strdup (profile); + + g_object_notify (G_OBJECT (info), "dlna-profile"); +} + +/** + * gupnp_protocol_info_set_play_speeds: + * @info: A #GUPnPProtocolInfo + * @speeds: The allowed play speeds + * + * Set the allowed play speeds on this info in the form of array of strings. + * + * Return value: None. + **/ +void +gupnp_protocol_info_set_play_speeds (GUPnPProtocolInfo *info, + const char **speeds) +{ + g_return_if_fail (GUPNP_IS_PROTOCOL_INFO (info)); + + if (info->priv->play_speeds) + g_strfreev (info->priv->play_speeds); + info->priv->play_speeds = (char **) g_boxed_copy (G_TYPE_STRV, speeds); + + g_object_notify (G_OBJECT (info), "play-speeds"); +} + +/** + * gupnp_protocol_info_set_dlna_conversion: + * @info: A #GUPnPProtocolInfo + * @conversion: The bitwise OR of one or more DLNA conversion flags + * + * Set the DLNA conversion flags. + * + * Return value: None. + **/ +void +gupnp_protocol_info_set_dlna_conversion (GUPnPProtocolInfo *info, + GUPnPDLNAConversion conversion) +{ + g_return_if_fail (GUPNP_IS_PROTOCOL_INFO (info)); + + info->priv->dlna_conversion = conversion; + + g_object_notify (G_OBJECT (info), "dlna-conversion"); +} + +/** + * gupnp_protocol_info_set_dlna_operation: + * @info: A #GUPnPProtocolInfo + * @operation: The bitwise OR of one or more DLNA operation flags + * + * Set the DLNA operation flags. + * + * Return value: None. + **/ +void +gupnp_protocol_info_set_dlna_operation (GUPnPProtocolInfo *info, + GUPnPDLNAOperation operation) +{ + g_return_if_fail (GUPNP_IS_PROTOCOL_INFO (info)); + + info->priv->dlna_operation = operation; + + g_object_notify (G_OBJECT (info), "dlna-operation"); +} + +/** + * gupnp_protocol_info_set_dlna_flags: + * @info: A #GUPnPProtocolInfo + * @flags: The bitwise OR of one or more generic DLNA flags + * + * Set the gereric DLNA flags. + * + * Return value: None. + **/ +void +gupnp_protocol_info_set_dlna_flags (GUPnPProtocolInfo *info, + GUPnPDLNAFlags flags) +{ + g_return_if_fail (GUPNP_IS_PROTOCOL_INFO (info)); + + info->priv->dlna_flags = flags; + + g_object_notify (G_OBJECT (info), "dlna-flags"); +} + +/** + * gupnp_protocol_info_is_compatible: + * @info1: The first #GUPnPProtocolInfo + * @info2: The second #GUPnPProtocolInfo + * + * Checks if the given protocolInfo string is compatible with @info. + * + * Return value: #TRUE if @protocol_info is compatible with @info, otherwise + * #FALSE. + **/ +gboolean +gupnp_protocol_info_is_compatible (GUPnPProtocolInfo *info1, + GUPnPProtocolInfo *info2) +{ + g_return_val_if_fail (GUPNP_IS_PROTOCOL_INFO (info1), FALSE); + g_return_val_if_fail (GUPNP_IS_PROTOCOL_INFO (info2), FALSE); + + return is_transport_compat (info1, info2) && + is_content_format_compat (info1, info2) && + is_additional_info_compat (info1, info2); +} + diff --git a/libgupnp-av/gupnp-protocol-info.h b/libgupnp-av/gupnp-protocol-info.h new file mode 100644 index 0000000..078ad4e --- /dev/null +++ b/libgupnp-av/gupnp-protocol-info.h @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2009 Nokia Corporation. + * Copyright (C) 2007, 2008 OpenedHand Ltd. + * + * Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com> + * <zeeshanak@gnome.org> + * Jorn Baayen <jorn@openedhand.com> + * + * 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. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __GUPNP_PROTOCOL_INFO_H__ +#define __GUPNP_PROTOCOL_INFO_H__ + +#include <stdarg.h> +#include <glib-object.h> + +#include "gupnp-dlna.h" + +G_BEGIN_DECLS + +GType +gupnp_protocol_info_get_type (void) G_GNUC_CONST; + +#define GUPNP_TYPE_PROTOCOL_INFO \ + (gupnp_protocol_info_get_type ()) +#define GUPNP_PROTOCOL_INFO(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + GUPNP_TYPE_PROTOCOL_INFO, \ + GUPnPProtocolInfo)) +#define GUPNP_PROTOCOL_INFO_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_CAST ((obj), \ + GUPNP_TYPE_PROTOCOL_INFO, \ + GUPnPProtocolInfoClass)) +#define GUPNP_IS_PROTOCOL_INFO(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + GUPNP_TYPE_PROTOCOL_INFO)) +#define GUPNP_IS_PROTOCOL_INFO_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE ((obj), \ + GUPNP_TYPE_PROTOCOL_INFO)) +#define GUPNP_PROTOCOL_INFO_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + GUPNP_TYPE_PROTOCOL_INFO, \ + GUPnPProtocolInfoClass)) + +typedef struct _GUPnPProtocolInfoPrivate GUPnPProtocolInfoPrivate; + +typedef struct { + GObject parent; + + GUPnPProtocolInfoPrivate *priv; +} GUPnPProtocolInfo; + +typedef struct { + GObjectClass parent_class; + + /* future padding */ + void (* _gupnp_reserved1) (void); + void (* _gupnp_reserved2) (void); + void (* _gupnp_reserved3) (void); + void (* _gupnp_reserved4) (void); +} GUPnPProtocolInfoClass; + +GUPnPProtocolInfo * +gupnp_protocol_info_new (void); + +GUPnPProtocolInfo * +gupnp_protocol_info_new_from_string (const char *protocol_info, + GError **error); + +char * +gupnp_protocol_info_to_string (GUPnPProtocolInfo *info); + +gboolean +gupnp_protocol_info_is_compatible (GUPnPProtocolInfo *info1, + GUPnPProtocolInfo *info2); + +void +gupnp_protocol_info_set_protocol (GUPnPProtocolInfo *info, + const char *protocol); + +void +gupnp_protocol_info_set_network (GUPnPProtocolInfo *info, + const char *network); + +void +gupnp_protocol_info_set_mime_type (GUPnPProtocolInfo *info, + const char *mime_type); + +void +gupnp_protocol_info_set_dlna_profile (GUPnPProtocolInfo *info, + const char *profile); + +void +gupnp_protocol_info_set_play_speeds (GUPnPProtocolInfo *info, + const char **speeds); + +void +gupnp_protocol_info_set_dlna_conversion (GUPnPProtocolInfo *info, + GUPnPDLNAConversion conversion); + +void +gupnp_protocol_info_set_dlna_operation (GUPnPProtocolInfo *info, + GUPnPDLNAOperation operation); + +void +gupnp_protocol_info_set_dlna_flags (GUPnPProtocolInfo *info, + GUPnPDLNAFlags flags); + +const char * +gupnp_protocol_info_get_protocol (GUPnPProtocolInfo *info); + +const char * +gupnp_protocol_info_get_network (GUPnPProtocolInfo *info); + +const char * +gupnp_protocol_info_get_mime_type (GUPnPProtocolInfo *info); + +const char * +gupnp_protocol_info_get_dlna_profile (GUPnPProtocolInfo *info); + +const char ** +gupnp_protocol_info_get_play_speeds (GUPnPProtocolInfo *info); + +GUPnPDLNAConversion +gupnp_protocol_info_get_dlna_conversion (GUPnPProtocolInfo *info); + +GUPnPDLNAOperation +gupnp_protocol_info_get_dlna_operation (GUPnPProtocolInfo *info); + +GUPnPDLNAFlags +gupnp_protocol_info_get_dlna_flags (GUPnPProtocolInfo *info); + +G_END_DECLS + +#endif /* __GUPNP_PROTOCOL_INFO_H__ */ diff --git a/libgupnp-av/gupnp-search-criteria-parser.c b/libgupnp-av/gupnp-search-criteria-parser.c new file mode 100644 index 0000000..9e4dbda --- /dev/null +++ b/libgupnp-av/gupnp-search-criteria-parser.c @@ -0,0 +1,607 @@ +/* + * Copyright (C) 2008 OpenedHand Ltd. + * + * Authors: Jorn Baayen <jorn@openedhand.com> + * + * 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. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +/** + * SECTION:gupnp-search-criteria-parser + * @short_description: A/V search criteria parser + * + * #GUPnPSearchCriteriaParser parses ContentDirectory search criteria + * strings. + * + * Note that no signals will be emitted if a wildcard is specified, + * and that the user is responsible for ensuring precedence of conjunction + * over disjunction. + */ + +#include <string.h> + +#include "gupnp-search-criteria-parser.h" +#include "gupnp-av-marshal.h" + +/* GType for GUPNPSearchCriteriaOp */ +GType +gupnp_search_criteria_op_get_type (void) +{ + static GType type = 0; + + if (type == 0) { + static const GEnumValue values[] = { + { GUPNP_SEARCH_CRITERIA_OP_EQ, + "GUPNP_SEARCH_CRITERIA_OP_EQ", + "none" }, + { GUPNP_SEARCH_CRITERIA_OP_NEQ, + "GUPNP_SEARCH_CRITERIA_OP_NEQ", + "none" }, + { GUPNP_SEARCH_CRITERIA_OP_LESS, + "GUPNP_SEARCH_CRITERIA_OP_LESS", + "none" }, + { GUPNP_SEARCH_CRITERIA_OP_LEQ, + "GUPNP_SEARCH_CRITERIA_OP_LEQ", + "none" }, + { GUPNP_SEARCH_CRITERIA_OP_GREATER, + "GUPNP_SEARCH_CRITERIA_OP_GREATER", + "none" }, + { GUPNP_SEARCH_CRITERIA_OP_GEQ, + "GUPNP_SEARCH_CRITERIA_OP_GEQ", + "none" }, + { GUPNP_SEARCH_CRITERIA_OP_CONTAINS, + "GUPNP_SEARCH_CRITERIA_OP_CONTAINS", + "none" }, + { GUPNP_SEARCH_CRITERIA_OP_DOES_NOT_CONTAIN, + "GUPNP_SEARCH_CRITERIA_OP_DOES_NOT_CONTAIN", + "none" }, + { GUPNP_SEARCH_CRITERIA_OP_DERIVED_FROM, + "GUPNP_SEARCH_CRITERIA_OP_DERIVED_FROM", + "none" }, + { GUPNP_SEARCH_CRITERIA_OP_EXISTS, + "GUPNP_SEARCH_CRITERIA_OP_EXISTS", + "none" }, + { 0, NULL, NULL } + }; + + type = g_enum_register_static + (g_intern_static_string ( + "GUPnPSearchCriteriaOp"), + values); + } + + return type; +} + +/* GUPnPSearchCriteriaParserError */ +GQuark +gupnp_search_criteria_parser_error_quark (void) +{ + return g_quark_from_static_string + ("gupnp-search-criteria-parser-error-quark"); +} + +/* GUPnPSearchCriteriaParser */ +G_DEFINE_TYPE (GUPnPSearchCriteriaParser, + gupnp_search_criteria_parser, + G_TYPE_OBJECT); + +struct _GUPnPSearchCriteriaParserPrivate { + GScanner *scanner; +}; + +enum { + BEGIN_PARENS, + END_PARENS, + CONJUNCTION, + DISJUNCTION, + EXPRESSION, + SIGNAL_LAST +}; + +static guint signals[SIGNAL_LAST]; + +/* Additional parsable symbols */ +enum { + SYMBOL_ASTERISK = G_TOKEN_LAST + 11, + SYMBOL_AND = G_TOKEN_LAST + 12, + SYMBOL_OR = G_TOKEN_LAST + 13, + SYMBOL_TRUE = G_TOKEN_LAST + 14, + SYMBOL_FALSE = G_TOKEN_LAST + 15 +}; + +#define NUM_SYMBOLS 15 + +struct { + const char *name; + int token; +} symbols[NUM_SYMBOLS] = { + { "*", + SYMBOL_ASTERISK }, + + { "and", + SYMBOL_AND }, + { "or", + SYMBOL_OR }, + + { "=", + GUPNP_SEARCH_CRITERIA_OP_EQ }, + { "!=", + GUPNP_SEARCH_CRITERIA_OP_NEQ }, + { "<", + GUPNP_SEARCH_CRITERIA_OP_LESS }, + { "<=", + GUPNP_SEARCH_CRITERIA_OP_LEQ }, + { ">", + GUPNP_SEARCH_CRITERIA_OP_GREATER }, + { ">=", + GUPNP_SEARCH_CRITERIA_OP_GEQ }, + + { "contains", + GUPNP_SEARCH_CRITERIA_OP_CONTAINS }, + { "doesNotContain", + GUPNP_SEARCH_CRITERIA_OP_DOES_NOT_CONTAIN }, + { "derivedfrom", + GUPNP_SEARCH_CRITERIA_OP_DERIVED_FROM }, + + { "exists", + GUPNP_SEARCH_CRITERIA_OP_EXISTS }, + + { "true", + SYMBOL_TRUE }, + { "false", + SYMBOL_FALSE } +}; + +static void +gupnp_search_criteria_parser_init (GUPnPSearchCriteriaParser *parser) +{ + int i; + + parser->priv = G_TYPE_INSTANCE_GET_PRIVATE + (parser, + GUPNP_TYPE_SEARCH_CRITERIA_PARSER, + GUPnPSearchCriteriaParserPrivate); + + /* Set up GScanner */ + parser->priv->scanner = g_scanner_new (NULL); + + parser->priv->scanner->config->cset_skip_characters = " \t\n\r\012" + "\013\014\015"; + parser->priv->scanner->config->scan_identifier_1char = TRUE; + parser->priv->scanner->config->cset_identifier_first = G_CSET_a_2_z + "_*<>=!@" + G_CSET_A_2_Z; + parser->priv->scanner->config->cset_identifier_nth = G_CSET_a_2_z + "_0123456789=:@" + G_CSET_A_2_Z + G_CSET_LATINS + G_CSET_LATINC; + parser->priv->scanner->config->symbol_2_token = TRUE; + + /* Add symbols */ + for (i = 0; i < NUM_SYMBOLS; i++) { + g_scanner_scope_add_symbol (parser->priv->scanner, + 0, + symbols[i].name, + GINT_TO_POINTER (symbols[i].token)); + } +} + +static void +gupnp_search_criteria_parser_finalize (GObject *object) +{ + GObjectClass *gobject_class; + GUPnPSearchCriteriaParser *parser; + + parser = GUPNP_SEARCH_CRITERIA_PARSER (object); + + /* Destroy GScanner */ + g_scanner_destroy (parser->priv->scanner); + + gobject_class = + G_OBJECT_CLASS (gupnp_search_criteria_parser_parent_class); + gobject_class->dispose (object); +} + +static void +gupnp_search_criteria_parser_class_init + (GUPnPSearchCriteriaParserClass *klass) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gupnp_search_criteria_parser_finalize; + + /** + * GUPnPSearchCriteriaParser::begin-parens: + * @parser: The #GUPnPSearchCriteriaParser that received the signal + * + * The ::begin_parens signal is emitted to mark the beginning of a + * parenthetical expression. + **/ + signals[BEGIN_PARENS] = + g_signal_new ("begin-parens", + GUPNP_TYPE_SEARCH_CRITERIA_PARSER, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GUPnPSearchCriteriaParserClass, + begin_parens), + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + /** + * GUPnPSearchCriteriaParser::end-parens: + * @parser: The #GUPnPSearchCriteriaParser that received the signal + * + * The ::end_parens signal is emitted to mark the end of a parenthetical + * expression. + **/ + signals[END_PARENS] = + g_signal_new ("end-parens", + GUPNP_TYPE_SEARCH_CRITERIA_PARSER, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GUPnPSearchCriteriaParserClass, + end_parens), + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + /** + * GUPnPSearchCriteriaParser::conjunction: + * @parser: The #GUPnPSearchCriteriaParser that received the signal + * + * The ::conjuction signal is emitted whenever a conjuction marker + * (and) is parsed. + **/ + signals[CONJUNCTION] = + g_signal_new ("conjunction", + GUPNP_TYPE_SEARCH_CRITERIA_PARSER, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GUPnPSearchCriteriaParserClass, + conjunction), + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + /** + * GUPnPSearchCriteriaParser::disjunction: + * @parser: The #GUPnPSearchCriteriaParser that received the signal + * + * The ::disjuction signal is emitted whenever a disjuction marker + * (or&rpar is parsed. + **/ + signals[DISJUNCTION] = + g_signal_new ("disjunction", + GUPNP_TYPE_SEARCH_CRITERIA_PARSER, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GUPnPSearchCriteriaParserClass, + disjunction), + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + /** + * GUPnPSearchCriteriaParser::expression: + * @parser: The #GUPnPSearchCriteriaParser that received the signal + * @property: The property + * @op: The operator as #GUPnPSearchCriteriaOp + * @value: The value as string + * @error: Place-holder for any possible errors from handler + * + * The ::expression signal is emitted whenever an expression is parsed. + * Set @error and return %FALSE if an error occurred. + **/ + signals[EXPRESSION] = + g_signal_new ("expression", + GUPNP_TYPE_SEARCH_CRITERIA_PARSER, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GUPnPSearchCriteriaParserClass, + expression), + NULL, + NULL, + gupnp_av_marshal_BOOLEAN__STRING_UINT_STRING_POINTER, + G_TYPE_BOOLEAN, + 4, + G_TYPE_STRING, + GUPNP_TYPE_SEARCH_CRITERIA_OP, + G_TYPE_STRING, + G_TYPE_POINTER); + + g_type_class_add_private (klass, + sizeof (GUPnPSearchCriteriaParserPrivate)); +} + +/** + * gupnp_search_criteria_parser_new: + * + * Return value: A new #GUPnPSearchCriteriaParser object. + **/ +GUPnPSearchCriteriaParser * +gupnp_search_criteria_parser_new (void) +{ + return g_object_new (GUPNP_TYPE_SEARCH_CRITERIA_PARSER, NULL); +} + +/* Scan a relExp portion of a search criteria string */ +static gboolean +scan_rel_exp (GUPnPSearchCriteriaParser *parser, + GError **error) +{ + GTokenValue value; + gboolean ret; + guint token; + GUPnPSearchCriteriaOp op; + char *arg1; + + token = g_scanner_get_next_token (parser->priv->scanner); + g_assert (token == G_TOKEN_IDENTIFIER); /* Already checked */ + + value = g_scanner_cur_value (parser->priv->scanner); + arg1 = g_strdup (value.v_string); + + token = g_scanner_get_next_token (parser->priv->scanner); + switch (token) { + case GUPNP_SEARCH_CRITERIA_OP_EQ: + case GUPNP_SEARCH_CRITERIA_OP_NEQ: + case GUPNP_SEARCH_CRITERIA_OP_LESS: + case GUPNP_SEARCH_CRITERIA_OP_LEQ: + case GUPNP_SEARCH_CRITERIA_OP_GREATER: + case GUPNP_SEARCH_CRITERIA_OP_GEQ: + case GUPNP_SEARCH_CRITERIA_OP_CONTAINS: + case GUPNP_SEARCH_CRITERIA_OP_DOES_NOT_CONTAIN: + case GUPNP_SEARCH_CRITERIA_OP_DERIVED_FROM: + op = token; + + token = g_scanner_get_next_token (parser->priv->scanner); + if (token != G_TOKEN_STRING) { + g_set_error + (error, + GUPNP_SEARCH_CRITERIA_PARSER_ERROR, + GUPNP_SEARCH_CRITERIA_PARSER_ERROR_FAILED, + "Expected quoted string at position %u", + g_scanner_cur_position + (parser->priv->scanner)); + + ret = FALSE; + + break; + } + + value = g_scanner_cur_value (parser->priv->scanner); + + g_signal_emit (parser, signals[EXPRESSION], 0, + arg1, op, value.v_string, error, &ret); + + break; + + case GUPNP_SEARCH_CRITERIA_OP_EXISTS: + op = token; + + token = g_scanner_get_next_token (parser->priv->scanner); + switch (token) { + case SYMBOL_TRUE: + g_signal_emit (parser, signals[EXPRESSION], 0, + arg1, op, "true", error, &ret); + + break; + case SYMBOL_FALSE: + g_signal_emit (parser, signals[EXPRESSION], 0, + arg1, op, "false", error, &ret); + + break; + default: + g_set_error + (error, + GUPNP_SEARCH_CRITERIA_PARSER_ERROR, + GUPNP_SEARCH_CRITERIA_PARSER_ERROR_FAILED, + "Expected boolean value at position %u", + g_scanner_cur_position + (parser->priv->scanner)); + + ret = FALSE; + + break; + } + + break; + + default: + g_set_error (error, + GUPNP_SEARCH_CRITERIA_PARSER_ERROR, + GUPNP_SEARCH_CRITERIA_PARSER_ERROR_FAILED, + "Expected operator at position %u", + g_scanner_cur_position + (parser->priv->scanner)); + + ret = FALSE; + } + + g_free (arg1); + + return ret; +} + +static gboolean +scan_search_exp (GUPnPSearchCriteriaParser *parser, + GError **error); + +/* Scan a Logical operator and the part after that */ +static gboolean +scan_logical_op (GUPnPSearchCriteriaParser *parser, + GError **error) +{ + gboolean ret; + guint token; + + token = g_scanner_peek_next_token (parser->priv->scanner); + + switch (token) { + case SYMBOL_AND: + g_scanner_get_next_token (parser->priv->scanner); + + g_signal_emit (parser, signals[CONJUNCTION], 0); + + ret = scan_search_exp (parser, error); + + break; + + case SYMBOL_OR: + g_scanner_get_next_token (parser->priv->scanner); + + g_signal_emit (parser, signals[DISJUNCTION], 0); + + ret = scan_search_exp (parser, error); + + break; + + default: + + ret = TRUE; + + break; + + } + + return ret; +} + +/* Scan a searchExp portion of a search criteria string */ +static gboolean +scan_search_exp (GUPnPSearchCriteriaParser *parser, + GError **error) +{ + gboolean ret; + guint token; + + token = g_scanner_peek_next_token (parser->priv->scanner); + switch (token) { + case G_TOKEN_LEFT_PAREN: + g_scanner_get_next_token (parser->priv->scanner); + + g_signal_emit (parser, signals[BEGIN_PARENS], 0); + + ret = scan_search_exp (parser, error); + if (ret == FALSE) + break; + + token = g_scanner_get_next_token (parser->priv->scanner); + if (token != G_TOKEN_RIGHT_PAREN) { + g_set_error + (error, + GUPNP_SEARCH_CRITERIA_PARSER_ERROR, + GUPNP_SEARCH_CRITERIA_PARSER_ERROR_FAILED, + "Expected right parenthesis at position %u", + g_scanner_cur_position + (parser->priv->scanner)); + + ret = FALSE; + + break; + } + + g_signal_emit (parser, signals[END_PARENS], 0); + + ret = scan_logical_op (parser, error); + + break; + + case G_TOKEN_IDENTIFIER: + ret = scan_rel_exp (parser, error); + if (ret == FALSE) + break; + + ret = scan_logical_op (parser, error); + + break; + + default: + g_scanner_get_next_token (parser->priv->scanner); + + g_set_error (error, + GUPNP_SEARCH_CRITERIA_PARSER_ERROR, + GUPNP_SEARCH_CRITERIA_PARSER_ERROR_FAILED, + "Expected property name or left parenthesis at " + "position %u", + g_scanner_cur_position (parser->priv->scanner)); + + ret = FALSE; + } + + return ret; +} + +/** + * gupnp_search_criteria_parser_parse_text: + * @parser: A #GUPnPSearchCriteriaParser + * @text: The search criteria string to be parsed + * @error: The location where to store the error information if any, or NULL + * + * Parses @text, emitting the various defined signals on the way. If an + * error occured @error will be set. + * + * Return value: TRUE on success. + **/ +gboolean +gupnp_search_criteria_parser_parse_text (GUPnPSearchCriteriaParser *parser, + const char *text, + GError **error) +{ + gboolean ret; + guint token; + + g_return_val_if_fail (GUPNP_IS_SEARCH_CRITERIA_PARSER (parser), + FALSE); + g_return_val_if_fail (text != NULL, FALSE); + + /* Feed into scanner */ + g_scanner_input_text (parser->priv->scanner, text, strlen (text)); + + token = g_scanner_peek_next_token (parser->priv->scanner); + if (token == SYMBOL_ASTERISK) { + g_scanner_get_next_token (parser->priv->scanner); + + /* Do nothing. */ + + ret = TRUE; + } else + ret = scan_search_exp (parser, error); + + if (ret == TRUE) { + /* Confirm that we have EOF now */ + token = g_scanner_get_next_token (parser->priv->scanner); + if (token != G_TOKEN_EOF) { + g_set_error + (error, + GUPNP_SEARCH_CRITERIA_PARSER_ERROR, + GUPNP_SEARCH_CRITERIA_PARSER_ERROR_FAILED, + "Expected EOF at position %u", + g_scanner_cur_position + (parser->priv->scanner)); + } + } + + return ret; +} diff --git a/libgupnp-av/gupnp-search-criteria-parser.h b/libgupnp-av/gupnp-search-criteria-parser.h new file mode 100644 index 0000000..ec9fa32 --- /dev/null +++ b/libgupnp-av/gupnp-search-criteria-parser.h @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2008 OpenedHand Ltd. + * + * Authors: Jorn Baayen <jorn@openedhand.com> + * + * 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. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __GUPNP_SEARCH_CRITERIA_PARSER_H__ +#define __GUPNP_SEARCH_CRITERIA_PARSER_H__ + +#include <glib-object.h> + +G_BEGIN_DECLS + +GType +gupnp_search_criteria_parser_get_type (void) G_GNUC_CONST; + +#define GUPNP_TYPE_SEARCH_CRITERIA_PARSER \ + (gupnp_search_criteria_parser_get_type ()) +#define GUPNP_SEARCH_CRITERIA_PARSER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + GUPNP_TYPE_SEARCH_CRITERIA_PARSER, \ + GUPnPSearchCriteriaParser)) +#define GUPNP_SEARCH_CRITERIA_PARSER_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_CAST ((obj), \ + GUPNP_TYPE_SEARCH_CRITERIA_PARSER, \ + GUPnPSearchCriteriaParserClass)) +#define GUPNP_IS_SEARCH_CRITERIA_PARSER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + GUPNP_TYPE_SEARCH_CRITERIA_PARSER)) +#define GUPNP_IS_SEARCH_CRITERIA_PARSER_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE ((obj), \ + GUPNP_TYPE_SEARCH_CRITERIA_PARSER)) +#define GUPNP_SEARCH_CRITERIA_PARSER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + GUPNP_TYPE_SEARCH_CRITERIA_PARSER, \ + GUPnPSearchCriteriaParserClass)) + +/** + * GUPnPSearchCriteriaOp: + * @GUPNP_SEARCH_CRITERIA_OP_EQ: '=' + * @GUPNP_SEARCH_CRITERIA_OP_NEQ: '!=' + * @GUPNP_SEARCH_CRITERIA_OP_LESS: '<' + * @GUPNP_SEARCH_CRITERIA_OP_LEQ: '<=' + * @GUPNP_SEARCH_CRITERIA_OP_GREATER: '>' + * @GUPNP_SEARCH_CRITERIA_OP_GEQ: '>=' + * @GUPNP_SEARCH_CRITERIA_OP_CONTAINS: 'contains' + * @GUPNP_SEARCH_CRITERIA_OP_DOES_NOT_CONTAIN: 'doesNotContain' + * @GUPNP_SEARCH_CRITERIA_OP_DERIVED_FROM: 'derivedFrom' + * @GUPNP_SEARCH_CRITERIA_OP_EXISTS: 'exists' + * + * The possible operators in SearchCriteria strings. + * + **/ +typedef enum { + /* G_TYPE_STRING */ + GUPNP_SEARCH_CRITERIA_OP_EQ = G_TOKEN_LAST + 1, + GUPNP_SEARCH_CRITERIA_OP_NEQ = G_TOKEN_LAST + 2, + GUPNP_SEARCH_CRITERIA_OP_LESS = G_TOKEN_LAST + 3, + GUPNP_SEARCH_CRITERIA_OP_LEQ = G_TOKEN_LAST + 4, + GUPNP_SEARCH_CRITERIA_OP_GREATER = G_TOKEN_LAST + 5, + GUPNP_SEARCH_CRITERIA_OP_GEQ = G_TOKEN_LAST + 6, + GUPNP_SEARCH_CRITERIA_OP_CONTAINS = G_TOKEN_LAST + 7, + GUPNP_SEARCH_CRITERIA_OP_DOES_NOT_CONTAIN = G_TOKEN_LAST + 8, + GUPNP_SEARCH_CRITERIA_OP_DERIVED_FROM = G_TOKEN_LAST + 9, + + /* G_TYPE_BOOLEAN */ + GUPNP_SEARCH_CRITERIA_OP_EXISTS = G_TOKEN_LAST + 10 +} GUPnPSearchCriteriaOp; + +GType +gupnp_search_criteria_op_get_type (void) G_GNUC_CONST; + +#define GUPNP_TYPE_SEARCH_CRITERIA_OP (gupnp_search_criteria_op_get_type ()) + +#define GUPNP_SEARCH_CRITERIA_PARSER_ERROR \ + (gupnp_search_criteria_parser_error_quark ()) + +GQuark +gupnp_search_criteria_parser_error_quark (void); + +typedef enum { + GUPNP_SEARCH_CRITERIA_PARSER_ERROR_FAILED +} GUPnPSearchCriteriaParserError; + +typedef struct _GUPnPSearchCriteriaParserPrivate + GUPnPSearchCriteriaParserPrivate; + +typedef struct { + GObject parent; + + GUPnPSearchCriteriaParserPrivate *priv; +} GUPnPSearchCriteriaParser; + +typedef struct { + GObjectClass parent_class; + + /* signals */ + void (* begin_parens) (GUPnPSearchCriteriaParser *parser); + void (* end_parens) (GUPnPSearchCriteriaParser *parser); + void (* conjunction) (GUPnPSearchCriteriaParser *parser); + void (* disjunction) (GUPnPSearchCriteriaParser *parser); + gboolean (* expression) (GUPnPSearchCriteriaParser *parser, + const char *property, + GUPnPSearchCriteriaOp op, + const char *value, + GError **error); + + /* future padding */ + void (* _gupnp_reserved1) (void); + void (* _gupnp_reserved2) (void); + void (* _gupnp_reserved3) (void); + void (* _gupnp_reserved4) (void); +} GUPnPSearchCriteriaParserClass; + +GUPnPSearchCriteriaParser * +gupnp_search_criteria_parser_new (void); + +gboolean +gupnp_search_criteria_parser_parse_text (GUPnPSearchCriteriaParser *parser, + const char *text, + GError **error); + +G_END_DECLS + +#endif /* __GUPNP_SEARCH_CRITERIA_PARSER_H__ */ diff --git a/libgupnp-av/gvalue-util.c b/libgupnp-av/gvalue-util.c new file mode 100644 index 0000000..4017648 --- /dev/null +++ b/libgupnp-av/gvalue-util.c @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2007 OpenedHand Ltd. + * + * Author: Jorn Baayen <jorn@openedhand.com> + * + * 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. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <string.h> +#include <stdlib.h> + +#include "gvalue-util.h" + +gboolean +gvalue_util_set_value_from_string (GValue *value, + const char *str) +{ + GValue tmp_value = {0, }; + int i; + long l; + double d; + + g_return_val_if_fail (str != NULL, FALSE); + + switch (G_VALUE_TYPE (value)) { + case G_TYPE_STRING: + g_value_set_string (value, str); + + break; + + case G_TYPE_CHAR: + g_value_set_char (value, *str); + + break; + + case G_TYPE_UCHAR: + g_value_set_uchar (value, *str); + + break; + + case G_TYPE_INT: + i = atoi (str); + g_value_set_int (value, i); + + break; + + case G_TYPE_UINT: + i = atoi (str); + g_value_set_uint (value, (guint) i); + + break; + + case G_TYPE_INT64: + i = atoi (str); + g_value_set_int64 (value, (gint64) i); + + break; + + case G_TYPE_UINT64: + i = atoi (str); + g_value_set_uint64 (value, (guint64) i); + + break; + + case G_TYPE_LONG: + l = atol (str); + g_value_set_long (value, l); + + break; + + case G_TYPE_ULONG: + l = atol (str); + g_value_set_ulong (value, (gulong) l); + + break; + + case G_TYPE_FLOAT: + d = atof (str); + g_value_set_float (value, (float) d); + + break; + + case G_TYPE_DOUBLE: + d = atof (str); + g_value_set_float (value, d); + + break; + + case G_TYPE_BOOLEAN: + if (g_ascii_strcasecmp (str, "true") == 0 || + g_ascii_strcasecmp (str, "yes") == 0) + g_value_set_boolean (value, TRUE); + else if (g_ascii_strcasecmp (str, "false") == 0 || + g_ascii_strcasecmp (str, "no") == 0) + g_value_set_boolean (value, FALSE); + else { + int i; + + i = atoi (str); + g_value_set_boolean (value, i ? TRUE : FALSE); + } + + break; + + default: + /* Try to convert */ + if (g_value_type_transformable (G_TYPE_STRING, + G_VALUE_TYPE (value))) { + g_value_init (&tmp_value, G_TYPE_STRING); + g_value_set_static_string (&tmp_value, str); + + g_value_transform (&tmp_value, value); + + g_value_unset (&tmp_value); + + } else if (g_value_type_transformable (G_TYPE_INT, + G_VALUE_TYPE (value))) { + i = atoi (str); + + g_value_init (&tmp_value, G_TYPE_INT); + g_value_set_int (&tmp_value, i); + + g_value_transform (&tmp_value, value); + + g_value_unset (&tmp_value); + + } else { + g_warning ("Failed to transform integer " + "value to type %s", + G_VALUE_TYPE_NAME (value)); + + return FALSE; + } + + break; + } + + return TRUE; +} + diff --git a/libgupnp-av/gvalue-util.h b/libgupnp-av/gvalue-util.h new file mode 100644 index 0000000..c3b883a --- /dev/null +++ b/libgupnp-av/gvalue-util.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2007 OpenedHand Ltd. + * + * Author: Jorn Baayen <jorn@openedhand.com> + * + * 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. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __GVALUE_UTIL_H__ +#define __GVALUE_UTIL_H__ + +#include <glib-object.h> + +G_GNUC_INTERNAL gboolean +gvalue_util_set_value_from_string (GValue *value, + const char *str); + +#endif /* __GVALUE_UTIL_H__ */ + diff --git a/libgupnp-av/xml-util.c b/libgupnp-av/xml-util.c new file mode 100644 index 0000000..92e71bb --- /dev/null +++ b/libgupnp-av/xml-util.c @@ -0,0 +1,236 @@ +/* + * Copyright (C) 2006, 2007 OpenedHand Ltd. + * Copyright (C) 2007 Zeeshan Ali. + * + * Author: Jorn Baayen <jorn@openedhand.com> + * Author: Zeeshan Ali (Khattak) <zeeshanak@gnome.org> + * + * 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. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <string.h> + +#include "xml-util.h" + +xmlNode * +xml_util_get_element (xmlNode *node, + ...) +{ + va_list var_args; + + va_start (var_args, node); + + while (TRUE) { + const char *arg; + + arg = va_arg (var_args, const char *); + if (!arg) + break; + + for (node = node->children; node; node = node->next) { + if (node->name == NULL) + continue; + + if (!g_ascii_strcasecmp (arg, (char *) node->name)) + break; + } + + if (!node) + break; + } + + va_end (var_args); + + return node; +} + +GList * +xml_util_get_child_elements_by_name (xmlNode *node, const char *name) +{ + GList *children = NULL; + + for (node = node->children; node; node = node->next) { + if (node->name == NULL) { + continue; + } + + if (strcmp (name, (char *) node->name) == 0) { + children = g_list_append (children, node); + } + } + + return children; +} + +const char * +xml_util_get_child_element_content (xmlNode *node, + const char *child_name) +{ + xmlNode *child_node; + const char *content; + + child_node = xml_util_get_element (node, child_name, NULL); + if (!child_node || !(child_node->children)) + return NULL; + + content = (const char *) child_node->children->content; + if (!content) + return NULL; + + return content; +} + +const char * +xml_util_get_attribute_content (xmlNode *node, + const char *attribute_name) +{ + xmlAttr *attribute; + + for (attribute = node->properties; + attribute; + attribute = attribute->next) { + if (attribute->name == NULL) + continue; + + if (strcmp (attribute_name, (char *) attribute->name) == 0) + break; + } + + if (attribute) + return (const char *) attribute->children->content; + else + return NULL; +} + +gboolean +xml_util_get_boolean_attribute (xmlNode *node, + const char *attribute_name) +{ + const char *content; + gchar *str; + gboolean ret; + + content = xml_util_get_attribute_content (node, attribute_name); + if (!content) + return FALSE; + + str = (char *) content; + if (g_ascii_strcasecmp (str, "true") == 0 || + g_ascii_strcasecmp (str, "yes") == 0) + ret = TRUE; + else if (g_ascii_strcasecmp (str, "false") == 0 || + g_ascii_strcasecmp (str, "no") == 0) + ret = FALSE; + else { + int i; + + i = atoi (str); + ret = i ? TRUE : FALSE; + } + + return ret; +} + +guint +xml_util_get_uint_attribute (xmlNode *node, + const char *attribute_name, + guint default_value) +{ + return (guint) xml_util_get_long_attribute (node, + attribute_name, + (glong) default_value); +} + +gint +xml_util_get_int_attribute (xmlNode *node, + const char *attribute_name, + gint default_value) +{ + return (gint) xml_util_get_long_attribute (node, + attribute_name, + (glong) default_value); +} + +glong +xml_util_get_long_attribute (xmlNode *node, + const char *attribute_name, + glong default_value) +{ + return (glong) xml_util_get_int64_attribute (node, + attribute_name, + (gint64) default_value); +} + +gint64 +xml_util_get_int64_attribute (xmlNode *node, + const char *attribute_name, + gint64 default_value) +{ + const char *content; + + content = xml_util_get_attribute_content (node, attribute_name); + if (!content) + return default_value; + + return g_ascii_strtoll (content, NULL, 0); +} + +xmlNode * +xml_util_set_child (xmlNode *parent_node, + xmlNs *namespace, + xmlDoc *doc, + const char *name, + const char *value) +{ + xmlNode *node; + xmlChar *escaped; + + node = xml_util_get_element (parent_node, name, NULL); + if (node == NULL) { + node = xmlNewChild (parent_node, + namespace, + (unsigned char *) name, + NULL); + } + + escaped = xmlEncodeSpecialChars (doc, (const unsigned char *) value); + xmlNodeSetContent (node, escaped); + xmlFree (escaped); + + return node; +} + +gboolean +xml_util_verify_attribute_is_boolean (xmlNode *node, + const char *attribute_name) +{ + const char *content; + char *str; + + content = xml_util_get_attribute_content (node, attribute_name); + if (content == NULL) + return FALSE; + + str = (char *) content; + + return g_ascii_strcasecmp (str, "true") == 0 || + g_ascii_strcasecmp (str, "yes") == 0 || + g_ascii_strcasecmp (str, "false") == 0 || + g_ascii_strcasecmp (str, "no") == 0 || + g_ascii_strcasecmp (str, "0") == 0 || + g_ascii_strcasecmp (str, "1") == 0; +} + diff --git a/libgupnp-av/xml-util.h b/libgupnp-av/xml-util.h new file mode 100644 index 0000000..e50066c --- /dev/null +++ b/libgupnp-av/xml-util.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2006, 2007 OpenedHand Ltd. + * Copyright (C) 2007 Zeeshan Ali. + * + * Author: Jorn Baayen <jorn@openedhand.com> + * Author: Zeeshan Ali (Khattak) <zeeshanak@gnome.org> + * + * 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. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __XML_UTIL_H__ +#define __XML_UTIL_H__ + +#include <glib.h> +#include <libxml/tree.h> +#include <stdarg.h> + +/* Misc utilities for inspecting xmlNodes */ +G_GNUC_INTERNAL xmlNode * +xml_util_get_element (xmlNode *node, + ...) G_GNUC_NULL_TERMINATED; + +G_GNUC_INTERNAL GList * +xml_util_get_child_elements_by_name (xmlNode *node, + const char *name); + +G_GNUC_INTERNAL const char * +xml_util_get_child_element_content (xmlNode *node, + const char *child_name); + +G_GNUC_INTERNAL const char * +xml_util_get_attribute_content (xmlNode *node, + const char *attribute_name); + +G_GNUC_INTERNAL gboolean +xml_util_get_boolean_attribute (xmlNode *node, + const char *attribute_name); + +G_GNUC_INTERNAL guint +xml_util_get_uint_attribute (xmlNode *node, + const char *attribute_name, + guint default_value); + +G_GNUC_INTERNAL gint +xml_util_get_int_attribute (xmlNode *node, + const char *attribute_name, + gint default_value); + +G_GNUC_INTERNAL glong +xml_util_get_long_attribute (xmlNode *node, + const char *attribute_name, + glong default_value); + +G_GNUC_INTERNAL gint64 +xml_util_get_int64_attribute (xmlNode *node, + const char *attribute_name, + gint64 default_value); + +G_GNUC_INTERNAL xmlNode * +xml_util_set_child (xmlNode *parent_node, + xmlNs *namespace, + xmlDoc *doc, + const char *name, + const char *value); + +G_GNUC_INTERNAL gboolean +xml_util_verify_attribute_is_boolean (xmlNode *node, + const char *attribute_name); + +#endif /* __XML_UTIL_H__ */ |