⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gupnp-service-introspection.c

📁 另一 UPNP SDK 支持在UNIX/LINUX上运行。 UPnP是一种网络协议
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 2007 Zeeshan Ali <zeenix@gstreamer.net> * Copyright (C) 2006, 2007 OpenedHand Ltd. * * Author: Zeeshan Ali <zeenix@gstreamer.net> *         Jorn Baayen <jorn@openedhand.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. *//** * SECTION:gupnp-service-introspection * @short_description: Service introspection class. * * The #GUPnPServiceIntrospection class provides methods for service * introspection based on information contained in its service description * document (SCPD). There is no constructor provided for this class, please use * #gupnp_service_info_get_introspection or * #gupnp_service_info_get_introspection_async to create an * #GUPnPServiceIntrospection object for a specific service. * * Note that all the introspection information is retreived from the service * description document (SCPD) provided by the service and hence can not be * guaranteed to be complete. A UPnP service is required to provide an SCPD but * unfortunately, many services either do not provide this document or the * document does not provide any or all of the introspection information. * * This class exposes internals of the UPnP protocol and should not need * to be used for regular device or control point development. * **/#include <libsoup/soup.h>#include <string.h>#include "gupnp-service-introspection.h"#include "gupnp-service-introspection-private.h"#include "xml-util.h"#include "gvalue-util.h"#include "gupnp-types.h"#include "gupnp-types-private.h"#define MAX_FIXED_14_4 99999999999999.9999G_DEFINE_TYPE (GUPnPServiceIntrospection,               gupnp_service_introspection,               G_TYPE_OBJECT);struct _GUPnPServiceIntrospectionPrivate {        GList *variables;        GList *actions;        /* For caching purposes */        GList *action_names;        GList *variable_names;};enum {        PROP_0,        PROP_SCPD};static voidconstruct_introspection_info (GUPnPServiceIntrospection *introspection,                              xmlDoc                    *scpd);/** * gupnp_service_state_variable_info_free * @argument: A #GUPnPServiceStateVariableInfo * * Frees a #GUPnPServiceStateVariableInfo. * **/static voidgupnp_service_state_variable_info_free                                (GUPnPServiceStateVariableInfo *variable){        g_free (variable->name);        g_value_unset (&variable->default_value);        if (variable->is_numeric) {                g_value_unset (&variable->minimum);                g_value_unset (&variable->maximum);                g_value_unset (&variable->step);        }        g_list_foreach (variable->allowed_values,                         (GFunc) g_free,                         NULL);        g_list_free (variable->allowed_values);        g_slice_free (GUPnPServiceStateVariableInfo, variable);}static voidgupnp_service_introspection_init (GUPnPServiceIntrospection *introspection){        introspection->priv =                G_TYPE_INSTANCE_GET_PRIVATE (introspection,                                             GUPNP_TYPE_SERVICE_INTROSPECTION,                                             GUPnPServiceIntrospectionPrivate);}static voidgupnp_service_introspection_set_property (GObject      *object,                                          guint        property_id,                                          const GValue *value,                                          GParamSpec   *pspec){        GUPnPServiceIntrospection *introspection;        introspection = GUPNP_SERVICE_INTROSPECTION (object);        switch (property_id) {        case PROP_SCPD:                /* Construct introspection data */                construct_introspection_info (introspection,                                              g_value_get_pointer (value));                break;        default:                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);                break;        }}/** * gupnp_service_action_arg_info_free * @argument: A #GUPnPServiceActionArgInfo * * Frees a #GUPnPServiceActionArgInfo. * **/static voidgupnp_service_action_arg_info_free (GUPnPServiceActionArgInfo *argument){        g_free (argument->name);        g_free (argument->related_state_variable);        g_slice_free (GUPnPServiceActionArgInfo, argument);}/** * gupnp_service_action_info_free * @argument: A #GUPnPServiceActionInfo * * Frees a #GUPnPServiceActionInfo. * **/static voidgupnp_service_action_info_free (GUPnPServiceActionInfo *action_info){        GList *iter;        g_free (action_info->name);        for (iter = action_info->arguments; iter; iter = iter->next) {                gupnp_service_action_arg_info_free (                                (GUPnPServiceActionArgInfo *) iter->data);        }        g_list_free (action_info->arguments);        g_slice_free (GUPnPServiceActionInfo, action_info);}static voidgupnp_service_introspection_finalize (GObject *object){        GUPnPServiceIntrospection *introspection;        introspection = GUPNP_SERVICE_INTROSPECTION (object);        if (introspection->priv->variables) {                g_list_foreach (introspection->priv->variables,                                (GFunc) gupnp_service_state_variable_info_free,                                NULL);                g_list_free (introspection->priv->variables);        }        if (introspection->priv->actions) {                g_list_foreach (introspection->priv->actions,                                (GFunc) gupnp_service_action_info_free,                                NULL);                g_list_free (introspection->priv->actions);        }        if (introspection->priv->variable_names)                g_list_free (introspection->priv->variable_names);        if (introspection->priv->action_names)                g_list_free (introspection->priv->action_names);}static voidgupnp_service_introspection_class_init (GUPnPServiceIntrospectionClass *klass){        GObjectClass *object_class;        object_class = G_OBJECT_CLASS (klass);        object_class->set_property = gupnp_service_introspection_set_property;        object_class->finalize     = gupnp_service_introspection_finalize;        g_type_class_add_private (klass,                                  sizeof (GUPnPServiceIntrospectionPrivate));        /**         * GUPnPServiceIntrospection:scpd         *         * The scpd of the device description file.         **/        g_object_class_install_property                (object_class,                 PROP_SCPD,                 g_param_spec_pointer ("scpd",                                       "SCPD",                                       "Pointer to SCPD",                                       G_PARAM_WRITABLE |                                       G_PARAM_CONSTRUCT_ONLY));}static voidset_default_value (xmlNodePtr                     variable_node,                   GUPnPServiceStateVariableInfo *variable){        xmlChar *default_str;        default_str = xml_util_get_child_element_content (variable_node,                                                          "defaultValue");        if (default_str) {                gvalue_util_set_value_from_string (&variable->default_value,                                                   (char *) default_str);                xmlFree (default_str);        }}static voidset_string_value_limits (xmlNodePtr   limit_node,                         GList     **limits){        xmlNodePtr value_node;        for (value_node = limit_node->children;             value_node;             value_node = value_node->next) {                xmlChar *allowed_value;                if (strcmp ("allowedValue", (char *) value_node->name) != 0)                        continue;                allowed_value = xmlNodeGetContent (value_node);                if (!allowed_value)                        continue;                *limits = g_list_append (*limits,                                          g_strdup ((char *) allowed_value));                xmlFree (allowed_value);        }}static voidset_value_limit_by_name (xmlNodePtr limit_node,                         GValue    *limit,                         char      *limit_name){        xmlChar *limit_str;        limit_str = xml_util_get_child_element_content (limit_node,                                                        limit_name);        if (limit_str) {                gvalue_util_set_value_from_string (limit, (char *) limit_str);                xmlFree (limit_str);        }}static voidset_variable_limits (xmlNodePtr                     variable_node,                     GUPnPServiceStateVariableInfo *variable){        xmlNodePtr limit_node;        if (variable->is_numeric) {                limit_node = xml_util_get_element (variable_node,                                                   "allowedValueRange",                                                   NULL);                if (limit_node == NULL)                        return;                set_value_limit_by_name (limit_node,                                &(variable->minimum),                                "minimum");                set_value_limit_by_name (limit_node,                                &(variable->maximum),                                "maximum");                set_value_limit_by_name (limit_node,                                &(variable->step),                                "step");        } else if (variable->type == G_TYPE_STRING) {                limit_node = xml_util_get_element (variable_node,                                                   "allowedValueList",                                                   NULL);                if (limit_node == NULL)                        return;                set_string_value_limits (limit_node,                                         &(variable->allowed_values));       }}static gbooleanset_variable_type (GUPnPServiceStateVariableInfo *variable,                   char                          *data_type){        GType type;        if (strcmp ("string", data_type) == 0) {                type = G_TYPE_STRING;        }        else if (strcmp ("char", data_type) == 0) {                type = G_TYPE_CHAR;        }        else if (strcmp ("boolean", data_type) == 0) {                type = G_TYPE_BOOLEAN;        }        else if (strcmp ("i1", data_type) == 0) {                type = G_TYPE_INT;                g_value_init (&variable->minimum, type);                g_value_set_int (&variable->minimum, G_MININT8);                g_value_init (&variable->maximum, type);                g_value_set_int (&variable->maximum, G_MAXINT8);                g_value_init (&variable->step, type);                g_value_set_int (&variable->step, 1);                variable->is_numeric = TRUE;        }        else if (strcmp ("i2", data_type) == 0) {                type = G_TYPE_INT;                g_value_init (&variable->minimum, type);                g_value_set_int (&variable->minimum, G_MININT16);                g_value_init (&variable->maximum, type);                g_value_set_int (&variable->maximum, G_MAXINT16);                g_value_init (&variable->step, type);                g_value_set_int (&variable->step, 1);                variable->is_numeric = TRUE;        }        else if (strcmp ("i4", data_type) == 0 ||                 strcmp ("int", data_type) == 0) {                type = G_TYPE_INT;                g_value_init (&variable->minimum, type);                g_value_set_int (&variable->minimum, G_MININT32);                g_value_init (&variable->maximum, type);                g_value_set_int (&variable->maximum, G_MAXINT32);                g_value_init (&variable->step, type);                g_value_set_int (&variable->step, 1);                variable->is_numeric = TRUE;        }        else if (strcmp ("ui1", data_type) == 0) {                type = G_TYPE_UINT;                g_value_init (&variable->minimum, type);                g_value_set_uint (&variable->minimum, 0);                g_value_init (&variable->maximum, type);                g_value_set_uint (&variable->maximum, G_MAXUINT8);                g_value_init (&variable->step, type);                g_value_set_uint (&variable->step, 1);                variable->is_numeric = TRUE;        }        else if (strcmp ("ui2", data_type) == 0) {                type = G_TYPE_UINT;                g_value_init (&variable->minimum, type);                g_value_set_uint (&variable->minimum, 0);                g_value_init (&variable->maximum, type);                g_value_set_uint (&variable->maximum, G_MAXUINT16);                g_value_init (&variable->step, type);                g_value_set_uint (&variable->step, 1);                variable->is_numeric = TRUE;        }        else if (strcmp ("ui4", data_type) == 0) {                type = G_TYPE_UINT;                g_value_init (&variable->minimum, type);                g_value_set_uint (&variable->minimum, 0);                g_value_init (&variable->maximum, type);                g_value_set_uint (&variable->maximum, G_MAXUINT32);                g_value_init (&variable->step, type);                g_value_set_uint (&variable->step, 1);                variable->is_numeric = TRUE;        }        else if (strcmp ("r4", data_type) == 0) {                type = G_TYPE_FLOAT;                g_value_init (&variable->minimum, type);                g_value_set_float (&variable->minimum, -G_MAXFLOAT);                g_value_init (&variable->maximum, type);                g_value_set_float (&variable->maximum, G_MAXFLOAT);                g_value_init (&variable->step, type);                g_value_set_float (&variable->step, 1.0);                variable->is_numeric = TRUE;        }        else if (strcmp ("r8", data_type) == 0 ||                 strcmp ("number", data_type) == 0) {                type = G_TYPE_DOUBLE;                g_value_init (&variable->minimum, type);                g_value_set_double (&variable->minimum,  -G_MAXDOUBLE);                g_value_init (&variable->maximum, type);                g_value_set_double (&variable->maximum, G_MAXDOUBLE);                g_value_init (&variable->step, type);                g_value_set_double (&variable->step, 1.0);                variable->is_numeric = TRUE;        }        else if (strcmp ("fixed.14.4", data_type) == 0) {                /* Just how did this get into the UPnP specs? */                type = G_TYPE_DOUBLE;                g_value_init (&variable->minimum, type);                g_value_set_double (&variable->minimum,  -MAX_FIXED_14_4);                g_value_init (&variable->maximum, type);                g_value_set_double (&variable->maximum, MAX_FIXED_14_4);                g_value_init (&variable->step, type);                g_value_set_double (&variable->step, 1.0);                variable->is_numeric = TRUE;        }        /* TODO: "float", "int" */        else {                type = gupnp_data_type_to_gtype (data_type);        }        if (type == G_TYPE_INVALID) {                g_warning ("Unkown type '%s' in the SCPD", data_type);                return FALSE;        }        g_value_init (&variable->default_value, type);        variable->type = type;        return TRUE;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -