summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Ryan <mark.d.ryan@intel.com>2013-01-25 15:36:50 +0100
committerMark Ryan <mark.d.ryan@intel.com>2013-01-25 15:40:20 +0100
commit4255ee16a5c8ce4e81775fb3f7792f8aef1fa6de (patch)
treec58bf4163af5d0eecd38713a1d33c42dd32cb6ac
parent1ecd50f6deec9a7e53134bbc30b300bb046f09a4 (diff)
downloadGUPnP-AV-4255ee16a5c8ce4e81775fb3f7792f8aef1fa6de.tar.gz
GUPnP-AV-4255ee16a5c8ce4e81775fb3f7792f8aef1fa6de.tar.bz2
GUPnP-AV-4255ee16a5c8ce4e81775fb3f7792f8aef1fa6de.zip
Updated GUPnP-AV to version 11.7 (a48bbd0)
This should fix bug TIVI-464
-rw-r--r--NEWS75
-rwxr-xr-xconfigure20
-rw-r--r--configure.ac4
-rw-r--r--data/didl-lite-v2.xsd2
-rw-r--r--doc/gupnp-av-docs.sgml3
-rw-r--r--doc/gupnp-av-sections.txt113
-rw-r--r--doc/gupnp-av.types3
-rw-r--r--doc/html/GUPnPCDSLastChangeParser.html361
-rw-r--r--doc/html/GUPnPDIDLLiteContainer.html215
-rw-r--r--doc/html/GUPnPDIDLLiteContributor.html4
-rw-r--r--doc/html/GUPnPDIDLLiteItem.html51
-rw-r--r--doc/html/GUPnPDIDLLiteObject.html402
-rw-r--r--doc/html/GUPnPDIDLLiteResource.html115
-rw-r--r--doc/html/GUPnPFeatureListParser.html4
-rw-r--r--doc/html/GUPnPLastChangeParser.html8
-rw-r--r--doc/html/GUPnPMediaCollection.html334
-rw-r--r--doc/html/GUPnPSearchCriteriaParser.html4
-rw-r--r--doc/html/annotation-glossary.html3
-rw-r--r--doc/html/ch01.html12
-rw-r--r--doc/html/ch02.html6
-rw-r--r--doc/html/gupnp-av-Error-codes.html9
-rw-r--r--doc/html/gupnp-av-GUPnPDIDLLiteCreateClass.html243
-rw-r--r--doc/html/gupnp-av.devhelp278
-rw-r--r--doc/html/index.html14
-rw-r--r--doc/html/index.sgml93
-rw-r--r--doc/version.xml2
-rw-r--r--libgupnp-av/Makefile.am10
-rw-r--r--libgupnp-av/Makefile.in20
-rw-r--r--libgupnp-av/gupnp-av-enums.h22
-rw-r--r--libgupnp-av/gupnp-av.h3
-rw-r--r--libgupnp-av/gupnp-cds-last-change-parser.c379
-rw-r--r--libgupnp-av/gupnp-cds-last-change-parser.h112
-rw-r--r--libgupnp-av/gupnp-didl-lite-item.c90
-rw-r--r--libgupnp-av/gupnp-didl-lite-item.h9
-rw-r--r--libgupnp-av/gupnp-didl-lite-object.c27
-rw-r--r--libgupnp-av/gupnp-didl-lite-object.h3
-rw-r--r--libgupnp-av/gupnp-didl-lite-parser-private.h36
-rw-r--r--libgupnp-av/gupnp-didl-lite-parser.c124
-rw-r--r--libgupnp-av/gupnp-didl-lite-resource.c44
-rw-r--r--libgupnp-av/gupnp-didl-lite-resource.h4
-rw-r--r--libgupnp-av/gupnp-didl-lite-writer-private.h41
-rw-r--r--libgupnp-av/gupnp-didl-lite-writer.c143
-rw-r--r--libgupnp-av/gupnp-last-change-parser.c13
-rw-r--r--libgupnp-av/gupnp-media-collection.c594
-rw-r--r--libgupnp-av/gupnp-media-collection.h109
-rw-r--r--libgupnp-av/gupnp-search-criteria-parser.h5
-rw-r--r--libgupnp-av/time-utils.c68
-rw-r--r--libgupnp-av/time-utils.h35
-rw-r--r--packaging/GUPnP-AV.spec2
-rw-r--r--tests/check-feature-list-parser.c2
-rw-r--r--tests/check-search.c2
-rw-r--r--tests/fragments.c2
-rw-r--r--tests/gtest/Makefile.am26
-rw-r--r--tests/gtest/Makefile.in76
-rw-r--r--tests/gtest/data/cds-last-change/00-cds-last-change.xml8
-rw-r--r--tests/gtest/data/cds-last-change/01-cds-last-change.xml19
-rw-r--r--tests/gtest/data/cds-last-change/02-cds-last-change.xml11
-rw-r--r--tests/gtest/data/cds-last-change/03-cds-last-change.xml14
-rw-r--r--tests/gtest/data/cds-last-change/04-cds-last-change.xml19
-rw-r--r--tests/gtest/data/cds-last-change/05-cds-last-change.xml19
-rw-r--r--tests/gtest/data/cds-last-change/06-cds-last-change.xml11
-rw-r--r--tests/gtest/data/cds-last-change/07-cds-last-change.xml15
-rw-r--r--tests/gtest/test-cds-last-change-parser.c496
-rw-r--r--tests/gtest/test-last-change-parser.c258
-rw-r--r--tests/gtest/test-media-collection.c493
-rw-r--r--tests/gtest/test-regression.c25
-rw-r--r--tests/test-search-criteria-parser.c2
67 files changed, 5417 insertions, 152 deletions
diff --git a/NEWS b/NEWS
index 02a8a69..944833b 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,78 @@
+0.11.6
+======
+
+Changes since 0.11.5:
+- Fix an unitialized variable.
+- Fix a wrong use of BAD_CAST.
+- Fix handling of updateID in the CDS LastChange parser.
+- Fix CDS LastChange test.
+
+All contributors to this release:
+
+Jens Georg <jensg@openismus.com>
+Mark Ryan <mark.d.ryan@intel.com>
+
+Bugs fixed in this release:
+ - https://bugzilla.gnome.org/show_bug.cgi?id=689701
+ - https://bugzilla.gnome.org/show_bug.cgi?id=689808
+
+0.11.5
+======
+
+Changes since 0.11.4:
+- Fix API definition in gupnp-cds-last-change-parser.h
+- Set items in a media collection to "restricted" by default.
+
+All contributors to this release:
+
+Jens Georg <jensg@openismus.com>
+Ludovic Ferrandis <ludovic.ferrandis@intel.com>
+
+Bugs fixed in this release:
+ - https://bugzilla.gnome.org/show_bug.cgi?id=689517
+
+0.11.4
+======
+
+Changes since 0.11.3:
+- Fix DIDL_S parsing issues in GUPnPMediaCollection.
+- Fix reference count issues in GUPnPMediaCollection.
+- Add more tests for GUPnPMediaCollection.
+- Add test for LastChange parser.
+- Fix LD_LIBRARAY_PATH handling on make check.
+- Silence XSD validation errors on make check.
+- Silence makefile portability warnings.
+- Some gtk-doc fixes.
+- Add LastChange parser for LastChange in ContentDirectory:3 including tests.
+
+All contributors to this release:
+
+Jens Georg <jensg@openismus.com>
+Krzesimir Nowak <krnowak@openismus.com>
+Regis Merlino <regis.merlino@intel.com>
+
+Bugs fixed in this release:
+ - https://bugzilla.gnome.org/show_bug.cgi?id=689094
+ - https://bugzilla.gnome.org/show_bug.cgi?id=689141
+ - https://bugzilla.gnome.org/show_bug.cgi?id=689276
+
+0.11.3
+======
+
+Changes since 0.11.2:
+- Fix documentation generation for recently added functionality.
+- Tweak XSD files to make the validation shut up completely.
+- Fix an issue in the DIDL-Lite filtering.
+- Add new class GUPnPMediaCollection for parsing and creation of DIDL_S
+ playlists.
+
+All contributors to this release:
+
+Jens Georg <jensg@openismus.com>
+
+Bugs fixed in this release:
+ - https://bugzilla.gnome.org/show_bug.cgi?id=687462
+
0.11.2
======
diff --git a/configure b/configure
index bcbc1f0..285b99a 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for gupnp-av 0.11.2.
+# Generated by GNU Autoconf 2.69 for gupnp-av 0.11.7.
#
# Report bugs to <https://bugzilla.gnome.org/enter_bug.cgi?product=GUPnP>.
#
@@ -651,8 +651,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='gupnp-av'
PACKAGE_TARNAME='gupnp-av'
-PACKAGE_VERSION='0.11.2'
-PACKAGE_STRING='gupnp-av 0.11.2'
+PACKAGE_VERSION='0.11.7'
+PACKAGE_STRING='gupnp-av 0.11.7'
PACKAGE_BUGREPORT='https://bugzilla.gnome.org/enter_bug.cgi?product=GUPnP'
PACKAGE_URL='http://www.gupnp.org/'
@@ -1421,7 +1421,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures gupnp-av 0.11.2 to adapt to many kinds of systems.
+\`configure' configures gupnp-av 0.11.7 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1491,7 +1491,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of gupnp-av 0.11.2:";;
+ short | recursive ) echo "Configuration of gupnp-av 0.11.7:";;
esac
cat <<\_ACEOF
@@ -1615,7 +1615,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-gupnp-av configure 0.11.2
+gupnp-av configure 0.11.7
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1893,7 +1893,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by gupnp-av $as_me 0.11.2, which was
+It was created by gupnp-av $as_me 0.11.7, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2717,7 +2717,7 @@ fi
# Define the identity of the package.
PACKAGE='gupnp-av'
- VERSION='0.11.2'
+ VERSION='0.11.7'
cat >>confdefs.h <<_ACEOF
@@ -13380,7 +13380,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by gupnp-av $as_me 0.11.2, which was
+This file was extended by gupnp-av $as_me 0.11.7, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -13447,7 +13447,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-gupnp-av config.status 0.11.2
+gupnp-av config.status 0.11.7
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/configure.ac b/configure.ac
index f8eeba3..0347529 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,6 @@
AC_PREREQ([2.63])
AC_INIT([gupnp-av],
- [0.11.2],
+ [0.11.7],
[https://bugzilla.gnome.org/enter_bug.cgi?product=GUPnP],
[gupnp-av],
[http://www.gupnp.org/])
@@ -10,7 +10,7 @@ AC_CONFIG_SRCDIR(libgupnp-av/gupnp-av.h)
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_AUX_DIR([build-aux])
-AM_INIT_AUTOMAKE([1.11 tar-ustar no-dist-gzip dist-xz])
+AM_INIT_AUTOMAKE([1.11 tar-ustar no-dist-gzip dist-xz -Wno-portability])
AM_SILENT_RULES([yes])
diff --git a/data/didl-lite-v2.xsd b/data/didl-lite-v2.xsd
index 6b05b1f..a0567c0 100644
--- a/data/didl-lite-v2.xsd
+++ b/data/didl-lite-v2.xsd
@@ -11,7 +11,7 @@
<xsd:import namespace="urn:schemas-upnp-org:metadata-1-0/upnp/" schemaLocation="http://www.upnp.org/schemas/av/upnp.xsd"/>
<xsd:import namespace="urn:schemas-upnp-org:av:av" schemaLocation="http://www.upnp.org/schemas/av/av.xsd"/>
<xsd:import namespace="http://purl.org/dc/elements/1.1/" schemaLocation="http://dublincore.org/schemas/xmls/simpledc20021212.xsd"/>
- <xsd:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2005/08/xml.xsd"/>
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/03/xml.xsd"/>
<!--============================================================
diff --git a/doc/gupnp-av-docs.sgml b/doc/gupnp-av-docs.sgml
index 03171be..0e2b00e 100644
--- a/doc/gupnp-av-docs.sgml
+++ b/doc/gupnp-av-docs.sgml
@@ -56,11 +56,14 @@
<xi:include href="xml/gupnp-didl-lite-resource.xml"/>
<xi:include href="xml/gupnp-didl-lite-descriptor.xml"/>
<xi:include href="xml/gupnp-didl-lite-contributor.xml"/>
+ <xi:include href="xml/gupnp-didl-lite-create-class.xml"/>
<xi:include href="xml/gupnp-last-change-parser.xml"/>
+ <xi:include href="xml/gupnp-cds-last-change-parser.xml"/>
<xi:include href="xml/gupnp-search-criteria-parser.xml"/>
<xi:include href="xml/gupnp-protocol-info.xml"/>
<xi:include href="xml/gupnp-feature.xml"/>
<xi:include href="xml/gupnp-feature-list-parser.xml"/>
+ <xi:include href="xml/gupnp-media-collection.xml"/>
</chapter>
diff --git a/doc/gupnp-av-sections.txt b/doc/gupnp-av-sections.txt
index c0d46b8..e373bc6 100644
--- a/doc/gupnp-av-sections.txt
+++ b/doc/gupnp-av-sections.txt
@@ -3,6 +3,7 @@
<TITLE>GUPnPDIDLLiteObject</TITLE>
GUPnPDIDLLiteObject
GUPnPOCMFlags
+GUPnPDIDLLiteFragmentResult
gupnp_didl_lite_object_get_xml_node
gupnp_didl_lite_object_get_upnp_namespace
gupnp_didl_lite_object_get_dc_namespace
@@ -51,8 +52,21 @@ gupnp_didl_lite_object_set_description
gupnp_didl_lite_object_set_date
gupnp_didl_lite_object_set_track_number
gupnp_didl_lite_object_set_dlna_managed
+gupnp_didl_lite_object_apply_fragments
+gupnp_didl_lite_object_get_album_xml_string
+gupnp_didl_lite_object_get_artists_xml_string
+gupnp_didl_lite_object_get_date_xml_string
+gupnp_didl_lite_object_get_title_xml_string
+gupnp_didl_lite_object_get_track_number_xml_string
+gupnp_didl_lite_object_get_update_id
+gupnp_didl_lite_object_get_upnp_class_xml_string
+gupnp_didl_lite_object_set_update_id
+gupnp_didl_lite_object_unset_artists
+gupnp_didl_lite_object_unset_update_id
+gupnp_didl_lite_object_update_id_is_set
<SUBSECTION Standard>
GUPnPDIDLLiteObjectClass
+GUPNP_TYPE_OCM_FLAGS
GUPNP_TYPE_DIDL_LITE_OBJECT
GUPNP_DIDL_LITE_OBJECT
GUPNP_DIDL_LITE_OBJECT_CLASS
@@ -62,6 +76,7 @@ GUPNP_DIDL_LITE_OBJECT_GET_CLASS
<SUBSECTION Private>
GUPnPDIDLLiteObjectPrivate
gupnp_didl_lite_object_get_type
+gupnp_ocm_flags_get_type
</SECTION>
<SECTION>
@@ -80,6 +95,15 @@ gupnp_didl_lite_container_add_create_class
gupnp_didl_lite_container_add_create_class_full
gupnp_didl_lite_container_add_search_class
gupnp_didl_lite_container_add_search_class_full
+gupnp_didl_lite_container_container_update_id_is_set
+gupnp_didl_lite_container_get_container_update_id
+gupnp_didl_lite_container_get_create_classes_full
+gupnp_didl_lite_container_get_total_deleted_child_count
+gupnp_didl_lite_container_set_container_update_id
+gupnp_didl_lite_container_set_total_deleted_child_count
+gupnp_didl_lite_container_total_deleted_child_count_is_set
+gupnp_didl_lite_container_unset_container_update_id
+gupnp_didl_lite_container_unset_total_deleted_child_count
<SUBSECTION Standard>
GUPnPDIDLLiteContainerClass
GUPNP_TYPE_DIDL_LITE_CONTAINER
@@ -99,6 +123,8 @@ gupnp_didl_lite_container_get_type
GUPnPDIDLLiteItem
gupnp_didl_lite_item_get_ref_id
gupnp_didl_lite_item_set_ref_id
+gupnp_didl_lite_item_get_lifetime
+gupnp_didl_lite_item_set_lifetime
<SUBSECTION Standard>
GUPnPDIDLLiteItemClass
GUPNP_TYPE_DIDL_LITE_ITEM
@@ -192,6 +218,10 @@ gupnp_didl_lite_resource_get_width
gupnp_didl_lite_resource_get_height
gupnp_didl_lite_resource_get_color_depth
gupnp_didl_lite_resource_get_xml_node
+gupnp_didl_lite_resource_get_update_count
+gupnp_didl_lite_resource_set_update_count
+gupnp_didl_lite_resource_unset_update_count
+gupnp_didl_lite_resource_update_count_is_set
<SUBSECTION Standard>
GUPNP_TYPE_DIDL_LITE_RESOURCE
GUPNP_DIDL_LITE_RESOURCE
@@ -251,6 +281,29 @@ gupnp_didl_lite_contributor_get_type
</SECTION>
<SECTION>
+<FILE>gupnp-didl-lite-create-class</FILE>
+<TITLE>GUPnPDIDLLiteCreateClass</TITLE>
+GUPnPDIDLLiteCreateClass
+gupnp_didl_lite_create_class_get_content
+gupnp_didl_lite_create_class_set_content
+gupnp_didl_lite_create_class_get_include_derived
+gupnp_didl_lite_create_class_set_include_derived
+gupnp_didl_lite_create_class_get_friendly_name
+gupnp_didl_lite_create_class_set_friendly_name
+gupnp_didl_lite_create_class_get_xml_node
+<SUBSECTION Standard>
+GUPNP_DIDL_LITE_CREATE_CLASS
+GUPNP_DIDL_LITE_CREATE_CLASS_CLASS
+GUPNP_DIDL_LITE_CREATE_CLASS_GET_CLASS
+GUPNP_IS_DIDL_LITE_CREATE_CLASS
+GUPNP_IS_DIDL_LITE_CREATE_CLASS_CLASS
+GUPNP_TYPE_DIDL_LITE_CREATE_CLASS
+<SUBSECTION Private>
+GUPnPDIDLLiteCreateClassPrivate
+gupnp_didl_lite_create_class_get_type
+</SECTION>
+
+<SECTION>
<FILE>gupnp-protocol-info</FILE>
<TITLE>GUPnPProtocolInfo</TITLE>
GUPnPProtocolInfo
@@ -348,6 +401,8 @@ gupnp_feature_get_object_ids
GUPnPFeatureClass
GUPNP_TYPE_FEATURE
GUPNP_FEATURE
+GUPNP_IS_FEATURE
+GUPNP_IS_FEATURE_CLASS
GUPNP_FEATURE_CLASS
GUPNP_IS_FEATURE_PARSER
GUPNP_IS_FEATURE_PARSER_CLASS
@@ -371,11 +426,69 @@ GUPNP_FEATURE_LIST_PARSER_CLASS
GUPNP_IS_FEATURE_LIST_PARSER_PARSER
GUPNP_IS_FEATURE_LIST_PARSER_PARSER_CLASS
GUPNP_FEATURE_LIST_PARSER_GET_CLASS
+GUPNP_IS_FEATURE_LIST_PARSER
+GUPNP_IS_FEATURE_LIST_PARSER_CLASS
<SUBSECTION Private>
gupnp_feature_list_parser_get_type
</SECTION>
<SECTION>
+<FILE>gupnp-media-collection</FILE>
+<TITLE>GUPnPMediaCollection</TITLE>
+GUPnPMediaCollection
+gupnp_media_collection_new
+gupnp_media_collection_new_from_string
+gupnp_media_collection_set_title
+gupnp_media_collection_get_title
+gupnp_media_collection_set_author
+gupnp_media_collection_get_author
+gupnp_media_collection_add_item
+gupnp_media_collection_get_string
+gupnp_media_collection_get_items
+gupnp_media_collection_get_mutable
+<SUBSECTION Standard>
+GUPnPMediaCollectionClass
+GUPNP_IS_MEDIA_COLLECTION
+GUPNP_IS_MEDIA_COLLECTION_CLASS
+GUPNP_MEDIA_COLLECTION
+GUPNP_MEDIA_COLLECTION_CLASS
+GUPNP_MEDIA_COLLECTION_GET_CLASS
+GUPNP_TYPE_MEDIA_COLLECTION
+GUPnPMediaCollectionPrivate
+gupnp_media_collection_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gupnp-cds-last-change-parser</FILE>
+<TITLE>GUPnPCDSLastChangeParser</TITLE>
+GUPnPCDSLastChangeParser
+GUPnPCDSLastChangeEvent
+GUPnPCDSLastChangeEntry
+gupnp_cds_last_change_parser_new
+gupnp_cds_last_change_parser_parse
+gupnp_cds_last_change_entry_ref
+gupnp_cds_last_change_entry_unref
+gupnp_cds_last_change_entry_get_event
+gupnp_cds_last_change_entry_get_object_id
+gupnp_cds_last_change_entry_get_parent_id
+gupnp_cds_last_change_entry_get_class
+gupnp_cds_last_change_entry_is_subtree_update
+gupnp_cds_last_change_entry_get_update_id
+<SUBSECTION Standard>
+GUPnPCDSLastChangeParserClass
+GUPNP_CDS_LAST_CHANGE_PARSER
+GUPNP_CDS_LAST_CHANGE_PARSER_CLASS
+GUPNP_CDS_LAST_CHANGE_PARSER_GET_CLASS
+GUPNP_IS_CDS_LAST_CHANGE_PARSER
+GUPNP_IS_CDS_LAST_CHANGE_PARSER_CLASS
+GUPNP_TYPE_CDS_LAST_CHANGE_PARSER
+GUPnPCDSLastChangeParserPrivate
+gupnp_cds_last_change_entry_get_type
+gupnp_cds_last_change_parser_get_type
+</SECTION>
+
+
+<SECTION>
<FILE>gupnp-av-error</FILE>
<TITLE>Error codes</TITLE>
GUPNP_PROTOCOL_ERROR
diff --git a/doc/gupnp-av.types b/doc/gupnp-av.types
index 6e75f28..9f48dc6 100644
--- a/doc/gupnp-av.types
+++ b/doc/gupnp-av.types
@@ -14,3 +14,6 @@ gupnp_search_criteria_parser_get_type
gupnp_search_criteria_op_get_type
gupnp_feature_get_type
gupnp_feature_list_parser_get_type
+gupnp_media_collection_get_type
+gupnp_cds_last_change_parser_get_type
+gupnp_cds_last_change_entry_get_type
diff --git a/doc/html/GUPnPCDSLastChangeParser.html b/doc/html/GUPnPCDSLastChangeParser.html
new file mode 100644
index 0000000..f7459e3
--- /dev/null
+++ b/doc/html/GUPnPCDSLastChangeParser.html
@@ -0,0 +1,361 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>GUPnPCDSLastChangeParser</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
+<link rel="home" href="index.html" title="GUPnP A/V Reference Manual">
+<link rel="up" href="ch01.html" title="GUPnP A/V">
+<link rel="prev" href="GUPnPLastChangeParser.html" title="GUPnPLastChangeParser">
+<link rel="next" href="GUPnPSearchCriteriaParser.html" title="GUPnPSearchCriteriaParser">
+<meta name="generator" content="GTK-Doc V1.18 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="2">
+<tr valign="middle">
+<td><a accesskey="p" href="GUPnPLastChangeParser.html"><img src="left.png" width="24" height="24" border="0" alt="Prev"></a></td>
+<td><a accesskey="u" href="ch01.html"><img src="up.png" width="24" height="24" border="0" alt="Up"></a></td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="24" height="24" border="0" alt="Home"></a></td>
+<th width="100%" align="center">GUPnP A/V Reference Manual</th>
+<td><a accesskey="n" href="GUPnPSearchCriteriaParser.html"><img src="right.png" width="24" height="24" border="0" alt="Next"></a></td>
+</tr>
+<tr><td colspan="5" class="shortcuts">
+<a href="#GUPnPCDSLastChangeParser.synopsis" class="shortcut">Top</a>
+  | 
+ <a href="#GUPnPCDSLastChangeParser.description" class="shortcut">Description</a>
+  | 
+ <a href="#GUPnPCDSLastChangeParser.object-hierarchy" class="shortcut">Object Hierarchy</a>
+</td></tr>
+</table>
+<div class="refentry">
+<a name="GUPnPCDSLastChangeParser"></a><div class="titlepage"></div>
+<div class="refnamediv"><table width="100%"><tr>
+<td valign="top">
+<h2><span class="refentrytitle"><a name="GUPnPCDSLastChangeParser.top_of_page"></a>GUPnPCDSLastChangeParser</span></h2>
+<p>GUPnPCDSLastChangeParser — LastChange parser for the format used in
+CDS:3</p>
+</td>
+<td valign="top" align="right"></td>
+</tr></table></div>
+<div class="refsynopsisdiv">
+<a name="GUPnPCDSLastChangeParser.synopsis"></a><h2>Synopsis</h2>
+<a name="GUPnPCDSLastChangeEntry"></a><pre class="synopsis">struct <a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeParser-struct" title="struct GUPnPCDSLastChangeParser">GUPnPCDSLastChangeParser</a>;
+enum <a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEvent" title="enum GUPnPCDSLastChangeEvent">GUPnPCDSLastChangeEvent</a>;
+ <a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEntry-struct" title="GUPnPCDSLastChangeEntry">GUPnPCDSLastChangeEntry</a>;
+<a class="link" href="GUPnPCDSLastChangeParser.html" title="GUPnPCDSLastChangeParser"><span class="returnvalue">GUPnPCDSLastChangeParser</span></a> * <a class="link" href="GUPnPCDSLastChangeParser.html#gupnp-cds-last-change-parser-new" title="gupnp_cds_last_change_parser_new ()">gupnp_cds_last_change_parser_new</a>
+ (<em class="parameter"><code><span class="type">void</span></code></em>);
+<span class="returnvalue">GList</span> * <a class="link" href="GUPnPCDSLastChangeParser.html#gupnp-cds-last-change-parser-parse" title="gupnp_cds_last_change_parser_parse ()">gupnp_cds_last_change_parser_parse</a> (<em class="parameter"><code><a class="link" href="GUPnPCDSLastChangeParser.html" title="GUPnPCDSLastChangeParser"><span class="type">GUPnPCDSLastChangeParser</span></a> *parser</code></em>,
+ <em class="parameter"><code>const <span class="type">char</span> *last_change</code></em>,
+ <em class="parameter"><code><span class="type">GError</span> **error</code></em>);
+<a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEntry"><span class="returnvalue">GUPnPCDSLastChangeEntry</span></a> * <a class="link" href="GUPnPCDSLastChangeParser.html#gupnp-cds-last-change-entry-ref" title="gupnp_cds_last_change_entry_ref ()">gupnp_cds_last_change_entry_ref</a>
+ (<em class="parameter"><code><a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEntry"><span class="type">GUPnPCDSLastChangeEntry</span></a> *entry</code></em>);
+<span class="returnvalue">void</span> <a class="link" href="GUPnPCDSLastChangeParser.html#gupnp-cds-last-change-entry-unref" title="gupnp_cds_last_change_entry_unref ()">gupnp_cds_last_change_entry_unref</a> (<em class="parameter"><code><a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEntry"><span class="type">GUPnPCDSLastChangeEntry</span></a> *entry</code></em>);
+<a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEvent" title="enum GUPnPCDSLastChangeEvent"><span class="returnvalue">GUPnPCDSLastChangeEvent</span></a> <a class="link" href="GUPnPCDSLastChangeParser.html#gupnp-cds-last-change-entry-get-event" title="gupnp_cds_last_change_entry_get_event ()">gupnp_cds_last_change_entry_get_event</a>
+ (<em class="parameter"><code><a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEntry"><span class="type">GUPnPCDSLastChangeEntry</span></a> *entry</code></em>);
+const <span class="returnvalue">char</span> * <a class="link" href="GUPnPCDSLastChangeParser.html#gupnp-cds-last-change-entry-get-object-id" title="gupnp_cds_last_change_entry_get_object_id ()">gupnp_cds_last_change_entry_get_object_id</a>
+ (<em class="parameter"><code><a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEntry"><span class="type">GUPnPCDSLastChangeEntry</span></a> *entry</code></em>);
+const <span class="returnvalue">char</span> * <a class="link" href="GUPnPCDSLastChangeParser.html#gupnp-cds-last-change-entry-get-parent-id" title="gupnp_cds_last_change_entry_get_parent_id ()">gupnp_cds_last_change_entry_get_parent_id</a>
+ (<em class="parameter"><code><a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEntry"><span class="type">GUPnPCDSLastChangeEntry</span></a> *entry</code></em>);
+const <span class="returnvalue">char</span> * <a class="link" href="GUPnPCDSLastChangeParser.html#gupnp-cds-last-change-entry-get-class" title="gupnp_cds_last_change_entry_get_class ()">gupnp_cds_last_change_entry_get_class</a>
+ (<em class="parameter"><code><a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEntry"><span class="type">GUPnPCDSLastChangeEntry</span></a> *entry</code></em>);
+<span class="returnvalue">gboolean</span> <a class="link" href="GUPnPCDSLastChangeParser.html#gupnp-cds-last-change-entry-is-subtree-update" title="gupnp_cds_last_change_entry_is_subtree_update ()">gupnp_cds_last_change_entry_is_subtree_update</a>
+ (<em class="parameter"><code><a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEntry"><span class="type">GUPnPCDSLastChangeEntry</span></a> *entry</code></em>);
+<span class="returnvalue">guint32</span> <a class="link" href="GUPnPCDSLastChangeParser.html#gupnp-cds-last-change-entry-get-update-id" title="gupnp_cds_last_change_entry_get_update_id ()">gupnp_cds_last_change_entry_get_update_id</a>
+ (<em class="parameter"><code><a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEntry"><span class="type">GUPnPCDSLastChangeEntry</span></a> *entry</code></em>);
+</pre>
+</div>
+<div class="refsect1">
+<a name="GUPnPCDSLastChangeParser.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<pre class="synopsis">
+ GObject
+ +----GUPnPCDSLastChangeParser
+</pre>
+<pre class="synopsis">
+ GBoxed
+ +----GUPnPCDSLastChangeEntry
+</pre>
+</div>
+<div class="refsect1">
+<a name="GUPnPCDSLastChangeParser.description"></a><h2>Description</h2>
+<p>
+<a class="link" href="GUPnPCDSLastChangeParser.html" title="GUPnPCDSLastChangeParser"><span class="type">GUPnPCDSLastChangeParser</span></a> parses XML strings from
+CDS's LastChange state variable.
+</p>
+</div>
+<div class="refsect1">
+<a name="GUPnPCDSLastChangeParser.details"></a><h2>Details</h2>
+<div class="refsect2">
+<a name="GUPnPCDSLastChangeParser-struct"></a><h3>struct GUPnPCDSLastChangeParser</h3>
+<pre class="programlisting">struct GUPnPCDSLastChangeParser;</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="GUPnPCDSLastChangeEvent"></a><h3>enum GUPnPCDSLastChangeEvent</h3>
+<pre class="programlisting">typedef enum {
+ GUPNP_CDS_LAST_CHANGE_EVENT_INVALID,
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED,
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_REMOVED,
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
+ GUPNP_CDS_LAST_CHANGE_EVENT_ST_DONE
+} GUPnPCDSLastChangeEvent;
+</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="GUPnPCDSLastChangeEntry-struct"></a><h3>GUPnPCDSLastChangeEntry</h3>
+<pre class="programlisting">typedef struct _GUPnPCDSLastChangeEntry GUPnPCDSLastChangeEntry;</pre>
+<p>
+Opaque struct which contains information about the event.
+</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-cds-last-change-parser-new"></a><h3>gupnp_cds_last_change_parser_new ()</h3>
+<pre class="programlisting"><a class="link" href="GUPnPCDSLastChangeParser.html" title="GUPnPCDSLastChangeParser"><span class="returnvalue">GUPnPCDSLastChangeParser</span></a> * gupnp_cds_last_change_parser_new
+ (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
+<p>
+Create a new <a class="link" href="GUPnPCDSLastChangeParser.html" title="GUPnPCDSLastChangeParser"><span class="type">GUPnPCDSLastChangeParser</span></a>.
+</p>
+<p>
+This parser is able to parse LastChange as defined in the
+ContentDirectory:3 specification.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody><tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>A new instance of <a class="link" href="GUPnPCDSLastChangeParser.html" title="GUPnPCDSLastChangeParser"><span class="type">GUPnPCDSLastChangeParser</span></a>. <span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span>
+</td>
+</tr></tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-cds-last-change-parser-parse"></a><h3>gupnp_cds_last_change_parser_parse ()</h3>
+<pre class="programlisting"><span class="returnvalue">GList</span> * gupnp_cds_last_change_parser_parse (<em class="parameter"><code><a class="link" href="GUPnPCDSLastChangeParser.html" title="GUPnPCDSLastChangeParser"><span class="type">GUPnPCDSLastChangeParser</span></a> *parser</code></em>,
+ <em class="parameter"><code>const <span class="type">char</span> *last_change</code></em>,
+ <em class="parameter"><code><span class="type">GError</span> **error</code></em>);</pre>
+<p>
+Parse a LastChange XML document in the flavor defined by the
+ContentDirectory:3 specification.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>parser</code></em> :</span></p></td>
+<td><a class="link" href="GUPnPCDSLastChangeParser.html" title="GUPnPCDSLastChangeParser"><span class="type">GUPnPCDSLastChangeParser</span></a></td>
+</tr>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>last_change</code></em> :</span></p></td>
+<td>XML string to parse</td>
+</tr>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>error</code></em> :</span></p></td>
+<td>Return value for parser error or <code class="literal">NULL</code> to ingore</td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>List of <a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEntry"><span class="type">GUPnPCDSLastChangeEntry</span></a>s. <span class="annotation">[<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> GUPnPCDSLastChangeEntry][<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span>
+</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-cds-last-change-entry-ref"></a><h3>gupnp_cds_last_change_entry_ref ()</h3>
+<pre class="programlisting"><a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEntry"><span class="returnvalue">GUPnPCDSLastChangeEntry</span></a> * gupnp_cds_last_change_entry_ref
+ (<em class="parameter"><code><a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEntry"><span class="type">GUPnPCDSLastChangeEntry</span></a> *entry</code></em>);</pre>
+<p>
+Increase reference count of a <a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEntry"><span class="type">GUPnPCDSLastChangeEntry</span></a>.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>entry</code></em> :</span></p></td>
+<td>A <a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEntry"><span class="type">GUPnPCDSLastChangeEntry</span></a>
+</td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>The object passed in <em class="parameter"><code>entry</code></em>. <span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span>
+</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-cds-last-change-entry-unref"></a><h3>gupnp_cds_last_change_entry_unref ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span> gupnp_cds_last_change_entry_unref (<em class="parameter"><code><a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEntry"><span class="type">GUPnPCDSLastChangeEntry</span></a> *entry</code></em>);</pre>
+<p>
+Decrease reference count of a <a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEntry"><span class="type">GUPnPCDSLastChangeEntry</span></a>. If the reference
+count drops to 0, <em class="parameter"><code>entry</code></em> is freed.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody><tr>
+<td><p><span class="term"><em class="parameter"><code>entry</code></em> :</span></p></td>
+<td>A <a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEntry"><span class="type">GUPnPCDSLastChangeEntry</span></a>
+</td>
+</tr></tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-cds-last-change-entry-get-event"></a><h3>gupnp_cds_last_change_entry_get_event ()</h3>
+<pre class="programlisting"><a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEvent" title="enum GUPnPCDSLastChangeEvent"><span class="returnvalue">GUPnPCDSLastChangeEvent</span></a> gupnp_cds_last_change_entry_get_event
+ (<em class="parameter"><code><a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEntry"><span class="type">GUPnPCDSLastChangeEntry</span></a> *entry</code></em>);</pre>
+<p>
+Get the type of the last change entry as defined in
+<a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEvent" title="enum GUPnPCDSLastChangeEvent"><span class="type">GUPnPCDSLastChangeEvent</span></a>.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>entry</code></em> :</span></p></td>
+<td>A <a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEntry"><span class="type">GUPnPCDSLastChangeEntry</span></a>
+</td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>An event from the <a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEvent" title="enum GUPnPCDSLastChangeEvent"><span class="type">GUPnPCDSLastChangeEvent</span></a> or
+<code class="literal">GUPNP_CDS_LAST_CHANGE_EVENT_INVALID</code> if the entry is not valid.</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-cds-last-change-entry-get-object-id"></a><h3>gupnp_cds_last_change_entry_get_object_id ()</h3>
+<pre class="programlisting">const <span class="returnvalue">char</span> * gupnp_cds_last_change_entry_get_object_id
+ (<em class="parameter"><code><a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEntry"><span class="type">GUPnPCDSLastChangeEntry</span></a> *entry</code></em>);</pre>
+<p>
+Get the ID of the object in this change entry.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>entry</code></em> :</span></p></td>
+<td>A <a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEntry"><span class="type">GUPnPCDSLastChangeEntry</span></a>
+</td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>The id of the object of this entry. <span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span>
+</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-cds-last-change-entry-get-parent-id"></a><h3>gupnp_cds_last_change_entry_get_parent_id ()</h3>
+<pre class="programlisting">const <span class="returnvalue">char</span> * gupnp_cds_last_change_entry_get_parent_id
+ (<em class="parameter"><code><a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEntry"><span class="type">GUPnPCDSLastChangeEntry</span></a> *entry</code></em>);</pre>
+<p>
+Get the parent object id of the object in this change entry. This is only
+valid if <a class="link" href="GUPnPCDSLastChangeParser.html#gupnp-cds-last-change-entry-get-event" title="gupnp_cds_last_change_entry_get_event ()"><code class="function">gupnp_cds_last_change_entry_get_event()</code></a> returns
+<code class="literal">GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED</code>.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>entry</code></em> :</span></p></td>
+<td>A <a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEntry"><span class="type">GUPnPCDSLastChangeEntry</span></a>
+</td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>The id of the object's parent of this entry. <span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span>
+</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-cds-last-change-entry-get-class"></a><h3>gupnp_cds_last_change_entry_get_class ()</h3>
+<pre class="programlisting">const <span class="returnvalue">char</span> * gupnp_cds_last_change_entry_get_class
+ (<em class="parameter"><code><a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEntry"><span class="type">GUPnPCDSLastChangeEntry</span></a> *entry</code></em>);</pre>
+<p>
+Get the class of the object in this change entry. This is only
+valid if <a class="link" href="GUPnPCDSLastChangeParser.html#gupnp-cds-last-change-entry-get-event" title="gupnp_cds_last_change_entry_get_event ()"><code class="function">gupnp_cds_last_change_entry_get_event()</code></a> returns
+<code class="literal">GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED</code>.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>entry</code></em> :</span></p></td>
+<td>A <a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEntry"><span class="type">GUPnPCDSLastChangeEntry</span></a>
+</td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>The upnp class of the object of this entry. <span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span>
+</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-cds-last-change-entry-is-subtree-update"></a><h3>gupnp_cds_last_change_entry_is_subtree_update ()</h3>
+<pre class="programlisting"><span class="returnvalue">gboolean</span> gupnp_cds_last_change_entry_is_subtree_update
+ (<em class="parameter"><code><a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEntry"><span class="type">GUPnPCDSLastChangeEntry</span></a> *entry</code></em>);</pre>
+<p>
+Returns whether this entry is part of a subtree update.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>entry</code></em> :</span></p></td>
+<td>A <a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEntry"><span class="type">GUPnPCDSLastChangeEntry</span></a>
+</td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>
+<code class="literal">TRUE</code>, if the entry is part of a subtree update, <code class="literal">FALSE</code> otherwise.</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-cds-last-change-entry-get-update-id"></a><h3>gupnp_cds_last_change_entry_get_update_id ()</h3>
+<pre class="programlisting"><span class="returnvalue">guint32</span> gupnp_cds_last_change_entry_get_update_id
+ (<em class="parameter"><code><a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEntry"><span class="type">GUPnPCDSLastChangeEntry</span></a> *entry</code></em>);</pre>
+<p>
+Get the update id of the last change entry.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>entry</code></em> :</span></p></td>
+<td>A <a class="link" href="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEntry"><span class="type">GUPnPCDSLastChangeEntry</span></a>
+</td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>update id of the entry or 0 if the entry is not valid.</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+</div>
+<div class="footer">
+<hr>
+ Generated by GTK-Doc V1.18</div>
+</body>
+</html> \ No newline at end of file
diff --git a/doc/html/GUPnPDIDLLiteContainer.html b/doc/html/GUPnPDIDLLiteContainer.html
index 8208f58..f44da65 100644
--- a/doc/html/GUPnPDIDLLiteContainer.html
+++ b/doc/html/GUPnPDIDLLiteContainer.html
@@ -75,6 +75,26 @@
(<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteContainer.html" title="GUPnPDIDLLiteContainer"><span class="type">GUPnPDIDLLiteContainer</span></a> *container</code></em>,
<em class="parameter"><code>const <span class="type">char</span> *search_class</code></em>,
<em class="parameter"><code><span class="type">gboolean</span> include_derived</code></em>);
+<span class="returnvalue">gboolean</span> <a class="link" href="GUPnPDIDLLiteContainer.html#gupnp-didl-lite-container-container-update-id-is-set" title="gupnp_didl_lite_container_container_update_id_is_set ()">gupnp_didl_lite_container_container_update_id_is_set</a>
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteContainer.html" title="GUPnPDIDLLiteContainer"><span class="type">GUPnPDIDLLiteContainer</span></a> *container</code></em>);
+<span class="returnvalue">guint</span> <a class="link" href="GUPnPDIDLLiteContainer.html#gupnp-didl-lite-container-get-container-update-id" title="gupnp_didl_lite_container_get_container_update_id ()">gupnp_didl_lite_container_get_container_update_id</a>
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteContainer.html" title="GUPnPDIDLLiteContainer"><span class="type">GUPnPDIDLLiteContainer</span></a> *container</code></em>);
+<span class="returnvalue">GList</span> * <a class="link" href="GUPnPDIDLLiteContainer.html#gupnp-didl-lite-container-get-create-classes-full" title="gupnp_didl_lite_container_get_create_classes_full ()">gupnp_didl_lite_container_get_create_classes_full</a>
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteContainer.html" title="GUPnPDIDLLiteContainer"><span class="type">GUPnPDIDLLiteContainer</span></a> *container</code></em>);
+<span class="returnvalue">guint</span> <a class="link" href="GUPnPDIDLLiteContainer.html#gupnp-didl-lite-container-get-total-deleted-child-count" title="gupnp_didl_lite_container_get_total_deleted_child_count ()">gupnp_didl_lite_container_get_total_deleted_child_count</a>
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteContainer.html" title="GUPnPDIDLLiteContainer"><span class="type">GUPnPDIDLLiteContainer</span></a> *container</code></em>);
+<span class="returnvalue">void</span> <a class="link" href="GUPnPDIDLLiteContainer.html#gupnp-didl-lite-container-set-container-update-id" title="gupnp_didl_lite_container_set_container_update_id ()">gupnp_didl_lite_container_set_container_update_id</a>
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteContainer.html" title="GUPnPDIDLLiteContainer"><span class="type">GUPnPDIDLLiteContainer</span></a> *container</code></em>,
+ <em class="parameter"><code><span class="type">guint</span> update_id</code></em>);
+<span class="returnvalue">void</span> <a class="link" href="GUPnPDIDLLiteContainer.html#gupnp-didl-lite-container-set-total-deleted-child-count" title="gupnp_didl_lite_container_set_total_deleted_child_count ()">gupnp_didl_lite_container_set_total_deleted_child_count</a>
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteContainer.html" title="GUPnPDIDLLiteContainer"><span class="type">GUPnPDIDLLiteContainer</span></a> *container</code></em>,
+ <em class="parameter"><code><span class="type">guint</span> count</code></em>);
+<span class="returnvalue">gboolean</span> <a class="link" href="GUPnPDIDLLiteContainer.html#gupnp-didl-lite-container-total-deleted-child-count-is-set" title="gupnp_didl_lite_container_total_deleted_child_count_is_set ()">gupnp_didl_lite_container_total_deleted_child_count_is_set</a>
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteContainer.html" title="GUPnPDIDLLiteContainer"><span class="type">GUPnPDIDLLiteContainer</span></a> *container</code></em>);
+<span class="returnvalue">void</span> <a class="link" href="GUPnPDIDLLiteContainer.html#gupnp-didl-lite-container-unset-container-update-id" title="gupnp_didl_lite_container_unset_container_update_id ()">gupnp_didl_lite_container_unset_container_update_id</a>
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteContainer.html" title="GUPnPDIDLLiteContainer"><span class="type">GUPnPDIDLLiteContainer</span></a> *container</code></em>);
+<span class="returnvalue">void</span> <a class="link" href="GUPnPDIDLLiteContainer.html#gupnp-didl-lite-container-unset-total-deleted-child-count" title="gupnp_didl_lite_container_unset_total_deleted_child_count ()">gupnp_didl_lite_container_unset_total_deleted_child_count</a>
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteContainer.html" title="GUPnPDIDLLiteContainer"><span class="type">GUPnPDIDLLiteContainer</span></a> *container</code></em>);
</pre>
</div>
<div class="refsect1">
@@ -416,6 +436,201 @@ Add a new search class to the <em class="parameter"><code>container</code></em>.
</tbody>
</table></div>
</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-didl-lite-container-container-update-id-is-set"></a><h3>gupnp_didl_lite_container_container_update_id_is_set ()</h3>
+<pre class="programlisting"><span class="returnvalue">gboolean</span> gupnp_didl_lite_container_container_update_id_is_set
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteContainer.html" title="GUPnPDIDLLiteContainer"><span class="type">GUPnPDIDLLiteContainer</span></a> *container</code></em>);</pre>
+<p>
+Get whether the container update ID of the <em class="parameter"><code>container</code></em> is set.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>container</code></em> :</span></p></td>
+<td><a class="link" href="GUPnPDIDLLiteContainer.html" title="GUPnPDIDLLiteContainer"><span class="type">GUPnPDIDLLiteContainer</span></a></td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>
+<code class="literal">TRUE</code> if update ID is set, otherwise <code class="literal">FALSE</code>
+</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-didl-lite-container-get-container-update-id"></a><h3>gupnp_didl_lite_container_get_container_update_id ()</h3>
+<pre class="programlisting"><span class="returnvalue">guint</span> gupnp_didl_lite_container_get_container_update_id
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteContainer.html" title="GUPnPDIDLLiteContainer"><span class="type">GUPnPDIDLLiteContainer</span></a> *container</code></em>);</pre>
+<p>
+Get the container update ID of the <em class="parameter"><code>container</code></em>.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>container</code></em> :</span></p></td>
+<td><a class="link" href="GUPnPDIDLLiteContainer.html" title="GUPnPDIDLLiteContainer"><span class="type">GUPnPDIDLLiteContainer</span></a></td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>The container update ID of the <em class="parameter"><code>container</code></em>.</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-didl-lite-container-get-create-classes-full"></a><h3>gupnp_didl_lite_container_get_create_classes_full ()</h3>
+<pre class="programlisting"><span class="returnvalue">GList</span> * gupnp_didl_lite_container_get_create_classes_full
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteContainer.html" title="GUPnPDIDLLiteContainer"><span class="type">GUPnPDIDLLiteContainer</span></a> *container</code></em>);</pre>
+<p>
+Gets the list of create classes of the <em class="parameter"><code>container</code></em>.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>container</code></em> :</span></p></td>
+<td><a class="link" href="GUPnPDIDLLiteContainer.html" title="GUPnPDIDLLiteContainer"><span class="type">GUPnPDIDLLiteContainer</span></a></td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>The list
+of create classes belonging to <em class="parameter"><code>container</code></em>, or <code class="literal">NULL</code>.
+<span class="type">g_list_free</span> the returned list after usage and unref each object in it. <span class="annotation">[<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> GUPnPDIDLLiteCreateClass*][<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span>
+</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-didl-lite-container-get-total-deleted-child-count"></a><h3>gupnp_didl_lite_container_get_total_deleted_child_count ()</h3>
+<pre class="programlisting"><span class="returnvalue">guint</span> gupnp_didl_lite_container_get_total_deleted_child_count
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteContainer.html" title="GUPnPDIDLLiteContainer"><span class="type">GUPnPDIDLLiteContainer</span></a> *container</code></em>);</pre>
+<p>
+Get the total deleted child count of the <em class="parameter"><code>container</code></em>.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>container</code></em> :</span></p></td>
+<td><a class="link" href="GUPnPDIDLLiteContainer.html" title="GUPnPDIDLLiteContainer"><span class="type">GUPnPDIDLLiteContainer</span></a></td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>The total deleted child count of the <em class="parameter"><code>container</code></em>.</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-didl-lite-container-set-container-update-id"></a><h3>gupnp_didl_lite_container_set_container_update_id ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span> gupnp_didl_lite_container_set_container_update_id
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteContainer.html" title="GUPnPDIDLLiteContainer"><span class="type">GUPnPDIDLLiteContainer</span></a> *container</code></em>,
+ <em class="parameter"><code><span class="type">guint</span> update_id</code></em>);</pre>
+<p>
+Set the container update ID of the <em class="parameter"><code>container</code></em>.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>container</code></em> :</span></p></td>
+<td><a class="link" href="GUPnPDIDLLiteContainer.html" title="GUPnPDIDLLiteContainer"><span class="type">GUPnPDIDLLiteContainer</span></a></td>
+</tr>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>update_id</code></em> :</span></p></td>
+<td>The container update ID</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-didl-lite-container-set-total-deleted-child-count"></a><h3>gupnp_didl_lite_container_set_total_deleted_child_count ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span> gupnp_didl_lite_container_set_total_deleted_child_count
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteContainer.html" title="GUPnPDIDLLiteContainer"><span class="type">GUPnPDIDLLiteContainer</span></a> *container</code></em>,
+ <em class="parameter"><code><span class="type">guint</span> count</code></em>);</pre>
+<p>
+Set the container update ID of the <em class="parameter"><code>container</code></em>.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>container</code></em> :</span></p></td>
+<td><a class="link" href="GUPnPDIDLLiteContainer.html" title="GUPnPDIDLLiteContainer"><span class="type">GUPnPDIDLLiteContainer</span></a></td>
+</tr>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>count</code></em> :</span></p></td>
+<td>The container update ID</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-didl-lite-container-total-deleted-child-count-is-set"></a><h3>gupnp_didl_lite_container_total_deleted_child_count_is_set ()</h3>
+<pre class="programlisting"><span class="returnvalue">gboolean</span> gupnp_didl_lite_container_total_deleted_child_count_is_set
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteContainer.html" title="GUPnPDIDLLiteContainer"><span class="type">GUPnPDIDLLiteContainer</span></a> *container</code></em>);</pre>
+<p>
+Get whether the total deleted child conut of the <em class="parameter"><code>container</code></em> is set.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>container</code></em> :</span></p></td>
+<td><a class="link" href="GUPnPDIDLLiteContainer.html" title="GUPnPDIDLLiteContainer"><span class="type">GUPnPDIDLLiteContainer</span></a></td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>
+<code class="literal">TRUE</code> if property is set, otherwise <code class="literal">FALSE</code>
+</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-didl-lite-container-unset-container-update-id"></a><h3>gupnp_didl_lite_container_unset_container_update_id ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span> gupnp_didl_lite_container_unset_container_update_id
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteContainer.html" title="GUPnPDIDLLiteContainer"><span class="type">GUPnPDIDLLiteContainer</span></a> *container</code></em>);</pre>
+<p>
+Unset the container update ID property of the <em class="parameter"><code>container</code></em>.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody><tr>
+<td><p><span class="term"><em class="parameter"><code>container</code></em> :</span></p></td>
+<td><a class="link" href="GUPnPDIDLLiteContainer.html" title="GUPnPDIDLLiteContainer"><span class="type">GUPnPDIDLLiteContainer</span></a></td>
+</tr></tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-didl-lite-container-unset-total-deleted-child-count"></a><h3>gupnp_didl_lite_container_unset_total_deleted_child_count ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span> gupnp_didl_lite_container_unset_total_deleted_child_count
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteContainer.html" title="GUPnPDIDLLiteContainer"><span class="type">GUPnPDIDLLiteContainer</span></a> *container</code></em>);</pre>
+<p>
+Unset the total deleted child count property of the <em class="parameter"><code>container</code></em>.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody><tr>
+<td><p><span class="term"><em class="parameter"><code>container</code></em> :</span></p></td>
+<td><a class="link" href="GUPnPDIDLLiteContainer.html" title="GUPnPDIDLLiteContainer"><span class="type">GUPnPDIDLLiteContainer</span></a></td>
+</tr></tbody>
+</table></div>
+</div>
</div>
<div class="refsect1">
<a name="GUPnPDIDLLiteContainer.property-details"></a><h2>Property Details</h2>
diff --git a/doc/html/GUPnPDIDLLiteContributor.html b/doc/html/GUPnPDIDLLiteContributor.html
index a24152b..601b868 100644
--- a/doc/html/GUPnPDIDLLiteContributor.html
+++ b/doc/html/GUPnPDIDLLiteContributor.html
@@ -7,7 +7,7 @@
<link rel="home" href="index.html" title="GUPnP A/V Reference Manual">
<link rel="up" href="ch01.html" title="GUPnP A/V">
<link rel="prev" href="GUPnPDIDLLiteDescriptor.html" title="GUPnPDIDLLiteDescriptor">
-<link rel="next" href="GUPnPLastChangeParser.html" title="GUPnPLastChangeParser">
+<link rel="next" href="gupnp-av-GUPnPDIDLLiteCreateClass.html" title="GUPnPDIDLLiteCreateClass">
<meta name="generator" content="GTK-Doc V1.18 (XML mode)">
<link rel="stylesheet" href="style.css" type="text/css">
</head>
@@ -18,7 +18,7 @@
<td><a accesskey="u" href="ch01.html"><img src="up.png" width="24" height="24" border="0" alt="Up"></a></td>
<td><a accesskey="h" href="index.html"><img src="home.png" width="24" height="24" border="0" alt="Home"></a></td>
<th width="100%" align="center">GUPnP A/V Reference Manual</th>
-<td><a accesskey="n" href="GUPnPLastChangeParser.html"><img src="right.png" width="24" height="24" border="0" alt="Next"></a></td>
+<td><a accesskey="n" href="gupnp-av-GUPnPDIDLLiteCreateClass.html"><img src="right.png" width="24" height="24" border="0" alt="Next"></a></td>
</tr>
<tr><td colspan="5" class="shortcuts">
<a href="#GUPnPDIDLLiteContributor.synopsis" class="shortcut">Top</a>
diff --git a/doc/html/GUPnPDIDLLiteItem.html b/doc/html/GUPnPDIDLLiteItem.html
index 5fb8906..5119289 100644
--- a/doc/html/GUPnPDIDLLiteItem.html
+++ b/doc/html/GUPnPDIDLLiteItem.html
@@ -45,6 +45,9 @@
const <span class="returnvalue">char</span> * <a class="link" href="GUPnPDIDLLiteItem.html#gupnp-didl-lite-item-get-ref-id" title="gupnp_didl_lite_item_get_ref_id ()">gupnp_didl_lite_item_get_ref_id</a> (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteItem.html" title="GUPnPDIDLLiteItem"><span class="type">GUPnPDIDLLiteItem</span></a> *item</code></em>);
<span class="returnvalue">void</span> <a class="link" href="GUPnPDIDLLiteItem.html#gupnp-didl-lite-item-set-ref-id" title="gupnp_didl_lite_item_set_ref_id ()">gupnp_didl_lite_item_set_ref_id</a> (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteItem.html" title="GUPnPDIDLLiteItem"><span class="type">GUPnPDIDLLiteItem</span></a> *item</code></em>,
<em class="parameter"><code>const <span class="type">char</span> *ref_id</code></em>);
+<span class="returnvalue">glong</span> <a class="link" href="GUPnPDIDLLiteItem.html#gupnp-didl-lite-item-get-lifetime" title="gupnp_didl_lite_item_get_lifetime ()">gupnp_didl_lite_item_get_lifetime</a> (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteItem.html" title="GUPnPDIDLLiteItem"><span class="type">GUPnPDIDLLiteItem</span></a> *item</code></em>);
+<span class="returnvalue">void</span> <a class="link" href="GUPnPDIDLLiteItem.html#gupnp-didl-lite-item-set-lifetime" title="gupnp_didl_lite_item_set_lifetime ()">gupnp_didl_lite_item_set_lifetime</a> (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteItem.html" title="GUPnPDIDLLiteItem"><span class="type">GUPnPDIDLLiteItem</span></a> *item</code></em>,
+ <em class="parameter"><code><span class="type">glong</span> lifetime</code></em>);
</pre>
</div>
<div class="refsect1">
@@ -58,6 +61,7 @@ const <span class="returnvalue">char</span> * <a class="link" href="GUPnP
<div class="refsect1">
<a name="GUPnPDIDLLiteItem.properties"></a><h2>Properties</h2>
<pre class="synopsis">
+ "<a class="link" href="GUPnPDIDLLiteItem.html#GUPnPDIDLLiteItem--lifetime" title='The "lifetime" property'>lifetime</a>" <span class="type">glong</span> : Read / Write
"<a class="link" href="GUPnPDIDLLiteItem.html#GUPnPDIDLLiteItem--ref-id" title='The "ref-id" property'>ref-id</a>" <span class="type">gchar</span>* : Read / Write
</pre>
</div>
@@ -116,10 +120,57 @@ Set the ref ID of the <em class="parameter"><code>item</code></em>.
</tbody>
</table></div>
</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-didl-lite-item-get-lifetime"></a><h3>gupnp_didl_lite_item_get_lifetime ()</h3>
+<pre class="programlisting"><span class="returnvalue">glong</span> gupnp_didl_lite_item_get_lifetime (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteItem.html" title="GUPnPDIDLLiteItem"><span class="type">GUPnPDIDLLiteItem</span></a> *item</code></em>);</pre>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>item</code></em> :</span></p></td>
+<td><a class="link" href="GUPnPDIDLLiteItem.html" title="GUPnPDIDLLiteItem"><span class="type">GUPnPDIDLLiteItem</span></a></td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>-1 if unset or the lifetime (in seconds) of the current item.</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-didl-lite-item-set-lifetime"></a><h3>gupnp_didl_lite_item_set_lifetime ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span> gupnp_didl_lite_item_set_lifetime (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteItem.html" title="GUPnPDIDLLiteItem"><span class="type">GUPnPDIDLLiteItem</span></a> *item</code></em>,
+ <em class="parameter"><code><span class="type">glong</span> lifetime</code></em>);</pre>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>item</code></em> :</span></p></td>
+<td><a class="link" href="GUPnPDIDLLiteItem.html" title="GUPnPDIDLLiteItem"><span class="type">GUPnPDIDLLiteItem</span></a></td>
+</tr>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>lifetime</code></em> :</span></p></td>
+<td>The lifetime (in seconds) of this item in a media collection.</td>
+</tr>
+</tbody>
+</table></div>
+</div>
</div>
<div class="refsect1">
<a name="GUPnPDIDLLiteItem.property-details"></a><h2>Property Details</h2>
<div class="refsect2">
+<a name="GUPnPDIDLLiteItem--lifetime"></a><h3>The <code class="literal">"lifetime"</code> property</h3>
+<pre class="programlisting"> "lifetime" <span class="type">glong</span> : Read / Write</pre>
+<p>
+The lifetime in seconds of this DIDLLite item in a media collection.
+</p>
+<p>Allowed values: &gt;= -1</p>
+<p>Default value: -1</p>
+</div>
+<hr>
+<div class="refsect2">
<a name="GUPnPDIDLLiteItem--ref-id"></a><h3>The <code class="literal">"ref-id"</code> property</h3>
<pre class="programlisting"> "ref-id" <span class="type">gchar</span>* : Read / Write</pre>
<p>
diff --git a/doc/html/GUPnPDIDLLiteObject.html b/doc/html/GUPnPDIDLLiteObject.html
index 0b7b7d8..05f2315 100644
--- a/doc/html/GUPnPDIDLLiteObject.html
+++ b/doc/html/GUPnPDIDLLiteObject.html
@@ -43,6 +43,7 @@
<a name="GUPnPDIDLLiteObject.synopsis"></a><h2>Synopsis</h2>
<pre class="synopsis"> <a class="link" href="GUPnPDIDLLiteObject.html#GUPnPDIDLLiteObject-struct" title="GUPnPDIDLLiteObject">GUPnPDIDLLiteObject</a>;
enum <a class="link" href="GUPnPDIDLLiteObject.html#GUPnPOCMFlags" title="enum GUPnPOCMFlags">GUPnPOCMFlags</a>;
+enum <a class="link" href="GUPnPDIDLLiteObject.html#GUPnPDIDLLiteFragmentResult" title="enum GUPnPDIDLLiteFragmentResult">GUPnPDIDLLiteFragmentResult</a>;
<span class="returnvalue">xmlNode</span> * <a class="link" href="GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-get-xml-node" title="gupnp_didl_lite_object_get_xml_node ()">gupnp_didl_lite_object_get_xml_node</a> (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a> *object</code></em>);
<span class="returnvalue">xmlNsPtr</span> <a class="link" href="GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-get-upnp-namespace" title="gupnp_didl_lite_object_get_upnp_namespace ()">gupnp_didl_lite_object_get_upnp_namespace</a>
(<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a> *object</code></em>);
@@ -138,6 +139,35 @@ const <span class="returnvalue">char</span> * <a class="link" href="GUPnP
<span class="returnvalue">void</span> <a class="link" href="GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-set-dlna-managed" title="gupnp_didl_lite_object_set_dlna_managed ()">gupnp_didl_lite_object_set_dlna_managed</a>
(<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a> *object</code></em>,
<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteObject.html#GUPnPOCMFlags" title="enum GUPnPOCMFlags"><span class="type">GUPnPOCMFlags</span></a> dlna_managed</code></em>);
+<a class="link" href="GUPnPDIDLLiteObject.html#GUPnPDIDLLiteFragmentResult" title="enum GUPnPDIDLLiteFragmentResult"><span class="returnvalue">GUPnPDIDLLiteFragmentResult</span></a> <a class="link" href="GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-apply-fragments" title="gupnp_didl_lite_object_apply_fragments ()">gupnp_didl_lite_object_apply_fragments</a>
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a> *object</code></em>,
+ <em class="parameter"><code><span class="type">gchar</span> **current_fragments</code></em>,
+ <em class="parameter"><code><span class="type">gint</span> current_size</code></em>,
+ <em class="parameter"><code><span class="type">gchar</span> **new_fragments</code></em>,
+ <em class="parameter"><code><span class="type">gint</span> new_size</code></em>);
+<span class="returnvalue">char</span> * <a class="link" href="GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-get-album-xml-string" title="gupnp_didl_lite_object_get_album_xml_string ()">gupnp_didl_lite_object_get_album_xml_string</a>
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a> *object</code></em>);
+<span class="returnvalue">char</span> * <a class="link" href="GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-get-artists-xml-string" title="gupnp_didl_lite_object_get_artists_xml_string ()">gupnp_didl_lite_object_get_artists_xml_string</a>
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a> *object</code></em>);
+<span class="returnvalue">char</span> * <a class="link" href="GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-get-date-xml-string" title="gupnp_didl_lite_object_get_date_xml_string ()">gupnp_didl_lite_object_get_date_xml_string</a>
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a> *object</code></em>);
+<span class="returnvalue">char</span> * <a class="link" href="GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-get-title-xml-string" title="gupnp_didl_lite_object_get_title_xml_string ()">gupnp_didl_lite_object_get_title_xml_string</a>
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a> *object</code></em>);
+<span class="returnvalue">char</span> * <a class="link" href="GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-get-track-number-xml-string" title="gupnp_didl_lite_object_get_track_number_xml_string ()">gupnp_didl_lite_object_get_track_number_xml_string</a>
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a> *object</code></em>);
+<span class="returnvalue">guint</span> <a class="link" href="GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-get-update-id" title="gupnp_didl_lite_object_get_update_id ()">gupnp_didl_lite_object_get_update_id</a>
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a> *object</code></em>);
+<span class="returnvalue">char</span> * <a class="link" href="GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-get-upnp-class-xml-string" title="gupnp_didl_lite_object_get_upnp_class_xml_string ()">gupnp_didl_lite_object_get_upnp_class_xml_string</a>
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a> *object</code></em>);
+<span class="returnvalue">void</span> <a class="link" href="GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-set-update-id" title="gupnp_didl_lite_object_set_update_id ()">gupnp_didl_lite_object_set_update_id</a>
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a> *object</code></em>,
+ <em class="parameter"><code><span class="type">guint</span> update_id</code></em>);
+<span class="returnvalue">void</span> <a class="link" href="GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-unset-artists" title="gupnp_didl_lite_object_unset_artists ()">gupnp_didl_lite_object_unset_artists</a>
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a> *object</code></em>);
+<span class="returnvalue">void</span> <a class="link" href="GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-unset-update-id" title="gupnp_didl_lite_object_unset_update_id ()">gupnp_didl_lite_object_unset_update_id</a>
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a> *object</code></em>);
+<span class="returnvalue">gboolean</span> <a class="link" href="GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-update-id-is-set" title="gupnp_didl_lite_object_update_id_is_set ()">gupnp_didl_lite_object_update_id_is_set</a>
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a> *object</code></em>);
</pre>
</div>
<div class="refsect1">
@@ -245,6 +275,83 @@ Interoperability Guidelines Volume 1, October 2006.
</div>
<hr>
<div class="refsect2">
+<a name="GUPnPDIDLLiteFragmentResult"></a><h3>enum GUPnPDIDLLiteFragmentResult</h3>
+<pre class="programlisting">typedef enum {
+ GUPNP_DIDL_LITE_FRAGMENT_RESULT_OK,
+ GUPNP_DIDL_LITE_FRAGMENT_RESULT_CURRENT_BAD_XML,
+ GUPNP_DIDL_LITE_FRAGMENT_RESULT_NEW_BAD_XML,
+ GUPNP_DIDL_LITE_FRAGMENT_RESULT_CURRENT_INVALID,
+ GUPNP_DIDL_LITE_FRAGMENT_RESULT_NEW_INVALID,
+ GUPNP_DIDL_LITE_FRAGMENT_RESULT_REQUIRED_TAG,
+ GUPNP_DIDL_LITE_FRAGMENT_RESULT_READONLY_TAG,
+ GUPNP_DIDL_LITE_FRAGMENT_RESULT_MISMATCH,
+ GUPNP_DIDL_LITE_FRAGMENT_RESULT_UNKNOWN_ERROR
+} GUPnPDIDLLiteFragmentResult;
+</pre>
+<p>
+Possible return values of the <a class="link" href="GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-apply-fragments" title="gupnp_didl_lite_object_apply_fragments ()"><code class="function">gupnp_didl_lite_object_apply_fragments()</code></a> call.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><a name="GUPNP-DIDL-LITE-FRAGMENT-RESULT-OK:CAPS"></a><span class="term"><code class="literal">GUPNP_DIDL_LITE_FRAGMENT_RESULT_OK</code></span></p></td>
+<td>Operation succeeded.
+</td>
+</tr>
+<tr>
+<td><p><a name="GUPNP-DIDL-LITE-FRAGMENT-RESULT-CURRENT-BAD-XML:CAPS"></a><span class="term"><code class="literal">GUPNP_DIDL_LITE_FRAGMENT_RESULT_CURRENT_BAD_XML</code></span></p></td>
+<td>Current set of fragments
+is bad XML
+</td>
+</tr>
+<tr>
+<td><p><a name="GUPNP-DIDL-LITE-FRAGMENT-RESULT-NEW-BAD-XML:CAPS"></a><span class="term"><code class="literal">GUPNP_DIDL_LITE_FRAGMENT_RESULT_NEW_BAD_XML</code></span></p></td>
+<td>New set of fragments is bad
+XML
+</td>
+</tr>
+<tr>
+<td><p><a name="GUPNP-DIDL-LITE-FRAGMENT-RESULT-CURRENT-INVALID:CAPS"></a><span class="term"><code class="literal">GUPNP_DIDL_LITE_FRAGMENT_RESULT_CURRENT_INVALID</code></span></p></td>
+<td>Current set of fragments
+is invalid
+</td>
+</tr>
+<tr>
+<td><p><a name="GUPNP-DIDL-LITE-FRAGMENT-RESULT-NEW-INVALID:CAPS"></a><span class="term"><code class="literal">GUPNP_DIDL_LITE_FRAGMENT_RESULT_NEW_INVALID</code></span></p></td>
+<td>New set of fragments is
+invalid
+</td>
+</tr>
+<tr>
+<td><p><a name="GUPNP-DIDL-LITE-FRAGMENT-RESULT-REQUIRED-TAG:CAPS"></a><span class="term"><code class="literal">GUPNP_DIDL_LITE_FRAGMENT_RESULT_REQUIRED_TAG</code></span></p></td>
+<td>Trying to remove a required
+tag
+</td>
+</tr>
+<tr>
+<td><p><a name="GUPNP-DIDL-LITE-FRAGMENT-RESULT-READONLY-TAG:CAPS"></a><span class="term"><code class="literal">GUPNP_DIDL_LITE_FRAGMENT_RESULT_READONLY_TAG</code></span></p></td>
+<td>Trying to modify or remove a
+read-only tag
+</td>
+</tr>
+<tr>
+<td><p><a name="GUPNP-DIDL-LITE-FRAGMENT-RESULT-MISMATCH:CAPS"></a><span class="term"><code class="literal">GUPNP_DIDL_LITE_FRAGMENT_RESULT_MISMATCH</code></span></p></td>
+<td>Length of the two fragment sets
+does not match
+</td>
+</tr>
+<tr>
+<td><p><a name="GUPNP-DIDL-LITE-FRAGMENT-RESULT-UNKNOWN-ERROR:CAPS"></a><span class="term"><code class="literal">GUPNP_DIDL_LITE_FRAGMENT_RESULT_UNKNOWN_ERROR</code></span></p></td>
+<td>General error sink if none
+of the others applies.
+</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
<a name="gupnp-didl-lite-object-get-xml-node"></a><h3>gupnp_didl_lite_object_get_xml_node ()</h3>
<pre class="programlisting"><span class="returnvalue">xmlNode</span> * gupnp_didl_lite_object_get_xml_node (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a> *object</code></em>);</pre>
<p>
@@ -1385,6 +1492,301 @@ Set the 'dlna:dlnaManaged' attribute of the <em class="parameter"><code>object</
</tbody>
</table></div>
</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-didl-lite-object-apply-fragments"></a><h3>gupnp_didl_lite_object_apply_fragments ()</h3>
+<pre class="programlisting"><a class="link" href="GUPnPDIDLLiteObject.html#GUPnPDIDLLiteFragmentResult" title="enum GUPnPDIDLLiteFragmentResult"><span class="returnvalue">GUPnPDIDLLiteFragmentResult</span></a> gupnp_didl_lite_object_apply_fragments
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a> *object</code></em>,
+ <em class="parameter"><code><span class="type">gchar</span> **current_fragments</code></em>,
+ <em class="parameter"><code><span class="type">gint</span> current_size</code></em>,
+ <em class="parameter"><code><span class="type">gchar</span> **new_fragments</code></em>,
+ <em class="parameter"><code><span class="type">gint</span> new_size</code></em>);</pre>
+<p>
+Updates object by applying <em class="parameter"><code>new_fragments</code></em> in places of
+<em class="parameter"><code>current_fragments</code></em>. For <em class="parameter"><code>current_size</code></em> and <em class="parameter"><code>new_size</code></em> -1 can be
+passed when respectively <em class="parameter"><code>current_fragments</code></em> and <em class="parameter"><code>new_fragments</code></em> are
+NULL terminated.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>object</code></em> :</span></p></td>
+<td>The <a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a>
+</td>
+</tr>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>current_fragments</code></em> :</span></p></td>
+<td>XML
+fragments of <em class="parameter"><code>object</code></em>. <span class="annotation">[<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=current_size][<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span>
+</td>
+</tr>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>current_size</code></em> :</span></p></td>
+<td>Size of <em class="parameter"><code>current_fragments</code></em> or -1.</td>
+</tr>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>new_fragments</code></em> :</span></p></td>
+<td>Substitutes
+for <em class="parameter"><code>current_fragments</code></em>. <span class="annotation">[<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=new_size][<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span>
+</td>
+</tr>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>new_size</code></em> :</span></p></td>
+<td>Size of <em class="parameter"><code>new_fragments</code></em> or -1.</td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>Result of operation.</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-didl-lite-object-get-album-xml-string"></a><h3>gupnp_didl_lite_object_get_album_xml_string ()</h3>
+<pre class="programlisting"><span class="returnvalue">char</span> * gupnp_didl_lite_object_get_album_xml_string
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a> *object</code></em>);</pre>
+<p>
+Creates a string representation of the DIDL-Lite XML fragment related to the
+object album.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>object</code></em> :</span></p></td>
+<td>A <a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a>
+</td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>A DIDL-Lite XML fragment string, or <code class="literal">NULL</code>. <span class="type">g_free</span> after usage.</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-didl-lite-object-get-artists-xml-string"></a><h3>gupnp_didl_lite_object_get_artists_xml_string ()</h3>
+<pre class="programlisting"><span class="returnvalue">char</span> * gupnp_didl_lite_object_get_artists_xml_string
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a> *object</code></em>);</pre>
+<p>
+Creates a string representation of the DIDL-Lite XML fragments related to the
+object artists.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>object</code></em> :</span></p></td>
+<td>A <a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a>
+</td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>A DIDL-Lite XML fragment string, or <code class="literal">NULL</code>. <span class="type">g_free</span> after usage.</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-didl-lite-object-get-date-xml-string"></a><h3>gupnp_didl_lite_object_get_date_xml_string ()</h3>
+<pre class="programlisting"><span class="returnvalue">char</span> * gupnp_didl_lite_object_get_date_xml_string
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a> *object</code></em>);</pre>
+<p>
+Creates a string representation of the DIDL-Lite XML fragment related to the
+object date.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>object</code></em> :</span></p></td>
+<td>A <a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a>
+</td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>A DIDL-Lite XML fragment string, or <code class="literal">NULL</code>. <span class="type">g_free</span> after usage.</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-didl-lite-object-get-title-xml-string"></a><h3>gupnp_didl_lite_object_get_title_xml_string ()</h3>
+<pre class="programlisting"><span class="returnvalue">char</span> * gupnp_didl_lite_object_get_title_xml_string
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a> *object</code></em>);</pre>
+<p>
+Creates a string representation of the DIDL-Lite XML fragment related to the
+object title.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>object</code></em> :</span></p></td>
+<td>A <a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a>
+</td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>A DIDL-Lite XML fragment string, or <code class="literal">NULL</code>. <span class="type">g_free</span> after usage.</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-didl-lite-object-get-track-number-xml-string"></a><h3>gupnp_didl_lite_object_get_track_number_xml_string ()</h3>
+<pre class="programlisting"><span class="returnvalue">char</span> * gupnp_didl_lite_object_get_track_number_xml_string
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a> *object</code></em>);</pre>
+<p>
+Creates a string representation of the DIDL-Lite XML fragment related to the
+object track number.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>object</code></em> :</span></p></td>
+<td>A <a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a>
+</td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>A DIDL-Lite XML fragment string, or <code class="literal">NULL</code>. <span class="type">g_free</span> after usage.</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-didl-lite-object-get-update-id"></a><h3>gupnp_didl_lite_object_get_update_id ()</h3>
+<pre class="programlisting"><span class="returnvalue">guint</span> gupnp_didl_lite_object_get_update_id
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a> *object</code></em>);</pre>
+<p>
+Get the update ID of the <em class="parameter"><code>object</code></em>.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>object</code></em> :</span></p></td>
+<td><a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a></td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>The update ID of the <em class="parameter"><code>object</code></em>.</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-didl-lite-object-get-upnp-class-xml-string"></a><h3>gupnp_didl_lite_object_get_upnp_class_xml_string ()</h3>
+<pre class="programlisting"><span class="returnvalue">char</span> * gupnp_didl_lite_object_get_upnp_class_xml_string
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a> *object</code></em>);</pre>
+<p>
+Creates a string representation of the DIDL-Lite XML fragment related to the
+object UPnP class.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>object</code></em> :</span></p></td>
+<td>A <a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a>
+</td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>A DIDL-Lite XML fragment string, or <code class="literal">NULL</code>. <span class="type">g_free</span> after usage.</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-didl-lite-object-set-update-id"></a><h3>gupnp_didl_lite_object_set_update_id ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span> gupnp_didl_lite_object_set_update_id
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a> *object</code></em>,
+ <em class="parameter"><code><span class="type">guint</span> update_id</code></em>);</pre>
+<p>
+Set the update ID of the <em class="parameter"><code>object</code></em>.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>object</code></em> :</span></p></td>
+<td><a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a></td>
+</tr>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>update_id</code></em> :</span></p></td>
+<td>Update ID</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-didl-lite-object-unset-artists"></a><h3>gupnp_didl_lite_object_unset_artists ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span> gupnp_didl_lite_object_unset_artists
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a> *object</code></em>);</pre>
+<p>
+Unset the artists properties of the <em class="parameter"><code>object</code></em>.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody><tr>
+<td><p><span class="term"><em class="parameter"><code>object</code></em> :</span></p></td>
+<td><a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a></td>
+</tr></tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-didl-lite-object-unset-update-id"></a><h3>gupnp_didl_lite_object_unset_update_id ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span> gupnp_didl_lite_object_unset_update_id
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a> *object</code></em>);</pre>
+<p>
+Unset the update ID property of the <em class="parameter"><code>object</code></em>.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody><tr>
+<td><p><span class="term"><em class="parameter"><code>object</code></em> :</span></p></td>
+<td><a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a></td>
+</tr></tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-didl-lite-object-update-id-is-set"></a><h3>gupnp_didl_lite_object_update_id_is_set ()</h3>
+<pre class="programlisting"><span class="returnvalue">gboolean</span> gupnp_didl_lite_object_update_id_is_set
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a> *object</code></em>);</pre>
+<p>
+Get whether the update ID of the <em class="parameter"><code>object</code></em> is set.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>object</code></em> :</span></p></td>
+<td><a class="link" href="GUPnPDIDLLiteObject.html" title="GUPnPDIDLLiteObject"><span class="type">GUPnPDIDLLiteObject</span></a></td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>
+<code class="literal">TRUE</code> if update ID is set, otherwise <code class="literal">FALSE</code>
+</td>
+</tr>
+</tbody>
+</table></div>
+</div>
</div>
<div class="refsect1">
<a name="GUPnPDIDLLiteObject.property-details"></a><h2>Property Details</h2>
diff --git a/doc/html/GUPnPDIDLLiteResource.html b/doc/html/GUPnPDIDLLiteResource.html
index 2c30af4..2b6fde6 100644
--- a/doc/html/GUPnPDIDLLiteResource.html
+++ b/doc/html/GUPnPDIDLLiteResource.html
@@ -51,12 +51,12 @@
(<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteResource.html" title="GUPnPDIDLLiteResource"><span class="type">GUPnPDIDLLiteResource</span></a> *resource</code></em>,
<em class="parameter"><code><a class="link" href="GUPnPProtocolInfo.html" title="GUPnPProtocolInfo"><span class="type">GUPnPProtocolInfo</span></a> *info</code></em>);
<span class="returnvalue">void</span> <a class="link" href="GUPnPDIDLLiteResource.html#gupnp-didl-lite-resource-set-size" title="gupnp_didl_lite_resource_set_size ()">gupnp_didl_lite_resource_set_size</a> (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteResource.html" title="GUPnPDIDLLiteResource"><span class="type">GUPnPDIDLLiteResource</span></a> *resource</code></em>,
- <em class="parameter"><code>long <span class="type">size</span> Param2</code></em>);
+ <em class="parameter"><code><span class="type">glong</span> size</code></em>);
<span class="returnvalue">void</span> <a class="link" href="GUPnPDIDLLiteResource.html#gupnp-didl-lite-resource-set-size64" title="gupnp_didl_lite_resource_set_size64 ()">gupnp_didl_lite_resource_set_size64</a> (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteResource.html" title="GUPnPDIDLLiteResource"><span class="type">GUPnPDIDLLiteResource</span></a> *resource</code></em>,
<em class="parameter"><code><span class="type">gint64</span> size</code></em>);
<span class="returnvalue">void</span> <a class="link" href="GUPnPDIDLLiteResource.html#gupnp-didl-lite-resource-set-duration" title="gupnp_didl_lite_resource_set_duration ()">gupnp_didl_lite_resource_set_duration</a>
(<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteResource.html" title="GUPnPDIDLLiteResource"><span class="type">GUPnPDIDLLiteResource</span></a> *resource</code></em>,
- <em class="parameter"><code>long <span class="type">duration</span> Param2</code></em>);
+ <em class="parameter"><code><span class="type">glong</span> duration</code></em>);
<span class="returnvalue">void</span> <a class="link" href="GUPnPDIDLLiteResource.html#gupnp-didl-lite-resource-set-bitrate" title="gupnp_didl_lite_resource_set_bitrate ()">gupnp_didl_lite_resource_set_bitrate</a>
(<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteResource.html" title="GUPnPDIDLLiteResource"><span class="type">GUPnPDIDLLiteResource</span></a> *resource</code></em>,
<em class="parameter"><code><span class="type">int</span> bitrate</code></em>);
@@ -104,6 +104,15 @@ const <span class="returnvalue">char</span> * <a class="link" href="GUPnP
(<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteResource.html" title="GUPnPDIDLLiteResource"><span class="type">GUPnPDIDLLiteResource</span></a> *resource</code></em>);
<span class="returnvalue">xmlNode</span> * <a class="link" href="GUPnPDIDLLiteResource.html#gupnp-didl-lite-resource-get-xml-node" title="gupnp_didl_lite_resource_get_xml_node ()">gupnp_didl_lite_resource_get_xml_node</a>
(<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteResource.html" title="GUPnPDIDLLiteResource"><span class="type">GUPnPDIDLLiteResource</span></a> *resource</code></em>);
+<span class="returnvalue">guint</span> <a class="link" href="GUPnPDIDLLiteResource.html#gupnp-didl-lite-resource-get-update-count" title="gupnp_didl_lite_resource_get_update_count ()">gupnp_didl_lite_resource_get_update_count</a>
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteResource.html" title="GUPnPDIDLLiteResource"><span class="type">GUPnPDIDLLiteResource</span></a> *resource</code></em>);
+<span class="returnvalue">void</span> <a class="link" href="GUPnPDIDLLiteResource.html#gupnp-didl-lite-resource-set-update-count" title="gupnp_didl_lite_resource_set_update_count ()">gupnp_didl_lite_resource_set_update_count</a>
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteResource.html" title="GUPnPDIDLLiteResource"><span class="type">GUPnPDIDLLiteResource</span></a> *resource</code></em>,
+ <em class="parameter"><code><span class="type">guint</span> update_count</code></em>);
+<span class="returnvalue">void</span> <a class="link" href="GUPnPDIDLLiteResource.html#gupnp-didl-lite-resource-unset-update-count" title="gupnp_didl_lite_resource_unset_update_count ()">gupnp_didl_lite_resource_unset_update_count</a>
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteResource.html" title="GUPnPDIDLLiteResource"><span class="type">GUPnPDIDLLiteResource</span></a> *resource</code></em>);
+<span class="returnvalue">gboolean</span> <a class="link" href="GUPnPDIDLLiteResource.html#gupnp-didl-lite-resource-update-count-is-set" title="gupnp_didl_lite_resource_update_count_is_set ()">gupnp_didl_lite_resource_update_count_is_set</a>
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteResource.html" title="GUPnPDIDLLiteResource"><span class="type">GUPnPDIDLLiteResource</span></a> *resource</code></em>);
</pre>
</div>
<div class="refsect1">
@@ -234,7 +243,7 @@ Set the protocol info associated with the <em class="parameter"><code>resource</
<div class="refsect2">
<a name="gupnp-didl-lite-resource-set-size"></a><h3>gupnp_didl_lite_resource_set_size ()</h3>
<pre class="programlisting"><span class="returnvalue">void</span> gupnp_didl_lite_resource_set_size (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteResource.html" title="GUPnPDIDLLiteResource"><span class="type">GUPnPDIDLLiteResource</span></a> *resource</code></em>,
- <em class="parameter"><code>long <span class="type">size</span> Param2</code></em>);</pre>
+ <em class="parameter"><code><span class="type">glong</span> size</code></em>);</pre>
<p>
Set the size (in bytes) of the <em class="parameter"><code>resource</code></em>. Passing a negative number will
unset this property.
@@ -291,7 +300,7 @@ unset this property.
<a name="gupnp-didl-lite-resource-set-duration"></a><h3>gupnp_didl_lite_resource_set_duration ()</h3>
<pre class="programlisting"><span class="returnvalue">void</span> gupnp_didl_lite_resource_set_duration
(<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteResource.html" title="GUPnPDIDLLiteResource"><span class="type">GUPnPDIDLLiteResource</span></a> *resource</code></em>,
- <em class="parameter"><code>long <span class="type">duration</span> Param2</code></em>);</pre>
+ <em class="parameter"><code><span class="type">glong</span> duration</code></em>);</pre>
<p>
Set the duration (in seconds) of the <em class="parameter"><code>resource</code></em>. Passing a negative number
will unset this property.
@@ -888,6 +897,104 @@ Get the pointer to res node in XML document.
</tbody>
</table></div>
</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-didl-lite-resource-get-update-count"></a><h3>gupnp_didl_lite_resource_get_update_count ()</h3>
+<pre class="programlisting"><span class="returnvalue">guint</span> gupnp_didl_lite_resource_get_update_count
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteResource.html" title="GUPnPDIDLLiteResource"><span class="type">GUPnPDIDLLiteResource</span></a> *resource</code></em>);</pre>
+<p>
+Get the update count of this resource.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>resource</code></em> :</span></p></td>
+<td>A <a class="link" href="GUPnPDIDLLiteResource.html" title="GUPnPDIDLLiteResource"><span class="type">GUPnPDIDLLiteResource</span></a>
+</td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>The update count of the <em class="parameter"><code>resource</code></em>.</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-didl-lite-resource-set-update-count"></a><h3>gupnp_didl_lite_resource_set_update_count ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span> gupnp_didl_lite_resource_set_update_count
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteResource.html" title="GUPnPDIDLLiteResource"><span class="type">GUPnPDIDLLiteResource</span></a> *resource</code></em>,
+ <em class="parameter"><code><span class="type">guint</span> update_count</code></em>);</pre>
+<p>
+Set the update count of this resource.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>resource</code></em> :</span></p></td>
+<td>A <a class="link" href="GUPnPDIDLLiteResource.html" title="GUPnPDIDLLiteResource"><span class="type">GUPnPDIDLLiteResource</span></a>
+</td>
+</tr>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>update_count</code></em> :</span></p></td>
+<td>The update_count</td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>None.</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-didl-lite-resource-unset-update-count"></a><h3>gupnp_didl_lite_resource_unset_update_count ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span> gupnp_didl_lite_resource_unset_update_count
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteResource.html" title="GUPnPDIDLLiteResource"><span class="type">GUPnPDIDLLiteResource</span></a> *resource</code></em>);</pre>
+<p>
+Unset the update count of this resource.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>resource</code></em> :</span></p></td>
+<td>A <a class="link" href="GUPnPDIDLLiteResource.html" title="GUPnPDIDLLiteResource"><span class="type">GUPnPDIDLLiteResource</span></a>
+</td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>None.</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-didl-lite-resource-update-count-is-set"></a><h3>gupnp_didl_lite_resource_update_count_is_set ()</h3>
+<pre class="programlisting"><span class="returnvalue">gboolean</span> gupnp_didl_lite_resource_update_count_is_set
+ (<em class="parameter"><code><a class="link" href="GUPnPDIDLLiteResource.html" title="GUPnPDIDLLiteResource"><span class="type">GUPnPDIDLLiteResource</span></a> *resource</code></em>);</pre>
+<p>
+Check whether the update count property of this resource is set.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>resource</code></em> :</span></p></td>
+<td>A <a class="link" href="GUPnPDIDLLiteResource.html" title="GUPnPDIDLLiteResource"><span class="type">GUPnPDIDLLiteResource</span></a>
+</td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>
+<code class="literal">TRUE</code> if set, otherwise <code class="literal">FALSE</code>.</td>
+</tr>
+</tbody>
+</table></div>
+</div>
</div>
<div class="refsect1">
<a name="GUPnPDIDLLiteResource.property-details"></a><h2>Property Details</h2>
diff --git a/doc/html/GUPnPFeatureListParser.html b/doc/html/GUPnPFeatureListParser.html
index 5e2d7eb..0f30e45 100644
--- a/doc/html/GUPnPFeatureListParser.html
+++ b/doc/html/GUPnPFeatureListParser.html
@@ -7,7 +7,7 @@
<link rel="home" href="index.html" title="GUPnP A/V Reference Manual">
<link rel="up" href="ch01.html" title="GUPnP A/V">
<link rel="prev" href="GUPnPFeature.html" title="GUPnPFeature">
-<link rel="next" href="ch02.html" title="Error Codes">
+<link rel="next" href="GUPnPMediaCollection.html" title="GUPnPMediaCollection">
<meta name="generator" content="GTK-Doc V1.18 (XML mode)">
<link rel="stylesheet" href="style.css" type="text/css">
</head>
@@ -18,7 +18,7 @@
<td><a accesskey="u" href="ch01.html"><img src="up.png" width="24" height="24" border="0" alt="Up"></a></td>
<td><a accesskey="h" href="index.html"><img src="home.png" width="24" height="24" border="0" alt="Home"></a></td>
<th width="100%" align="center">GUPnP A/V Reference Manual</th>
-<td><a accesskey="n" href="ch02.html"><img src="right.png" width="24" height="24" border="0" alt="Next"></a></td>
+<td><a accesskey="n" href="GUPnPMediaCollection.html"><img src="right.png" width="24" height="24" border="0" alt="Next"></a></td>
</tr>
<tr><td colspan="5" class="shortcuts">
<a href="#GUPnPFeatureListParser.synopsis" class="shortcut">Top</a>
diff --git a/doc/html/GUPnPLastChangeParser.html b/doc/html/GUPnPLastChangeParser.html
index f6f26da..eac3d3b 100644
--- a/doc/html/GUPnPLastChangeParser.html
+++ b/doc/html/GUPnPLastChangeParser.html
@@ -6,19 +6,19 @@
<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
<link rel="home" href="index.html" title="GUPnP A/V Reference Manual">
<link rel="up" href="ch01.html" title="GUPnP A/V">
-<link rel="prev" href="GUPnPDIDLLiteContributor.html" title="GUPnPDIDLLiteContributor">
-<link rel="next" href="GUPnPSearchCriteriaParser.html" title="GUPnPSearchCriteriaParser">
+<link rel="prev" href="gupnp-av-GUPnPDIDLLiteCreateClass.html" title="GUPnPDIDLLiteCreateClass">
+<link rel="next" href="GUPnPCDSLastChangeParser.html" title="GUPnPCDSLastChangeParser">
<meta name="generator" content="GTK-Doc V1.18 (XML mode)">
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="2">
<tr valign="middle">
-<td><a accesskey="p" href="GUPnPDIDLLiteContributor.html"><img src="left.png" width="24" height="24" border="0" alt="Prev"></a></td>
+<td><a accesskey="p" href="gupnp-av-GUPnPDIDLLiteCreateClass.html"><img src="left.png" width="24" height="24" border="0" alt="Prev"></a></td>
<td><a accesskey="u" href="ch01.html"><img src="up.png" width="24" height="24" border="0" alt="Up"></a></td>
<td><a accesskey="h" href="index.html"><img src="home.png" width="24" height="24" border="0" alt="Home"></a></td>
<th width="100%" align="center">GUPnP A/V Reference Manual</th>
-<td><a accesskey="n" href="GUPnPSearchCriteriaParser.html"><img src="right.png" width="24" height="24" border="0" alt="Next"></a></td>
+<td><a accesskey="n" href="GUPnPCDSLastChangeParser.html"><img src="right.png" width="24" height="24" border="0" alt="Next"></a></td>
</tr>
<tr><td colspan="5" class="shortcuts">
<a href="#GUPnPLastChangeParser.synopsis" class="shortcut">Top</a>
diff --git a/doc/html/GUPnPMediaCollection.html b/doc/html/GUPnPMediaCollection.html
new file mode 100644
index 0000000..3f9071e
--- /dev/null
+++ b/doc/html/GUPnPMediaCollection.html
@@ -0,0 +1,334 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>GUPnPMediaCollection</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
+<link rel="home" href="index.html" title="GUPnP A/V Reference Manual">
+<link rel="up" href="ch01.html" title="GUPnP A/V">
+<link rel="prev" href="GUPnPFeatureListParser.html" title="GUPnPFeatureListParser">
+<link rel="next" href="ch02.html" title="Error Codes">
+<meta name="generator" content="GTK-Doc V1.18 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="2">
+<tr valign="middle">
+<td><a accesskey="p" href="GUPnPFeatureListParser.html"><img src="left.png" width="24" height="24" border="0" alt="Prev"></a></td>
+<td><a accesskey="u" href="ch01.html"><img src="up.png" width="24" height="24" border="0" alt="Up"></a></td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="24" height="24" border="0" alt="Home"></a></td>
+<th width="100%" align="center">GUPnP A/V Reference Manual</th>
+<td><a accesskey="n" href="ch02.html"><img src="right.png" width="24" height="24" border="0" alt="Next"></a></td>
+</tr>
+<tr><td colspan="5" class="shortcuts">
+<a href="#GUPnPMediaCollection.synopsis" class="shortcut">Top</a>
+  | 
+ <a href="#GUPnPMediaCollection.description" class="shortcut">Description</a>
+  | 
+ <a href="#GUPnPMediaCollection.object-hierarchy" class="shortcut">Object Hierarchy</a>
+  | 
+ <a href="#GUPnPMediaCollection.properties" class="shortcut">Properties</a>
+</td></tr>
+</table>
+<div class="refentry">
+<a name="GUPnPMediaCollection"></a><div class="titlepage"></div>
+<div class="refnamediv"><table width="100%"><tr>
+<td valign="top">
+<h2><span class="refentrytitle"><a name="GUPnPMediaCollection.top_of_page"></a>GUPnPMediaCollection</span></h2>
+<p>GUPnPMediaCollection — Media collection writer</p>
+</td>
+<td valign="top" align="right"></td>
+</tr></table></div>
+<div class="refsynopsisdiv">
+<a name="GUPnPMediaCollection.synopsis"></a><h2>Synopsis</h2>
+<pre class="synopsis">struct <a class="link" href="GUPnPMediaCollection.html#GUPnPMediaCollection-struct" title="struct GUPnPMediaCollection">GUPnPMediaCollection</a>;
+<a class="link" href="GUPnPMediaCollection.html" title="GUPnPMediaCollection"><span class="returnvalue">GUPnPMediaCollection</span></a> * <a class="link" href="GUPnPMediaCollection.html#gupnp-media-collection-new" title="gupnp_media_collection_new ()">gupnp_media_collection_new</a> (<em class="parameter"><code><span class="type">void</span></code></em>);
+<a class="link" href="GUPnPMediaCollection.html" title="GUPnPMediaCollection"><span class="returnvalue">GUPnPMediaCollection</span></a> * <a class="link" href="GUPnPMediaCollection.html#gupnp-media-collection-new-from-string" title="gupnp_media_collection_new_from_string ()">gupnp_media_collection_new_from_string</a>
+ (<em class="parameter"><code>const <span class="type">char</span> *data</code></em>);
+<span class="returnvalue">void</span> <a class="link" href="GUPnPMediaCollection.html#gupnp-media-collection-set-title" title="gupnp_media_collection_set_title ()">gupnp_media_collection_set_title</a> (<em class="parameter"><code><a class="link" href="GUPnPMediaCollection.html" title="GUPnPMediaCollection"><span class="type">GUPnPMediaCollection</span></a> *collection</code></em>,
+ <em class="parameter"><code>const <span class="type">char</span> *title</code></em>);
+const <span class="returnvalue">char</span> * <a class="link" href="GUPnPMediaCollection.html#gupnp-media-collection-get-title" title="gupnp_media_collection_get_title ()">gupnp_media_collection_get_title</a> (<em class="parameter"><code><a class="link" href="GUPnPMediaCollection.html" title="GUPnPMediaCollection"><span class="type">GUPnPMediaCollection</span></a> *collection</code></em>);
+<span class="returnvalue">void</span> <a class="link" href="GUPnPMediaCollection.html#gupnp-media-collection-set-author" title="gupnp_media_collection_set_author ()">gupnp_media_collection_set_author</a> (<em class="parameter"><code><a class="link" href="GUPnPMediaCollection.html" title="GUPnPMediaCollection"><span class="type">GUPnPMediaCollection</span></a> *collection</code></em>,
+ <em class="parameter"><code>const <span class="type">char</span> *author</code></em>);
+const <span class="returnvalue">char</span> * <a class="link" href="GUPnPMediaCollection.html#gupnp-media-collection-get-author" title="gupnp_media_collection_get_author ()">gupnp_media_collection_get_author</a> (<em class="parameter"><code><a class="link" href="GUPnPMediaCollection.html" title="GUPnPMediaCollection"><span class="type">GUPnPMediaCollection</span></a> *collection</code></em>);
+<a class="link" href="GUPnPDIDLLiteItem.html" title="GUPnPDIDLLiteItem"><span class="returnvalue">GUPnPDIDLLiteItem</span></a> * <a class="link" href="GUPnPMediaCollection.html#gupnp-media-collection-add-item" title="gupnp_media_collection_add_item ()">gupnp_media_collection_add_item</a> (<em class="parameter"><code><a class="link" href="GUPnPMediaCollection.html" title="GUPnPMediaCollection"><span class="type">GUPnPMediaCollection</span></a> *collection</code></em>);
+<span class="returnvalue">char</span> * <a class="link" href="GUPnPMediaCollection.html#gupnp-media-collection-get-string" title="gupnp_media_collection_get_string ()">gupnp_media_collection_get_string</a> (<em class="parameter"><code><a class="link" href="GUPnPMediaCollection.html" title="GUPnPMediaCollection"><span class="type">GUPnPMediaCollection</span></a> *collection</code></em>);
+<span class="returnvalue">GList</span> * <a class="link" href="GUPnPMediaCollection.html#gupnp-media-collection-get-items" title="gupnp_media_collection_get_items ()">gupnp_media_collection_get_items</a> (<em class="parameter"><code><a class="link" href="GUPnPMediaCollection.html" title="GUPnPMediaCollection"><span class="type">GUPnPMediaCollection</span></a> *collection</code></em>);
+<span class="returnvalue">gboolean</span> <a class="link" href="GUPnPMediaCollection.html#gupnp-media-collection-get-mutable" title="gupnp_media_collection_get_mutable ()">gupnp_media_collection_get_mutable</a> (<em class="parameter"><code><a class="link" href="GUPnPMediaCollection.html" title="GUPnPMediaCollection"><span class="type">GUPnPMediaCollection</span></a> *collection</code></em>);
+</pre>
+</div>
+<div class="refsect1">
+<a name="GUPnPMediaCollection.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<pre class="synopsis">
+ GObject
+ +----GUPnPMediaCollection
+</pre>
+</div>
+<div class="refsect1">
+<a name="GUPnPMediaCollection.properties"></a><h2>Properties</h2>
+<pre class="synopsis">
+ "<a class="link" href="GUPnPMediaCollection.html#GUPnPMediaCollection--author" title='The "author" property'>author</a>" <span class="type">gchar</span>* : Read / Write / Construct
+ "<a class="link" href="GUPnPMediaCollection.html#GUPnPMediaCollection--data" title='The "data" property'>data</a>" <span class="type">gchar</span>* : Write / Construct Only
+ "<a class="link" href="GUPnPMediaCollection.html#GUPnPMediaCollection--mutable" title='The "mutable" property'>mutable</a>" <span class="type">gboolean</span> : Read
+ "<a class="link" href="GUPnPMediaCollection.html#GUPnPMediaCollection--title" title='The "title" property'>title</a>" <span class="type">gchar</span>* : Read / Write / Construct
+</pre>
+</div>
+<div class="refsect1">
+<a name="GUPnPMediaCollection.description"></a><h2>Description</h2>
+<p>
+<a class="link" href="GUPnPMediaCollection.html" title="GUPnPMediaCollection"><span class="type">GUPnPMediaCollection</span></a> is a helper class for writing media collection files.
+</p>
+</div>
+<div class="refsect1">
+<a name="GUPnPMediaCollection.details"></a><h2>Details</h2>
+<div class="refsect2">
+<a name="GUPnPMediaCollection-struct"></a><h3>struct GUPnPMediaCollection</h3>
+<pre class="programlisting">struct GUPnPMediaCollection;</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-media-collection-new"></a><h3>gupnp_media_collection_new ()</h3>
+<pre class="programlisting"><a class="link" href="GUPnPMediaCollection.html" title="GUPnPMediaCollection"><span class="returnvalue">GUPnPMediaCollection</span></a> * gupnp_media_collection_new (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
+<p>
+Create a new writable media collection.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody><tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>A new <a class="link" href="GUPnPMediaCollection.html" title="GUPnPMediaCollection"><span class="type">GUPnPMediaCollection</span></a>. <span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span>
+</td>
+</tr></tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-media-collection-new-from-string"></a><h3>gupnp_media_collection_new_from_string ()</h3>
+<pre class="programlisting"><a class="link" href="GUPnPMediaCollection.html" title="GUPnPMediaCollection"><span class="returnvalue">GUPnPMediaCollection</span></a> * gupnp_media_collection_new_from_string
+ (<em class="parameter"><code>const <span class="type">char</span> *data</code></em>);</pre>
+<p>
+Parse a new <a class="link" href="GUPnPMediaCollection.html" title="GUPnPMediaCollection"><span class="type">GUPnPMediaCollection</span></a> from a block of XML data.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>data</code></em> :</span></p></td>
+<td>XML string.</td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>A new <a class="link" href="GUPnPMediaCollection.html" title="GUPnPMediaCollection"><span class="type">GUPnPMediaCollection</span></a>. <span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span>
+</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-media-collection-set-title"></a><h3>gupnp_media_collection_set_title ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span> gupnp_media_collection_set_title (<em class="parameter"><code><a class="link" href="GUPnPMediaCollection.html" title="GUPnPMediaCollection"><span class="type">GUPnPMediaCollection</span></a> *collection</code></em>,
+ <em class="parameter"><code>const <span class="type">char</span> *title</code></em>);</pre>
+<p>
+Set the title of a <a class="link" href="GUPnPMediaCollection.html" title="GUPnPMediaCollection"><span class="type">GUPnPMediaCollection</span></a>.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>collection</code></em> :</span></p></td>
+<td><a class="link" href="GUPnPMediaCollection.html" title="GUPnPMediaCollection"><span class="type">GUPnPMediaCollection</span></a></td>
+</tr>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>title</code></em> :</span></p></td>
+<td>New Title of this collection;</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-media-collection-get-title"></a><h3>gupnp_media_collection_get_title ()</h3>
+<pre class="programlisting">const <span class="returnvalue">char</span> * gupnp_media_collection_get_title (<em class="parameter"><code><a class="link" href="GUPnPMediaCollection.html" title="GUPnPMediaCollection"><span class="type">GUPnPMediaCollection</span></a> *collection</code></em>);</pre>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>collection</code></em> :</span></p></td>
+<td><a class="link" href="GUPnPMediaCollection.html" title="GUPnPMediaCollection"><span class="type">GUPnPMediaCollection</span></a></td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>The title of this media collection or <code class="literal">NULL</code> if not set.</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-media-collection-set-author"></a><h3>gupnp_media_collection_set_author ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span> gupnp_media_collection_set_author (<em class="parameter"><code><a class="link" href="GUPnPMediaCollection.html" title="GUPnPMediaCollection"><span class="type">GUPnPMediaCollection</span></a> *collection</code></em>,
+ <em class="parameter"><code>const <span class="type">char</span> *author</code></em>);</pre>
+<p>
+Set the author of the media collection
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>collection</code></em> :</span></p></td>
+<td><a class="link" href="GUPnPMediaCollection.html" title="GUPnPMediaCollection"><span class="type">GUPnPMediaCollection</span></a></td>
+</tr>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>author</code></em> :</span></p></td>
+<td>New author of this media collection.</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-media-collection-get-author"></a><h3>gupnp_media_collection_get_author ()</h3>
+<pre class="programlisting">const <span class="returnvalue">char</span> * gupnp_media_collection_get_author (<em class="parameter"><code><a class="link" href="GUPnPMediaCollection.html" title="GUPnPMediaCollection"><span class="type">GUPnPMediaCollection</span></a> *collection</code></em>);</pre>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>collection</code></em> :</span></p></td>
+<td><a class="link" href="GUPnPMediaCollection.html" title="GUPnPMediaCollection"><span class="type">GUPnPMediaCollection</span></a></td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>The author of this media collection or <code class="literal">NULL</code> if not set.</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-media-collection-add-item"></a><h3>gupnp_media_collection_add_item ()</h3>
+<pre class="programlisting"><a class="link" href="GUPnPDIDLLiteItem.html" title="GUPnPDIDLLiteItem"><span class="returnvalue">GUPnPDIDLLiteItem</span></a> * gupnp_media_collection_add_item (<em class="parameter"><code><a class="link" href="GUPnPMediaCollection.html" title="GUPnPMediaCollection"><span class="type">GUPnPMediaCollection</span></a> *collection</code></em>);</pre>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>collection</code></em> :</span></p></td>
+<td><a class="link" href="GUPnPMediaCollection.html" title="GUPnPMediaCollection"><span class="type">GUPnPMediaCollection</span></a></td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>A new <a class="link" href="GUPnPDIDLLiteItem.html" title="GUPnPDIDLLiteItem"><span class="type">GUPnPDIDLLiteItem</span></a> object. Unref after
+use. <span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span>
+</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-media-collection-get-string"></a><h3>gupnp_media_collection_get_string ()</h3>
+<pre class="programlisting"><span class="returnvalue">char</span> * gupnp_media_collection_get_string (<em class="parameter"><code><a class="link" href="GUPnPMediaCollection.html" title="GUPnPMediaCollection"><span class="type">GUPnPMediaCollection</span></a> *collection</code></em>);</pre>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>collection</code></em> :</span></p></td>
+<td><a class="link" href="GUPnPMediaCollection.html" title="GUPnPMediaCollection"><span class="type">GUPnPMediaCollection</span></a></td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>XML string representing this media
+collection. <code class="function">g_free()</code> after use. If the colleciton is not mutable, returns a
+copy of the original string. <span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span>
+</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-media-collection-get-items"></a><h3>gupnp_media_collection_get_items ()</h3>
+<pre class="programlisting"><span class="returnvalue">GList</span> * gupnp_media_collection_get_items (<em class="parameter"><code><a class="link" href="GUPnPMediaCollection.html" title="GUPnPMediaCollection"><span class="type">GUPnPMediaCollection</span></a> *collection</code></em>);</pre>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>collection</code></em> :</span></p></td>
+<td><a class="link" href="GUPnPMediaCollection.html" title="GUPnPMediaCollection"><span class="type">GUPnPMediaCollection</span></a></td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>A <span class="type">GList</span>
+containing the elemens of this collection, in proper order. Unref all items
+and free the list after use. <span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> GUPnPDIDLLiteItem]</span>
+</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-media-collection-get-mutable"></a><h3>gupnp_media_collection_get_mutable ()</h3>
+<pre class="programlisting"><span class="returnvalue">gboolean</span> gupnp_media_collection_get_mutable (<em class="parameter"><code><a class="link" href="GUPnPMediaCollection.html" title="GUPnPMediaCollection"><span class="type">GUPnPMediaCollection</span></a> *collection</code></em>);</pre>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>collection</code></em> :</span></p></td>
+<td><a class="link" href="GUPnPMediaCollection.html" title="GUPnPMediaCollection"><span class="type">GUPnPMediaCollection</span></a></td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>
+<span class="type">TRUE</span> if the collections is modifiable, <span class="type">FALSE</span> otherwise.</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+<div class="refsect1">
+<a name="GUPnPMediaCollection.property-details"></a><h2>Property Details</h2>
+<div class="refsect2">
+<a name="GUPnPMediaCollection--author"></a><h3>The <code class="literal">"author"</code> property</h3>
+<pre class="programlisting"> "author" <span class="type">gchar</span>* : Read / Write / Construct</pre>
+<p>
+The author of this media collection.
+</p>
+<p>Default value: NULL</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="GUPnPMediaCollection--data"></a><h3>The <code class="literal">"data"</code> property</h3>
+<pre class="programlisting"> "data" <span class="type">gchar</span>* : Write / Construct Only</pre>
+<p>
+Block of data to parse a collection from. If data is set upon
+construction it will override the other properties and create a
+unmutable collection parsed from data.
+</p>
+<p>Default value: NULL</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="GUPnPMediaCollection--mutable"></a><h3>The <code class="literal">"mutable"</code> property</h3>
+<pre class="programlisting"> "mutable" <span class="type">gboolean</span> : Read</pre>
+<p>
+Whether this media collation is modifyable or not.
+</p>
+<p>Default value: FALSE</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="GUPnPMediaCollection--title"></a><h3>The <code class="literal">"title"</code> property</h3>
+<pre class="programlisting"> "title" <span class="type">gchar</span>* : Read / Write / Construct</pre>
+<p>
+The title of this media collection.
+</p>
+<p>Default value: NULL</p>
+</div>
+</div>
+</div>
+<div class="footer">
+<hr>
+ Generated by GTK-Doc V1.18</div>
+</body>
+</html> \ No newline at end of file
diff --git a/doc/html/GUPnPSearchCriteriaParser.html b/doc/html/GUPnPSearchCriteriaParser.html
index 8cda766..159614d 100644
--- a/doc/html/GUPnPSearchCriteriaParser.html
+++ b/doc/html/GUPnPSearchCriteriaParser.html
@@ -6,7 +6,7 @@
<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
<link rel="home" href="index.html" title="GUPnP A/V Reference Manual">
<link rel="up" href="ch01.html" title="GUPnP A/V">
-<link rel="prev" href="GUPnPLastChangeParser.html" title="GUPnPLastChangeParser">
+<link rel="prev" href="GUPnPCDSLastChangeParser.html" title="GUPnPCDSLastChangeParser">
<link rel="next" href="GUPnPProtocolInfo.html" title="GUPnPProtocolInfo">
<meta name="generator" content="GTK-Doc V1.18 (XML mode)">
<link rel="stylesheet" href="style.css" type="text/css">
@@ -14,7 +14,7 @@
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="2">
<tr valign="middle">
-<td><a accesskey="p" href="GUPnPLastChangeParser.html"><img src="left.png" width="24" height="24" border="0" alt="Prev"></a></td>
+<td><a accesskey="p" href="GUPnPCDSLastChangeParser.html"><img src="left.png" width="24" height="24" border="0" alt="Prev"></a></td>
<td><a accesskey="u" href="ch01.html"><img src="up.png" width="24" height="24" border="0" alt="Up"></a></td>
<td><a accesskey="h" href="index.html"><img src="home.png" width="24" height="24" border="0" alt="Home"></a></td>
<th width="100%" align="center">GUPnP A/V Reference Manual</th>
diff --git a/doc/html/annotation-glossary.html b/doc/html/annotation-glossary.html
index 3559cb5..647d904 100644
--- a/doc/html/annotation-glossary.html
+++ b/doc/html/annotation-glossary.html
@@ -32,6 +32,9 @@
<a name="annotation-glossary"></a>Annotation Glossary</h2></div></div></div>
<a name="glsA"></a><h3 class="title">A</h3>
<dt>
+<a name="annotation-glossterm-array"></a>array</dt>
+<dd><p>Parameter points to an array of items.</p></dd>
+<dt>
<a name="annotation-glossterm-allow-none"></a>allow-none</dt>
<dd><p>NULL is ok, both for passing and for returning.</p></dd>
<a name="glsE"></a><h3 class="title">E</h3>
diff --git a/doc/html/ch01.html b/doc/html/ch01.html
index 0e58fc6..03bb716 100644
--- a/doc/html/ch01.html
+++ b/doc/html/ch01.html
@@ -21,7 +21,7 @@
</tr></table>
<div class="chapter">
<div class="titlepage"><div><div><h2 class="title">
-<a name="idp102136"></a>GUPnP A/V</h2></div></div></div>
+<a name="idp2375048"></a>GUPnP A/V</h2></div></div></div>
<div class="toc"><dl>
<dt>
<span class="refentrytitle"><a href="GUPnPDIDLLiteParser.html">GUPnPDIDLLiteParser</a></span><span class="refpurpose"> — A/V DIDL-Lite XML parser</span>
@@ -48,9 +48,16 @@
<span class="refentrytitle"><a href="GUPnPDIDLLiteContributor.html">GUPnPDIDLLiteContributor</a></span><span class="refpurpose"> — DIDL-Lite Contributor</span>
</dt>
<dt>
+<span class="refentrytitle"><a href="gupnp-av-GUPnPDIDLLiteCreateClass.html">GUPnPDIDLLiteCreateClass</a></span><span class="refpurpose"> — DIDL-Lite CreateClass</span>
+</dt>
+<dt>
<span class="refentrytitle"><a href="GUPnPLastChangeParser.html">GUPnPLastChangeParser</a></span><span class="refpurpose"> — A/V LastChange event XML parser</span>
</dt>
<dt>
+<span class="refentrytitle"><a href="GUPnPCDSLastChangeParser.html">GUPnPCDSLastChangeParser</a></span><span class="refpurpose"> — LastChange parser for the format used in
+CDS:3</span>
+</dt>
+<dt>
<span class="refentrytitle"><a href="GUPnPSearchCriteriaParser.html">GUPnPSearchCriteriaParser</a></span><span class="refpurpose"> — A/V search criteria parser</span>
</dt>
<dt>
@@ -62,6 +69,9 @@
<dt>
<span class="refentrytitle"><a href="GUPnPFeatureListParser.html">GUPnPFeatureListParser</a></span><span class="refpurpose"> — FeatureList state variable XML parser</span>
</dt>
+<dt>
+<span class="refentrytitle"><a href="GUPnPMediaCollection.html">GUPnPMediaCollection</a></span><span class="refpurpose"> — Media collection writer</span>
+</dt>
</dl></div>
</div>
<div class="footer">
diff --git a/doc/html/ch02.html b/doc/html/ch02.html
index 3d2a9ce..5c10bff 100644
--- a/doc/html/ch02.html
+++ b/doc/html/ch02.html
@@ -6,14 +6,14 @@
<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
<link rel="home" href="index.html" title="GUPnP A/V Reference Manual">
<link rel="up" href="index.html" title="GUPnP A/V Reference Manual">
-<link rel="prev" href="GUPnPFeatureListParser.html" title="GUPnPFeatureListParser">
+<link rel="prev" href="GUPnPMediaCollection.html" title="GUPnPMediaCollection">
<link rel="next" href="gupnp-av-Error-codes.html" title="Error codes">
<meta name="generator" content="GTK-Doc V1.18 (XML mode)">
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="2"><tr valign="middle">
-<td><a accesskey="p" href="GUPnPFeatureListParser.html"><img src="left.png" width="24" height="24" border="0" alt="Prev"></a></td>
+<td><a accesskey="p" href="GUPnPMediaCollection.html"><img src="left.png" width="24" height="24" border="0" alt="Prev"></a></td>
<td> </td>
<td><a accesskey="h" href="index.html"><img src="home.png" width="24" height="24" border="0" alt="Home"></a></td>
<th width="100%" align="center">GUPnP A/V Reference Manual</th>
@@ -21,7 +21,7 @@
</tr></table>
<div class="chapter">
<div class="titlepage"><div><div><h2 class="title">
-<a name="idp1251560"></a>Error Codes</h2></div></div></div>
+<a name="idp2379536"></a>Error Codes</h2></div></div></div>
<div class="toc"><dl><dt>
<span class="refentrytitle"><a href="gupnp-av-Error-codes.html">Error codes</a></span><span class="refpurpose"> — Error domains and codes.</span>
</dt></dl></div>
diff --git a/doc/html/gupnp-av-Error-codes.html b/doc/html/gupnp-av-Error-codes.html
index 9defda9..028207f 100644
--- a/doc/html/gupnp-av-Error-codes.html
+++ b/doc/html/gupnp-av-Error-codes.html
@@ -103,6 +103,15 @@ protocol related errors.
GUPNP_SEARCH_CRITERIA_PARSER_ERROR_FAILED
} GUPnPSearchCriteriaParserError;
</pre>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody><tr>
+<td><p><a name="GUPNP-SEARCH-CRITERIA-PARSER-ERROR-FAILED:CAPS"></a><span class="term"><code class="literal">GUPNP_SEARCH_CRITERIA_PARSER_ERROR_FAILED</code></span></p></td>
+<td>Parsing the search criteria
+failed.
+</td>
+</tr></tbody>
+</table></div>
</div>
</div>
</div>
diff --git a/doc/html/gupnp-av-GUPnPDIDLLiteCreateClass.html b/doc/html/gupnp-av-GUPnPDIDLLiteCreateClass.html
new file mode 100644
index 0000000..448ad52
--- /dev/null
+++ b/doc/html/gupnp-av-GUPnPDIDLLiteCreateClass.html
@@ -0,0 +1,243 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>GUPnPDIDLLiteCreateClass</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
+<link rel="home" href="index.html" title="GUPnP A/V Reference Manual">
+<link rel="up" href="ch01.html" title="GUPnP A/V">
+<link rel="prev" href="GUPnPDIDLLiteContributor.html" title="GUPnPDIDLLiteContributor">
+<link rel="next" href="GUPnPLastChangeParser.html" title="GUPnPLastChangeParser">
+<meta name="generator" content="GTK-Doc V1.18 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="2">
+<tr valign="middle">
+<td><a accesskey="p" href="GUPnPDIDLLiteContributor.html"><img src="left.png" width="24" height="24" border="0" alt="Prev"></a></td>
+<td><a accesskey="u" href="ch01.html"><img src="up.png" width="24" height="24" border="0" alt="Up"></a></td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="24" height="24" border="0" alt="Home"></a></td>
+<th width="100%" align="center">GUPnP A/V Reference Manual</th>
+<td><a accesskey="n" href="GUPnPLastChangeParser.html"><img src="right.png" width="24" height="24" border="0" alt="Next"></a></td>
+</tr>
+<tr><td colspan="5" class="shortcuts">
+<a href="#gupnp-av-GUPnPDIDLLiteCreateClass.synopsis" class="shortcut">Top</a>
+  | 
+ <a href="#gupnp-av-GUPnPDIDLLiteCreateClass.description" class="shortcut">Description</a>
+</td></tr>
+</table>
+<div class="refentry">
+<a name="gupnp-av-GUPnPDIDLLiteCreateClass"></a><div class="titlepage"></div>
+<div class="refnamediv"><table width="100%"><tr>
+<td valign="top">
+<h2><span class="refentrytitle"><a name="gupnp-av-GUPnPDIDLLiteCreateClass.top_of_page"></a>GUPnPDIDLLiteCreateClass</span></h2>
+<p>GUPnPDIDLLiteCreateClass — DIDL-Lite CreateClass</p>
+</td>
+<td valign="top" align="right"></td>
+</tr></table></div>
+<div class="refsynopsisdiv">
+<a name="gupnp-av-GUPnPDIDLLiteCreateClass.synopsis"></a><h2>Synopsis</h2>
+<pre class="synopsis"> <a class="link" href="gupnp-av-GUPnPDIDLLiteCreateClass.html#GUPnPDIDLLiteCreateClass" title="GUPnPDIDLLiteCreateClass">GUPnPDIDLLiteCreateClass</a>;
+const <span class="returnvalue">char</span> * <a class="link" href="gupnp-av-GUPnPDIDLLiteCreateClass.html#gupnp-didl-lite-create-class-get-content" title="gupnp_didl_lite_create_class_get_content ()">gupnp_didl_lite_create_class_get_content</a>
+ (<em class="parameter"><code><a class="link" href="gupnp-av-GUPnPDIDLLiteCreateClass.html#GUPnPDIDLLiteCreateClass" title="GUPnPDIDLLiteCreateClass"><span class="type">GUPnPDIDLLiteCreateClass</span></a> *create_class</code></em>);
+<span class="returnvalue">void</span> <a class="link" href="gupnp-av-GUPnPDIDLLiteCreateClass.html#gupnp-didl-lite-create-class-set-content" title="gupnp_didl_lite_create_class_set_content ()">gupnp_didl_lite_create_class_set_content</a>
+ (<em class="parameter"><code><a class="link" href="gupnp-av-GUPnPDIDLLiteCreateClass.html#GUPnPDIDLLiteCreateClass" title="GUPnPDIDLLiteCreateClass"><span class="type">GUPnPDIDLLiteCreateClass</span></a> *create_class</code></em>,
+ <em class="parameter"><code>const <span class="type">char</span> *content</code></em>);
+<span class="returnvalue">gboolean</span> <a class="link" href="gupnp-av-GUPnPDIDLLiteCreateClass.html#gupnp-didl-lite-create-class-get-include-derived" title="gupnp_didl_lite_create_class_get_include_derived ()">gupnp_didl_lite_create_class_get_include_derived</a>
+ (<em class="parameter"><code><a class="link" href="gupnp-av-GUPnPDIDLLiteCreateClass.html#GUPnPDIDLLiteCreateClass" title="GUPnPDIDLLiteCreateClass"><span class="type">GUPnPDIDLLiteCreateClass</span></a> *create_class</code></em>);
+<span class="returnvalue">void</span> <a class="link" href="gupnp-av-GUPnPDIDLLiteCreateClass.html#gupnp-didl-lite-create-class-set-include-derived" title="gupnp_didl_lite_create_class_set_include_derived ()">gupnp_didl_lite_create_class_set_include_derived</a>
+ (<em class="parameter"><code><a class="link" href="gupnp-av-GUPnPDIDLLiteCreateClass.html#GUPnPDIDLLiteCreateClass" title="GUPnPDIDLLiteCreateClass"><span class="type">GUPnPDIDLLiteCreateClass</span></a> *create_class</code></em>,
+ <em class="parameter"><code><span class="type">gboolean</span> include_derived</code></em>);
+const <span class="returnvalue">char</span> * <a class="link" href="gupnp-av-GUPnPDIDLLiteCreateClass.html#gupnp-didl-lite-create-class-get-friendly-name" title="gupnp_didl_lite_create_class_get_friendly_name ()">gupnp_didl_lite_create_class_get_friendly_name</a>
+ (<em class="parameter"><code><a class="link" href="gupnp-av-GUPnPDIDLLiteCreateClass.html#GUPnPDIDLLiteCreateClass" title="GUPnPDIDLLiteCreateClass"><span class="type">GUPnPDIDLLiteCreateClass</span></a> *create_class</code></em>);
+<span class="returnvalue">void</span> <a class="link" href="gupnp-av-GUPnPDIDLLiteCreateClass.html#gupnp-didl-lite-create-class-set-friendly-name" title="gupnp_didl_lite_create_class_set_friendly_name ()">gupnp_didl_lite_create_class_set_friendly_name</a>
+ (<em class="parameter"><code><a class="link" href="gupnp-av-GUPnPDIDLLiteCreateClass.html#GUPnPDIDLLiteCreateClass" title="GUPnPDIDLLiteCreateClass"><span class="type">GUPnPDIDLLiteCreateClass</span></a> *create_class</code></em>,
+ <em class="parameter"><code>const <span class="type">char</span> *friendly_name</code></em>);
+<span class="returnvalue">xmlNode</span> * <a class="link" href="gupnp-av-GUPnPDIDLLiteCreateClass.html#gupnp-didl-lite-create-class-get-xml-node" title="gupnp_didl_lite_create_class_get_xml_node ()">gupnp_didl_lite_create_class_get_xml_node</a>
+ (<em class="parameter"><code><a class="link" href="gupnp-av-GUPnPDIDLLiteCreateClass.html#GUPnPDIDLLiteCreateClass" title="GUPnPDIDLLiteCreateClass"><span class="type">GUPnPDIDLLiteCreateClass</span></a> *create_class</code></em>);
+</pre>
+</div>
+<div class="refsect1">
+<a name="gupnp-av-GUPnPDIDLLiteCreateClass.description"></a><h2>Description</h2>
+<p>
+<a class="link" href="gupnp-av-GUPnPDIDLLiteCreateClass.html#GUPnPDIDLLiteCreateClass" title="GUPnPDIDLLiteCreateClass"><span class="type">GUPnPDIDLLiteCreateClass</span></a> respresents a DIDL-Lite create class element.
+</p>
+</div>
+<div class="refsect1">
+<a name="gupnp-av-GUPnPDIDLLiteCreateClass.details"></a><h2>Details</h2>
+<div class="refsect2">
+<a name="GUPnPDIDLLiteCreateClass"></a><h3>GUPnPDIDLLiteCreateClass</h3>
+<pre class="programlisting">typedef struct {
+ GObject parent;
+
+ GUPnPDIDLLiteCreateClassPrivate *priv;
+} GUPnPDIDLLiteCreateClass;
+</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-didl-lite-create-class-get-content"></a><h3>gupnp_didl_lite_create_class_get_content ()</h3>
+<pre class="programlisting">const <span class="returnvalue">char</span> * gupnp_didl_lite_create_class_get_content
+ (<em class="parameter"><code><a class="link" href="gupnp-av-GUPnPDIDLLiteCreateClass.html#GUPnPDIDLLiteCreateClass" title="GUPnPDIDLLiteCreateClass"><span class="type">GUPnPDIDLLiteCreateClass</span></a> *create_class</code></em>);</pre>
+<p>
+Get the content of the <em class="parameter"><code>create_class</code></em>.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>create_class</code></em> :</span></p></td>
+<td><a class="link" href="gupnp-av-GUPnPDIDLLiteCreateClass.html#GUPnPDIDLLiteCreateClass" title="GUPnPDIDLLiteCreateClass"><span class="type">GUPnPDIDLLiteCreateClass</span></a></td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>The Content of the <em class="parameter"><code>create_class</code></em>, or <code class="literal">NULL</code>.</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-didl-lite-create-class-set-content"></a><h3>gupnp_didl_lite_create_class_set_content ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span> gupnp_didl_lite_create_class_set_content
+ (<em class="parameter"><code><a class="link" href="gupnp-av-GUPnPDIDLLiteCreateClass.html#GUPnPDIDLLiteCreateClass" title="GUPnPDIDLLiteCreateClass"><span class="type">GUPnPDIDLLiteCreateClass</span></a> *create_class</code></em>,
+ <em class="parameter"><code>const <span class="type">char</span> *content</code></em>);</pre>
+<p>
+Set the content of the <em class="parameter"><code>create_class</code></em>.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>create_class</code></em> :</span></p></td>
+<td><a class="link" href="gupnp-av-GUPnPDIDLLiteCreateClass.html#GUPnPDIDLLiteCreateClass" title="GUPnPDIDLLiteCreateClass"><span class="type">GUPnPDIDLLiteCreateClass</span></a></td>
+</tr>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>content</code></em> :</span></p></td>
+<td>The content</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-didl-lite-create-class-get-include-derived"></a><h3>gupnp_didl_lite_create_class_get_include_derived ()</h3>
+<pre class="programlisting"><span class="returnvalue">gboolean</span> gupnp_didl_lite_create_class_get_include_derived
+ (<em class="parameter"><code><a class="link" href="gupnp-av-GUPnPDIDLLiteCreateClass.html#GUPnPDIDLLiteCreateClass" title="GUPnPDIDLLiteCreateClass"><span class="type">GUPnPDIDLLiteCreateClass</span></a> *create_class</code></em>);</pre>
+<p>
+Checks whether <em class="parameter"><code>create_class</code></em> can be derived.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>create_class</code></em> :</span></p></td>
+<td><a class="link" href="gupnp-av-GUPnPDIDLLiteCreateClass.html#GUPnPDIDLLiteCreateClass" title="GUPnPDIDLLiteCreateClass"><span class="type">GUPnPDIDLLiteCreateClass</span></a></td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>
+<span class="type">TRUE</span> if <em class="parameter"><code>create_class</code></em> can be derived.</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-didl-lite-create-class-set-include-derived"></a><h3>gupnp_didl_lite_create_class_set_include_derived ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span> gupnp_didl_lite_create_class_set_include_derived
+ (<em class="parameter"><code><a class="link" href="gupnp-av-GUPnPDIDLLiteCreateClass.html#GUPnPDIDLLiteCreateClass" title="GUPnPDIDLLiteCreateClass"><span class="type">GUPnPDIDLLiteCreateClass</span></a> *create_class</code></em>,
+ <em class="parameter"><code><span class="type">gboolean</span> include_derived</code></em>);</pre>
+<p>
+(Un)set the derivability of create_class.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>create_class</code></em> :</span></p></td>
+<td><a class="link" href="gupnp-av-GUPnPDIDLLiteCreateClass.html#GUPnPDIDLLiteCreateClass" title="GUPnPDIDLLiteCreateClass"><span class="type">GUPnPDIDLLiteCreateClass</span></a></td>
+</tr>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>include_derived</code></em> :</span></p></td>
+<td>the derivability</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-didl-lite-create-class-get-friendly-name"></a><h3>gupnp_didl_lite_create_class_get_friendly_name ()</h3>
+<pre class="programlisting">const <span class="returnvalue">char</span> * gupnp_didl_lite_create_class_get_friendly_name
+ (<em class="parameter"><code><a class="link" href="gupnp-av-GUPnPDIDLLiteCreateClass.html#GUPnPDIDLLiteCreateClass" title="GUPnPDIDLLiteCreateClass"><span class="type">GUPnPDIDLLiteCreateClass</span></a> *create_class</code></em>);</pre>
+<p>
+Get the friendly name of the <em class="parameter"><code>create_class</code></em>.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>create_class</code></em> :</span></p></td>
+<td><a class="link" href="gupnp-av-GUPnPDIDLLiteCreateClass.html#GUPnPDIDLLiteCreateClass" title="GUPnPDIDLLiteCreateClass"><span class="type">GUPnPDIDLLiteCreateClass</span></a></td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>The FriendlyName of the <em class="parameter"><code>create_class</code></em>, or <code class="literal">NULL</code>.</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-didl-lite-create-class-set-friendly-name"></a><h3>gupnp_didl_lite_create_class_set_friendly_name ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span> gupnp_didl_lite_create_class_set_friendly_name
+ (<em class="parameter"><code><a class="link" href="gupnp-av-GUPnPDIDLLiteCreateClass.html#GUPnPDIDLLiteCreateClass" title="GUPnPDIDLLiteCreateClass"><span class="type">GUPnPDIDLLiteCreateClass</span></a> *create_class</code></em>,
+ <em class="parameter"><code>const <span class="type">char</span> *friendly_name</code></em>);</pre>
+<p>
+Set the friendly name of the <em class="parameter"><code>create_class</code></em>.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>create_class</code></em> :</span></p></td>
+<td><a class="link" href="gupnp-av-GUPnPDIDLLiteCreateClass.html#GUPnPDIDLLiteCreateClass" title="GUPnPDIDLLiteCreateClass"><span class="type">GUPnPDIDLLiteCreateClass</span></a></td>
+</tr>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>friendly_name</code></em> :</span></p></td>
+<td>The friendly name</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gupnp-didl-lite-create-class-get-xml-node"></a><h3>gupnp_didl_lite_create_class_get_xml_node ()</h3>
+<pre class="programlisting"><span class="returnvalue">xmlNode</span> * gupnp_didl_lite_create_class_get_xml_node
+ (<em class="parameter"><code><a class="link" href="gupnp-av-GUPnPDIDLLiteCreateClass.html#GUPnPDIDLLiteCreateClass" title="GUPnPDIDLLiteCreateClass"><span class="type">GUPnPDIDLLiteCreateClass</span></a> *create_class</code></em>);</pre>
+<p>
+Get the pointer to relevant node in XML document.
+</p>
+<div class="variablelist"><table border="0">
+<col align="left" valign="top">
+<tbody>
+<tr>
+<td><p><span class="term"><em class="parameter"><code>create_class</code></em> :</span></p></td>
+<td>The <a class="link" href="gupnp-av-GUPnPDIDLLiteCreateClass.html#GUPnPDIDLLiteCreateClass" title="GUPnPDIDLLiteCreateClass"><span class="type">GUPnPDIDLLiteCreateClass</span></a>
+</td>
+</tr>
+<tr>
+<td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td>
+<td>The pointer to relevant node in XML document. <span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span>
+</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+</div>
+<div class="footer">
+<hr>
+ Generated by GTK-Doc V1.18</div>
+</body>
+</html> \ No newline at end of file
diff --git a/doc/html/gupnp-av.devhelp2 b/doc/html/gupnp-av.devhelp2
index 39058c1..190c732 100644
--- a/doc/html/gupnp-av.devhelp2
+++ b/doc/html/gupnp-av.devhelp2
@@ -11,11 +11,14 @@
<sub name="GUPnPDIDLLiteResource" link="GUPnPDIDLLiteResource.html"/>
<sub name="GUPnPDIDLLiteDescriptor" link="GUPnPDIDLLiteDescriptor.html"/>
<sub name="GUPnPDIDLLiteContributor" link="GUPnPDIDLLiteContributor.html"/>
+ <sub name="GUPnPDIDLLiteCreateClass" link="gupnp-av-GUPnPDIDLLiteCreateClass.html"/>
<sub name="GUPnPLastChangeParser" link="GUPnPLastChangeParser.html"/>
+ <sub name="GUPnPCDSLastChangeParser" link="GUPnPCDSLastChangeParser.html"/>
<sub name="GUPnPSearchCriteriaParser" link="GUPnPSearchCriteriaParser.html"/>
<sub name="GUPnPProtocolInfo" link="GUPnPProtocolInfo.html"/>
<sub name="GUPnPFeature" link="GUPnPFeature.html"/>
<sub name="GUPnPFeatureListParser" link="GUPnPFeatureListParser.html"/>
+ <sub name="GUPnPMediaCollection" link="GUPnPMediaCollection.html"/>
</sub>
<sub name="Error Codes" link="ch02.html">
<sub name="Error codes" link="gupnp-av-Error-codes.html"/>
@@ -31,6 +34,7 @@
<keyword type="signal" name="The &quot;object-available&quot; signal" link="GUPnPDIDLLiteParser.html#GUPnPDIDLLiteParser-object-available"/>
<keyword type="struct" name="GUPnPDIDLLiteObject" link="GUPnPDIDLLiteObject.html#GUPnPDIDLLiteObject-struct"/>
<keyword type="enum" name="enum GUPnPOCMFlags" link="GUPnPDIDLLiteObject.html#GUPnPOCMFlags"/>
+ <keyword type="enum" name="enum GUPnPDIDLLiteFragmentResult" link="GUPnPDIDLLiteObject.html#GUPnPDIDLLiteFragmentResult"/>
<keyword type="function" name="gupnp_didl_lite_object_get_xml_node ()" link="GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-get-xml-node"/>
<keyword type="function" name="gupnp_didl_lite_object_get_upnp_namespace ()" link="GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-get-upnp-namespace"/>
<keyword type="function" name="gupnp_didl_lite_object_get_dc_namespace ()" link="GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-get-dc-namespace"/>
@@ -79,6 +83,18 @@
<keyword type="function" name="gupnp_didl_lite_object_set_date ()" link="GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-set-date"/>
<keyword type="function" name="gupnp_didl_lite_object_set_track_number ()" link="GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-set-track-number"/>
<keyword type="function" name="gupnp_didl_lite_object_set_dlna_managed ()" link="GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-set-dlna-managed"/>
+ <keyword type="function" name="gupnp_didl_lite_object_apply_fragments ()" link="GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-apply-fragments"/>
+ <keyword type="function" name="gupnp_didl_lite_object_get_album_xml_string ()" link="GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-get-album-xml-string"/>
+ <keyword type="function" name="gupnp_didl_lite_object_get_artists_xml_string ()" link="GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-get-artists-xml-string"/>
+ <keyword type="function" name="gupnp_didl_lite_object_get_date_xml_string ()" link="GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-get-date-xml-string"/>
+ <keyword type="function" name="gupnp_didl_lite_object_get_title_xml_string ()" link="GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-get-title-xml-string"/>
+ <keyword type="function" name="gupnp_didl_lite_object_get_track_number_xml_string ()" link="GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-get-track-number-xml-string"/>
+ <keyword type="function" name="gupnp_didl_lite_object_get_update_id ()" link="GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-get-update-id"/>
+ <keyword type="function" name="gupnp_didl_lite_object_get_upnp_class_xml_string ()" link="GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-get-upnp-class-xml-string"/>
+ <keyword type="function" name="gupnp_didl_lite_object_set_update_id ()" link="GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-set-update-id"/>
+ <keyword type="function" name="gupnp_didl_lite_object_unset_artists ()" link="GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-unset-artists"/>
+ <keyword type="function" name="gupnp_didl_lite_object_unset_update_id ()" link="GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-unset-update-id"/>
+ <keyword type="function" name="gupnp_didl_lite_object_update_id_is_set ()" link="GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-update-id-is-set"/>
<keyword type="property" name="The &quot;album&quot; property" link="GUPnPDIDLLiteObject.html#GUPnPDIDLLiteObject--album"/>
<keyword type="property" name="The &quot;album-art&quot; property" link="GUPnPDIDLLiteObject.html#GUPnPDIDLLiteObject--album-art"/>
<keyword type="property" name="The &quot;artist&quot; property" link="GUPnPDIDLLiteObject.html#GUPnPDIDLLiteObject--artist"/>
@@ -114,6 +130,15 @@
<keyword type="function" name="gupnp_didl_lite_container_add_create_class_full ()" link="GUPnPDIDLLiteContainer.html#gupnp-didl-lite-container-add-create-class-full"/>
<keyword type="function" name="gupnp_didl_lite_container_add_search_class ()" link="GUPnPDIDLLiteContainer.html#gupnp-didl-lite-container-add-search-class"/>
<keyword type="function" name="gupnp_didl_lite_container_add_search_class_full ()" link="GUPnPDIDLLiteContainer.html#gupnp-didl-lite-container-add-search-class-full"/>
+ <keyword type="function" name="gupnp_didl_lite_container_container_update_id_is_set ()" link="GUPnPDIDLLiteContainer.html#gupnp-didl-lite-container-container-update-id-is-set"/>
+ <keyword type="function" name="gupnp_didl_lite_container_get_container_update_id ()" link="GUPnPDIDLLiteContainer.html#gupnp-didl-lite-container-get-container-update-id"/>
+ <keyword type="function" name="gupnp_didl_lite_container_get_create_classes_full ()" link="GUPnPDIDLLiteContainer.html#gupnp-didl-lite-container-get-create-classes-full"/>
+ <keyword type="function" name="gupnp_didl_lite_container_get_total_deleted_child_count ()" link="GUPnPDIDLLiteContainer.html#gupnp-didl-lite-container-get-total-deleted-child-count"/>
+ <keyword type="function" name="gupnp_didl_lite_container_set_container_update_id ()" link="GUPnPDIDLLiteContainer.html#gupnp-didl-lite-container-set-container-update-id"/>
+ <keyword type="function" name="gupnp_didl_lite_container_set_total_deleted_child_count ()" link="GUPnPDIDLLiteContainer.html#gupnp-didl-lite-container-set-total-deleted-child-count"/>
+ <keyword type="function" name="gupnp_didl_lite_container_total_deleted_child_count_is_set ()" link="GUPnPDIDLLiteContainer.html#gupnp-didl-lite-container-total-deleted-child-count-is-set"/>
+ <keyword type="function" name="gupnp_didl_lite_container_unset_container_update_id ()" link="GUPnPDIDLLiteContainer.html#gupnp-didl-lite-container-unset-container-update-id"/>
+ <keyword type="function" name="gupnp_didl_lite_container_unset_total_deleted_child_count ()" link="GUPnPDIDLLiteContainer.html#gupnp-didl-lite-container-unset-total-deleted-child-count"/>
<keyword type="property" name="The &quot;child-count&quot; property" link="GUPnPDIDLLiteContainer.html#GUPnPDIDLLiteContainer--child-count"/>
<keyword type="property" name="The &quot;container-update-id&quot; property" link="GUPnPDIDLLiteContainer.html#GUPnPDIDLLiteContainer--container-update-id"/>
<keyword type="property" name="The &quot;searchable&quot; property" link="GUPnPDIDLLiteContainer.html#GUPnPDIDLLiteContainer--searchable"/>
@@ -122,6 +147,9 @@
<keyword type="struct" name="GUPnPDIDLLiteItem" link="GUPnPDIDLLiteItem.html#GUPnPDIDLLiteItem-struct"/>
<keyword type="function" name="gupnp_didl_lite_item_get_ref_id ()" link="GUPnPDIDLLiteItem.html#gupnp-didl-lite-item-get-ref-id"/>
<keyword type="function" name="gupnp_didl_lite_item_set_ref_id ()" link="GUPnPDIDLLiteItem.html#gupnp-didl-lite-item-set-ref-id"/>
+ <keyword type="function" name="gupnp_didl_lite_item_get_lifetime ()" link="GUPnPDIDLLiteItem.html#gupnp-didl-lite-item-get-lifetime"/>
+ <keyword type="function" name="gupnp_didl_lite_item_set_lifetime ()" link="GUPnPDIDLLiteItem.html#gupnp-didl-lite-item-set-lifetime"/>
+ <keyword type="property" name="The &quot;lifetime&quot; property" link="GUPnPDIDLLiteItem.html#GUPnPDIDLLiteItem--lifetime"/>
<keyword type="property" name="The &quot;ref-id&quot; property" link="GUPnPDIDLLiteItem.html#GUPnPDIDLLiteItem--ref-id"/>
<keyword type="struct" name="GUPnPDIDLLiteWriter" link="GUPnPDIDLLiteWriter.html#GUPnPDIDLLiteWriter-struct"/>
<keyword type="function" name="gupnp_didl_lite_writer_new ()" link="GUPnPDIDLLiteWriter.html#gupnp-didl-lite-writer-new"/>
@@ -164,6 +192,10 @@
<keyword type="function" name="gupnp_didl_lite_resource_get_height ()" link="GUPnPDIDLLiteResource.html#gupnp-didl-lite-resource-get-height"/>
<keyword type="function" name="gupnp_didl_lite_resource_get_color_depth ()" link="GUPnPDIDLLiteResource.html#gupnp-didl-lite-resource-get-color-depth"/>
<keyword type="function" name="gupnp_didl_lite_resource_get_xml_node ()" link="GUPnPDIDLLiteResource.html#gupnp-didl-lite-resource-get-xml-node"/>
+ <keyword type="function" name="gupnp_didl_lite_resource_get_update_count ()" link="GUPnPDIDLLiteResource.html#gupnp-didl-lite-resource-get-update-count"/>
+ <keyword type="function" name="gupnp_didl_lite_resource_set_update_count ()" link="GUPnPDIDLLiteResource.html#gupnp-didl-lite-resource-set-update-count"/>
+ <keyword type="function" name="gupnp_didl_lite_resource_unset_update_count ()" link="GUPnPDIDLLiteResource.html#gupnp-didl-lite-resource-unset-update-count"/>
+ <keyword type="function" name="gupnp_didl_lite_resource_update_count_is_set ()" link="GUPnPDIDLLiteResource.html#gupnp-didl-lite-resource-update-count-is-set"/>
<keyword type="property" name="The &quot;audio-channels&quot; property" link="GUPnPDIDLLiteResource.html#GUPnPDIDLLiteResource--audio-channels"/>
<keyword type="property" name="The &quot;bitrate&quot; property" link="GUPnPDIDLLiteResource.html#GUPnPDIDLLiteResource--bitrate"/>
<keyword type="property" name="The &quot;bits-per-sample&quot; property" link="GUPnPDIDLLiteResource.html#GUPnPDIDLLiteResource--bits-per-sample"/>
@@ -207,10 +239,31 @@
<keyword type="property" name="The &quot;role&quot; property" link="GUPnPDIDLLiteContributor.html#GUPnPDIDLLiteContributor--role"/>
<keyword type="property" name="The &quot;xml-doc&quot; property" link="GUPnPDIDLLiteContributor.html#GUPnPDIDLLiteContributor--xml-doc"/>
<keyword type="property" name="The &quot;xml-node&quot; property" link="GUPnPDIDLLiteContributor.html#GUPnPDIDLLiteContributor--xml-node"/>
+ <keyword type="struct" name="GUPnPDIDLLiteCreateClass" link="gupnp-av-GUPnPDIDLLiteCreateClass.html#GUPnPDIDLLiteCreateClass"/>
+ <keyword type="function" name="gupnp_didl_lite_create_class_get_content ()" link="gupnp-av-GUPnPDIDLLiteCreateClass.html#gupnp-didl-lite-create-class-get-content"/>
+ <keyword type="function" name="gupnp_didl_lite_create_class_set_content ()" link="gupnp-av-GUPnPDIDLLiteCreateClass.html#gupnp-didl-lite-create-class-set-content"/>
+ <keyword type="function" name="gupnp_didl_lite_create_class_get_include_derived ()" link="gupnp-av-GUPnPDIDLLiteCreateClass.html#gupnp-didl-lite-create-class-get-include-derived"/>
+ <keyword type="function" name="gupnp_didl_lite_create_class_set_include_derived ()" link="gupnp-av-GUPnPDIDLLiteCreateClass.html#gupnp-didl-lite-create-class-set-include-derived"/>
+ <keyword type="function" name="gupnp_didl_lite_create_class_get_friendly_name ()" link="gupnp-av-GUPnPDIDLLiteCreateClass.html#gupnp-didl-lite-create-class-get-friendly-name"/>
+ <keyword type="function" name="gupnp_didl_lite_create_class_set_friendly_name ()" link="gupnp-av-GUPnPDIDLLiteCreateClass.html#gupnp-didl-lite-create-class-set-friendly-name"/>
+ <keyword type="function" name="gupnp_didl_lite_create_class_get_xml_node ()" link="gupnp-av-GUPnPDIDLLiteCreateClass.html#gupnp-didl-lite-create-class-get-xml-node"/>
<keyword type="struct" name="GUPnPLastChangeParser" link="GUPnPLastChangeParser.html#GUPnPLastChangeParser-struct"/>
<keyword type="function" name="gupnp_last_change_parser_new ()" link="GUPnPLastChangeParser.html#gupnp-last-change-parser-new"/>
<keyword type="function" name="gupnp_last_change_parser_parse_last_change_valist ()" link="GUPnPLastChangeParser.html#gupnp-last-change-parser-parse-last-change-valist"/>
<keyword type="function" name="gupnp_last_change_parser_parse_last_change ()" link="GUPnPLastChangeParser.html#gupnp-last-change-parser-parse-last-change"/>
+ <keyword type="struct" name="struct GUPnPCDSLastChangeParser" link="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeParser-struct"/>
+ <keyword type="enum" name="enum GUPnPCDSLastChangeEvent" link="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEvent"/>
+ <keyword type="struct" name="GUPnPCDSLastChangeEntry" link="GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEntry-struct"/>
+ <keyword type="function" name="gupnp_cds_last_change_parser_new ()" link="GUPnPCDSLastChangeParser.html#gupnp-cds-last-change-parser-new"/>
+ <keyword type="function" name="gupnp_cds_last_change_parser_parse ()" link="GUPnPCDSLastChangeParser.html#gupnp-cds-last-change-parser-parse"/>
+ <keyword type="function" name="gupnp_cds_last_change_entry_ref ()" link="GUPnPCDSLastChangeParser.html#gupnp-cds-last-change-entry-ref"/>
+ <keyword type="function" name="gupnp_cds_last_change_entry_unref ()" link="GUPnPCDSLastChangeParser.html#gupnp-cds-last-change-entry-unref"/>
+ <keyword type="function" name="gupnp_cds_last_change_entry_get_event ()" link="GUPnPCDSLastChangeParser.html#gupnp-cds-last-change-entry-get-event"/>
+ <keyword type="function" name="gupnp_cds_last_change_entry_get_object_id ()" link="GUPnPCDSLastChangeParser.html#gupnp-cds-last-change-entry-get-object-id"/>
+ <keyword type="function" name="gupnp_cds_last_change_entry_get_parent_id ()" link="GUPnPCDSLastChangeParser.html#gupnp-cds-last-change-entry-get-parent-id"/>
+ <keyword type="function" name="gupnp_cds_last_change_entry_get_class ()" link="GUPnPCDSLastChangeParser.html#gupnp-cds-last-change-entry-get-class"/>
+ <keyword type="function" name="gupnp_cds_last_change_entry_is_subtree_update ()" link="GUPnPCDSLastChangeParser.html#gupnp-cds-last-change-entry-is-subtree-update"/>
+ <keyword type="function" name="gupnp_cds_last_change_entry_get_update_id ()" link="GUPnPCDSLastChangeParser.html#gupnp-cds-last-change-entry-get-update-id"/>
<keyword type="struct" name="GUPnPSearchCriteriaParser" link="GUPnPSearchCriteriaParser.html#GUPnPSearchCriteriaParser-struct"/>
<keyword type="enum" name="enum GUPnPSearchCriteriaOp" link="GUPnPSearchCriteriaParser.html#GUPnPSearchCriteriaOp-enum"/>
<keyword type="function" name="gupnp_search_criteria_parser_new ()" link="GUPnPSearchCriteriaParser.html#gupnp-search-criteria-parser-new"/>
@@ -262,6 +315,21 @@
<keyword type="struct" name="GUPnPFeatureListParser" link="GUPnPFeatureListParser.html#GUPnPFeatureListParser-struct"/>
<keyword type="function" name="gupnp_feature_list_parser_new ()" link="GUPnPFeatureListParser.html#gupnp-feature-list-parser-new"/>
<keyword type="function" name="gupnp_feature_list_parser_parse_text ()" link="GUPnPFeatureListParser.html#gupnp-feature-list-parser-parse-text"/>
+ <keyword type="struct" name="struct GUPnPMediaCollection" link="GUPnPMediaCollection.html#GUPnPMediaCollection-struct"/>
+ <keyword type="function" name="gupnp_media_collection_new ()" link="GUPnPMediaCollection.html#gupnp-media-collection-new"/>
+ <keyword type="function" name="gupnp_media_collection_new_from_string ()" link="GUPnPMediaCollection.html#gupnp-media-collection-new-from-string"/>
+ <keyword type="function" name="gupnp_media_collection_set_title ()" link="GUPnPMediaCollection.html#gupnp-media-collection-set-title"/>
+ <keyword type="function" name="gupnp_media_collection_get_title ()" link="GUPnPMediaCollection.html#gupnp-media-collection-get-title"/>
+ <keyword type="function" name="gupnp_media_collection_set_author ()" link="GUPnPMediaCollection.html#gupnp-media-collection-set-author"/>
+ <keyword type="function" name="gupnp_media_collection_get_author ()" link="GUPnPMediaCollection.html#gupnp-media-collection-get-author"/>
+ <keyword type="function" name="gupnp_media_collection_add_item ()" link="GUPnPMediaCollection.html#gupnp-media-collection-add-item"/>
+ <keyword type="function" name="gupnp_media_collection_get_string ()" link="GUPnPMediaCollection.html#gupnp-media-collection-get-string"/>
+ <keyword type="function" name="gupnp_media_collection_get_items ()" link="GUPnPMediaCollection.html#gupnp-media-collection-get-items"/>
+ <keyword type="function" name="gupnp_media_collection_get_mutable ()" link="GUPnPMediaCollection.html#gupnp-media-collection-get-mutable"/>
+ <keyword type="property" name="The &quot;author&quot; property" link="GUPnPMediaCollection.html#GUPnPMediaCollection--author"/>
+ <keyword type="property" name="The &quot;data&quot; property" link="GUPnPMediaCollection.html#GUPnPMediaCollection--data"/>
+ <keyword type="property" name="The &quot;mutable&quot; property" link="GUPnPMediaCollection.html#GUPnPMediaCollection--mutable"/>
+ <keyword type="property" name="The &quot;title&quot; property" link="GUPnPMediaCollection.html#GUPnPMediaCollection--title"/>
<keyword type="macro" name="GUPNP_PROTOCOL_ERROR" link="gupnp-av-Error-codes.html#GUPNP-PROTOCOL-ERROR:CAPS"/>
<keyword type="macro" name="GUPNP_SEARCH_CRITERIA_PARSER_ERROR" link="gupnp-av-Error-codes.html#GUPNP-SEARCH-CRITERIA-PARSER-ERROR:CAPS"/>
<keyword type="enum" name="enum GUPnPProtocolError" link="gupnp-av-Error-codes.html#GUPnPProtocolError"/>
@@ -272,6 +340,15 @@
<keyword type="constant" name="GUPNP_OCM_FLAGS_DESTROYABLE" link="GUPnPDIDLLiteObject.html#GUPNP-OCM-FLAGS-DESTROYABLE:CAPS"/>
<keyword type="constant" name="GUPNP_OCM_FLAGS_UPLOAD_DESTROYABLE" link="GUPnPDIDLLiteObject.html#GUPNP-OCM-FLAGS-UPLOAD-DESTROYABLE:CAPS"/>
<keyword type="constant" name="GUPNP_OCM_FLAGS_CHANGE_METADATA" link="GUPnPDIDLLiteObject.html#GUPNP-OCM-FLAGS-CHANGE-METADATA:CAPS"/>
+ <keyword type="constant" name="GUPNP_DIDL_LITE_FRAGMENT_RESULT_OK" link="GUPnPDIDLLiteObject.html#GUPNP-DIDL-LITE-FRAGMENT-RESULT-OK:CAPS"/>
+ <keyword type="constant" name="GUPNP_DIDL_LITE_FRAGMENT_RESULT_CURRENT_BAD_XML" link="GUPnPDIDLLiteObject.html#GUPNP-DIDL-LITE-FRAGMENT-RESULT-CURRENT-BAD-XML:CAPS"/>
+ <keyword type="constant" name="GUPNP_DIDL_LITE_FRAGMENT_RESULT_NEW_BAD_XML" link="GUPnPDIDLLiteObject.html#GUPNP-DIDL-LITE-FRAGMENT-RESULT-NEW-BAD-XML:CAPS"/>
+ <keyword type="constant" name="GUPNP_DIDL_LITE_FRAGMENT_RESULT_CURRENT_INVALID" link="GUPnPDIDLLiteObject.html#GUPNP-DIDL-LITE-FRAGMENT-RESULT-CURRENT-INVALID:CAPS"/>
+ <keyword type="constant" name="GUPNP_DIDL_LITE_FRAGMENT_RESULT_NEW_INVALID" link="GUPnPDIDLLiteObject.html#GUPNP-DIDL-LITE-FRAGMENT-RESULT-NEW-INVALID:CAPS"/>
+ <keyword type="constant" name="GUPNP_DIDL_LITE_FRAGMENT_RESULT_REQUIRED_TAG" link="GUPnPDIDLLiteObject.html#GUPNP-DIDL-LITE-FRAGMENT-RESULT-REQUIRED-TAG:CAPS"/>
+ <keyword type="constant" name="GUPNP_DIDL_LITE_FRAGMENT_RESULT_READONLY_TAG" link="GUPnPDIDLLiteObject.html#GUPNP-DIDL-LITE-FRAGMENT-RESULT-READONLY-TAG:CAPS"/>
+ <keyword type="constant" name="GUPNP_DIDL_LITE_FRAGMENT_RESULT_MISMATCH" link="GUPnPDIDLLiteObject.html#GUPNP-DIDL-LITE-FRAGMENT-RESULT-MISMATCH:CAPS"/>
+ <keyword type="constant" name="GUPNP_DIDL_LITE_FRAGMENT_RESULT_UNKNOWN_ERROR" link="GUPnPDIDLLiteObject.html#GUPNP-DIDL-LITE-FRAGMENT-RESULT-UNKNOWN-ERROR:CAPS"/>
<keyword type="constant" name="GUPNP_SEARCH_CRITERIA_OP_EQ" link="GUPnPSearchCriteriaParser.html#GUPNP-SEARCH-CRITERIA-OP-EQ:CAPS"/>
<keyword type="constant" name="GUPNP_SEARCH_CRITERIA_OP_NEQ" link="GUPnPSearchCriteriaParser.html#GUPNP-SEARCH-CRITERIA-OP-NEQ:CAPS"/>
<keyword type="constant" name="GUPNP_SEARCH_CRITERIA_OP_LESS" link="GUPnPSearchCriteriaParser.html#GUPNP-SEARCH-CRITERIA-OP-LESS:CAPS"/>
@@ -302,5 +379,6 @@
<keyword type="constant" name="GUPNP_DLNA_OPERATION_TIMESEEK" link="GUPnPProtocolInfo.html#GUPNP-DLNA-OPERATION-TIMESEEK:CAPS"/>
<keyword type="constant" name="GUPNP_PROTOCOL_ERROR_INVALID_SYNTAX" link="gupnp-av-Error-codes.html#GUPNP-PROTOCOL-ERROR-INVALID-SYNTAX:CAPS"/>
<keyword type="constant" name="GUPNP_PROTOCOL_ERROR_OTHER" link="gupnp-av-Error-codes.html#GUPNP-PROTOCOL-ERROR-OTHER:CAPS"/>
+ <keyword type="constant" name="GUPNP_SEARCH_CRITERIA_PARSER_ERROR_FAILED" link="gupnp-av-Error-codes.html#GUPNP-SEARCH-CRITERIA-PARSER-ERROR-FAILED:CAPS"/>
</functions>
</book>
diff --git a/doc/html/index.html b/doc/html/index.html
index 1fe4fa9..6425cbb 100644
--- a/doc/html/index.html
+++ b/doc/html/index.html
@@ -14,13 +14,13 @@
<div class="titlepage">
<div>
<div><table class="navigation" id="top" width="100%" cellpadding="2" cellspacing="0"><tr><th valign="middle"><p class="title">GUPnP A/V Reference Manual</p></th></tr></table></div>
-<div><p class="releaseinfo">Version 0.11.2
+<div><p class="releaseinfo">Version 0.11.7
</p></div>
<div><p class="copyright">Copyright © 2007,2008 OpenedHand LTD</p></div>
<div><p class="copyright">Copyright © 2007,2008 Zeeshan Ali &lt;zeenix@gmail.com&gt;</p></div>
<div><p class="copyright">Copyright © 2009,2010 Nokia Corporation</p></div>
<div><div class="legalnotice">
-<a name="idp1987464"></a><p>
+<a name="idp2892296"></a><p>
Permission is granted to copy, distribute and/or modify this
document under the terms of the <em class="citetitle">GNU Free
Documentation License</em>, Version 1.1 or any later
@@ -72,9 +72,16 @@
<span class="refentrytitle"><a href="GUPnPDIDLLiteContributor.html">GUPnPDIDLLiteContributor</a></span><span class="refpurpose"> — DIDL-Lite Contributor</span>
</dt>
<dt>
+<span class="refentrytitle"><a href="gupnp-av-GUPnPDIDLLiteCreateClass.html">GUPnPDIDLLiteCreateClass</a></span><span class="refpurpose"> — DIDL-Lite CreateClass</span>
+</dt>
+<dt>
<span class="refentrytitle"><a href="GUPnPLastChangeParser.html">GUPnPLastChangeParser</a></span><span class="refpurpose"> — A/V LastChange event XML parser</span>
</dt>
<dt>
+<span class="refentrytitle"><a href="GUPnPCDSLastChangeParser.html">GUPnPCDSLastChangeParser</a></span><span class="refpurpose"> — LastChange parser for the format used in
+CDS:3</span>
+</dt>
+<dt>
<span class="refentrytitle"><a href="GUPnPSearchCriteriaParser.html">GUPnPSearchCriteriaParser</a></span><span class="refpurpose"> — A/V search criteria parser</span>
</dt>
<dt>
@@ -86,6 +93,9 @@
<dt>
<span class="refentrytitle"><a href="GUPnPFeatureListParser.html">GUPnPFeatureListParser</a></span><span class="refpurpose"> — FeatureList state variable XML parser</span>
</dt>
+<dt>
+<span class="refentrytitle"><a href="GUPnPMediaCollection.html">GUPnPMediaCollection</a></span><span class="refpurpose"> — Media collection writer</span>
+</dt>
</dl></dd>
<dt><span class="chapter"><a href="ch02.html">Error Codes</a></span></dt>
<dd><dl><dt>
diff --git a/doc/html/index.sgml b/doc/html/index.sgml
index cc7090b..45af4ce 100644
--- a/doc/html/index.sgml
+++ b/doc/html/index.sgml
@@ -25,6 +25,16 @@
<ANCHOR id="GUPNP-OCM-FLAGS-DESTROYABLE:CAPS" href="gupnp-av/GUPnPDIDLLiteObject.html#GUPNP-OCM-FLAGS-DESTROYABLE:CAPS">
<ANCHOR id="GUPNP-OCM-FLAGS-UPLOAD-DESTROYABLE:CAPS" href="gupnp-av/GUPnPDIDLLiteObject.html#GUPNP-OCM-FLAGS-UPLOAD-DESTROYABLE:CAPS">
<ANCHOR id="GUPNP-OCM-FLAGS-CHANGE-METADATA:CAPS" href="gupnp-av/GUPnPDIDLLiteObject.html#GUPNP-OCM-FLAGS-CHANGE-METADATA:CAPS">
+<ANCHOR id="GUPnPDIDLLiteFragmentResult" href="gupnp-av/GUPnPDIDLLiteObject.html#GUPnPDIDLLiteFragmentResult">
+<ANCHOR id="GUPNP-DIDL-LITE-FRAGMENT-RESULT-OK:CAPS" href="gupnp-av/GUPnPDIDLLiteObject.html#GUPNP-DIDL-LITE-FRAGMENT-RESULT-OK:CAPS">
+<ANCHOR id="GUPNP-DIDL-LITE-FRAGMENT-RESULT-CURRENT-BAD-XML:CAPS" href="gupnp-av/GUPnPDIDLLiteObject.html#GUPNP-DIDL-LITE-FRAGMENT-RESULT-CURRENT-BAD-XML:CAPS">
+<ANCHOR id="GUPNP-DIDL-LITE-FRAGMENT-RESULT-NEW-BAD-XML:CAPS" href="gupnp-av/GUPnPDIDLLiteObject.html#GUPNP-DIDL-LITE-FRAGMENT-RESULT-NEW-BAD-XML:CAPS">
+<ANCHOR id="GUPNP-DIDL-LITE-FRAGMENT-RESULT-CURRENT-INVALID:CAPS" href="gupnp-av/GUPnPDIDLLiteObject.html#GUPNP-DIDL-LITE-FRAGMENT-RESULT-CURRENT-INVALID:CAPS">
+<ANCHOR id="GUPNP-DIDL-LITE-FRAGMENT-RESULT-NEW-INVALID:CAPS" href="gupnp-av/GUPnPDIDLLiteObject.html#GUPNP-DIDL-LITE-FRAGMENT-RESULT-NEW-INVALID:CAPS">
+<ANCHOR id="GUPNP-DIDL-LITE-FRAGMENT-RESULT-REQUIRED-TAG:CAPS" href="gupnp-av/GUPnPDIDLLiteObject.html#GUPNP-DIDL-LITE-FRAGMENT-RESULT-REQUIRED-TAG:CAPS">
+<ANCHOR id="GUPNP-DIDL-LITE-FRAGMENT-RESULT-READONLY-TAG:CAPS" href="gupnp-av/GUPnPDIDLLiteObject.html#GUPNP-DIDL-LITE-FRAGMENT-RESULT-READONLY-TAG:CAPS">
+<ANCHOR id="GUPNP-DIDL-LITE-FRAGMENT-RESULT-MISMATCH:CAPS" href="gupnp-av/GUPnPDIDLLiteObject.html#GUPNP-DIDL-LITE-FRAGMENT-RESULT-MISMATCH:CAPS">
+<ANCHOR id="GUPNP-DIDL-LITE-FRAGMENT-RESULT-UNKNOWN-ERROR:CAPS" href="gupnp-av/GUPnPDIDLLiteObject.html#GUPNP-DIDL-LITE-FRAGMENT-RESULT-UNKNOWN-ERROR:CAPS">
<ANCHOR id="gupnp-didl-lite-object-get-xml-node" href="gupnp-av/GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-get-xml-node">
<ANCHOR id="gupnp-didl-lite-object-get-upnp-namespace" href="gupnp-av/GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-get-upnp-namespace">
<ANCHOR id="gupnp-didl-lite-object-get-dc-namespace" href="gupnp-av/GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-get-dc-namespace">
@@ -73,6 +83,18 @@
<ANCHOR id="gupnp-didl-lite-object-set-date" href="gupnp-av/GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-set-date">
<ANCHOR id="gupnp-didl-lite-object-set-track-number" href="gupnp-av/GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-set-track-number">
<ANCHOR id="gupnp-didl-lite-object-set-dlna-managed" href="gupnp-av/GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-set-dlna-managed">
+<ANCHOR id="gupnp-didl-lite-object-apply-fragments" href="gupnp-av/GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-apply-fragments">
+<ANCHOR id="gupnp-didl-lite-object-get-album-xml-string" href="gupnp-av/GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-get-album-xml-string">
+<ANCHOR id="gupnp-didl-lite-object-get-artists-xml-string" href="gupnp-av/GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-get-artists-xml-string">
+<ANCHOR id="gupnp-didl-lite-object-get-date-xml-string" href="gupnp-av/GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-get-date-xml-string">
+<ANCHOR id="gupnp-didl-lite-object-get-title-xml-string" href="gupnp-av/GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-get-title-xml-string">
+<ANCHOR id="gupnp-didl-lite-object-get-track-number-xml-string" href="gupnp-av/GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-get-track-number-xml-string">
+<ANCHOR id="gupnp-didl-lite-object-get-update-id" href="gupnp-av/GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-get-update-id">
+<ANCHOR id="gupnp-didl-lite-object-get-upnp-class-xml-string" href="gupnp-av/GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-get-upnp-class-xml-string">
+<ANCHOR id="gupnp-didl-lite-object-set-update-id" href="gupnp-av/GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-set-update-id">
+<ANCHOR id="gupnp-didl-lite-object-unset-artists" href="gupnp-av/GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-unset-artists">
+<ANCHOR id="gupnp-didl-lite-object-unset-update-id" href="gupnp-av/GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-unset-update-id">
+<ANCHOR id="gupnp-didl-lite-object-update-id-is-set" href="gupnp-av/GUPnPDIDLLiteObject.html#gupnp-didl-lite-object-update-id-is-set">
<ANCHOR id="GUPnPDIDLLiteObject.property-details" href="gupnp-av/GUPnPDIDLLiteObject.html#GUPnPDIDLLiteObject.property-details">
<ANCHOR id="GUPnPDIDLLiteObject--album" href="gupnp-av/GUPnPDIDLLiteObject.html#GUPnPDIDLLiteObject--album">
<ANCHOR id="GUPnPDIDLLiteObject--album-art" href="gupnp-av/GUPnPDIDLLiteObject.html#GUPnPDIDLLiteObject--album-art">
@@ -115,6 +137,15 @@
<ANCHOR id="gupnp-didl-lite-container-add-create-class-full" href="gupnp-av/GUPnPDIDLLiteContainer.html#gupnp-didl-lite-container-add-create-class-full">
<ANCHOR id="gupnp-didl-lite-container-add-search-class" href="gupnp-av/GUPnPDIDLLiteContainer.html#gupnp-didl-lite-container-add-search-class">
<ANCHOR id="gupnp-didl-lite-container-add-search-class-full" href="gupnp-av/GUPnPDIDLLiteContainer.html#gupnp-didl-lite-container-add-search-class-full">
+<ANCHOR id="gupnp-didl-lite-container-container-update-id-is-set" href="gupnp-av/GUPnPDIDLLiteContainer.html#gupnp-didl-lite-container-container-update-id-is-set">
+<ANCHOR id="gupnp-didl-lite-container-get-container-update-id" href="gupnp-av/GUPnPDIDLLiteContainer.html#gupnp-didl-lite-container-get-container-update-id">
+<ANCHOR id="gupnp-didl-lite-container-get-create-classes-full" href="gupnp-av/GUPnPDIDLLiteContainer.html#gupnp-didl-lite-container-get-create-classes-full">
+<ANCHOR id="gupnp-didl-lite-container-get-total-deleted-child-count" href="gupnp-av/GUPnPDIDLLiteContainer.html#gupnp-didl-lite-container-get-total-deleted-child-count">
+<ANCHOR id="gupnp-didl-lite-container-set-container-update-id" href="gupnp-av/GUPnPDIDLLiteContainer.html#gupnp-didl-lite-container-set-container-update-id">
+<ANCHOR id="gupnp-didl-lite-container-set-total-deleted-child-count" href="gupnp-av/GUPnPDIDLLiteContainer.html#gupnp-didl-lite-container-set-total-deleted-child-count">
+<ANCHOR id="gupnp-didl-lite-container-total-deleted-child-count-is-set" href="gupnp-av/GUPnPDIDLLiteContainer.html#gupnp-didl-lite-container-total-deleted-child-count-is-set">
+<ANCHOR id="gupnp-didl-lite-container-unset-container-update-id" href="gupnp-av/GUPnPDIDLLiteContainer.html#gupnp-didl-lite-container-unset-container-update-id">
+<ANCHOR id="gupnp-didl-lite-container-unset-total-deleted-child-count" href="gupnp-av/GUPnPDIDLLiteContainer.html#gupnp-didl-lite-container-unset-total-deleted-child-count">
<ANCHOR id="GUPnPDIDLLiteContainer.property-details" href="gupnp-av/GUPnPDIDLLiteContainer.html#GUPnPDIDLLiteContainer.property-details">
<ANCHOR id="GUPnPDIDLLiteContainer--child-count" href="gupnp-av/GUPnPDIDLLiteContainer.html#GUPnPDIDLLiteContainer--child-count">
<ANCHOR id="GUPnPDIDLLiteContainer--container-update-id" href="gupnp-av/GUPnPDIDLLiteContainer.html#GUPnPDIDLLiteContainer--container-update-id">
@@ -130,7 +161,10 @@
<ANCHOR id="GUPnPDIDLLiteItem-struct" href="gupnp-av/GUPnPDIDLLiteItem.html#GUPnPDIDLLiteItem-struct">
<ANCHOR id="gupnp-didl-lite-item-get-ref-id" href="gupnp-av/GUPnPDIDLLiteItem.html#gupnp-didl-lite-item-get-ref-id">
<ANCHOR id="gupnp-didl-lite-item-set-ref-id" href="gupnp-av/GUPnPDIDLLiteItem.html#gupnp-didl-lite-item-set-ref-id">
+<ANCHOR id="gupnp-didl-lite-item-get-lifetime" href="gupnp-av/GUPnPDIDLLiteItem.html#gupnp-didl-lite-item-get-lifetime">
+<ANCHOR id="gupnp-didl-lite-item-set-lifetime" href="gupnp-av/GUPnPDIDLLiteItem.html#gupnp-didl-lite-item-set-lifetime">
<ANCHOR id="GUPnPDIDLLiteItem.property-details" href="gupnp-av/GUPnPDIDLLiteItem.html#GUPnPDIDLLiteItem.property-details">
+<ANCHOR id="GUPnPDIDLLiteItem--lifetime" href="gupnp-av/GUPnPDIDLLiteItem.html#GUPnPDIDLLiteItem--lifetime">
<ANCHOR id="GUPnPDIDLLiteItem--ref-id" href="gupnp-av/GUPnPDIDLLiteItem.html#GUPnPDIDLLiteItem--ref-id">
<ANCHOR id="GUPnPDIDLLiteWriter" href="gupnp-av/GUPnPDIDLLiteWriter.html">
<ANCHOR id="GUPnPDIDLLiteWriter.synopsis" href="gupnp-av/GUPnPDIDLLiteWriter.html#GUPnPDIDLLiteWriter.synopsis">
@@ -186,6 +220,10 @@
<ANCHOR id="gupnp-didl-lite-resource-get-height" href="gupnp-av/GUPnPDIDLLiteResource.html#gupnp-didl-lite-resource-get-height">
<ANCHOR id="gupnp-didl-lite-resource-get-color-depth" href="gupnp-av/GUPnPDIDLLiteResource.html#gupnp-didl-lite-resource-get-color-depth">
<ANCHOR id="gupnp-didl-lite-resource-get-xml-node" href="gupnp-av/GUPnPDIDLLiteResource.html#gupnp-didl-lite-resource-get-xml-node">
+<ANCHOR id="gupnp-didl-lite-resource-get-update-count" href="gupnp-av/GUPnPDIDLLiteResource.html#gupnp-didl-lite-resource-get-update-count">
+<ANCHOR id="gupnp-didl-lite-resource-set-update-count" href="gupnp-av/GUPnPDIDLLiteResource.html#gupnp-didl-lite-resource-set-update-count">
+<ANCHOR id="gupnp-didl-lite-resource-unset-update-count" href="gupnp-av/GUPnPDIDLLiteResource.html#gupnp-didl-lite-resource-unset-update-count">
+<ANCHOR id="gupnp-didl-lite-resource-update-count-is-set" href="gupnp-av/GUPnPDIDLLiteResource.html#gupnp-didl-lite-resource-update-count-is-set">
<ANCHOR id="GUPnPDIDLLiteResource.property-details" href="gupnp-av/GUPnPDIDLLiteResource.html#GUPnPDIDLLiteResource.property-details">
<ANCHOR id="GUPnPDIDLLiteResource--audio-channels" href="gupnp-av/GUPnPDIDLLiteResource.html#GUPnPDIDLLiteResource--audio-channels">
<ANCHOR id="GUPnPDIDLLiteResource--bitrate" href="gupnp-av/GUPnPDIDLLiteResource.html#GUPnPDIDLLiteResource--bitrate">
@@ -244,6 +282,18 @@
<ANCHOR id="GUPnPDIDLLiteContributor--role" href="gupnp-av/GUPnPDIDLLiteContributor.html#GUPnPDIDLLiteContributor--role">
<ANCHOR id="GUPnPDIDLLiteContributor--xml-doc" href="gupnp-av/GUPnPDIDLLiteContributor.html#GUPnPDIDLLiteContributor--xml-doc">
<ANCHOR id="GUPnPDIDLLiteContributor--xml-node" href="gupnp-av/GUPnPDIDLLiteContributor.html#GUPnPDIDLLiteContributor--xml-node">
+<ANCHOR id="gupnp-av-GUPnPDIDLLiteCreateClass" href="gupnp-av/gupnp-av-GUPnPDIDLLiteCreateClass.html">
+<ANCHOR id="gupnp-av-GUPnPDIDLLiteCreateClass.synopsis" href="gupnp-av/gupnp-av-GUPnPDIDLLiteCreateClass.html#gupnp-av-GUPnPDIDLLiteCreateClass.synopsis">
+<ANCHOR id="gupnp-av-GUPnPDIDLLiteCreateClass.description" href="gupnp-av/gupnp-av-GUPnPDIDLLiteCreateClass.html#gupnp-av-GUPnPDIDLLiteCreateClass.description">
+<ANCHOR id="gupnp-av-GUPnPDIDLLiteCreateClass.details" href="gupnp-av/gupnp-av-GUPnPDIDLLiteCreateClass.html#gupnp-av-GUPnPDIDLLiteCreateClass.details">
+<ANCHOR id="GUPnPDIDLLiteCreateClass" href="gupnp-av/gupnp-av-GUPnPDIDLLiteCreateClass.html#GUPnPDIDLLiteCreateClass">
+<ANCHOR id="gupnp-didl-lite-create-class-get-content" href="gupnp-av/gupnp-av-GUPnPDIDLLiteCreateClass.html#gupnp-didl-lite-create-class-get-content">
+<ANCHOR id="gupnp-didl-lite-create-class-set-content" href="gupnp-av/gupnp-av-GUPnPDIDLLiteCreateClass.html#gupnp-didl-lite-create-class-set-content">
+<ANCHOR id="gupnp-didl-lite-create-class-get-include-derived" href="gupnp-av/gupnp-av-GUPnPDIDLLiteCreateClass.html#gupnp-didl-lite-create-class-get-include-derived">
+<ANCHOR id="gupnp-didl-lite-create-class-set-include-derived" href="gupnp-av/gupnp-av-GUPnPDIDLLiteCreateClass.html#gupnp-didl-lite-create-class-set-include-derived">
+<ANCHOR id="gupnp-didl-lite-create-class-get-friendly-name" href="gupnp-av/gupnp-av-GUPnPDIDLLiteCreateClass.html#gupnp-didl-lite-create-class-get-friendly-name">
+<ANCHOR id="gupnp-didl-lite-create-class-set-friendly-name" href="gupnp-av/gupnp-av-GUPnPDIDLLiteCreateClass.html#gupnp-didl-lite-create-class-set-friendly-name">
+<ANCHOR id="gupnp-didl-lite-create-class-get-xml-node" href="gupnp-av/gupnp-av-GUPnPDIDLLiteCreateClass.html#gupnp-didl-lite-create-class-get-xml-node">
<ANCHOR id="GUPnPLastChangeParser" href="gupnp-av/GUPnPLastChangeParser.html">
<ANCHOR id="GUPnPLastChangeParser.synopsis" href="gupnp-av/GUPnPLastChangeParser.html#GUPnPLastChangeParser.synopsis">
<ANCHOR id="GUPnPLastChangeParser.object-hierarchy" href="gupnp-av/GUPnPLastChangeParser.html#GUPnPLastChangeParser.object-hierarchy">
@@ -253,6 +303,25 @@
<ANCHOR id="gupnp-last-change-parser-new" href="gupnp-av/GUPnPLastChangeParser.html#gupnp-last-change-parser-new">
<ANCHOR id="gupnp-last-change-parser-parse-last-change-valist" href="gupnp-av/GUPnPLastChangeParser.html#gupnp-last-change-parser-parse-last-change-valist">
<ANCHOR id="gupnp-last-change-parser-parse-last-change" href="gupnp-av/GUPnPLastChangeParser.html#gupnp-last-change-parser-parse-last-change">
+<ANCHOR id="GUPnPCDSLastChangeParser" href="gupnp-av/GUPnPCDSLastChangeParser.html">
+<ANCHOR id="GUPnPCDSLastChangeParser.synopsis" href="gupnp-av/GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeParser.synopsis">
+<ANCHOR id="GUPnPCDSLastChangeEntry" href="gupnp-av/GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEntry">
+<ANCHOR id="GUPnPCDSLastChangeParser.object-hierarchy" href="gupnp-av/GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeParser.object-hierarchy">
+<ANCHOR id="GUPnPCDSLastChangeParser.description" href="gupnp-av/GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeParser.description">
+<ANCHOR id="GUPnPCDSLastChangeParser.details" href="gupnp-av/GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeParser.details">
+<ANCHOR id="GUPnPCDSLastChangeParser-struct" href="gupnp-av/GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeParser-struct">
+<ANCHOR id="GUPnPCDSLastChangeEvent" href="gupnp-av/GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEvent">
+<ANCHOR id="GUPnPCDSLastChangeEntry-struct" href="gupnp-av/GUPnPCDSLastChangeParser.html#GUPnPCDSLastChangeEntry-struct">
+<ANCHOR id="gupnp-cds-last-change-parser-new" href="gupnp-av/GUPnPCDSLastChangeParser.html#gupnp-cds-last-change-parser-new">
+<ANCHOR id="gupnp-cds-last-change-parser-parse" href="gupnp-av/GUPnPCDSLastChangeParser.html#gupnp-cds-last-change-parser-parse">
+<ANCHOR id="gupnp-cds-last-change-entry-ref" href="gupnp-av/GUPnPCDSLastChangeParser.html#gupnp-cds-last-change-entry-ref">
+<ANCHOR id="gupnp-cds-last-change-entry-unref" href="gupnp-av/GUPnPCDSLastChangeParser.html#gupnp-cds-last-change-entry-unref">
+<ANCHOR id="gupnp-cds-last-change-entry-get-event" href="gupnp-av/GUPnPCDSLastChangeParser.html#gupnp-cds-last-change-entry-get-event">
+<ANCHOR id="gupnp-cds-last-change-entry-get-object-id" href="gupnp-av/GUPnPCDSLastChangeParser.html#gupnp-cds-last-change-entry-get-object-id">
+<ANCHOR id="gupnp-cds-last-change-entry-get-parent-id" href="gupnp-av/GUPnPCDSLastChangeParser.html#gupnp-cds-last-change-entry-get-parent-id">
+<ANCHOR id="gupnp-cds-last-change-entry-get-class" href="gupnp-av/GUPnPCDSLastChangeParser.html#gupnp-cds-last-change-entry-get-class">
+<ANCHOR id="gupnp-cds-last-change-entry-is-subtree-update" href="gupnp-av/GUPnPCDSLastChangeParser.html#gupnp-cds-last-change-entry-is-subtree-update">
+<ANCHOR id="gupnp-cds-last-change-entry-get-update-id" href="gupnp-av/GUPnPCDSLastChangeParser.html#gupnp-cds-last-change-entry-get-update-id">
<ANCHOR id="GUPnPSearchCriteriaParser" href="gupnp-av/GUPnPSearchCriteriaParser.html">
<ANCHOR id="GUPnPSearchCriteriaParser.synopsis" href="gupnp-av/GUPnPSearchCriteriaParser.html#GUPnPSearchCriteriaParser.synopsis">
<ANCHOR id="GUPnPSearchCriteriaOp" href="gupnp-av/GUPnPSearchCriteriaParser.html#GUPnPSearchCriteriaOp">
@@ -359,6 +428,28 @@
<ANCHOR id="GUPnPFeatureListParser-struct" href="gupnp-av/GUPnPFeatureListParser.html#GUPnPFeatureListParser-struct">
<ANCHOR id="gupnp-feature-list-parser-new" href="gupnp-av/GUPnPFeatureListParser.html#gupnp-feature-list-parser-new">
<ANCHOR id="gupnp-feature-list-parser-parse-text" href="gupnp-av/GUPnPFeatureListParser.html#gupnp-feature-list-parser-parse-text">
+<ANCHOR id="GUPnPMediaCollection" href="gupnp-av/GUPnPMediaCollection.html">
+<ANCHOR id="GUPnPMediaCollection.synopsis" href="gupnp-av/GUPnPMediaCollection.html#GUPnPMediaCollection.synopsis">
+<ANCHOR id="GUPnPMediaCollection.object-hierarchy" href="gupnp-av/GUPnPMediaCollection.html#GUPnPMediaCollection.object-hierarchy">
+<ANCHOR id="GUPnPMediaCollection.properties" href="gupnp-av/GUPnPMediaCollection.html#GUPnPMediaCollection.properties">
+<ANCHOR id="GUPnPMediaCollection.description" href="gupnp-av/GUPnPMediaCollection.html#GUPnPMediaCollection.description">
+<ANCHOR id="GUPnPMediaCollection.details" href="gupnp-av/GUPnPMediaCollection.html#GUPnPMediaCollection.details">
+<ANCHOR id="GUPnPMediaCollection-struct" href="gupnp-av/GUPnPMediaCollection.html#GUPnPMediaCollection-struct">
+<ANCHOR id="gupnp-media-collection-new" href="gupnp-av/GUPnPMediaCollection.html#gupnp-media-collection-new">
+<ANCHOR id="gupnp-media-collection-new-from-string" href="gupnp-av/GUPnPMediaCollection.html#gupnp-media-collection-new-from-string">
+<ANCHOR id="gupnp-media-collection-set-title" href="gupnp-av/GUPnPMediaCollection.html#gupnp-media-collection-set-title">
+<ANCHOR id="gupnp-media-collection-get-title" href="gupnp-av/GUPnPMediaCollection.html#gupnp-media-collection-get-title">
+<ANCHOR id="gupnp-media-collection-set-author" href="gupnp-av/GUPnPMediaCollection.html#gupnp-media-collection-set-author">
+<ANCHOR id="gupnp-media-collection-get-author" href="gupnp-av/GUPnPMediaCollection.html#gupnp-media-collection-get-author">
+<ANCHOR id="gupnp-media-collection-add-item" href="gupnp-av/GUPnPMediaCollection.html#gupnp-media-collection-add-item">
+<ANCHOR id="gupnp-media-collection-get-string" href="gupnp-av/GUPnPMediaCollection.html#gupnp-media-collection-get-string">
+<ANCHOR id="gupnp-media-collection-get-items" href="gupnp-av/GUPnPMediaCollection.html#gupnp-media-collection-get-items">
+<ANCHOR id="gupnp-media-collection-get-mutable" href="gupnp-av/GUPnPMediaCollection.html#gupnp-media-collection-get-mutable">
+<ANCHOR id="GUPnPMediaCollection.property-details" href="gupnp-av/GUPnPMediaCollection.html#GUPnPMediaCollection.property-details">
+<ANCHOR id="GUPnPMediaCollection--author" href="gupnp-av/GUPnPMediaCollection.html#GUPnPMediaCollection--author">
+<ANCHOR id="GUPnPMediaCollection--data" href="gupnp-av/GUPnPMediaCollection.html#GUPnPMediaCollection--data">
+<ANCHOR id="GUPnPMediaCollection--mutable" href="gupnp-av/GUPnPMediaCollection.html#GUPnPMediaCollection--mutable">
+<ANCHOR id="GUPnPMediaCollection--title" href="gupnp-av/GUPnPMediaCollection.html#GUPnPMediaCollection--title">
<ANCHOR id="gupnp-av-Error-codes" href="gupnp-av/gupnp-av-Error-codes.html">
<ANCHOR id="gupnp-av-Error-codes.synopsis" href="gupnp-av/gupnp-av-Error-codes.html#gupnp-av-Error-codes.synopsis">
<ANCHOR id="gupnp-av-Error-codes.description" href="gupnp-av/gupnp-av-Error-codes.html#gupnp-av-Error-codes.description">
@@ -369,6 +460,8 @@
<ANCHOR id="GUPNP-PROTOCOL-ERROR-INVALID-SYNTAX:CAPS" href="gupnp-av/gupnp-av-Error-codes.html#GUPNP-PROTOCOL-ERROR-INVALID-SYNTAX:CAPS">
<ANCHOR id="GUPNP-PROTOCOL-ERROR-OTHER:CAPS" href="gupnp-av/gupnp-av-Error-codes.html#GUPNP-PROTOCOL-ERROR-OTHER:CAPS">
<ANCHOR id="GUPnPSearchCriteriaParserError" href="gupnp-av/gupnp-av-Error-codes.html#GUPnPSearchCriteriaParserError">
+<ANCHOR id="GUPNP-SEARCH-CRITERIA-PARSER-ERROR-FAILED:CAPS" href="gupnp-av/gupnp-av-Error-codes.html#GUPNP-SEARCH-CRITERIA-PARSER-ERROR-FAILED:CAPS">
+<ANCHOR id="annotation-glossterm-array" href="gupnp-av/annotation-glossary.html#annotation-glossterm-array">
<ANCHOR id="annotation-glossterm-allow-none" href="gupnp-av/annotation-glossary.html#annotation-glossterm-allow-none">
<ANCHOR id="annotation-glossterm-element-type" href="gupnp-av/annotation-glossary.html#annotation-glossterm-element-type">
<ANCHOR id="annotation-glossterm-transfer container" href="gupnp-av/annotation-glossary.html#annotation-glossterm-transfer container">
diff --git a/doc/version.xml b/doc/version.xml
index bc859cb..b80f98e 100644
--- a/doc/version.xml
+++ b/doc/version.xml
@@ -1 +1 @@
-0.11.2
+0.11.7
diff --git a/libgupnp-av/Makefile.am b/libgupnp-av/Makefile.am
index 8c5ea5c..7db04eb 100644
--- a/libgupnp-av/Makefile.am
+++ b/libgupnp-av/Makefile.am
@@ -27,6 +27,8 @@ libgupnp_av_inc_HEADERS = gupnp-didl-lite-object.h \
gupnp-protocol-info.h \
gupnp-search-criteria-parser.h \
gupnp-last-change-parser.h \
+ gupnp-cds-last-change-parser.h \
+ gupnp-media-collection.h \
gupnp-feature.h \
gupnp-feature-list-parser.h \
gupnp-dlna.h \
@@ -54,6 +56,7 @@ libgupnp_av_1_0_la_SOURCES = gupnp-didl-lite-object.c \
gupnp-didl-lite-createclass.c \
gupnp-didl-lite-createclass-private.h \
gupnp-didl-lite-parser.c \
+ gupnp-didl-lite-parser-private.h \
gupnp-didl-lite-resource.c \
gupnp-didl-lite-resource-private.h \
gupnp-didl-lite-descriptor.c \
@@ -61,9 +64,12 @@ libgupnp_av_1_0_la_SOURCES = gupnp-didl-lite-object.c \
gupnp-didl-lite-contributor.c \
gupnp-didl-lite-contributor-private.h \
gupnp-didl-lite-writer.c \
+ gupnp-didl-lite-writer-private.h \
gupnp-protocol-info.c \
gupnp-search-criteria-parser.c \
gupnp-last-change-parser.c \
+ gupnp-cds-last-change-parser.c \
+ gupnp-media-collection.c \
gupnp-feature.c \
gupnp-feature-list-parser.c \
gupnp-dlna.c \
@@ -74,6 +80,8 @@ libgupnp_av_1_0_la_SOURCES = gupnp-didl-lite-object.c \
gvalue-util.h \
fragment-util.c \
fragment-util.h \
+ time-utils.c \
+ time-utils.h \
xsd-data.c \
xsd-data.h \
$(BUILT_SOURCES)
@@ -105,6 +113,8 @@ introspection_sources = \
$(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-cds-last-change-parser.c \
+ $(top_srcdir)/libgupnp-av/gupnp-media-collection.c \
$(top_srcdir)/libgupnp-av/gupnp-feature.c \
$(top_srcdir)/libgupnp-av/gupnp-feature-list-parser.c \
$(top_srcdir)/libgupnp-av/gupnp-dlna.c \
diff --git a/libgupnp-av/Makefile.in b/libgupnp-av/Makefile.in
index 52b1c5c..6b42481 100644
--- a/libgupnp-av/Makefile.in
+++ b/libgupnp-av/Makefile.in
@@ -108,10 +108,11 @@ am_libgupnp_av_1_0_la_OBJECTS = gupnp-didl-lite-object.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-feature.lo \
+ gupnp-last-change-parser.lo gupnp-cds-last-change-parser.lo \
+ gupnp-media-collection.lo gupnp-feature.lo \
gupnp-feature-list-parser.lo gupnp-dlna.lo gupnp-av-error.lo \
- xml-util.lo gvalue-util.lo fragment-util.lo xsd-data.lo \
- $(am__objects_1)
+ xml-util.lo gvalue-util.lo fragment-util.lo time-utils.lo \
+ xsd-data.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@)
@@ -320,6 +321,8 @@ libgupnp_av_inc_HEADERS = gupnp-didl-lite-object.h \
gupnp-protocol-info.h \
gupnp-search-criteria-parser.h \
gupnp-last-change-parser.h \
+ gupnp-cds-last-change-parser.h \
+ gupnp-media-collection.h \
gupnp-feature.h \
gupnp-feature-list-parser.h \
gupnp-dlna.h \
@@ -336,6 +339,7 @@ libgupnp_av_1_0_la_SOURCES = gupnp-didl-lite-object.c \
gupnp-didl-lite-createclass.c \
gupnp-didl-lite-createclass-private.h \
gupnp-didl-lite-parser.c \
+ gupnp-didl-lite-parser-private.h \
gupnp-didl-lite-resource.c \
gupnp-didl-lite-resource-private.h \
gupnp-didl-lite-descriptor.c \
@@ -343,9 +347,12 @@ libgupnp_av_1_0_la_SOURCES = gupnp-didl-lite-object.c \
gupnp-didl-lite-contributor.c \
gupnp-didl-lite-contributor-private.h \
gupnp-didl-lite-writer.c \
+ gupnp-didl-lite-writer-private.h \
gupnp-protocol-info.c \
gupnp-search-criteria-parser.c \
gupnp-last-change-parser.c \
+ gupnp-cds-last-change-parser.c \
+ gupnp-media-collection.c \
gupnp-feature.c \
gupnp-feature-list-parser.c \
gupnp-dlna.c \
@@ -356,6 +363,8 @@ libgupnp_av_1_0_la_SOURCES = gupnp-didl-lite-object.c \
gvalue-util.h \
fragment-util.c \
fragment-util.h \
+ time-utils.c \
+ time-utils.h \
xsd-data.c \
xsd-data.h \
$(BUILT_SOURCES)
@@ -380,6 +389,8 @@ INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir)
@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-cds-last-change-parser.c \
+@HAVE_INTROSPECTION_TRUE@ $(top_srcdir)/libgupnp-av/gupnp-media-collection.c \
@HAVE_INTROSPECTION_TRUE@ $(top_srcdir)/libgupnp-av/gupnp-feature.c \
@HAVE_INTROSPECTION_TRUE@ $(top_srcdir)/libgupnp-av/gupnp-feature-list-parser.c \
@HAVE_INTROSPECTION_TRUE@ $(top_srcdir)/libgupnp-av/gupnp-dlna.c \
@@ -477,6 +488,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fragment-util.Plo@am__quote@
@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-cds-last-change-parser.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-createclass.Plo@am__quote@
@@ -490,9 +502,11 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gupnp-feature-list-parser.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gupnp-feature.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-media-collection.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)/time-utils.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml-util.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xsd-data.Plo@am__quote@
diff --git a/libgupnp-av/gupnp-av-enums.h b/libgupnp-av/gupnp-av-enums.h
index 701fd14..a230240 100644
--- a/libgupnp-av/gupnp-av-enums.h
+++ b/libgupnp-av/gupnp-av-enums.h
@@ -26,6 +26,28 @@
G_BEGIN_DECLS
+/**
+ * GUPnPDIDLLiteFragmentResult:
+ * @GUPNP_DIDL_LITE_FRAGMENT_RESULT_OK: Operation succeeded.
+ * @GUPNP_DIDL_LITE_FRAGMENT_RESULT_CURRENT_BAD_XML: Current set of fragments
+ * is bad XML
+ * @GUPNP_DIDL_LITE_FRAGMENT_RESULT_NEW_BAD_XML: New set of fragments is bad
+ * XML
+ * @GUPNP_DIDL_LITE_FRAGMENT_RESULT_CURRENT_INVALID: Current set of fragments
+ * is invalid
+ * @GUPNP_DIDL_LITE_FRAGMENT_RESULT_NEW_INVALID: New set of fragments is
+ * invalid
+ * @GUPNP_DIDL_LITE_FRAGMENT_RESULT_REQUIRED_TAG: Trying to remove a required
+ * tag
+ * @GUPNP_DIDL_LITE_FRAGMENT_RESULT_READONLY_TAG: Trying to modify or remove a
+ * read-only tag
+ * @GUPNP_DIDL_LITE_FRAGMENT_RESULT_MISMATCH: Length of the two fragment sets
+ * does not match
+ * @GUPNP_DIDL_LITE_FRAGMENT_RESULT_UNKNOWN_ERROR: General error sink if none
+ * of the others applies.
+ *
+ * Possible return values of the gupnp_didl_lite_object_apply_fragments() call.
+ **/
typedef enum {
GUPNP_DIDL_LITE_FRAGMENT_RESULT_OK,
GUPNP_DIDL_LITE_FRAGMENT_RESULT_CURRENT_BAD_XML,
diff --git a/libgupnp-av/gupnp-av.h b/libgupnp-av/gupnp-av.h
index 21da810..6741c02 100644
--- a/libgupnp-av/gupnp-av.h
+++ b/libgupnp-av/gupnp-av.h
@@ -33,7 +33,8 @@
#include "gupnp-protocol-info.h"
#include "gupnp-search-criteria-parser.h"
#include "gupnp-last-change-parser.h"
+#include "gupnp-cds-last-change-parser.h"
#include "gupnp-feature.h"
#include "gupnp-feature-list-parser.h"
#include "gupnp-dlna.h"
-
+#include "gupnp-media-collection.h"
diff --git a/libgupnp-av/gupnp-cds-last-change-parser.c b/libgupnp-av/gupnp-cds-last-change-parser.c
new file mode 100644
index 0000000..d51d385
--- /dev/null
+++ b/libgupnp-av/gupnp-cds-last-change-parser.c
@@ -0,0 +1,379 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.
+ *
+ * Authors: Jens Georg <jensg@openismus.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-cds-last-change-parser
+ * @short_description: LastChange parser for the format used in
+ * CDS:3
+ *
+ * #GUPnPCDSLastChangeParser parses XML strings from
+ * CDS's LastChange state variable.
+ *
+ */
+
+#include <libgupnp/gupnp-error.h>
+
+#include "xml-util.h"
+#include "gupnp-cds-last-change-parser.h"
+
+/**
+ * GUPnPCDSLastChangeEntry:
+ *
+ * Opaque struct which contains information about the event.
+ **/
+struct _GUPnPCDSLastChangeEntry {
+ int ref_count;
+ GUPnPCDSLastChangeEvent event;
+ char *object_id;
+ char *parent_id;
+ char *class;
+ guint32 update_id;
+ gboolean is_subtree_update;
+};
+
+G_DEFINE_TYPE (GUPnPCDSLastChangeParser,
+ gupnp_cds_last_change_parser,
+ G_TYPE_OBJECT)
+
+G_DEFINE_BOXED_TYPE (GUPnPCDSLastChangeEntry,
+ gupnp_cds_last_change_entry,
+ gupnp_cds_last_change_entry_ref,
+ gupnp_cds_last_change_entry_unref);
+
+static void
+gupnp_cds_last_change_parser_init (GUPnPCDSLastChangeParser *parser)
+{
+}
+
+static void
+gupnp_cds_last_change_parser_class_init (GUPnPCDSLastChangeParserClass *klass)
+{
+}
+
+/**
+ * gupnp_cds_last_change_parser_new:
+ *
+ * Create a new #GUPnPCDSLastChangeParser.
+ *
+ * This parser is able to parse LastChange as defined in the
+ * ContentDirectory:3 specification.
+ *
+ * Returns:(transfer full): A new instance of #GUPnPCDSLastChangeParser.
+ **/
+GUPnPCDSLastChangeParser *
+gupnp_cds_last_change_parser_new (void)
+{
+ return g_object_new (GUPNP_TYPE_CDS_LAST_CHANGE_PARSER,
+ NULL);
+}
+
+/**
+ * gupnp_cds_last_change_parser_parse:
+ * @parser: #GUPnPCDSLastChangeParser
+ * @last_change: XML string to parse
+ * @error: Return value for parser error or %NULL to ingore
+ *
+ * Parse a LastChange XML document in the flavor defined by the
+ * ContentDirectory:3 specification.
+ *
+ * Returns: (element-type GUPnPCDSLastChangeEntry)(transfer full):
+ * List of #GUPnPCDSLastChangeEntry<!-- -->s
+ **/
+GList *
+gupnp_cds_last_change_parser_parse (GUPnPCDSLastChangeParser *parser,
+ const char *last_change,
+ GError **error)
+
+{
+ xmlDoc *doc;
+ xmlNode *state_event, *it;
+ GList *result = NULL;
+ GUPnPCDSLastChangeEntry *entry;
+
+ g_return_val_if_fail (GUPNP_IS_CDS_LAST_CHANGE_PARSER (parser),
+ NULL);
+
+ doc = xmlParseDoc ((const xmlChar *) last_change);
+ if (doc == NULL) {
+ g_set_error (error,
+ GUPNP_XML_ERROR,
+ GUPNP_XML_ERROR_PARSE,
+ "Could not parse LastChange XML");
+
+ goto out;
+ }
+
+ state_event = xml_util_get_element ((xmlNode *) doc,
+ "StateEvent",
+ NULL);
+ if (state_event == NULL) {
+ g_set_error (error,
+ GUPNP_XML_ERROR,
+ GUPNP_XML_ERROR_PARSE,
+ "Missing StateEvent node");
+
+ goto out;
+ }
+
+ for (it = state_event->children; it != NULL; it = it->next) {
+ if (it->type == XML_TEXT_NODE)
+ continue;
+ else if (g_ascii_strcasecmp ((const char *) it->name,
+ "objAdd") == 0) {
+ const char *tmp;
+
+ entry = g_slice_new0 (GUPnPCDSLastChangeEntry);
+ entry->ref_count = 1;
+ entry->event = GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED;
+
+ tmp = xml_util_get_attribute_content (it, "objID");
+ entry->object_id = g_strdup (tmp);
+
+ tmp = xml_util_get_attribute_content (it,
+ "objParentID");
+ entry->parent_id = g_strdup (tmp);
+
+ tmp = xml_util_get_attribute_content (it, "objClass");
+ entry->class = g_strdup (tmp);
+
+ entry->update_id = (guint32) xml_util_get_uint_attribute
+ (it,
+ "updateID",
+ 0);
+ entry->is_subtree_update =
+ xml_util_get_boolean_attribute
+ (it,
+ "stUpdate");
+ } else if (g_ascii_strcasecmp ((const char *) it->name,
+ "objMod") == 0) {
+ const char *tmp;
+
+ entry = g_slice_new0 (GUPnPCDSLastChangeEntry);
+ entry->ref_count = 1;
+ entry->event = GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED;
+
+ tmp = xml_util_get_attribute_content (it, "objID");
+ entry->object_id = g_strdup (tmp);
+
+ entry->update_id = (guint32) xml_util_get_uint_attribute
+ (it,
+ "updateID",
+ 0);
+ entry->is_subtree_update =
+ xml_util_get_boolean_attribute
+ (it,
+ "stUpdate");
+ } else if (g_ascii_strcasecmp ((const char *) it->name,
+ "objDel") == 0) {
+ const char *tmp;
+
+ entry = g_slice_new0 (GUPnPCDSLastChangeEntry);
+ entry->ref_count = 1;
+ entry->event = GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_REMOVED;
+
+ tmp = xml_util_get_attribute_content (it, "objID");
+ entry->object_id = g_strdup (tmp);
+
+ entry->update_id = (guint32) xml_util_get_uint_attribute
+ (it,
+ "updateID",
+ 0);
+ entry->is_subtree_update =
+ xml_util_get_boolean_attribute
+ (it,
+ "stUpdate");
+ } else if (g_ascii_strcasecmp ((const char *) it->name,
+ "stDone") == 0) {
+ const char *tmp;
+
+ entry = g_slice_new0 (GUPnPCDSLastChangeEntry);
+ entry->ref_count = 1;
+ entry->event = GUPNP_CDS_LAST_CHANGE_EVENT_ST_DONE;
+
+ tmp = xml_util_get_attribute_content (it, "objID");
+ entry->object_id = g_strdup (tmp);
+
+ entry->update_id = (guint32) xml_util_get_uint_attribute
+ (it,
+ "updateID",
+ 0);
+ } else {
+ g_warning ("Skipping invalid LastChange entry: %s",
+ (const char *) it->name);
+ continue;
+ }
+
+ result = g_list_prepend (result, entry);
+ }
+
+ result = g_list_reverse (result);
+out:
+ if (doc != NULL) {
+ xmlFreeDoc (doc);
+ }
+
+ return result;
+
+}
+
+/**
+ * gupnp_cds_last_change_entry_ref:
+ * @entry: A #GUPnPCDSLastChangeEntry
+ *
+ * Increase reference count of a #GUPnPCDSLastChangeEntry.
+ *
+ * Returns:(transfer full): The object passed in @entry.
+ **/
+GUPnPCDSLastChangeEntry *
+gupnp_cds_last_change_entry_ref (GUPnPCDSLastChangeEntry *entry)
+{
+ g_return_val_if_fail (entry != NULL, NULL);
+ g_return_val_if_fail (entry->ref_count > 0, NULL);
+
+ g_atomic_int_inc (&entry->ref_count);
+
+ return entry;
+}
+
+/**
+ * gupnp_cds_last_change_entry_unref:
+ * @entry: A #GUPnPCDSLastChangeEntry
+ *
+ * Decrease reference count of a #GUPnPCDSLastChangeEntry. If the reference
+ * count drops to 0, @entry is freed.
+ **/
+void
+gupnp_cds_last_change_entry_unref (GUPnPCDSLastChangeEntry *entry)
+{
+ g_return_if_fail (entry != NULL);
+ g_return_if_fail (entry->ref_count > 0);
+
+ if (g_atomic_int_dec_and_test (&entry->ref_count)) {
+ g_free (entry->class);
+ g_free (entry->object_id);
+ g_free (entry->parent_id);
+
+ g_slice_free (GUPnPCDSLastChangeEntry, entry);
+ }
+}
+
+/**
+ * gupnp_cds_last_change_entry_get_event:
+ * @entry: A #GUPnPCDSLastChangeEntry
+ *
+ * Get the type of the last change entry as defined in
+ * #GUPnPCDSLastChangeEvent.
+ *
+ * Returns: An event from the #GUPnPCDSLastChangeEvent or
+ * %GUPNP_CDS_LAST_CHANGE_EVENT_INVALID if the entry is not valid.
+ **/
+GUPnPCDSLastChangeEvent
+gupnp_cds_last_change_entry_get_event (GUPnPCDSLastChangeEntry *entry)
+{
+ g_return_val_if_fail (entry != NULL,
+ GUPNP_CDS_LAST_CHANGE_EVENT_INVALID);
+
+ return entry->event;
+}
+
+/**
+ * gupnp_cds_last_change_entry_get_object_id:
+ * @entry: A #GUPnPCDSLastChangeEntry
+ *
+ * Get the ID of the object in this change entry.
+ *
+ * Returns: (transfer none): The id of the object of this entry.
+ **/
+const char *
+gupnp_cds_last_change_entry_get_object_id (GUPnPCDSLastChangeEntry *entry)
+{
+ g_return_val_if_fail (entry != NULL, NULL);
+
+ return entry->object_id;
+}
+
+/**
+ * gupnp_cds_last_change_entry_get_parent_id:
+ * @entry: A #GUPnPCDSLastChangeEntry
+ *
+ * Get the parent object id of the object in this change entry. This is only
+ * valid if gupnp_cds_last_change_entry_get_event() returns
+ * %GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED.
+ *
+ * Returns: (transfer none): The id of the object's parent of this entry.
+ **/
+const char *
+gupnp_cds_last_change_entry_get_parent_id (GUPnPCDSLastChangeEntry *entry)
+{
+ g_return_val_if_fail (entry != NULL, NULL);
+
+ return entry->parent_id;
+}
+
+/**
+ * gupnp_cds_last_change_entry_get_class:
+ * @entry: A #GUPnPCDSLastChangeEntry
+ *
+ * Get the class of the object in this change entry. This is only
+ * valid if gupnp_cds_last_change_entry_get_event() returns
+ * %GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED.
+ *
+ * Returns: (transfer none): The upnp class of the object of this entry.
+ **/
+const char *
+gupnp_cds_last_change_entry_get_class (GUPnPCDSLastChangeEntry *entry)
+{
+ g_return_val_if_fail (entry != NULL, NULL);
+
+ return entry->class;
+}
+
+/**
+ * gupnp_cds_last_change_entry_is_subtree_update:
+ * @entry: A #GUPnPCDSLastChangeEntry
+ *
+ * Returns whether this entry is part of a subtree update.
+ *
+ * Returns: %TRUE, if the entry is part of a subtree update, %FALSE otherwise.
+ **/
+gboolean
+gupnp_cds_last_change_entry_is_subtree_update (GUPnPCDSLastChangeEntry *entry)
+{
+ g_return_val_if_fail (entry != NULL, FALSE);
+
+ return entry->is_subtree_update;
+}
+
+/**
+ * gupnp_cds_last_change_entry_get_update_id:
+ * @entry: A #GUPnPCDSLastChangeEntry
+ *
+ * Get the update id of the last change entry.
+ *
+ * Returns: update id of the entry or 0 if the entry is not valid.
+ **/
+guint32
+gupnp_cds_last_change_entry_get_update_id (GUPnPCDSLastChangeEntry *entry)
+{
+ g_return_val_if_fail (entry != NULL, 0);
+
+ return entry->update_id;
+}
diff --git a/libgupnp-av/gupnp-cds-last-change-parser.h b/libgupnp-av/gupnp-cds-last-change-parser.h
new file mode 100644
index 0000000..8c29d4f
--- /dev/null
+++ b/libgupnp-av/gupnp-cds-last-change-parser.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.
+ *
+ * Authors: Jens Georg <jensg@openismus.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_CDS_LAST_CHANGE_PARSER_H__
+#define __GUPNP_CDS_LAST_CHANGE_PARSER_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+GType
+gupnp_cds_last_change_parser_get_type (void) G_GNUC_CONST;
+
+GType
+gupnp_cds_last_change_entry_get_type (void) G_GNUC_CONST;
+
+#define GUPNP_TYPE_CDS_LAST_CHANGE_PARSER \
+ (gupnp_cds_last_change_parser_get_type ())
+#define GUPNP_CDS_LAST_CHANGE_PARSER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ GUPNP_TYPE_CDS_LAST_CHANGE_PARSER, \
+ GUPnPCDSLastChangeParser))
+#define GUPNP_CDS_LAST_CHANGE_PARSER_CLASS(obj) \
+ (G_TYPE_CHECK_CLASS_CAST ((obj), \
+ GUPNP_TYPE_CDS_LAST_CHANGE_PARSER, \
+ GUPnPCDSLastChangeParserClass))
+#define GUPNP_IS_CDS_LAST_CHANGE_PARSER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ GUPNP_TYPE_CDS_LAST_CHANGE_PARSER))
+#define GUPNP_IS_CDS_LAST_CHANGE_PARSER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+ GUPNP_TYPE_CDS_LAST_CHANGE_PARSER))
+#define GUPNP_CDS_LAST_CHANGE_PARSER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ GUPNP_TYPE_CDS_LAST_CHANGE_PARSER, \
+ GUPnPCDSLastChangeParserClass))
+
+typedef struct _GUPnPCDSLastChangeParser GUPnPCDSLastChangeParser;
+typedef struct _GUPnPCDSLastChangeParserClass GUPnPCDSLastChangeParserClass;
+typedef struct _GUPnPCDSLastChangeParserPrivate GUPnPCDSLastChangeParserPrivate;
+typedef struct _GUPnPCDSLastChangeEntry GUPnPCDSLastChangeEntry;
+
+struct _GUPnPCDSLastChangeParser {
+ GObject parent;
+
+ GUPnPCDSLastChangeParserPrivate *priv;
+};
+
+struct _GUPnPCDSLastChangeParserClass {
+ GObjectClass parent_class;
+};
+
+typedef enum GUPnPCDSLastChangeEvent {
+ GUPNP_CDS_LAST_CHANGE_EVENT_INVALID,
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED,
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_REMOVED,
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
+ GUPNP_CDS_LAST_CHANGE_EVENT_ST_DONE
+} GUPnPCDSLastChangeEvent;
+
+GUPnPCDSLastChangeParser *
+gupnp_cds_last_change_parser_new (void);
+
+GList *
+gupnp_cds_last_change_parser_parse (GUPnPCDSLastChangeParser *parser,
+ const char *last_change,
+ GError **error);
+
+GUPnPCDSLastChangeEntry *
+gupnp_cds_last_change_entry_ref (GUPnPCDSLastChangeEntry *entry);
+void
+gupnp_cds_last_change_entry_unref (GUPnPCDSLastChangeEntry *entry);
+
+GUPnPCDSLastChangeEvent
+gupnp_cds_last_change_entry_get_event (GUPnPCDSLastChangeEntry *entry);
+
+const char *
+gupnp_cds_last_change_entry_get_object_id (GUPnPCDSLastChangeEntry *entry);
+
+const char *
+gupnp_cds_last_change_entry_get_parent_id (GUPnPCDSLastChangeEntry *entry);
+
+const char *
+gupnp_cds_last_change_entry_get_class (GUPnPCDSLastChangeEntry *entry);
+
+gboolean
+gupnp_cds_last_change_entry_is_subtree_update (GUPnPCDSLastChangeEntry *entry);
+
+guint32
+gupnp_cds_last_change_entry_get_update_id (GUPnPCDSLastChangeEntry *entry);
+
+G_END_DECLS
+
+#endif /* __GUPNP_CDS_LAST_CHANGE_PARSER_H__ */
diff --git a/libgupnp-av/gupnp-didl-lite-item.c b/libgupnp-av/gupnp-didl-lite-item.c
index 9e5d34c..ab38cb6 100644
--- a/libgupnp-av/gupnp-didl-lite-item.c
+++ b/libgupnp-av/gupnp-didl-lite-item.c
@@ -31,6 +31,7 @@
#include "gupnp-didl-lite-item.h"
#include "xml-util.h"
+#include "time-utils.h"
G_DEFINE_TYPE (GUPnPDIDLLiteItem,
gupnp_didl_lite_item,
@@ -38,7 +39,8 @@ G_DEFINE_TYPE (GUPnPDIDLLiteItem,
enum {
PROP_0,
- PROP_REF_ID
+ PROP_REF_ID,
+ PROP_LIFETIME
};
static void
@@ -63,6 +65,11 @@ gupnp_didl_lite_item_get_property (GObject *object,
(value,
gupnp_didl_lite_item_get_ref_id (item));
break;
+ case PROP_LIFETIME:
+ g_value_set_long
+ (value,
+ gupnp_didl_lite_item_get_lifetime (item));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -85,6 +92,10 @@ gupnp_didl_lite_item_set_property (GObject *object,
gupnp_didl_lite_item_set_ref_id (item,
g_value_get_string (value));
break;
+ case PROP_LIFETIME:
+ gupnp_didl_lite_item_set_lifetime (item,
+ g_value_get_long (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -117,6 +128,24 @@ gupnp_didl_lite_item_class_init (GUPnPDIDLLiteItemClass *klass)
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
+
+ /**
+ * GUPnPDIDLLiteItem:lifetime:
+ *
+ * The lifetime in seconds of this DIDLLite item in a media collection.
+ **/
+ g_object_class_install_property
+ (object_class,
+ PROP_LIFETIME,
+ g_param_spec_long ("lifetime",
+ "Lifetime",
+ "The lifetime (in seconds) of this"
+ " item.",
+ -1,
+ G_MAXLONG,
+ -1,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
}
/**
@@ -166,3 +195,62 @@ gupnp_didl_lite_item_set_ref_id (GUPnPDIDLLiteItem *item,
g_object_notify (G_OBJECT (item), "ref-id");
}
+
+/**
+ * gupnp_didl_lite_item_set_lifetime:
+ * @item: #GUPnPDIDLLiteItem
+ * @lifetime: The lifetime (in seconds) of this item in a media collection.
+ **/
+void
+gupnp_didl_lite_item_set_lifetime (GUPnPDIDLLiteItem *item,
+ glong lifetime)
+{
+ xmlNode *node = NULL;
+ xmlNs *ns = NULL;
+ GUPnPXMLDoc *doc = NULL;
+ GUPnPDIDLLiteObject *object = NULL;
+
+ g_return_if_fail (GUPNP_IS_DIDL_LITE_ITEM (item));
+
+ object = GUPNP_DIDL_LITE_OBJECT (item);
+ node = gupnp_didl_lite_object_get_xml_node (object);
+ ns = gupnp_didl_lite_object_get_dlna_namespace (object);
+ g_object_get (G_OBJECT (object), "xml-doc", &doc, NULL);
+
+ if (lifetime < 0)
+ xml_util_unset_child (node, "lifetime");
+ else {
+ char *str;
+
+ str = seconds_to_time (lifetime);
+ xml_util_set_child (node, ns, doc->doc, "lifetime", str);
+ g_free (str);
+ }
+
+ g_object_notify (G_OBJECT (object), "lifetime");
+}
+
+/**
+ * gupnp_didl_lite_item_get_lifetime:
+ * @item: #GUPnPDIDLLiteItem
+ *
+ * Returns: -1 if unset or the lifetime (in seconds) of the current item.
+ **/
+glong
+gupnp_didl_lite_item_get_lifetime (GUPnPDIDLLiteItem *item)
+{
+ xmlNode *node = NULL;
+ const char *lifetime_str;
+ long lifetime;
+ GUPnPDIDLLiteObject *object = NULL;
+
+ g_return_val_if_fail (GUPNP_IS_DIDL_LITE_ITEM (item), -1);
+
+ object = GUPNP_DIDL_LITE_OBJECT (item);
+ node = gupnp_didl_lite_object_get_xml_node (object);
+
+ lifetime_str = xml_util_get_child_element_content (node, "lifetime");
+ lifetime = seconds_from_time (lifetime_str);
+
+ return lifetime;
+}
diff --git a/libgupnp-av/gupnp-didl-lite-item.h b/libgupnp-av/gupnp-didl-lite-item.h
index 1719729..e55c271 100644
--- a/libgupnp-av/gupnp-didl-lite-item.h
+++ b/libgupnp-av/gupnp-didl-lite-item.h
@@ -1,8 +1,10 @@
/*
* Copyright (C) 2009 Nokia Corporation.
+ * Copyright (C) 2012 Intel Corporation.
*
* Authors: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com>
* <zeeshanak@gnome.org>
+ * Jens Georg <jensg@openismus.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -73,6 +75,13 @@ void
gupnp_didl_lite_item_set_ref_id (GUPnPDIDLLiteItem *item,
const char *ref_id);
+void
+gupnp_didl_lite_item_set_lifetime (GUPnPDIDLLiteItem *item,
+ glong lifetime);
+
+glong
+gupnp_didl_lite_item_get_lifetime (GUPnPDIDLLiteItem *item);
+
G_END_DECLS
#endif /* __GUPNP_DIDL_LITE_ITEM_H__ */
diff --git a/libgupnp-av/gupnp-didl-lite-object.c b/libgupnp-av/gupnp-didl-lite-object.c
index 30533c5..5e527bc 100644
--- a/libgupnp-av/gupnp-didl-lite-object.c
+++ b/libgupnp-av/gupnp-didl-lite-object.c
@@ -2428,3 +2428,30 @@ gupnp_didl_lite_object_apply_fragments (GUPnPDIDLLiteObject *object,
xmlFreeDoc (modified.doc);
return result;
}
+
+/**
+ * gupnp_didl_lite_object_get_xml_string:
+ * @object: #GUPnPDIDLLiteObject
+ *
+ * Get the representation of this object as an XML string.
+ * Returns: (transfer full): XML representation of this object as string.
+ **/
+char *
+gupnp_didl_lite_object_get_xml_string (GUPnPDIDLLiteObject *object)
+{
+ xmlBuffer *buffer = NULL;
+ char *ret = NULL;
+
+ buffer = xmlBufferCreate ();
+ xmlNodeDump (buffer,
+ object->priv->xml_doc->doc,
+ object->priv->xml_node,
+ 0,
+ 0);
+
+ ret = g_strndup ((char *) xmlBufferContent (buffer),
+ xmlBufferLength (buffer));
+ xmlBufferFree (buffer);
+
+ return ret;
+}
diff --git a/libgupnp-av/gupnp-didl-lite-object.h b/libgupnp-av/gupnp-didl-lite-object.h
index 6ca982d..872f26b 100644
--- a/libgupnp-av/gupnp-didl-lite-object.h
+++ b/libgupnp-av/gupnp-didl-lite-object.h
@@ -301,6 +301,9 @@ gupnp_didl_lite_object_apply_fragments
gchar **new_fragments,
gint new_size);
+char *
+gupnp_didl_lite_object_get_xml_string (GUPnPDIDLLiteObject *object);
+
G_END_DECLS
#endif /* __GUPNP_DIDL_LITE_OBJECT_H__ */
diff --git a/libgupnp-av/gupnp-didl-lite-parser-private.h b/libgupnp-av/gupnp-didl-lite-parser-private.h
new file mode 100644
index 0000000..b9e88aa
--- /dev/null
+++ b/libgupnp-av/gupnp-didl-lite-parser-private.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.
+ *
+ * Authors: Jens Georg <jensg@openismus.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_PARSER_PRIVATE_H__
+#define __GUPNP_DIDL_LITE_PARSER_PRIVATE_H__
+
+#include "gupnp-didl-lite-parser.h"
+
+G_BEGIN_DECLS
+
+G_GNUC_INTERNAL gboolean
+gupnp_didl_lite_parser_parse_didl_recursive (GUPnPDIDLLiteParser *parser,
+ const char *didl,
+ gboolean recursive,
+ GError **error);
+G_END_DECLS
+
+#endif /* __GUPNP_DIDL_LITE_PARSER_PRIVATE_H__ */
diff --git a/libgupnp-av/gupnp-didl-lite-parser.c b/libgupnp-av/gupnp-didl-lite-parser.c
index 8b1088d..086c2cc 100644
--- a/libgupnp-av/gupnp-didl-lite-parser.c
+++ b/libgupnp-av/gupnp-didl-lite-parser.c
@@ -32,6 +32,7 @@
#include "gupnp-av.h"
#include "gupnp-didl-lite-object-private.h"
#include "xml-util.h"
+#include "gupnp-didl-lite-parser-private.h"
G_DEFINE_TYPE (GUPnPDIDLLiteParser,
gupnp_didl_lite_parser,
@@ -75,6 +76,16 @@ verify_didl_attributes (xmlNode *node)
return xml_util_verify_attribute_is_boolean (node, "restricted");
}
+static gboolean
+parse_elements (GUPnPDIDLLiteParser *parser,
+ xmlNode *node,
+ GUPnPXMLDoc *xml_doc,
+ xmlNs *upnp_ns,
+ xmlNs *dc_ns,
+ xmlNs *dlna_ns,
+ gboolean recursive,
+ GError **error);
+
static void
gupnp_didl_lite_parser_init (GUPnPDIDLLiteParser *parser)
{
@@ -190,17 +201,41 @@ gupnp_didl_lite_parser_parse_didl (GUPnPDIDLLiteParser *parser,
const char *didl,
GError **error)
{
+ return gupnp_didl_lite_parser_parse_didl_recursive (parser,
+ didl,
+ FALSE,
+ error);
+}
+
+/**
+ * gupnp_didl_lite_parser_parse_didl_recursive:
+ * @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_recursive (GUPnPDIDLLiteParser *parser,
+ const char *didl,
+ gboolean recursive,
+ 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;
+ gboolean result;
doc = xmlRecoverMemory (didl, strlen (didl));
- if (doc == NULL) {
+ if (doc == NULL) {
g_set_error (error,
GUPNP_XML_ERROR,
GUPNP_XML_ERROR_PARSE,
@@ -284,7 +319,32 @@ gupnp_didl_lite_parser_parse_didl (GUPnPDIDLLiteParser *parser,
xml_doc = gupnp_xml_doc_new (doc);
- for (element = element->children; element; element = element->next) {
+ result = parse_elements (parser,
+ element,
+ xml_doc,
+ upnp_ns,
+ dc_ns,
+ dlna_ns,
+ recursive,
+ error);
+ g_object_unref (xml_doc);
+
+ return result;
+}
+
+static gboolean
+parse_elements (GUPnPDIDLLiteParser *parser,
+ xmlNode *node,
+ GUPnPXMLDoc *xml_doc,
+ xmlNs *upnp_ns,
+ xmlNs *dc_ns,
+ xmlNs *dlna_ns,
+ gboolean recursive,
+ GError **error)
+{
+ xmlNode *element;
+
+ for (element = node->children; element; element = element->next) {
GUPnPDIDLLiteObject *object;
object = gupnp_didl_lite_object_new_from_xml (element, xml_doc,
@@ -294,41 +354,49 @@ gupnp_didl_lite_parser_parse_didl (GUPnPDIDLLiteParser *parser,
if (object == NULL)
continue;
- if (GUPNP_IS_DIDL_LITE_CONTAINER (object))
+ 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;
+ signals[CONTAINER_AVAILABLE],
+ 0,
+ object);
+ if (recursive &&
+ !parse_elements (parser,
+ element,
+ xml_doc,
+ upnp_ns,
+ dc_ns,
+ dlna_ns,
+ recursive,
+ error)) {
+ g_object_unref (object);
+
+ return FALSE;
+ }
+ } 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_set_error (error,
+ GUPNP_XML_ERROR,
+ GUPNP_XML_ERROR_INVALID_ATTRIBUTE,
+ "Could not parse DIDL-Lite XML");
+
+ return FALSE;
}
g_signal_emit (parser,
- signals[ITEM_AVAILABLE],
- 0,
- object);
+ signals[ITEM_AVAILABLE],
+ 0,
+ object);
}
g_signal_emit (parser,
- signals[OBJECT_AVAILABLE],
- 0,
- object);
+ signals[OBJECT_AVAILABLE],
+ 0,
+ object);
g_object_unref (object);
}
- g_object_unref (xml_doc);
-
return TRUE;
}
-
diff --git a/libgupnp-av/gupnp-didl-lite-resource.c b/libgupnp-av/gupnp-didl-lite-resource.c
index 8b4e064..041976a 100644
--- a/libgupnp-av/gupnp-didl-lite-resource.c
+++ b/libgupnp-av/gupnp-didl-lite-resource.c
@@ -35,9 +35,7 @@
#include "gupnp-didl-lite-resource.h"
#include "xml-util.h"
-
-#define SEC_PER_MIN 60
-#define SEC_PER_HOUR 3600
+#include "time-utils.h"
G_DEFINE_TYPE (GUPnPDIDLLiteResource,
gupnp_didl_lite_resource,
@@ -106,31 +104,6 @@ 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,
@@ -822,10 +795,10 @@ gupnp_didl_lite_resource_get_protocol_info (GUPnPDIDLLiteResource *resource)
*
* Return value: The size (in bytes) of the @resource or -1.
**/
-long
+glong
gupnp_didl_lite_resource_get_size (GUPnPDIDLLiteResource *resource)
{
- return (long) gupnp_didl_lite_resource_get_size64 (resource);
+ return (glong) gupnp_didl_lite_resource_get_size64 (resource);
}
/**
@@ -855,7 +828,7 @@ gupnp_didl_lite_resource_get_size64 (GUPnPDIDLLiteResource *resource)
*
* Return value: The duration (in seconds) of the @resource or -1.
**/
-long
+glong
gupnp_didl_lite_resource_get_duration (GUPnPDIDLLiteResource *resource)
{
const char *duration_str;
@@ -1159,7 +1132,7 @@ gupnp_didl_lite_resource_set_protocol_info (GUPnPDIDLLiteResource *resource,
**/
void
gupnp_didl_lite_resource_set_size (GUPnPDIDLLiteResource *resource,
- long size)
+ glong size)
{
gupnp_didl_lite_resource_set_size64 (resource, size);
}
@@ -1210,7 +1183,7 @@ gupnp_didl_lite_resource_set_size64 (GUPnPDIDLLiteResource *resource,
**/
void
gupnp_didl_lite_resource_set_duration (GUPnPDIDLLiteResource *resource,
- long duration)
+ glong duration)
{
g_return_if_fail (GUPNP_IS_DIDL_LITE_RESOURCE (resource));
@@ -1220,10 +1193,7 @@ gupnp_didl_lite_resource_set_duration (GUPnPDIDLLiteResource *resource,
else {
char *str;
- str = g_strdup_printf ("%ld:%.2ld:%.2ld.000",
- duration / (60 * 60),
- (duration / 60) % 60,
- duration % 60);
+ str = seconds_to_time (duration);
xmlSetProp (resource->priv->xml_node,
(unsigned char *) "duration",
(unsigned char *) str);
diff --git a/libgupnp-av/gupnp-didl-lite-resource.h b/libgupnp-av/gupnp-didl-lite-resource.h
index cba2e71..2c257b7 100644
--- a/libgupnp-av/gupnp-didl-lite-resource.h
+++ b/libgupnp-av/gupnp-didl-lite-resource.h
@@ -95,7 +95,7 @@ gupnp_didl_lite_resource_set_protocol_info
void
gupnp_didl_lite_resource_set_size (GUPnPDIDLLiteResource *resource,
- long size);
+ glong size);
void
gupnp_didl_lite_resource_set_size64 (GUPnPDIDLLiteResource *resource,
@@ -103,7 +103,7 @@ gupnp_didl_lite_resource_set_size64 (GUPnPDIDLLiteResource *resource,
void
gupnp_didl_lite_resource_set_duration (GUPnPDIDLLiteResource *resource,
- long duration);
+ glong duration);
void
gupnp_didl_lite_resource_set_bitrate (GUPnPDIDLLiteResource *resource,
diff --git a/libgupnp-av/gupnp-didl-lite-writer-private.h b/libgupnp-av/gupnp-didl-lite-writer-private.h
new file mode 100644
index 0000000..128a7b3
--- /dev/null
+++ b/libgupnp-av/gupnp-didl-lite-writer-private.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.
+ *
+ * Authors: Jens Georg <jensg@openismus.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_PRIVATE_H__
+#define __GUPNP_DIDL_LITE_WRITER_PRIVATE_H__
+
+#include "gupnp-didl-lite-writer.h"
+#include "gupnp-didl-lite-container.h"
+
+G_BEGIN_DECLS
+
+G_GNUC_INTERNAL GUPnPDIDLLiteItem *
+gupnp_didl_lite_writer_add_container_child_item
+ (GUPnPDIDLLiteWriter *writer,
+ GUPnPDIDLLiteContainer *container);
+
+G_GNUC_INTERNAL void
+gupnp_didl_lite_writer_filter_tags (GUPnPDIDLLiteWriter *writer,
+ const char *filter);
+
+G_END_DECLS
+
+#endif /* __GUPNP_DIDL_LITE_WRITER_PRIVATE_H__ */
diff --git a/libgupnp-av/gupnp-didl-lite-writer.c b/libgupnp-av/gupnp-didl-lite-writer.c
index e4dcaef..9ab0654 100644
--- a/libgupnp-av/gupnp-didl-lite-writer.c
+++ b/libgupnp-av/gupnp-didl-lite-writer.c
@@ -1,7 +1,9 @@
/*
* Copyright (C) 2007, 2008 OpenedHand Ltd.
+ * Copyright (C) 2012 Intel Corporation.
*
* Authors: Jorn Baayen <jorn@openedhand.com>
+ * Jens Georg <jensg@openismus.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -32,6 +34,7 @@
#include "gupnp-didl-lite-object.h"
#include "gupnp-didl-lite-object-private.h"
#include "gupnp-didl-lite-descriptor-private.h"
+#include "gupnp-didl-lite-writer-private.h"
#include "xml-util.h"
@@ -107,10 +110,10 @@ static int
compare_node_name (const char *a, const char *b)
{
const char *p;
- int len;
+ int len, result;
if (a[0] == '@')
- /* Filer is for top-level property */
+ /* Filter is for top-level property */
return -1;
p = strstr (a, "@");
@@ -120,7 +123,15 @@ compare_node_name (const char *a, const char *b)
else
len = strlen (a);
- return strncmp (a, b, len);
+ result = strncmp (a, b, len);
+
+ if (result == 0) {
+ /* Avoid that we return a match although only prefixes match like
+ * in upnp:album and upnp:albumArtUri, cf. bgo#687462 */
+ return strlen (b) - len;
+ }
+
+ return result;
}
static gboolean
@@ -198,15 +209,17 @@ filter_attributes (xmlNode *node,
static void
filter_node (xmlNode *node,
GList *allowed,
- GUPnPDIDLLiteWriter *writer)
+ GUPnPDIDLLiteWriter *writer,
+ gboolean tags_only)
{
xmlNode *child;
GList *forbidden = NULL;
GList *l;
- gboolean is_container;
+ gboolean is_container = FALSE;
const char *container_class = NULL;
- filter_attributes (node, allowed, writer);
+ if (!tags_only)
+ filter_attributes (node, allowed, writer);
if (strcmp ((const char *) node->name, "container") == 0) {
is_container = TRUE;
@@ -250,9 +263,41 @@ filter_node (xmlNode *node,
/* Recurse */
for (child = node->children; child != NULL; child = child->next)
if (!xmlNodeIsText (child))
- filter_node (child, allowed, writer);
+ filter_node (child, allowed, writer, tags_only);
+}
+
+static void
+apply_filter (GUPnPDIDLLiteWriter *writer,
+ const char *filter,
+ gboolean tags_only)
+{
+ 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, tags_only);
+
+ g_list_free (allowed);
+ g_strfreev (tokens);
}
+
static void
gupnp_didl_lite_writer_init (GUPnPDIDLLiteWriter *writer)
{
@@ -483,6 +528,44 @@ gupnp_didl_lite_writer_add_item (GUPnPDIDLLiteWriter *writer)
}
/**
+ * gupnp_didl_lite_writer_add_container_child_item:
+ * @writer: #GUPnPDIDLLiteWriter
+ * @container: #GUPnPDIDLLiteContainer
+ *
+ * Add a child item to a container. This is only useful in DIDL_S playlist
+ * creation.
+ *
+ * Returns: (transfer full): A new #GUPnPDIDLLiteItem object. Unref after
+ * usage.
+ **/
+GUPnPDIDLLiteItem *
+gupnp_didl_lite_writer_add_container_child_item
+ (GUPnPDIDLLiteWriter *writer,
+ GUPnPDIDLLiteContainer *container)
+{
+ xmlNode *item_node, *container_node;
+ GUPnPDIDLLiteObject *object;
+ GUPnPXMLDoc *doc;
+
+ g_return_val_if_fail (GUPNP_IS_DIDL_LITE_CONTAINER (container), NULL);
+
+ object = GUPNP_DIDL_LITE_OBJECT (container);
+ container_node = gupnp_didl_lite_object_get_xml_node (object);
+
+ item_node = xmlNewChild (container_node,
+ NULL,
+ (xmlChar *) "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
*
@@ -613,28 +696,28 @@ 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);
+ apply_filter (writer, filter, FALSE);
+}
- g_list_free (allowed);
- g_strfreev (tokens);
+/**
+ * gupnp_didl_lite_writer_filter_tags:
+ * @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.
+ *
+ * In contrast to gupnp_didl_lite_writer_filter(), this function only removes
+ * unwanted tags but leaves all attributes in-place.
+ *
+ * Return value: None.
+ **/
+void
+gupnp_didl_lite_writer_filter_tags (GUPnPDIDLLiteWriter *writer,
+ const char *filter)
+{
+ apply_filter (writer, filter, TRUE);
}
diff --git a/libgupnp-av/gupnp-last-change-parser.c b/libgupnp-av/gupnp-last-change-parser.c
index 43aabe7..cddddd8 100644
--- a/libgupnp-av/gupnp-last-change-parser.c
+++ b/libgupnp-av/gupnp-last-change-parser.c
@@ -76,7 +76,6 @@ read_state_variable (const char *variable_name,
const char *val_str;
variable_node = xml_util_get_element (instance_node,
- "InstanceID",
variable_name,
NULL);
if (!variable_node)
@@ -102,13 +101,17 @@ get_instance_node (xmlDoc *doc,
{
xmlNode *node;
- for (node = doc->children;
+ if (doc->children == NULL)
+ return NULL;
+
+ for (node = doc->children->children;
node;
node = node->next) {
- guint id;
+ if (node->type != XML_ELEMENT_NODE)
+ continue;
- id = xml_util_get_uint_attribute (node, "val", 0);
- if (id == instance_id)
+ if (!xmlStrcmp (node->name, BAD_CAST ("InstanceID")) &&
+ xml_util_get_uint_attribute (node, "val", 0) == instance_id)
break;
}
diff --git a/libgupnp-av/gupnp-media-collection.c b/libgupnp-av/gupnp-media-collection.c
new file mode 100644
index 0000000..e04931e
--- /dev/null
+++ b/libgupnp-av/gupnp-media-collection.c
@@ -0,0 +1,594 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.
+ *
+ * Authors: Jens Georg <jensg@openismus.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-media-collection
+ * @short_description: Media collection writer
+ *
+ * #GUPnPMediaCollection is a helper class for writing media collection files.
+ **/
+
+#include "gupnp-media-collection.h"
+#include "gupnp-didl-lite-writer.h"
+#include "gupnp-didl-lite-writer-private.h"
+#include "gupnp-didl-lite-parser.h"
+#include "gupnp-didl-lite-parser-private.h"
+
+// DIDL_S allowed tags as per DLNA Guidelines 11.1
+#define DIDL_S_FILTER "dc:title,dc:creator,upnp:class,upnp:album,res,item," \
+ "container,dlna:lifetime"
+
+G_DEFINE_TYPE (GUPnPMediaCollection,
+ gupnp_media_collection,
+ G_TYPE_OBJECT);
+
+struct _GUPnPMediaCollectionPrivate {
+ GUPnPDIDLLiteWriter *writer;
+ GUPnPDIDLLiteObject *container;
+ GList *items;
+ gboolean mutable;
+ char *data;
+};
+
+enum {
+ PROP_0,
+ PROP_AUTHOR,
+ PROP_TITLE,
+ PROP_MUTABLE,
+ PROP_DATA,
+};
+
+static void
+reparent_children (GUPnPMediaCollection *collection)
+{
+ GList *it;
+ xmlNode *container_node;
+
+ container_node = gupnp_didl_lite_object_get_xml_node
+ (collection->priv->container);
+
+ /* Reverse iterate the list to get the correct order in XML */
+ it = g_list_last (collection->priv->items);
+ while (it) {
+ xmlNode *node;
+
+ node = gupnp_didl_lite_object_get_xml_node
+ (GUPNP_DIDL_LITE_OBJECT (it->data));
+ xmlUnlinkNode (node);
+ node = xmlAddChild (container_node, node);
+
+ it = it->prev;
+ }
+}
+
+static void
+on_container_available (GUPnPMediaCollection *self,
+ GUPnPDIDLLiteContainer *container,
+ gpointer user_data)
+{
+ /* According to media format spec, there's only one container allowed;
+ * We allow any number of containers, but only the last one wins. */
+ if (self->priv->container != NULL)
+ g_object_unref (self->priv->container);
+
+ self->priv->container = g_object_ref (container);
+}
+
+static void
+on_item_available (GUPnPMediaCollection *self,
+ GUPnPDIDLLiteItem *item,
+ gpointer user_data)
+{
+ self->priv->items = g_list_prepend (self->priv->items,
+ g_object_ref (item));
+}
+
+static void
+parse_data (GUPnPMediaCollection *collection, const char *data)
+{
+ GUPnPDIDLLiteParser *parser;
+ GError *error = NULL;
+ gboolean result;
+
+ parser = gupnp_didl_lite_parser_new ();
+ g_signal_connect_swapped (G_OBJECT (parser),
+ "container-available",
+ G_CALLBACK (on_container_available),
+ collection);
+ g_signal_connect_swapped (G_OBJECT (parser),
+ "item-available",
+ G_CALLBACK (on_item_available),
+ collection);
+
+ result = gupnp_didl_lite_parser_parse_didl_recursive (parser,
+ data,
+ TRUE,
+ &error);
+ if (!result) {
+ GUPnPMediaCollectionPrivate *priv = collection->priv;
+
+ g_warning ("Failed to parse DIDL-Lite: %s", error->message);
+ g_error_free (error);
+ if (priv->container) {
+ g_object_unref (priv->container);
+ priv->container = NULL;
+ }
+ if (priv->items) {
+ g_list_free_full (priv->items, g_object_unref);
+ priv->items = NULL;
+ }
+ }
+}
+
+static void
+gupnp_media_collection_init (GUPnPMediaCollection *collection)
+{
+ collection->priv = G_TYPE_INSTANCE_GET_PRIVATE
+ (collection,
+ GUPNP_TYPE_MEDIA_COLLECTION,
+ GUPnPMediaCollectionPrivate);
+ /* Initialize as mutable and decide later on in constructed() if we
+ * really are. */
+ collection->priv->mutable = TRUE;
+}
+
+static void
+gupnp_media_collection_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GUPnPMediaCollection *collection;
+
+ collection = GUPNP_MEDIA_COLLECTION (object);
+
+ switch (property_id) {
+ case PROP_AUTHOR:
+ gupnp_media_collection_set_author (collection,
+ g_value_get_string (value));
+ break;
+ case PROP_TITLE:
+ gupnp_media_collection_set_title (collection,
+ g_value_get_string (value));
+ break;
+ case PROP_DATA:
+ collection->priv->data = g_value_dup_string (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gupnp_media_collection_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GUPnPMediaCollection *collection;
+
+ collection = GUPNP_MEDIA_COLLECTION (object);
+
+ switch (property_id) {
+ case PROP_AUTHOR:
+ g_value_set_string
+ (value, gupnp_media_collection_get_author (collection));
+ break;
+ case PROP_TITLE:
+ g_value_set_string
+ (value, gupnp_media_collection_get_title (collection));
+ break;
+ case PROP_MUTABLE:
+ g_value_set_boolean
+ (value, gupnp_media_collection_get_mutable (collection));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gupnp_media_collection_constructed (GObject *object)
+{
+ GUPnPMediaCollection *collection;
+ GObjectClass *object_class;
+
+ collection = GUPNP_MEDIA_COLLECTION (object);
+
+ /* Check if we have some data. If there's data, we assume that the
+ * user meant to parse a playlist. We ignore title and author then. */
+ if (collection->priv->data != NULL) {
+ if (collection->priv->container != NULL) {
+ g_object_unref (collection->priv->container);
+ collection->priv->container = NULL;
+ }
+
+ if (collection->priv->writer != NULL) {
+ g_object_unref (collection->priv->writer);
+ collection->priv->writer = NULL;
+ }
+
+ parse_data (collection, collection->priv->data);
+ collection->priv->mutable = FALSE;
+ } else if (collection->priv->writer == NULL) {
+ collection->priv->writer =
+ gupnp_didl_lite_writer_new (NULL);
+ collection->priv->mutable = TRUE;
+ }
+
+ /* Chain up */
+ object_class = G_OBJECT_CLASS (gupnp_media_collection_parent_class);
+ if (object_class->constructed != NULL)
+ object_class->constructed (object);
+}
+
+static void
+gupnp_media_collection_dispose (GObject *object)
+{
+ GUPnPMediaCollection *collection;
+ GObjectClass *object_class;
+
+ collection = GUPNP_MEDIA_COLLECTION (object);
+
+ if (collection->priv->writer) {
+ g_object_unref (collection->priv->writer);
+ collection->priv->writer = NULL;
+ }
+
+ if (collection->priv->items) {
+ g_list_free_full (collection->priv->items, g_object_unref);
+ collection->priv->items = NULL;
+ }
+
+ if (collection->priv->container) {
+ g_object_unref (collection->priv->container);
+ collection->priv->container = NULL;
+ }
+
+ g_free (collection->priv->data);
+ collection->priv->data = NULL;
+
+ object_class = G_OBJECT_CLASS (gupnp_media_collection_parent_class);
+ object_class->dispose (object);
+}
+
+static void
+gupnp_media_collection_class_init (GUPnPMediaCollectionClass *klass)
+{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (klass);
+
+ object_class->set_property = gupnp_media_collection_set_property;
+ object_class->get_property = gupnp_media_collection_get_property;
+ object_class->constructed = gupnp_media_collection_constructed;
+ object_class->dispose = gupnp_media_collection_dispose;
+
+ g_type_class_add_private (klass, sizeof (GUPnPMediaCollectionPrivate));
+
+ /**
+ * GUPnPMediaCollection:author:
+ *
+ * The author of this media collection.
+ **/
+ g_object_class_install_property
+ (object_class,
+ PROP_AUTHOR,
+ g_param_spec_string ("author",
+ "Author",
+ "The author of this collection",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GUPnPMediaCollection:title:
+ *
+ * The title of this media collection.
+ **/
+ g_object_class_install_property
+ (object_class,
+ PROP_AUTHOR,
+ g_param_spec_string ("title",
+ "Title",
+ "The title of this collection",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GUPnPMediaCollection:mutable:
+ *
+ * Whether this media collation is modifyable or not.
+ **/
+ g_object_class_install_property
+ (object_class,
+ PROP_MUTABLE,
+ g_param_spec_boolean ("mutable",
+ "Mutable",
+ "The mutability of this collection",
+ FALSE,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GUPnPMediaCollection:data:
+ *
+ * Block of data to parse a collection from. If data is set upon
+ * construction it will override the other properties and create a
+ * unmutable collection parsed from data.
+ **/
+ g_object_class_install_property
+ (object_class,
+ PROP_DATA,
+ g_param_spec_string ("data",
+ "Data",
+ "Data to construct the playlist from",
+ NULL,
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+}
+
+/**
+ * gupnp_media_collection_new:
+ *
+ * Create a new writable media collection.
+ *
+ * Returns: (transfer full): A new #GUPnPMediaCollection.
+ **/
+GUPnPMediaCollection *
+gupnp_media_collection_new (void)
+{
+ return g_object_new (GUPNP_TYPE_MEDIA_COLLECTION, NULL);
+}
+
+/**
+ * gupnp_media_collection_new_from_string:
+ * @data: XML string.
+ *
+ * Parse a new #GUPnPMediaCollection from a block of XML data.
+ *
+ * Returns: (transfer full): A new #GUPnPMediaCollection.
+ **/
+GUPnPMediaCollection *
+gupnp_media_collection_new_from_string (const char *data)
+{
+ return g_object_new (GUPNP_TYPE_MEDIA_COLLECTION,
+ "data", data,
+ NULL);
+}
+
+/**
+ * gupnp_media_collection_set_title:
+ * @collection: #GUPnPMediaCollection
+ * @title: New Title of this collection;
+ *
+ * Set the title of a #GUPnPMediaCollection.
+ **/
+void
+gupnp_media_collection_set_title (GUPnPMediaCollection *collection,
+ const char *title)
+{
+ GUPnPDIDLLiteContainer *container;
+
+ g_return_if_fail (GUPNP_IS_MEDIA_COLLECTION (collection));
+ g_return_if_fail (collection->priv->mutable);
+
+ if (title == NULL)
+ return;
+
+ if (collection->priv->container != NULL) {
+ gupnp_didl_lite_object_set_title (collection->priv->container,
+ title);
+
+ return;
+ }
+
+ if (collection->priv->writer == NULL)
+ collection->priv->writer = gupnp_didl_lite_writer_new (NULL);
+
+ container = gupnp_didl_lite_writer_add_container
+ (collection->priv->writer);
+ collection->priv->container = GUPNP_DIDL_LITE_OBJECT (container);
+
+ reparent_children (collection);
+
+ gupnp_didl_lite_object_set_title (collection->priv->container,
+ title);
+}
+
+/**
+ * gupnp_media_collection_get_title:
+ * @collection: #GUPnPMediaCollection
+ *
+ * Returns: The title of this media collection or %NULL if not set.
+ **/
+const char *
+gupnp_media_collection_get_title (GUPnPMediaCollection *collection)
+{
+ g_return_val_if_fail (GUPNP_IS_MEDIA_COLLECTION (collection), NULL);
+
+ if (collection->priv->container == NULL)
+ return NULL;
+
+ return gupnp_didl_lite_object_get_title (collection->priv->container);
+}
+
+/**
+ * gupnp_media_collection_set_author:
+ * @collection: #GUPnPMediaCollection
+ * @author: New author of this media collection.
+ *
+ * Set the author of the media collection
+ **/
+void
+gupnp_media_collection_set_author (GUPnPMediaCollection *collection,
+ const char *author)
+{
+ GUPnPDIDLLiteContainer *container;
+
+ g_return_if_fail (GUPNP_IS_MEDIA_COLLECTION (collection));
+ g_return_if_fail (collection->priv->mutable);
+
+ if (author == NULL)
+ return;
+
+ if (collection->priv->container != NULL) {
+ gupnp_didl_lite_object_set_creator (collection->priv->container,
+ author);
+
+ return;
+ }
+
+ if (collection->priv->writer == NULL)
+ collection->priv->writer = gupnp_didl_lite_writer_new (NULL);
+
+ container = gupnp_didl_lite_writer_add_container
+ (collection->priv->writer);
+ collection->priv->container = GUPNP_DIDL_LITE_OBJECT (container);
+
+ reparent_children (collection);
+
+ gupnp_didl_lite_object_set_creator (collection->priv->container,
+ author);
+}
+
+/**
+ * gupnp_media_collection_get_author:
+ * @collection: #GUPnPMediaCollection
+ *
+ * Returns: The author of this media collection or %NULL if not set.
+ **/
+const char *
+gupnp_media_collection_get_author (GUPnPMediaCollection *collection)
+{
+ g_return_val_if_fail (GUPNP_IS_MEDIA_COLLECTION (collection), NULL);
+
+ if (collection->priv->container == NULL)
+ return NULL;
+
+ return gupnp_didl_lite_object_get_creator (collection->priv->container);
+}
+
+/**
+ * gupnp_media_collection_add_item:
+ * @collection: #GUPnPMediaCollection
+ *
+ * Return value: (transfer full): A new #GUPnPDIDLLiteItem object. Unref after
+ * use.
+ **/
+GUPnPDIDLLiteItem *
+gupnp_media_collection_add_item (GUPnPMediaCollection *collection)
+{
+ g_return_val_if_fail (collection != NULL, NULL);
+ g_return_val_if_fail (GUPNP_IS_MEDIA_COLLECTION (collection), NULL);
+ g_return_val_if_fail (collection->priv->mutable, NULL);
+
+ GUPnPDIDLLiteItem *item = NULL;
+
+ if (collection->priv->container != NULL)
+ item = gupnp_didl_lite_writer_add_container_child_item
+ (collection->priv->writer,
+ GUPNP_DIDL_LITE_CONTAINER
+ (collection->priv->container));
+ else
+ item = gupnp_didl_lite_writer_add_item
+ (collection->priv->writer);
+
+ /* Keep a reference of the object in case we need to do reparenting */
+ collection->priv->items = g_list_prepend (collection->priv->items,
+ g_object_ref (item));
+
+ /* Mandatory in DLNA for object. Not specified if mandatory for
+ * DIDL_S, but to avoid problems with clients reusing their normal
+ * DIDL-Lite parser, we set it here if the application doesn't.
+ */
+ gupnp_didl_lite_object_set_restricted (GUPNP_DIDL_LITE_OBJECT (item),
+ TRUE);
+
+ return item;
+}
+
+/**
+ * gupnp_media_collection_get_string:
+ * @collection: #GUPnPMediaCollection
+ *
+ * Return value: (transfer full): XML string representing this media
+ * collection. g_free() after use. If the colleciton is not mutable, returns a
+ * copy of the original string.
+ **/
+char *
+gupnp_media_collection_get_string (GUPnPMediaCollection *collection)
+{
+ g_return_val_if_fail (collection != NULL, NULL);
+ g_return_val_if_fail (GUPNP_IS_MEDIA_COLLECTION (collection), NULL);
+
+ if (collection->priv->data)
+ return g_strdup (collection->priv->data);
+
+ gupnp_didl_lite_writer_filter_tags (collection->priv->writer,
+ DIDL_S_FILTER);
+
+ return gupnp_didl_lite_writer_get_string (collection->priv->writer);
+}
+
+/**
+ * gupnp_media_collection_get_items:
+ * @collection: #GUPnPMediaCollection
+ *
+ * Return value: (transfer full)(element-type GUPnPDIDLLiteItem): A #GList
+ * containing the elemens of this collection, in proper order. Unref all items
+ * and free the list after use.
+ **/
+GList *
+gupnp_media_collection_get_items (GUPnPMediaCollection *collection)
+{
+ g_return_val_if_fail (collection != NULL, NULL);
+ g_return_val_if_fail (GUPNP_IS_MEDIA_COLLECTION (collection), NULL);
+
+ GList *tmp = NULL, *iter;
+
+ for (iter = collection->priv->items; iter != NULL; iter = iter->next) {
+ tmp = g_list_prepend (tmp, g_object_ref (iter->data));
+ }
+
+ return tmp;
+}
+
+/**
+ * gupnp_media_collection_get_mutable:
+ * @collection: #GUPnPMediaCollection
+ *
+ * Return value: #TRUE if the collections is modifiable, #FALSE otherwise.
+ **/
+gboolean
+gupnp_media_collection_get_mutable (GUPnPMediaCollection *collection)
+{
+ g_return_val_if_fail (collection != NULL, FALSE);
+ g_return_val_if_fail (GUPNP_IS_MEDIA_COLLECTION (collection), FALSE);
+
+ return collection->priv->mutable;
+}
diff --git a/libgupnp-av/gupnp-media-collection.h b/libgupnp-av/gupnp-media-collection.h
new file mode 100644
index 0000000..9c5a755
--- /dev/null
+++ b/libgupnp-av/gupnp-media-collection.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.
+ *
+ * Authors: Jens Georg <jensg@openismus.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_MEDIA_COLLECTION_H__
+#define __GUPNP_DIDL_LITE_MEDIA_COLLECTION_H__
+
+#include <glib-object.h>
+
+#include "gupnp-didl-lite-item.h"
+
+G_BEGIN_DECLS
+
+GType
+gupnp_media_collection_get_type (void) G_GNUC_CONST;
+
+#define GUPNP_TYPE_MEDIA_COLLECTION \
+ (gupnp_media_collection_get_type ())
+#define GUPNP_MEDIA_COLLECTION(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ GUPNP_TYPE_MEDIA_COLLECTION, \
+ GUPnPMediaCollection))
+#define GUPNP_MEDIA_COLLECTION_CLASS(obj) \
+ (G_TYPE_CHECK_CLASS_CAST ((obj), \
+ GUPNP_TYPE_MEDIA_COLLECTION, \
+ GUPnPMediaCollectionClass))
+#define GUPNP_IS_MEDIA_COLLECTION(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ GUPNP_TYPE_MEDIA_COLLECTION))
+#define GUPNP_IS_MEDIA_COLLECTION_CLASS(obj) \
+ (G_TYPE_CHECK_CLASS_TYPE ((obj), \
+ GUPNP_TYPE_MEDIA_COLLECTION))
+#define GUPNP_MEDIA_COLLECTION_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ GUPNP_TYPE_MEDIA_COLLECTION, \
+ GUPnPMediaCollectionClass))
+
+typedef struct _GUPnPMediaCollectionPrivate GUPnPMediaCollectionPrivate;
+typedef struct _GUPnPMediaCollection GUPnPMediaCollection;
+typedef struct _GUPnPMediaCollectionClass GUPnPMediaCollectionClass;
+
+struct _GUPnPMediaCollection {
+ GObject parent;
+
+ GUPnPMediaCollectionPrivate *priv;
+};
+
+struct _GUPnPMediaCollectionClass {
+ GObjectClass parent_class;
+
+ /* padding */
+ void (* _gupnp_reserved1) (void);
+ void (* _gupnp_reserved2) (void);
+ void (* _gupnp_reserved3) (void);
+ void (* _gupnp_reserved4) (void);
+};
+
+GUPnPMediaCollection *
+gupnp_media_collection_new (void);
+
+GUPnPMediaCollection *
+gupnp_media_collection_new_from_string (const char *data);
+
+void
+gupnp_media_collection_set_title (GUPnPMediaCollection *collection,
+ const char *title);
+
+const char *
+gupnp_media_collection_get_title (GUPnPMediaCollection *collection);
+
+void
+gupnp_media_collection_set_author (GUPnPMediaCollection *collection,
+ const char *author);
+
+const char *
+gupnp_media_collection_get_author (GUPnPMediaCollection *collection);
+
+GUPnPDIDLLiteItem *
+gupnp_media_collection_add_item (GUPnPMediaCollection *collection);
+
+char *
+gupnp_media_collection_get_string (GUPnPMediaCollection *collection);
+
+GList *
+gupnp_media_collection_get_items (GUPnPMediaCollection *collection);
+
+gboolean
+gupnp_media_collection_get_mutable (GUPnPMediaCollection *collection);
+
+G_END_DECLS
+
+#endif /* __GUPNP_DIDL_LITE_MEDIA_COLLECTION_H__ */
diff --git a/libgupnp-av/gupnp-search-criteria-parser.h b/libgupnp-av/gupnp-search-criteria-parser.h
index ec9fa32..832a17a 100644
--- a/libgupnp-av/gupnp-search-criteria-parser.h
+++ b/libgupnp-av/gupnp-search-criteria-parser.h
@@ -93,6 +93,11 @@ gupnp_search_criteria_op_get_type (void) G_GNUC_CONST;
GQuark
gupnp_search_criteria_parser_error_quark (void);
+/**
+ * GUPnPSearchCriteriaParserError:
+ * @GUPNP_SEARCH_CRITERIA_PARSER_ERROR_FAILED: Parsing the search criteria
+ * failed.
+ **/
typedef enum {
GUPNP_SEARCH_CRITERIA_PARSER_ERROR_FAILED
} GUPnPSearchCriteriaParserError;
diff --git a/libgupnp-av/time-utils.c b/libgupnp-av/time-utils.c
new file mode 100644
index 0000000..0964f9e
--- /dev/null
+++ b/libgupnp-av/time-utils.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.
+ *
+ * Authors: Jens Georg <jensg@openismus.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 <glib.h>
+
+#include "time-utils.h"
+
+#define SEC_PER_MIN 60
+#define SEC_PER_HOUR 3600
+
+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;
+}
+
+char *
+seconds_to_time (long seconds)
+{
+ char *str;
+
+ if (seconds < 0)
+ return NULL;
+
+ str = g_strdup_printf ("%ld:%.2ld:%.2ld.000",
+ seconds / (60 * 60),
+ (seconds / 60) % 60,
+ seconds % 60);
+
+ return str;
+}
diff --git a/libgupnp-av/time-utils.h b/libgupnp-av/time-utils.h
new file mode 100644
index 0000000..d15c598
--- /dev/null
+++ b/libgupnp-av/time-utils.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.
+ *
+ * Authors: Jens Georg <jensg@openismus.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 __TIME_UTILS_H__
+#define __TIME_UTILS_H__
+
+G_BEGIN_DECLS
+
+G_GNUC_INTERNAL long
+seconds_from_time (const char *time_string);
+
+G_GNUC_INTERNAL char *
+seconds_to_time (long seconds);
+
+G_END_DECLS
+
+#endif /* __TIME_UTILS_H__ */
diff --git a/packaging/GUPnP-AV.spec b/packaging/GUPnP-AV.spec
index a4d2d3f..9e490ca 100644
--- a/packaging/GUPnP-AV.spec
+++ b/packaging/GUPnP-AV.spec
@@ -7,7 +7,7 @@
Name: gupnp-av
Summary: GUPnP-AV is a collection of helpers for building UPnP AV applications
-Version: 0.11.2
+Version: 0.11.7
Release: 0
Group: System/Libraries
License: LGPLv2+
diff --git a/tests/check-feature-list-parser.c b/tests/check-feature-list-parser.c
index 492d9ed..990920d 100644
--- a/tests/check-feature-list-parser.c
+++ b/tests/check-feature-list-parser.c
@@ -83,7 +83,9 @@ main (int argc, char **argv)
GList *item;
gboolean success = TRUE;
+#if !GLIB_CHECK_VERSION (2, 35, 0)
g_type_init ();
+#endif
parser = gupnp_feature_list_parser_new ();
diff --git a/tests/check-search.c b/tests/check-search.c
index 9f4bb4b..7916912 100644
--- a/tests/check-search.c
+++ b/tests/check-search.c
@@ -36,7 +36,9 @@ main (int argc, char **argv)
GError *error;
int i;
+#if !GLIB_CHECK_VERSION (2, 35, 0)
g_type_init ();
+#endif
parser = gupnp_search_criteria_parser_new ();
diff --git a/tests/fragments.c b/tests/fragments.c
index 0ecb47b..44fb617 100644
--- a/tests/fragments.c
+++ b/tests/fragments.c
@@ -131,7 +131,9 @@ int main (void)
GList* artists;
GUPnPDIDLLiteContributor *artist;
+#if !GLIB_CHECK_VERSION (2, 35, 0)
g_type_init ();
+#endif
g_setenv ("GUPNP_AV_DATADIR", ABS_TOP_SRCDIR G_DIR_SEPARATOR_S "data", FALSE);
writer = gupnp_didl_lite_writer_new (NULL);
diff --git a/tests/gtest/Makefile.am b/tests/gtest/Makefile.am
index b28b6c6..9beeafa 100644
--- a/tests/gtest/Makefile.am
+++ b/tests/gtest/Makefile.am
@@ -1,12 +1,26 @@
TESTS_ENVIRONMENT = G_SLICE=debug-blocks \
- LD_LIBRARY_PATH=$(top_builddir)/libgssdp/.libs
+ LD_LIBRARY_PATH=$(top_builddir)/libgupnp-av/.libs:$(LD_LIBRARY_PATH) \
+ GUPNP_AV_DATADIR=$(top_srcdir)/data
TESTS=$(check_PROGRAMS)
-check_PROGRAMS = test-regression
+check_PROGRAMS = \
+ test-regression \
+ test-media-collection \
+ test-last-change-parser \
+ test-cds-last-change-parser
test_regression_SOURCES = test-regression.c
+test_media_collection_SOURCES = \
+ test-media-collection.c
+
+test_last_change_parser_SOURCES = \
+ test-last-change-parser.c
+
+test_cds_last_change_parser_SOURCES = \
+ test-cds-last-change-parser.c
+
LDADD = \
$(top_builddir)/libgupnp-av/libgupnp-av-1.0.la \
$(LIBGUPNP_LIBS)
@@ -16,3 +30,11 @@ AM_CFLAGS = \
-I $(top_srcdir) \
-DDATA_PATH="\"$(srcdir)\""
+EXTRA_DIST = data/cds-last-change/00-cds-last-change.xml \
+ data/cds-last-change/01-cds-last-change.xml \
+ data/cds-last-change/02-cds-last-change.xml \
+ data/cds-last-change/03-cds-last-change.xml \
+ data/cds-last-change/04-cds-last-change.xml \
+ data/cds-last-change/05-cds-last-change.xml \
+ data/cds-last-change/06-cds-last-change.xml \
+ data/cds-last-change/07-cds-last-change.xml
diff --git a/tests/gtest/Makefile.in b/tests/gtest/Makefile.in
index bb54c2c..48ac8b7 100644
--- a/tests/gtest/Makefile.in
+++ b/tests/gtest/Makefile.in
@@ -50,7 +50,10 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-check_PROGRAMS = test-regression$(EXEEXT)
+check_PROGRAMS = test-regression$(EXEEXT) \
+ test-media-collection$(EXEEXT) \
+ test-last-change-parser$(EXEEXT) \
+ test-cds-last-change-parser$(EXEEXT)
subdir = tests/gtest
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -65,16 +68,38 @@ mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
-am_test_regression_OBJECTS = test-regression.$(OBJEXT)
-test_regression_OBJECTS = $(am_test_regression_OBJECTS)
-test_regression_LDADD = $(LDADD)
+am_test_cds_last_change_parser_OBJECTS = \
+ test-cds-last-change-parser.$(OBJEXT)
+test_cds_last_change_parser_OBJECTS = \
+ $(am_test_cds_last_change_parser_OBJECTS)
+test_cds_last_change_parser_LDADD = $(LDADD)
am__DEPENDENCIES_1 =
-test_regression_DEPENDENCIES = \
+test_cds_last_change_parser_DEPENDENCIES = \
$(top_builddir)/libgupnp-av/libgupnp-av-1.0.la \
$(am__DEPENDENCIES_1)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
+am_test_last_change_parser_OBJECTS = \
+ test-last-change-parser.$(OBJEXT)
+test_last_change_parser_OBJECTS = \
+ $(am_test_last_change_parser_OBJECTS)
+test_last_change_parser_LDADD = $(LDADD)
+test_last_change_parser_DEPENDENCIES = \
+ $(top_builddir)/libgupnp-av/libgupnp-av-1.0.la \
+ $(am__DEPENDENCIES_1)
+am_test_media_collection_OBJECTS = test-media-collection.$(OBJEXT)
+test_media_collection_OBJECTS = $(am_test_media_collection_OBJECTS)
+test_media_collection_LDADD = $(LDADD)
+test_media_collection_DEPENDENCIES = \
+ $(top_builddir)/libgupnp-av/libgupnp-av-1.0.la \
+ $(am__DEPENDENCIES_1)
+am_test_regression_OBJECTS = test-regression.$(OBJEXT)
+test_regression_OBJECTS = $(am_test_regression_OBJECTS)
+test_regression_LDADD = $(LDADD)
+test_regression_DEPENDENCIES = \
+ $(top_builddir)/libgupnp-av/libgupnp-av-1.0.la \
+ $(am__DEPENDENCIES_1)
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
am__depfiles_maybe = depfiles
@@ -101,8 +126,12 @@ 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 = $(test_regression_SOURCES)
-DIST_SOURCES = $(test_regression_SOURCES)
+SOURCES = $(test_cds_last_change_parser_SOURCES) \
+ $(test_last_change_parser_SOURCES) \
+ $(test_media_collection_SOURCES) $(test_regression_SOURCES)
+DIST_SOURCES = $(test_cds_last_change_parser_SOURCES) \
+ $(test_last_change_parser_SOURCES) \
+ $(test_media_collection_SOURCES) $(test_regression_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
@@ -250,10 +279,20 @@ top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
TESTS_ENVIRONMENT = G_SLICE=debug-blocks \
- LD_LIBRARY_PATH=$(top_builddir)/libgssdp/.libs
+ LD_LIBRARY_PATH=$(top_builddir)/libgupnp-av/.libs:$(LD_LIBRARY_PATH) \
+ GUPNP_AV_DATADIR=$(top_srcdir)/data
TESTS = $(check_PROGRAMS)
test_regression_SOURCES = test-regression.c
+test_media_collection_SOURCES = \
+ test-media-collection.c
+
+test_last_change_parser_SOURCES = \
+ test-last-change-parser.c
+
+test_cds_last_change_parser_SOURCES = \
+ test-cds-last-change-parser.c
+
LDADD = \
$(top_builddir)/libgupnp-av/libgupnp-av-1.0.la \
$(LIBGUPNP_LIBS)
@@ -263,6 +302,15 @@ AM_CFLAGS = \
-I $(top_srcdir) \
-DDATA_PATH="\"$(srcdir)\""
+EXTRA_DIST = data/cds-last-change/00-cds-last-change.xml \
+ data/cds-last-change/01-cds-last-change.xml \
+ data/cds-last-change/02-cds-last-change.xml \
+ data/cds-last-change/03-cds-last-change.xml \
+ data/cds-last-change/04-cds-last-change.xml \
+ data/cds-last-change/05-cds-last-change.xml \
+ data/cds-last-change/06-cds-last-change.xml \
+ data/cds-last-change/07-cds-last-change.xml
+
all: all-am
.SUFFIXES:
@@ -306,6 +354,15 @@ clean-checkPROGRAMS:
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
echo " rm -f" $$list; \
rm -f $$list
+test-cds-last-change-parser$(EXEEXT): $(test_cds_last_change_parser_OBJECTS) $(test_cds_last_change_parser_DEPENDENCIES) $(EXTRA_test_cds_last_change_parser_DEPENDENCIES)
+ @rm -f test-cds-last-change-parser$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_cds_last_change_parser_OBJECTS) $(test_cds_last_change_parser_LDADD) $(LIBS)
+test-last-change-parser$(EXEEXT): $(test_last_change_parser_OBJECTS) $(test_last_change_parser_DEPENDENCIES) $(EXTRA_test_last_change_parser_DEPENDENCIES)
+ @rm -f test-last-change-parser$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_last_change_parser_OBJECTS) $(test_last_change_parser_LDADD) $(LIBS)
+test-media-collection$(EXEEXT): $(test_media_collection_OBJECTS) $(test_media_collection_DEPENDENCIES) $(EXTRA_test_media_collection_DEPENDENCIES)
+ @rm -f test-media-collection$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_media_collection_OBJECTS) $(test_media_collection_LDADD) $(LIBS)
test-regression$(EXEEXT): $(test_regression_OBJECTS) $(test_regression_DEPENDENCIES) $(EXTRA_test_regression_DEPENDENCIES)
@rm -f test-regression$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(test_regression_OBJECTS) $(test_regression_LDADD) $(LIBS)
@@ -316,6 +373,9 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-cds-last-change-parser.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-last-change-parser.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-media-collection.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-regression.Po@am__quote@
.c.o:
diff --git a/tests/gtest/data/cds-last-change/00-cds-last-change.xml b/tests/gtest/data/cds-last-change/00-cds-last-change.xml
new file mode 100644
index 0000000..12f72a7
--- /dev/null
+++ b/tests/gtest/data/cds-last-change/00-cds-last-change.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<StateEvent
+xmlns="urn:schemas-upnp-org:av:cds-event"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="urn:schemas-upnp-org:av:cds-event
+http://www.upnp.org/schemas/av/cds-event.xsd">
+</StateEvent>
+
diff --git a/tests/gtest/data/cds-last-change/01-cds-last-change.xml b/tests/gtest/data/cds-last-change/01-cds-last-change.xml
new file mode 100644
index 0000000..c29aae6
--- /dev/null
+++ b/tests/gtest/data/cds-last-change/01-cds-last-change.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<StateEvent
+xmlns="urn:schemas-upnp-org:av:cds-event"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="urn:schemas-upnp-org:av:cds-event
+http://www.upnp.org/schemas/av/cds-event.xsd">
+<objAdd objID="s002" updateID="213" objParentID="s001"
+objClass="object.container.album" stUpdate="1"/>
+<objMod objID="s001" updateID="214" stUpdate="1"/>
+<objAdd objID="s003" updateID="215" objParentID="s001"
+objClass="object.item.audioItem" stUpdate="0"/>
+<objAdd objID="s004" updateID="216" objParentID="s002"
+objClass="object.item.audioItem" stUpdate="1"/>
+<objDel objID="s003" updateID="217" stUpdate="0"/>
+<objMod objID="s001" updateID="218" stUpdate="0"/>
+<objMod objID="s004" updateID="219" stUpdate="1"/>
+<stDone objID="s001" updateID="219"/>
+</StateEvent>
+
diff --git a/tests/gtest/data/cds-last-change/02-cds-last-change.xml b/tests/gtest/data/cds-last-change/02-cds-last-change.xml
new file mode 100644
index 0000000..1ed696f
--- /dev/null
+++ b/tests/gtest/data/cds-last-change/02-cds-last-change.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<StateEvent
+xmlns="urn:schemas-upnp-org:av:cds-event"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="urn:schemas-upnp-org:av:cds-event
+http://www.upnp.org/schemas/av/cds-event.xsd">
+<objAdd objID="Album001" updateID="101" objParentID="0"
+objClass="object.container.album.musicAlbum" stUpdate="0"/>
+<objMod objID="0" updateID="102" stUpdate="0"/>
+</StateEvent>
+
diff --git a/tests/gtest/data/cds-last-change/03-cds-last-change.xml b/tests/gtest/data/cds-last-change/03-cds-last-change.xml
new file mode 100644
index 0000000..83b2749
--- /dev/null
+++ b/tests/gtest/data/cds-last-change/03-cds-last-change.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<StateEvent
+xmlns="urn:schemas-upnp-org:av:cds-event"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="urn:schemas-upnp-org:av:cds-event
+http://www.upnp.org/schemas/av/cds-event.xsd">
+<objAdd objID="Album001" updateID="101" objParentID="0"
+objClass="object.container.album.musicAlbum" stUpdate="0"/>
+<objMod objID="0" updateID="102" stUpdate="0"/>
+<objAdd objID="Song001" updateID="103" objParentID="Album001"
+objClass="object.item.audioItem" stUpdate="0"/>
+<objMod objID="Album001" updateID="104" stUpdate="0"/>
+</StateEvent>
+
diff --git a/tests/gtest/data/cds-last-change/04-cds-last-change.xml b/tests/gtest/data/cds-last-change/04-cds-last-change.xml
new file mode 100644
index 0000000..3005ca9
--- /dev/null
+++ b/tests/gtest/data/cds-last-change/04-cds-last-change.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<StateEvent
+xmlns="urn:schemas-upnp-org:av:cds-event"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="urn:schemas-upnp-org:av:cds-event
+http://www.upnp.org/schemas/av/cds-event.xsd">
+<objAdd objID="Album001" updateID="101" objParentID="0"
+objClass="object.container.album.musicAlbum" stUpdate="0"/>
+<objMod objID="0" updateID="102" stUpdate="0"/>
+<objAdd objID="Song001" updateID="103" objParentID="Album001"
+objClass="object.item.audioItem" stUpdate="0"/>
+<objMod objID="Album001" updateID="104" stUpdate="0"/>
+<objAdd objID="Song002" updateID="105" objParentID="Album001"
+objClass="object.item.audioItem" stUpdate="0"/>
+<objMod objID="Album001" updateID="106" stUpdate="0"/>
+<objDel objID="Song001" updateID="107" stUpdate="0"/>
+<objMod objID="Album001" updateID="108" stUpdate="0"/>
+</StateEvent>
+
diff --git a/tests/gtest/data/cds-last-change/05-cds-last-change.xml b/tests/gtest/data/cds-last-change/05-cds-last-change.xml
new file mode 100644
index 0000000..3005ca9
--- /dev/null
+++ b/tests/gtest/data/cds-last-change/05-cds-last-change.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<StateEvent
+xmlns="urn:schemas-upnp-org:av:cds-event"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="urn:schemas-upnp-org:av:cds-event
+http://www.upnp.org/schemas/av/cds-event.xsd">
+<objAdd objID="Album001" updateID="101" objParentID="0"
+objClass="object.container.album.musicAlbum" stUpdate="0"/>
+<objMod objID="0" updateID="102" stUpdate="0"/>
+<objAdd objID="Song001" updateID="103" objParentID="Album001"
+objClass="object.item.audioItem" stUpdate="0"/>
+<objMod objID="Album001" updateID="104" stUpdate="0"/>
+<objAdd objID="Song002" updateID="105" objParentID="Album001"
+objClass="object.item.audioItem" stUpdate="0"/>
+<objMod objID="Album001" updateID="106" stUpdate="0"/>
+<objDel objID="Song001" updateID="107" stUpdate="0"/>
+<objMod objID="Album001" updateID="108" stUpdate="0"/>
+</StateEvent>
+
diff --git a/tests/gtest/data/cds-last-change/06-cds-last-change.xml b/tests/gtest/data/cds-last-change/06-cds-last-change.xml
new file mode 100644
index 0000000..9765122
--- /dev/null
+++ b/tests/gtest/data/cds-last-change/06-cds-last-change.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<StateEvent
+xmlns="urn:schemas-upnp-org:av:cds-event"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="urn:schemas-upnp-org:av:cds-event
+http://www.upnp.org/schemas/av/cds-event.xsd">
+<objAdd objID="Song003" updateID="109" objParentID="Album001"
+objClass="object.item.audioItem" stUpdate="0"/>
+<objMod objID="Album001" updateID="110" stUpdate="0"/>
+</StateEvent>
+
diff --git a/tests/gtest/data/cds-last-change/07-cds-last-change.xml b/tests/gtest/data/cds-last-change/07-cds-last-change.xml
new file mode 100644
index 0000000..791d5fe
--- /dev/null
+++ b/tests/gtest/data/cds-last-change/07-cds-last-change.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<StateEvent
+xmlns="urn:schemas-upnp-org:av:cds-event"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="urn:schemas-upnp-org:av:cds-event
+http://www.upnp.org/schemas/av/cds-event.xsd">
+<objAdd objID="Song003" updateID="234" objParentID="Album001"
+objClass="object.item.audioItem" stUpdate="1"/>
+<objMod objID="Album001" updateID="235" stUpdate="1"/>
+<objMod objID="Song001" updateID="236" stUpdate="1"/>
+<objDel objID="Song002" updateID="237" stUpdate="1"/>
+<objMod objID="Album001" updateID="238" stUpdate="1"/>
+<stDone objID="Album001" updateID="238"/>
+</StateEvent>
+
diff --git a/tests/gtest/test-cds-last-change-parser.c b/tests/gtest/test-cds-last-change-parser.c
new file mode 100644
index 0000000..7ddf6cb
--- /dev/null
+++ b/tests/gtest/test-cds-last-change-parser.c
@@ -0,0 +1,496 @@
+/*
+ * Copyright (C) 2012 Intel Corporation
+ *
+ * Author: Jens Georg <jensg@openismus.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 <stdio.h>
+
+#include <libgupnp-av/gupnp-cds-last-change-parser.h>
+
+typedef struct {
+ GUPnPCDSLastChangeEvent event;
+ const char *object_id;
+ const char *parent_id;
+ const char *class;
+ guint32 update_id;
+ gboolean is_st_update;
+} TestReferenceEntry;
+
+typedef struct {
+ const char *file_name;
+ guint entry_count;
+ TestReferenceEntry data[100];
+} TestReference;
+
+TestReference test_reference_data[] = {
+ {
+ "00-cds-last-change.xml",
+ 0,
+ {}
+ },
+ {
+ "01-cds-last-change.xml",
+ 8,
+ {
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED,
+ "s002",
+ "s001",
+ "object.container.album",
+ 213,
+ TRUE,
+ },
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
+ "s001",
+ NULL,
+ NULL,
+ 214,
+ TRUE,
+ },
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED,
+ "s003",
+ "s001",
+ "object.item.audioItem",
+ 215,
+ FALSE,
+ },
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED,
+ "s004",
+ "s002",
+ "object.item.audioItem",
+ 216,
+ TRUE,
+ },
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_REMOVED,
+ "s003",
+ NULL,
+ NULL,
+ 217,
+ FALSE,
+ },
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
+ "s001",
+ NULL,
+ NULL,
+ 218,
+ FALSE,
+ },
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
+ "s004",
+ NULL,
+ NULL,
+ 219,
+ TRUE,
+ },
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_ST_DONE,
+ "s001",
+ NULL,
+ NULL,
+ 219,
+ FALSE
+ }
+ }
+ },
+ {
+ "02-cds-last-change.xml",
+ 2,
+ {
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED,
+ "Album001",
+ "0",
+ "object.container.album.musicAlbum",
+ 101,
+ FALSE,
+ },
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
+ "0",
+ NULL,
+ NULL,
+ 102,
+ FALSE
+ }
+ }
+ },
+ {
+ "03-cds-last-change.xml",
+ 4,
+ {
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED,
+ "Album001",
+ "0",
+ "object.container.album.musicAlbum",
+ 101,
+ FALSE
+ },
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
+ "0",
+ NULL,
+ NULL,
+ 102,
+ FALSE
+ },
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED,
+ "Song001",
+ "Album001",
+ "object.item.audioItem",
+ 103,
+ FALSE
+ },
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
+ "Album001",
+ NULL,
+ NULL,
+ 104,
+ FALSE
+ }
+ }
+ },
+ {
+ "04-cds-last-change.xml",
+ 8,
+ {
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED,
+ "Album001",
+ "0",
+ "object.container.album.musicAlbum",
+ 101,
+ FALSE,
+ },
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
+ "0",
+ NULL,
+ NULL,
+ 102,
+ FALSE,
+ },
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED,
+ "Song001",
+ "Album001",
+ "object.item.audioItem",
+ 103,
+ FALSE,
+ },
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
+ "Album001",
+ NULL,
+ NULL,
+ 104,
+ FALSE,
+ },
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED,
+ "Song002",
+ "Album001",
+ "object.item.audioItem",
+ 105,
+ FALSE,
+ },
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
+ "Album001",
+ NULL,
+ NULL,
+ 106,
+ FALSE,
+ },
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_REMOVED,
+ "Song001",
+ NULL,
+ NULL,
+ 107,
+ FALSE
+ },
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
+ "Album001",
+ NULL,
+ NULL,
+ 108,
+ FALSE
+ }
+ }
+ },
+ {
+ "05-cds-last-change.xml",
+ 8,
+ {
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED,
+ "Album001",
+ "0",
+ "object.container.album.musicAlbum",
+ 101,
+ FALSE
+ },
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
+ "0",
+ NULL,
+ NULL,
+ 102,
+ FALSE
+ },
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED,
+ "Song001",
+ "Album001",
+ "object.item.audioItem",
+ 103,
+ FALSE
+ },
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
+ "Album001",
+ NULL,
+ NULL,
+ 104,
+ FALSE
+ },
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED,
+ "Song002",
+ "Album001",
+ "object.item.audioItem",
+ 105,
+ FALSE
+ },
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
+ "Album001",
+ NULL,
+ NULL,
+ 106,
+ FALSE
+ },
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_REMOVED,
+ "Song001",
+ NULL,
+ NULL,
+ 107,
+ FALSE
+ },
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
+ "Album001",
+ NULL,
+ NULL,
+ 108,
+ FALSE
+ }
+ }
+ },
+ {
+ "06-cds-last-change.xml",
+ 2,
+ {
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED,
+ "Song003",
+ "Album001",
+ "object.item.audioItem",
+ 109,
+ FALSE
+ },
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
+ "Album001",
+ NULL,
+ NULL,
+ 110,
+ FALSE
+ }
+ }
+ },
+ {
+ "07-cds-last-change.xml",
+ 6,
+ {
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_ADDED,
+ "Song003",
+ "Album001",
+ "object.item.audioItem",
+ 234,
+ TRUE
+ },
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
+ "Album001",
+ NULL,
+ NULL,
+ 235,
+ TRUE
+ },
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
+ "Song001",
+ NULL,
+ NULL,
+ 236,
+ TRUE,
+ },
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_REMOVED,
+ "Song002",
+ NULL,
+ NULL,
+ 237,
+ TRUE,
+ },
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED,
+ "Album001",
+ NULL,
+ NULL,
+ 238,
+ TRUE,
+ },
+ {
+ GUPNP_CDS_LAST_CHANGE_EVENT_ST_DONE,
+ "Album001",
+ NULL,
+ NULL,
+ 238,
+ FALSE,
+ }
+ }
+ }
+};
+
+static void
+compare_entries (const char *file, GList *entries)
+{
+ int reference_size, i, j;
+ GList *it = entries;
+
+ reference_size = G_N_ELEMENTS (test_reference_data);
+
+ /* Find reference entries */
+ for (i = 0; i < reference_size; i++) {
+ if (strcmp (test_reference_data[i].file_name, file) != 0)
+ continue;
+ g_assert_cmpint (g_list_length (entries),
+ ==,
+ test_reference_data[i].entry_count);
+ for (j = 0;
+ j < test_reference_data[i].entry_count;
+ j++, it = it->next) {
+ TestReferenceEntry* entry;
+ entry = &test_reference_data[i].data[j];
+ g_assert_cmpstr (entry->class, ==,
+ gupnp_cds_last_change_entry_get_class (it->data));
+ g_assert_cmpstr (entry->parent_id, ==,
+ gupnp_cds_last_change_entry_get_parent_id (it->data));
+ g_assert_cmpuint (entry->update_id, ==,
+ gupnp_cds_last_change_entry_get_update_id (it->data));
+ g_assert_cmpstr (entry->object_id, ==,
+ gupnp_cds_last_change_entry_get_object_id (it->data));
+ g_assert_cmpint (entry->event, ==,
+ gupnp_cds_last_change_entry_get_event (it->data));
+ g_assert_cmpint (entry->is_st_update, ==,
+ gupnp_cds_last_change_entry_is_subtree_update (it->data));
+ }
+
+ return;
+ }
+
+ g_message ("No reference entry found for file %s", file);
+ g_assert_not_reached ();
+}
+
+static void
+test_parse_spec_samples (void)
+{
+ GDir *dir;
+ GError *error = NULL;
+ const char *file;
+ char *data_path;
+ GUPnPCDSLastChangeParser *parser;
+
+ parser = gupnp_cds_last_change_parser_new ();
+ data_path = g_build_filename (DATA_PATH,
+ "data",
+ "cds-last-change",
+ NULL);
+
+ dir = g_dir_open (data_path, 0, &error);
+ g_assert_no_error (error);
+ while ((file = g_dir_read_name (dir)) != NULL) {
+ char *contents;
+ gsize length;
+ char *file_path;
+ GList *entries;
+
+ if (g_str_has_prefix (file, ".") ||
+ g_str_has_suffix (file, "~"))
+ continue;
+
+ file_path = g_build_filename (data_path, file, NULL);
+
+ g_file_get_contents (file_path, &contents, &length, &error);
+ g_assert_no_error (error);
+ g_free (file_path);
+
+ entries = gupnp_cds_last_change_parser_parse (parser,
+ contents,
+ &error);
+ g_assert_no_error (error);
+ compare_entries (file, entries);
+ g_list_free_full (entries,
+ (GDestroyNotify) gupnp_cds_last_change_entry_unref);
+ g_free (contents);
+ }
+
+ g_object_unref (parser);
+ g_dir_close (dir);
+ g_free (data_path);
+}
+
+int
+main (int argc, char *argv[])
+{
+#if !GLIB_CHECK_VERSION (2, 35, 0)
+ g_type_init ();
+#endif
+ g_test_init (&argc, &argv, NULL);
+
+ g_test_add_func ("/cds-last-change/parse-spec-samples",
+ test_parse_spec_samples);
+
+ return g_test_run ();
+}
diff --git a/tests/gtest/test-last-change-parser.c b/tests/gtest/test-last-change-parser.c
new file mode 100644
index 0000000..58fb717
--- /dev/null
+++ b/tests/gtest/test-last-change-parser.c
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2012 Intel Corporation
+ *
+ * Author: Krzesimir Nowak <krnowak@openismus.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 <libgupnp-av/gupnp-last-change-parser.h>
+
+#define TEST_GENERAL \
+"<?xml version=\"1.0\" encoding=\"UTF-8\"?> " \
+"<Event " \
+"xmlns=\"urn:schemas-upnp-org:metadata-1-0/RCS/\" " \
+"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " \
+"xsi:schemaLocation=\" " \
+"urn:schemas-upnp-org:metadata-1-0/RCS/ " \
+"http://www.upnp.org/schemas/av/rcs-event-v1-20060531.xsd\"> " \
+"<InstanceID val=\"0\"> " \
+"<Foo val=\"-13\"/> " \
+"<Bar val=\"ajwaj\"/> " \
+"</InstanceID> " \
+"<InstanceID val=\"1\"> " \
+"<Baz val=\"true\"/> " \
+"<Qux val=\"42\"/> " \
+"</InstanceID> " \
+"</Event>"
+
+#define BOGUS_TEXT "This is not an XML document!"
+
+#define TEST_TWO_MUTES \
+"<?xml version=\"1.0\" encoding=\"UTF-8\"?> " \
+"<Event " \
+"xmlns=\"urn:schemas-upnp-org:metadata-1-0/RCS/\" " \
+"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " \
+"xsi:schemaLocation=\" " \
+"urn:schemas-upnp-org:metadata-1-0/RCS/ " \
+"http://www.upnp.org/schemas/av/rcs-event-v1-20060531.xsd\"> " \
+"<InstanceID val=\"0\"> " \
+"<Mute channel=\"Master\" val=\"0\"/> " \
+"<Mute channel=\"CF\" val=\"1\"/> " \
+"</InstanceID> " \
+"</Event>"
+
+static void
+general (void)
+{
+ GUPnPLastChangeParser *parser = gupnp_last_change_parser_new ();
+ GError *error1 = NULL;
+ GError *error2 = NULL;
+ gboolean r1;
+ gboolean r2;
+ gint foo = -1;
+ gchar *bar = NULL;
+ gboolean baz = FALSE;
+ guint qux = G_MAXUINT;;
+
+ r1 = gupnp_last_change_parser_parse_last_change (parser,
+ 0,
+ TEST_GENERAL,
+ &error1,
+ "Foo",
+ G_TYPE_INT,
+ &foo,
+ "Bar",
+ G_TYPE_STRING,
+ &bar,
+ NULL);
+ r2 = gupnp_last_change_parser_parse_last_change (parser,
+ 1,
+ TEST_GENERAL,
+ &error2,
+ "Baz",
+ G_TYPE_BOOLEAN,
+ &baz,
+ "Qux",
+ G_TYPE_UINT,
+ &qux,
+ NULL);
+
+ g_object_unref (parser);
+
+ g_assert (r1 == TRUE);
+ g_assert_no_error (error1);
+ g_assert_cmpint (foo, ==, -13);
+ g_assert_cmpstr (bar, ==, "ajwaj");
+
+ g_free (bar);
+
+ g_assert (r2 == TRUE);
+ g_assert_no_error (error2);
+ g_assert (baz == TRUE);
+ g_assert_cmpuint (qux, ==, 42);
+}
+
+static void
+bogus_text (void)
+{
+ GUPnPLastChangeParser *parser = gupnp_last_change_parser_new ();
+ GError *error = NULL;
+ gboolean r;
+ int whatever = -1;
+
+ r = gupnp_last_change_parser_parse_last_change (parser,
+ 0,
+ BOGUS_TEXT,
+ &error,
+ "whatever",
+ G_TYPE_INT,
+ &whatever,
+ NULL);
+
+ g_object_unref (parser);
+
+ g_assert (r == FALSE);
+ g_assert_error (error, GUPNP_XML_ERROR, GUPNP_XML_ERROR_PARSE);
+ g_assert_cmpint (whatever, ==, -1);
+}
+
+static void
+nonexistent_instance (void)
+{
+ GUPnPLastChangeParser *parser = gupnp_last_change_parser_new ();
+ GError *error = NULL;
+ gboolean r;
+ gint foo = -1;
+ gchar *bar = NULL;
+ gboolean baz = FALSE;
+ guint qux = G_MAXUINT;;
+
+ r = gupnp_last_change_parser_parse_last_change (parser,
+ 42,
+ TEST_GENERAL,
+ &error,
+ "Foo",
+ G_TYPE_INT,
+ &foo,
+ "Bar",
+ G_TYPE_STRING,
+ &bar,
+ "Baz",
+ G_TYPE_BOOLEAN,
+ &baz,
+ "Qux",
+ G_TYPE_UINT,
+ &qux,
+ NULL);
+
+ g_object_unref (parser);
+
+ g_assert (r == FALSE);
+ g_assert_no_error (error);
+ g_assert_cmpint (foo, ==, -1);
+ g_assert_cmpstr (bar, ==, NULL);
+ g_assert (baz == FALSE);
+ g_assert_cmpuint (qux, ==, G_MAXUINT);
+}
+
+/* FIXME: We really have no way to test whether some variable does not
+ exist. In the test below I set baz to FALSE and qux to G_MAXUINT
+ and check whether those variables have still the same values after
+ parsing. It may happen that those variable existed in LastChange
+ document and had exactly those values. */
+static void
+nonexistent_variable (void)
+{
+ GUPnPLastChangeParser *parser = gupnp_last_change_parser_new ();
+ GError *error = NULL;
+ gboolean r;
+ gboolean baz = FALSE;
+ guint qux = G_MAXUINT;;
+
+ r = gupnp_last_change_parser_parse_last_change (parser,
+ 0,
+ TEST_GENERAL,
+ &error,
+ "Baz",
+ G_TYPE_BOOLEAN,
+ &baz,
+ "Qux",
+ G_TYPE_UINT,
+ &qux,
+ NULL);
+
+ g_object_unref (parser);
+
+ g_assert (r == TRUE);
+ g_assert_no_error (error);
+ g_assert (baz == FALSE);
+ g_assert_cmpuint (qux, ==, G_MAXUINT);
+}
+
+/* FIXME: There is no possibility for fine-grained selection of
+ variables we want to extract. There can be two "Mute" variables on
+ different "channel"s, but currently the code can only take the
+ first "Mute" variable ignoring "channel" attribute. */
+static void
+two_mutes (void)
+{
+ GUPnPLastChangeParser *parser = gupnp_last_change_parser_new ();
+ GError *error = NULL;
+ gint master_mute = -1;
+ gint cf_mute = -1;
+ gboolean r;
+
+ r = gupnp_last_change_parser_parse_last_change (parser,
+ 0,
+ TEST_TWO_MUTES,
+ &error,
+ "Mute",
+ G_TYPE_INT,
+ &master_mute,
+ "Mute",
+ G_TYPE_INT,
+ &cf_mute,
+ NULL);
+
+ g_object_unref (parser);
+
+ g_assert (r == TRUE);
+ g_assert_no_error (error);
+ g_assert_cmpint (master_mute, ==, 0);
+ g_message ("Omitting the check of \"Mute\" for \"CF\" channel as this test "
+ "fails, because of design issues.");
+ //g_assert_cmpint (cf_mute, ==, 1);
+}
+
+int
+main (int argc, char **argv)
+{
+#if !GLIB_CHECK_VERSION (2, 35, 0)
+ g_type_init ();
+#endif
+ g_test_init (&argc, &argv, NULL);
+
+ g_test_add_func ("/last-change-parser/general", general);
+ g_test_add_func ("/last-change-parser/bogus-text", bogus_text);
+ g_test_add_func ("/last-change-parser/nonexistent-instance", nonexistent_instance);
+ g_test_add_func ("/last-change-parser/nonexistent-variable", nonexistent_variable);
+ g_test_add_func ("/last-change-parser/two-mutes", two_mutes);
+
+ g_test_run ();
+
+ return 0;
+}
diff --git a/tests/gtest/test-media-collection.c b/tests/gtest/test-media-collection.c
new file mode 100644
index 0000000..0979f0e
--- /dev/null
+++ b/tests/gtest/test-media-collection.c
@@ -0,0 +1,493 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.
+ *
+ * Author: Jens Georg <jensg@openismus.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 <libgupnp-av/gupnp-media-collection.h>
+
+/* Flat DIDL_S playlist */
+#define TEST_PARSE_COLLECTION_1 \
+"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" \
+"<DIDL-Lite" \
+" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"" \
+" xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\"" \
+" xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\"" \
+" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" \
+" xsi:schemaLocation=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/" \
+" http://www.upnp.org/schemas/av/didl-lite-v2-20060531.xsd" \
+" urn:schemas-upnp-org:metadata-1-0/upnp/" \
+" http://www.upnp.org/schemas/av/upnp-v2-20060531.xsd\">" \
+" <item id=\"\" parentID=\"0\" restricted=\"0\">" \
+" <dc:title>Song1</dc:title>" \
+" <upnp:class>object.item.audioItem</upnp:class>" \
+" <res protocolInfo=\"*:*:*:*\" />" \
+" <upnp:artist></upnp:artist>" \
+" </item>" \
+" <item id=\"\" parentID=\"0\" restricted=\"0\">" \
+" <dc:title>Song2</dc:title>" \
+" <upnp:class>object.item.audioItem</upnp:class>" \
+" <res protocolInfo=\"*:*:*:*\" />" \
+" </item>" \
+" <item id=\"\" parentID=\"0\" restricted=\"0\">" \
+" <dc:title>Song3</dc:title>" \
+" <upnp:class>object.item.audioItem</upnp:class>" \
+" <res protocolInfo=\"*:*:*:*\" />" \
+" </item>" \
+"</DIDL-Lite>"
+
+/* Nested DIDL_S playlist */
+#define TEST_PARSE_COLLECTION_2 \
+"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" \
+"<DIDL-Lite" \
+" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"" \
+" xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\"" \
+" xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\"" \
+" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" \
+" xsi:schemaLocation=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/" \
+" http://www.upnp.org/schemas/av/didl-lite-v2-20060531.xsd" \
+" urn:schemas-upnp-org:metadata-1-0/upnp/" \
+" http://www.upnp.org/schemas/av/upnp-v2-20060531.xsd\">" \
+" <container id=\"1\" parentID=\"0\" restricted=\"0\">" \
+" <dc:title>NonFlatCollection</dc:title>" \
+" <dc:creator>NonFlatCollection Author</dc:creator>" \
+" <item id=\"\" parentID=\"1\" restricted=\"0\">" \
+" <dc:title>Song1</dc:title>" \
+" <upnp:class>object.item.audioItem</upnp:class>" \
+" <res protocolInfo=\"*:*:*:*\" />" \
+" <upnp:artist></upnp:artist>" \
+" </item>" \
+" <item id=\"\" parentID=\"1\" restricted=\"0\">" \
+" <dc:title>Song2</dc:title>" \
+" <upnp:class>object.item.audioItem</upnp:class>" \
+" <res protocolInfo=\"*:*:*:*\" />" \
+" </item>" \
+" <item id=\"\" parentID=\"1\" restricted=\"0\">" \
+" <dc:title>Song3</dc:title>" \
+" <upnp:class>object.item.audioItem</upnp:class>" \
+" <res protocolInfo=\"*:*:*:*\" />" \
+" </item>" \
+" </container>" \
+"</DIDL-Lite>"
+
+#define TEST_CREATE_FLAT \
+"<DIDL-Lite " \
+ "xmlns:dc=\"http://purl.org/dc/elements/1.1/\" " \
+ "xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\" " \
+ "xmlns:dlna=\"urn:schemas-dlna-org:metadata-1-0/\" " \
+ "xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\">" \
+ "<item restricted=\"1\">" \
+ "<dc:title>Song1</dc:title>" \
+ "<upnp:class>object.item.audioItem</upnp:class>" \
+ "<res>http://example.com/song1.mp3</res>" \
+ "</item>" \
+ "<item restricted=\"1\">" \
+ "<dc:title>Song2</dc:title>" \
+ "<upnp:class>object.item.audioItem</upnp:class>" \
+ "<res>http://example.com/song2.mp3</res>" \
+ "</item>" \
+ "<item restricted=\"1\">" \
+ "<dc:title>Song3</dc:title>" \
+ "<upnp:class>object.item.audioItem</upnp:class>" \
+ "<res>http://example.com/song3.mp3</res>" \
+ "</item>" \
+"</DIDL-Lite>"
+
+#define TEST_CREATE_FULL \
+"<DIDL-Lite " \
+ "xmlns:dc=\"http://purl.org/dc/elements/1.1/\" " \
+ "xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\" " \
+ "xmlns:dlna=\"urn:schemas-dlna-org:metadata-1-0/\" " \
+ "xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\">" \
+ "<container>" \
+ "<dc:title>TestCollection1</dc:title>" \
+ "<dc:creator>TestCollection1Author</dc:creator>" \
+ "<item restricted=\"1\">" \
+ "<dc:title>Song1</dc:title>" \
+ "<upnp:class>object.item.audioItem</upnp:class>" \
+ "<res>http://example.com/song1.mp3</res>" \
+ "</item>" \
+ "<item restricted=\"1\">" \
+ "<dc:title>Song2</dc:title>" \
+ "<upnp:class>object.item.audioItem</upnp:class>" \
+ "<res>http://example.com/song2.mp3</res>" \
+ "</item>" \
+ "<item restricted=\"1\">" \
+ "<dc:title>Song3</dc:title>" \
+ "<upnp:class>object.item.audioItem</upnp:class>" \
+ "<res>http://example.com/song3.mp3</res>" \
+ "</item>" \
+ "</container>" \
+"</DIDL-Lite>"
+
+#define TEST_CREATE_FULL_REPARENT \
+"<DIDL-Lite " \
+ "xmlns:dc=\"http://purl.org/dc/elements/1.1/\" " \
+ "xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\" " \
+ "xmlns:dlna=\"urn:schemas-dlna-org:metadata-1-0/\" " \
+ "xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\">" \
+ "<container>" \
+ "<item restricted=\"1\">" \
+ "<dc:title>Song1</dc:title>" \
+ "<upnp:class>object.item.audioItem</upnp:class>" \
+ "<res>http://example.com/song1.mp3</res>" \
+ "</item>" \
+ "<item restricted=\"1\">" \
+ "<dc:title>Song2</dc:title>" \
+ "<upnp:class>object.item.audioItem</upnp:class>" \
+ "<res>http://example.com/song2.mp3</res>" \
+ "</item>" \
+ "<item restricted=\"1\">" \
+ "<dc:title>Song3</dc:title>" \
+ "<upnp:class>object.item.audioItem</upnp:class>" \
+ "<res>http://example.com/song3.mp3</res>" \
+ "</item>" \
+ "<dc:title>TestCollection1</dc:title>" \
+ "<dc:creator>TestCollection1Author</dc:creator>" \
+ "</container>" \
+"</DIDL-Lite>"
+
+#define TEST_PARSE_NO_XML "This is just some random text"
+
+void
+test_didl_collection_construction ()
+{
+ GUPnPMediaCollection *collection;
+
+ /* Check that a collection created via auxillary function is mutable */
+ collection = gupnp_media_collection_new ();
+ g_assert (gupnp_media_collection_get_mutable (collection));
+ g_object_unref (collection);
+
+ /* Check that a collection created via auxillary parse function is
+ * not mutable */
+ collection = gupnp_media_collection_new_from_string
+ (TEST_PARSE_COLLECTION_1);
+ g_assert (!gupnp_media_collection_get_mutable (collection));
+ g_object_unref (collection);
+
+ /* Check that creating a collection via g_object_new and title/author
+ * properties set is mutable */
+ collection = g_object_new (GUPNP_TYPE_MEDIA_COLLECTION,
+ "title", "test01collection",
+ "author", "test01author",
+ NULL);
+ g_assert (gupnp_media_collection_get_mutable (collection));
+ g_object_unref (collection);
+
+ /* Check that creating a collection via g_object_new and data is not
+ * mutable */
+ collection = g_object_new (GUPNP_TYPE_MEDIA_COLLECTION,
+ "data", TEST_PARSE_COLLECTION_1,
+ NULL);
+ g_assert (!gupnp_media_collection_get_mutable (collection));
+ g_object_unref (collection);
+
+ /* Check that creating a collection with all properties set will result
+ * in a collection that ignored "title" and "author" properties.
+ */
+ collection = g_object_new (GUPNP_TYPE_MEDIA_COLLECTION,
+ "title", "test01collection",
+ "author", "test01author",
+ "data", TEST_PARSE_COLLECTION_1,
+ NULL);
+ g_assert (!gupnp_media_collection_get_mutable (collection));
+ g_assert_cmpstr (gupnp_media_collection_get_author (collection), ==,
+ NULL);
+ g_assert_cmpstr (gupnp_media_collection_get_title (collection), ==,
+ NULL);
+ g_assert_cmpstr (gupnp_media_collection_get_string (collection), ==,
+ TEST_PARSE_COLLECTION_1);
+ g_object_unref (collection);
+}
+
+void
+test_didl_collection_parse_flat ()
+{
+ GUPnPMediaCollection *collection;
+ GList *items, *it;
+
+ collection = gupnp_media_collection_new_from_string
+ (TEST_PARSE_COLLECTION_1);
+ g_assert_cmpstr (gupnp_media_collection_get_author (collection), ==,
+ NULL);
+ g_assert_cmpstr (gupnp_media_collection_get_title (collection), ==,
+ NULL);
+ g_assert_cmpstr (gupnp_media_collection_get_string (collection), ==,
+ TEST_PARSE_COLLECTION_1);
+
+ it = items = gupnp_media_collection_get_items (collection);
+ g_assert_cmpint (g_list_length (items), ==, 3);
+ g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
+ "Song1");
+ it = it->next;
+ g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
+ "Song2");
+ it = it->next;
+ g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
+ "Song3");
+ g_list_free_full (items, (GDestroyNotify) g_object_unref);
+}
+
+void
+test_didl_collection_parse_full ()
+{
+ GUPnPMediaCollection *collection;
+ GList *items, *it;
+
+ collection = gupnp_media_collection_new_from_string
+ (TEST_PARSE_COLLECTION_2);
+ g_assert_cmpstr (gupnp_media_collection_get_author (collection), ==,
+ "NonFlatCollection Author");
+ g_assert_cmpstr (gupnp_media_collection_get_title (collection), ==,
+ "NonFlatCollection");
+ g_assert_cmpstr (gupnp_media_collection_get_string (collection), ==,
+ TEST_PARSE_COLLECTION_2);
+
+ it = items = gupnp_media_collection_get_items (collection);
+ g_assert_cmpint (g_list_length (items), ==, 3);
+ g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
+ "Song1");
+ it = it->next;
+ g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
+ "Song2");
+ it = it->next;
+ g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
+ "Song3");
+ g_list_free_full (items, (GDestroyNotify) g_object_unref);
+}
+
+#define ERROR_MESSAGE "Failed to parse DIDL-Lite: No 'DIDL-Lite' node in the DIDL-Lite XML:"
+
+static gboolean
+ignore_xml_parse_error (const gchar *log_domain,
+ GLogLevelFlags log_level,
+ const gchar *message,
+ gpointer user_data)
+{
+ if (strncmp (message,
+ ERROR_MESSAGE,
+ g_utf8_strlen (ERROR_MESSAGE, -1) - 1) == 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void
+test_didl_collection_parse_invalid ()
+{
+ GUPnPMediaCollection *collection;
+ GList *items;
+
+ g_test_log_set_fatal_handler (ignore_xml_parse_error, NULL);
+ collection = gupnp_media_collection_new_from_string (TEST_PARSE_NO_XML);
+ items = gupnp_media_collection_get_items (collection);
+
+ g_assert (items == NULL);
+ g_object_unref (collection);
+}
+
+void
+test_didl_collection_create_flat ()
+{
+ GUPnPMediaCollection *collection;
+ GUPnPDIDLLiteItem *item;
+ GList *items, *it;
+ GUPnPDIDLLiteResource *res;
+
+ collection = gupnp_media_collection_new ();
+ item = gupnp_media_collection_add_item (collection);
+ gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
+ "Song1");
+ gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
+ "object.item.audioItem");
+ res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
+ gupnp_didl_lite_resource_set_uri (res, "http://example.com/song1.mp3");
+ g_object_unref (res);
+ g_object_unref (item);
+ item = gupnp_media_collection_add_item (collection);
+ gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
+ "Song2");
+ gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
+ "object.item.audioItem");
+ res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
+ gupnp_didl_lite_resource_set_uri (res, "http://example.com/song2.mp3");
+ g_object_unref (res);
+ g_object_unref (item);
+ item = gupnp_media_collection_add_item (collection);
+ gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
+ "Song3");
+ gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
+ "object.item.audioItem");
+ res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
+ gupnp_didl_lite_resource_set_uri (res, "http://example.com/song3.mp3");
+ g_object_unref (res);
+ g_object_unref (item);
+ it = items = gupnp_media_collection_get_items (collection);
+ g_assert_cmpint (g_list_length (items), ==, 3);
+ g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
+ "Song1");
+ it = it->next;
+ g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
+ "Song2");
+ it = it->next;
+ g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
+ "Song3");
+ g_list_free_full (items, (GDestroyNotify) g_object_unref);
+ g_assert_cmpstr (gupnp_media_collection_get_string (collection), ==,
+ TEST_CREATE_FLAT);
+}
+
+void
+test_didl_collection_create_full ()
+{
+ GUPnPMediaCollection *collection;
+ GUPnPDIDLLiteItem *item;
+ GList *items, *it;
+ GUPnPDIDLLiteResource *res;
+
+ collection = gupnp_media_collection_new ();
+ gupnp_media_collection_set_title (collection, "TestCollection1");
+ gupnp_media_collection_set_author (collection, "TestCollection1Author");
+
+ item = gupnp_media_collection_add_item (collection);
+ gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
+ "Song1");
+ gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
+ "object.item.audioItem");
+ res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
+ gupnp_didl_lite_resource_set_uri (res, "http://example.com/song1.mp3");
+ g_object_unref (res);
+ g_object_unref (item);
+ item = gupnp_media_collection_add_item (collection);
+ gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
+ "Song2");
+ gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
+ "object.item.audioItem");
+ res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
+ gupnp_didl_lite_resource_set_uri (res, "http://example.com/song2.mp3");
+ g_object_unref (res);
+ g_object_unref (item);
+ item = gupnp_media_collection_add_item (collection);
+ gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
+ "Song3");
+ gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
+ "object.item.audioItem");
+ res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
+ gupnp_didl_lite_resource_set_uri (res, "http://example.com/song3.mp3");
+ g_object_unref (res);
+ g_object_unref (item);
+ it = items = gupnp_media_collection_get_items (collection);
+ g_assert_cmpint (g_list_length (items), ==, 3);
+ g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
+ "Song1");
+ it = it->next;
+ g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
+ "Song2");
+ it = it->next;
+ g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
+ "Song3");
+ g_list_free_full (items, (GDestroyNotify) g_object_unref);
+ g_assert_cmpstr (gupnp_media_collection_get_string (collection), ==,
+ TEST_CREATE_FULL);
+}
+
+void
+test_didl_collection_create_reparent ()
+{
+ GUPnPMediaCollection *collection;
+ GUPnPDIDLLiteItem *item;
+ GList *items, *it;
+ GUPnPDIDLLiteResource *res;
+
+ collection = gupnp_media_collection_new ();
+
+ item = gupnp_media_collection_add_item (collection);
+ gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
+ "Song1");
+ gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
+ "object.item.audioItem");
+ res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
+ gupnp_didl_lite_resource_set_uri (res, "http://example.com/song1.mp3");
+ g_object_unref (res);
+ g_object_unref (item);
+ item = gupnp_media_collection_add_item (collection);
+ gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
+ "Song2");
+ gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
+ "object.item.audioItem");
+ res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
+ gupnp_didl_lite_resource_set_uri (res, "http://example.com/song2.mp3");
+ g_object_unref (res);
+ g_object_unref (item);
+ item = gupnp_media_collection_add_item (collection);
+ gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
+ "Song3");
+ gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
+ "object.item.audioItem");
+ res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
+ gupnp_didl_lite_resource_set_uri (res, "http://example.com/song3.mp3");
+ g_object_unref (res);
+ g_object_unref (item);
+ it = items = gupnp_media_collection_get_items (collection);
+
+ /* Force reparenting of the items in the XML */
+ gupnp_media_collection_set_title (collection, "TestCollection1");
+ gupnp_media_collection_set_author (collection, "TestCollection1Author");
+
+ g_assert_cmpint (g_list_length (items), ==, 3);
+ g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
+ "Song1");
+ it = it->next;
+ g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
+ "Song2");
+ it = it->next;
+ g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
+ "Song3");
+ g_list_free_full (items, (GDestroyNotify) g_object_unref);
+
+ g_assert_cmpstr (gupnp_media_collection_get_string (collection), ==,
+ TEST_CREATE_FULL_REPARENT);
+}
+
+int main (int argc, char *argv[])
+{
+#if !GLIB_CHECK_VERSION (2, 35, 0)
+ g_type_init ();
+#endif
+ g_test_init (&argc, &argv, NULL);
+
+ g_test_add_func ("/didl/collection/construction",
+ test_didl_collection_construction);
+ g_test_add_func ("/didl/collection/parse_flat",
+ test_didl_collection_parse_flat);
+ g_test_add_func ("/didl/collection/parse_full",
+ test_didl_collection_parse_full);
+ g_test_add_func ("/didl/collection/parse_invalid",
+ test_didl_collection_parse_invalid);
+
+ g_test_add_func ("/didl/collection/create_flat",
+ test_didl_collection_create_flat);
+ g_test_add_func ("/didl/collection/create_full",
+ test_didl_collection_create_full);
+ g_test_add_func ("/didl/collection/create_reparent",
+ test_didl_collection_create_reparent);
+
+ return g_test_run ();
+}
diff --git a/tests/gtest/test-regression.c b/tests/gtest/test-regression.c
index d535636..ed548e3 100644
--- a/tests/gtest/test-regression.c
+++ b/tests/gtest/test-regression.c
@@ -20,6 +20,7 @@
*/
#include <libgupnp-av/gupnp-didl-lite-parser.h>
+#include <libgupnp-av/gupnp-didl-lite-writer.h>
#define TEST_DIDL_BGO674319 \
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" \
@@ -68,12 +69,36 @@ test_bgo674319 (void)
g_assert (artists == NULL);
}
+static void
+test_bgo687462 (void)
+{
+ GUPnPDIDLLiteWriter *writer;
+ GUPnPDIDLLiteObject *object;
+
+ writer = gupnp_didl_lite_writer_new (NULL);
+ object = (GUPnPDIDLLiteObject *)
+ gupnp_didl_lite_writer_add_item (writer);
+ gupnp_didl_lite_object_set_album (object, "Test");
+ g_assert_cmpstr (gupnp_didl_lite_object_get_album (object), ==, "Test");
+
+ gupnp_didl_lite_object_set_album_art (object, "AlbumArt");
+ g_assert_cmpstr (gupnp_didl_lite_object_get_album_art (object), ==, "AlbumArt");
+
+ gupnp_didl_lite_writer_filter (writer, "upnp:album");
+
+ g_assert_cmpstr (gupnp_didl_lite_object_get_album (object), ==, "Test");
+ g_assert (gupnp_didl_lite_object_get_album_art (object) == NULL);
+}
+
int main (int argc, char *argv[])
{
+#if !GLIB_CHECK_VERSION (2, 35, 0)
g_type_init ();
+#endif
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/bugs/gnome/674319", test_bgo674319);
+ g_test_add_func ("/bugs/gnome/687462", test_bgo687462);
g_test_run ();
diff --git a/tests/test-search-criteria-parser.c b/tests/test-search-criteria-parser.c
index e1fc1d9..7e49fba 100644
--- a/tests/test-search-criteria-parser.c
+++ b/tests/test-search-criteria-parser.c
@@ -71,7 +71,9 @@ main (int argc, char **argv)
g_assert (argc == 2);
+#if !GLIB_CHECK_VERSION (2, 35, 0)
g_type_init ();
+#endif
parser = gupnp_search_criteria_parser_new ();