コード例 #1
0
/* Reads a value of state variable @variable_name to an initialised GValue pair
 * from the InstanceID node of a LastChange xml doc */
static gboolean
read_state_variable (const char *variable_name,
                     GValue     *value,
                     xmlNode    *instance_node)
{
        xmlNode    *variable_node;
        const char *val_str;

        variable_node = xml_util_get_element (instance_node,
                                              variable_name,
                                              NULL);
        if (!variable_node)
                return FALSE;

        val_str = xml_util_get_attribute_content (variable_node, "val");
        if (!val_str) {
                g_warning ("No value provided for variable \"%s\" in "
                           "LastChange event",
                           variable_name);

                return FALSE;
        }

        gvalue_util_set_value_from_string (value, val_str);

        return TRUE;
}
コード例 #2
0
ファイル: upnp.c プロジェクト: prajoshpremdas/gupnp-tools
static void init_uuid (void)
{
        xmlNode *uuid_node;
        char *udn;

        uuid = gupnp_get_uuid ();

        uuid_node = xml_util_get_element ((xmlNode *) doc->doc,
                                          "root",
                                          "device",
                                          "UDN",
                                          NULL);
        if (uuid_node == NULL) {
                g_critical ("Failed to find UDN element"
                            "in device description");

                return;
        }

        udn = g_strdup_printf ("uuid:%s", uuid);

        xmlNodeSetContent (uuid_node, (unsigned char *) udn);

        g_free (udn);
}
コード例 #3
0
/*
 * Called when the description document is loaded.
 */
static void
description_loaded (GUPnPControlPoint *control_point,
                    GUPnPXMLDoc       *doc,
                    const char        *udn,
                    const char        *service_type,
                    const char        *description_url)
{
        xmlNode *element;
        SoupURI *url_base;

        /* Save the URL base, if any */
        element = xml_util_get_element ((xmlNode *) doc->doc,
                                        "root",
                                        NULL);
        if (element == NULL) {
                g_warning ("No 'root' element found in description document"
                           " '%s'. Ignoring device '%s'\n",
                           description_url,
                           udn);

                return;
        }

        if (element == NULL)
                return;

        url_base = xml_util_get_child_element_content_uri (element,
                                                           "URLBase",
                                                           NULL);
        if (!url_base)
                url_base = soup_uri_new (description_url);

        /* Iterate matching devices */
        process_device_list (element,
                             control_point,
                             doc,
                             udn,
                             service_type,
                             description_url,
                             url_base);

        /* Cleanup */
        soup_uri_free (url_base);
}
コード例 #4
0
ファイル: upnp.c プロジェクト: prajoshpremdas/gupnp-tools
static void init_friendly_name (gchar *name)
{
        xmlNode *fdn_node;

        fdn_node = xml_util_get_element ((xmlNode *) doc->doc,
                                          "root",
                                          "device",
                                          "friendlyName",
                                          NULL);
        if (fdn_node == NULL) {
                g_warning ("Failed to find friendly name element"
                            "in device description, "
                            "using default value");

                return;
        }

        xmlNodeSetContent (fdn_node, (unsigned char *) name);
}
コード例 #5
0
ファイル: gupnp-control-point.c プロジェクト: Ham22/gupnp
/* Recursively search @element for matching devices */
static void
process_device_list (xmlNode           *element,
                     GUPnPControlPoint *control_point,
                     GUPnPXMLDoc       *doc,
                     const char        *udn,
                     const char        *service_type,
                     const char        *description_url,
                     SoupURI           *url_base)
{
        g_object_ref (control_point);

        for (element = element->children; element; element = element->next) {
                xmlNode *children;
                xmlChar *prop;
                gboolean match;

                if (strcmp ((char *) element->name, "device") != 0)
                        continue;

                /* Recurse into children */
                children = xml_util_get_element (element,
                                                 "deviceList",
                                                 NULL);

                if (children) {
                        process_device_list (children,
                                             control_point,
                                             doc,
                                             udn,
                                             service_type,
                                             description_url,
                                             url_base);
                }

                /* See if this is a matching device */
                prop = xml_util_get_child_element_content (element, "UDN");
                if (!prop)
                        continue;

                match = (strcmp ((char *) prop, udn) == 0);

                xmlFree (prop);

                if (!match)
                        continue;

                /* Match */

                if (service_type) {
                        /* Dive into serviceList */
                        children = xml_util_get_element (element,
                                                         "serviceList",
                                                         NULL);

                        if (children) {
                                process_service_list (children,
                                                      control_point,
                                                      doc,
                                                      udn,
                                                      service_type,
                                                      description_url,
                                                      url_base);
                        }
                } else
                        create_and_report_device_proxy (control_point,
                                                        doc,
                                                        element,
                                                        udn,
                                                        description_url,
                                                        url_base);
        }

        g_object_unref (control_point);
}
コード例 #6
0
/**
 * gupnp_device_info_get_icon_url:
 * @info: A #GUPnPDeviceInfo
 * @requested_mime_type: (allow-none) (transfer none): The requested file
 * format, or %NULL for any
 * @requested_depth: The requested color depth, or -1 for any
 * @requested_width: The requested width, or -1 for any
 * @requested_height: The requested height, or -1 for any
 * @prefer_bigger: %TRUE if a bigger, rather than a smaller icon should be
 * returned if no exact match could be found
 * @mime_type: (out) (allow-none): The location where to store the the format
 * of the returned icon, or %NULL. The returned string should be freed after
 * use
 * @depth: (out) (allow-none) :  The location where to store the depth of the
 * returned icon, or %NULL
 * @width: (out) (allow-none) : The location where to store the width of the
 * returned icon, or %NULL
 * @height: (out) (allow-none) : The location where to store the height of the
 * returned icon, or %NULL
 *
 * Get a URL pointing to the icon most closely matching the
 * given criteria, or %NULL. If @requested_mime_type is set, only icons with
 * this mime type will be returned. If @requested_depth is set, only icons with
 * this or lower depth will be returned. If @requested_width and/or
 * @requested_height are set, only icons that are this size or smaller are
 * returned, unless @prefer_bigger is set, in which case the next biggest icon
 * will be returned. The returned strings should be freed.
 *
 * Return value: (transfer full): a string, or %NULL.  g_free() after use.
 **/
char *
gupnp_device_info_get_icon_url (GUPnPDeviceInfo *info,
                                const char      *requested_mime_type,
                                int              requested_depth,
                                int              requested_width,
                                int              requested_height,
                                gboolean         prefer_bigger,
                                char           **mime_type,
                                int             *depth,
                                int             *width,
                                int             *height)
{
        GList *icons, *l;
        xmlNode *element;
        Icon *icon, *closest;
        char *ret;

        g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);

        /* List available icons */
        icons = NULL;

        element = xml_util_get_element (info->priv->element,
                                        "iconList",
                                        NULL);
        if (!element)
                return NULL;

        for (element = element->children; element; element = element->next) {
                if (!strcmp ("icon", (char *) element->name)) {
                        gboolean mime_type_ok;

                        icon = icon_parse (info, element);

                        if (requested_mime_type) {
                                mime_type_ok =
                                        !strcmp (requested_mime_type,
                                                 (char *) icon->mime_type);
                        } else
                                mime_type_ok = TRUE;

                        if (requested_depth >= 0)
                                icon->weight = requested_depth - icon->depth;

                        /* Filter out icons with incorrect mime type or
                         * incorrect depth. */
                        if (mime_type_ok && icon->weight >= 0) {
                                if (requested_width >= 0) {
                                        if (prefer_bigger) {
                                                icon->weight +=
                                                        icon->width -
                                                        requested_width;
                                        } else {
                                                icon->weight +=
                                                        requested_width -
                                                        icon->width;
                                        }
                                }

                                if (requested_height >= 0) {
                                        if (prefer_bigger) {
                                                icon->weight +=
                                                        icon->height -
                                                        requested_height;
                                        } else {
                                                icon->weight +=
                                                        requested_height -
                                                        icon->height;
                                        }
                                }

                                icons = g_list_prepend (icons, icon);
                        } else
                                icon_free (icon);
                }
        }

        if (icons == NULL)
                return NULL;

        /* Find closest match */
        closest = NULL;
        for (l = icons; l; l = l->next) {
                icon = l->data;

                /* Look between icons with positive weight first */
                if (icon->weight >= 0) {
                        if (!closest || icon->weight < closest->weight)
                                closest = icon;
                }
        }

        if (!closest) {
                for (l = icons; l; l = l->next) {
                        icon = l->data;

                        /* No icons with positive weight, look at ones with
                         * negative weight */
                        if (!closest || icon->weight > closest->weight)
                                closest = icon;
                }
        }

        /* Fill in return values */
        if (closest) {
                icon = closest;

                if (mime_type) {
                        if (icon->mime_type) {
                                *mime_type = g_strdup
                                                ((char *) icon->mime_type);
                        } else
                                *mime_type = NULL;
                }

                if (depth)
                        *depth = icon->depth;
                if (width)
                        *width = icon->width;
                if (height)
                        *height = icon->height;

                if (icon->url) {
                        SoupURI *uri;

                        uri = soup_uri_new_with_base (info->priv->url_base,
                                                      (const char *) icon->url);
                        ret = soup_uri_to_string (uri, FALSE);
                        soup_uri_free (uri);
                } else
                        ret = NULL;
        } else {
                if (mime_type)
                        *mime_type = NULL;
                if (depth)
                        *depth = -1;
                if (width)
                        *width = -1;
                if (height)
                        *height = -1;

                ret = NULL;
        }

        /* Cleanup */
        while (icons) {
                icon_free (icons->data);
                icons = g_list_delete_link (icons, icons);
        }

        return ret;
}
コード例 #7
0
gupnp_device_info_list_devices (GUPnPDeviceInfo *info)
{
        GUPnPDeviceInfoClass *class;
        GList *devices;
        xmlNode *element;

        g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);

        class = GUPNP_DEVICE_INFO_GET_CLASS (info);

        g_return_val_if_fail (class->get_device, NULL);

        devices = NULL;

        element = xml_util_get_element (info->priv->element,
                                        "deviceList",
                                        NULL);
        if (!element)
                return NULL;

        for (element = element->children; element; element = element->next) {
                if (!strcmp ("device", (char *) element->name)) {
                        GUPnPDeviceInfo *child;

                        child = class->get_device (info, element);
                        devices = g_list_prepend (devices, child);
                }
        }

        return devices;
}
コード例 #8
0
/**
 * 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;
        xmlNs         *upnp_ns = NULL;
        xmlNs         *dc_ns   = NULL;
        xmlNs         *dlna_ns = NULL;
        xmlNs         *pv_ns   = NULL;
        GUPnPAVXMLDoc *xml_doc = NULL;
        gboolean       result;

        doc = xmlRecoverMemory (didl, strlen (didl));
        if (doc == NULL) {
                g_set_error (error,
                             G_MARKUP_ERROR,
                             G_MARKUP_ERROR_PARSE,
                             "Could not parse DIDL-Lite XML:\n%s", didl);

                return FALSE;
        }

        /* Get a pointer to root element */
        element = xml_util_get_element ((xmlNode *) doc,
                                        "DIDL-Lite",
                                        NULL);
        if (element == NULL) {
                g_set_error (error,
                             G_MARKUP_ERROR,
                             G_MARKUP_ERROR_PARSE,
                             "No 'DIDL-Lite' node in the DIDL-Lite XML:\n%s",
                             didl);
                xmlFreeDoc (doc);

                return FALSE;
        }

        if (element->children == NULL) {
                g_set_error (error,
                             G_MARKUP_ERROR,
                             G_MARKUP_ERROR_EMPTY,
                             "Empty 'DIDL-Lite' node in the DIDL-Lite XML:\n%s",
                             didl);
                xmlFreeDoc (doc);

                return FALSE;
        }

        /* Create namespaces if they don't exist */
        upnp_ns = xml_util_lookup_namespace (doc, GUPNP_XML_NAMESPACE_UPNP);
        if (! upnp_ns)
                upnp_ns = xml_util_create_namespace (xmlDocGetRootElement (doc),
                                                     GUPNP_XML_NAMESPACE_UPNP);

        dc_ns = xml_util_lookup_namespace (doc, GUPNP_XML_NAMESPACE_DC);
        if (! dc_ns)
                dc_ns = xml_util_create_namespace (xmlDocGetRootElement (doc),
                                                   GUPNP_XML_NAMESPACE_DC);
        dlna_ns = xml_util_lookup_namespace (doc, GUPNP_XML_NAMESPACE_DLNA);
        if (! dlna_ns)
                dlna_ns = xml_util_create_namespace (xmlDocGetRootElement (doc),
                                                   GUPNP_XML_NAMESPACE_DLNA);

        pv_ns = xml_util_lookup_namespace (doc, GUPNP_XML_NAMESPACE_PV);
        if (! pv_ns)
                pv_ns = xml_util_create_namespace (xmlDocGetRootElement (doc),
                                                   GUPNP_XML_NAMESPACE_PV);

        xml_doc = xml_doc_new (doc);

        result = parse_elements (parser,
                                 element,
                                 xml_doc,
                                 upnp_ns,
                                 dc_ns,
                                 dlna_ns,
                                 pv_ns,
                                 recursive,
                                 error);
        xml_doc_unref (xml_doc);

        return result;
}