From: <svn...@op...> - 2009-06-19 14:33:05
|
Author: bellmich Date: Fri Jun 19 16:32:59 2009 New Revision: 1098 URL: http://libsyncml.opensync.org/changeset/1098 Log: migrated SmlDevInfCTCap to GObject style Added: trunk/libsyncml/dev_inf_api/sml_dev_inf_ctcap.c trunk/libsyncml/dev_inf_api/sml_dev_inf_ctcap.h trunk/tests/check_dev_inf_ctcap.c Modified: trunk/libsyncml/CMakeLists.txt trunk/libsyncml/data_sync_api/data_sync_devinf.c trunk/libsyncml/parser/sml_xml_assm.c trunk/libsyncml/parser/sml_xml_parse.c trunk/libsyncml/sml_devinf.c trunk/libsyncml/sml_devinf.h trunk/libsyncml/syncml.h trunk/tests/CMakeLists.txt Modified: trunk/libsyncml/CMakeLists.txt ============================================================================== --- trunk/libsyncml/CMakeLists.txt Fri Jun 19 12:59:56 2009 (r1097) +++ trunk/libsyncml/CMakeLists.txt Fri Jun 19 16:32:59 2009 (r1098) @@ -36,6 +36,7 @@ dev_inf_api/sml_dev_inf_content_type.c dev_inf_api/sml_dev_inf_prop_param.c dev_inf_api/sml_dev_inf_property.c + dev_inf_api/sml_dev_inf_ctcap.c ) IF ( ENABLE_OBEX ) @@ -99,6 +100,7 @@ dev_inf_api/sml_dev_inf_content_type.h dev_inf_api/sml_dev_inf_prop_param.h dev_inf_api/sml_dev_inf_property.h + dev_inf_api/sml_dev_inf_ctcap.h DESTINATION ${LIBSYNCML_INCLUDE_DIR}/libsyncml/dev_inf_api ) Modified: trunk/libsyncml/data_sync_api/data_sync_devinf.c ============================================================================== --- trunk/libsyncml/data_sync_api/data_sync_devinf.c Fri Jun 19 12:59:56 2009 (r1097) +++ trunk/libsyncml/data_sync_api/data_sync_devinf.c Fri Jun 19 16:32:59 2009 (r1098) @@ -32,22 +32,24 @@ smlAssert(ctcap); smlAssert(name); + GError *gerror = NULL; SmlDevInfProperty *prop = sml_dev_inf_property_new(); if (!prop) { smlErrorSet(error, SML_ERROR_GENERIC, "Cannot create new instance of SmlDevInfProperty - out of memory."); goto error; } - GError *gerror = NULL; - if (!sml_dev_inf_property_set_prop_name(prop, name, &gerror)) { - smlErrorSet(error, gerror->code, "%s", gerror->message); - g_error_free(gerror); + if (!sml_dev_inf_property_set_prop_name(prop, name, &gerror)) + goto error; + if (!sml_dev_inf_ctcap_add_property(ctcap, prop, &gerror)) goto error; - } - smlDevInfCTCapAddProperty(ctcap, prop); smlTrace(TRACE_EXIT, "%s", __func__); return prop; error: + if (gerror) { + smlErrorSet(error, gerror->code, "%s", gerror->message); + g_error_free(gerror); + } smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error)); return NULL; } @@ -169,12 +171,15 @@ !strcmp(verct, "2.1")) { smlTrace(TRACE_INTERNAL, "%s: vCard 2.1 detected", __func__); - ctcap = smlDevInfNewCTCap(error); + + SmlDevInfContentType *ct = sml_dev_inf_content_type_new(SML_ELEMENT_TEXT_VCARD, "2.1", &gerror); + if (!ct) + goto error; + ctcap = sml_dev_inf_ctcap_new(ct, &gerror); + g_object_unref(ct); if (!ctcap) goto error; - smlDevInfCTCapSetCTType(ctcap, SML_ELEMENT_TEXT_VCARD); - smlDevInfCTCapSetVerCT(ctcap, "2.1"); _ADD_CTCAP_PROPERTY_BY_NAME("ADR") _ADD_PROPERTY_PARAM("TYPE") _ADD_PROP_PARAM_VAL_ENUM("HOME") @@ -285,12 +290,15 @@ // FIXME: this is no vCard 3.0 spec // FIXME: this is in terms of vCard 3.0 a bug smlTrace(TRACE_INTERNAL, "%s: vCard 3.0 detected", __func__); - ctcap = smlDevInfNewCTCap(error); + + SmlDevInfContentType *ct = sml_dev_inf_content_type_new(SML_ELEMENT_TEXT_VCARD_30, "3.0", &gerror); + if (!ct) + goto error; + ctcap = sml_dev_inf_ctcap_new(ct, &gerror); + g_object_unref(ct); if (!ctcap) goto error; - smlDevInfCTCapSetCTType(ctcap, SML_ELEMENT_TEXT_VCARD_30); - smlDevInfCTCapSetVerCT(ctcap, "3.0"); _ADD_CTCAP_PROPERTY_BY_NAME_VALUE("BEGIN", "VCARD") _ADD_CTCAP_PROPERTY_BY_NAME_VALUE("END", "VCARD") _ADD_CTCAP_PROPERTY_BY_NAME_VALUE("VERSION", "3.0") @@ -329,12 +337,15 @@ !strcmp(verct, "1.0")) { smlTrace(TRACE_INTERNAL, "%s: vCalendar 1.0 detected", __func__); - ctcap = smlDevInfNewCTCap(error); + + SmlDevInfContentType *ct = sml_dev_inf_content_type_new(SML_ELEMENT_TEXT_VCAL, "1.0", &gerror); + if (!ct) + goto error; + ctcap = sml_dev_inf_ctcap_new(ct, &gerror); + g_object_unref(ct); if (!ctcap) goto error; - smlDevInfCTCapSetCTType(ctcap, SML_ELEMENT_TEXT_VCAL); - smlDevInfCTCapSetVerCT(ctcap, "1.0"); _ADD_CTCAP_PROPERTY_BY_NAME("AALARM") _ADD_CTCAP_PROPERTY_BY_NAME("ATTACH") _ADD_CTCAP_PROPERTY_BY_NAME("ATTENDEE") @@ -381,12 +392,15 @@ // FIXME: this is nearly a direct copy&paste from vCal // FIXME: this is a bug in terms of iCal smlTrace(TRACE_INTERNAL, "%s: iCalendar (vCalendar 2.0) detected", __func__); - ctcap = smlDevInfNewCTCap(error); + + SmlDevInfContentType *ct = sml_dev_inf_content_type_new(SML_ELEMENT_TEXT_ICAL, "2.0", &gerror); + if (!ct) + goto error; + ctcap = sml_dev_inf_ctcap_new(ct, &gerror); + g_object_unref(ct); if (!ctcap) goto error; - smlDevInfCTCapSetCTType(ctcap, SML_ELEMENT_TEXT_ICAL); - smlDevInfCTCapSetVerCT(ctcap, "2.0"); _ADD_CTCAP_PROPERTY_BY_NAME("AALARM") _ADD_CTCAP_PROPERTY_BY_NAME("ATTACH") _ADD_CTCAP_PROPERTY_BY_NAME("ATTENDEE") @@ -429,11 +443,15 @@ { /* trace the missing stuff and create a minimal CTCap */ smlTrace(TRACE_INTERNAL, "%s: unknown content type - %s %s", __func__, VA_STRING(cttype), VA_STRING(verct)); - ctcap = smlDevInfNewCTCap(error); + + SmlDevInfContentType *ct = sml_dev_inf_content_type_new(cttype, verct, &gerror); + if (!ct) + goto error; + ctcap = sml_dev_inf_ctcap_new(ct, &gerror); + g_object_unref(ct); if (!ctcap) goto error; - smlDevInfCTCapSetCTType(ctcap, cttype); - smlDevInfCTCapSetVerCT(ctcap, verct); + smlDevInfAppendCTCap(devinf, ctcap); } Added: trunk/libsyncml/dev_inf_api/sml_dev_inf_ctcap.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ trunk/libsyncml/dev_inf_api/sml_dev_inf_ctcap.c Fri Jun 19 16:32:59 2009 (r1098) @@ -0,0 +1,249 @@ +/* sml_dev_inf_ctcap.c + * + * Copyright (C) 2009 Michael Bell <mic...@op...> + * + * 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 "sml_dev_inf_ctcap.h" +#include <libsyncml/syncml.h> + +G_DEFINE_TYPE (SmlDevInfCTCap, sml_dev_inf_ctcap, G_TYPE_OBJECT) + +enum +{ + PROP_0, + PROP_CONTENT_TYPE, + PROP_PROPERTIES +}; + +struct _SmlDevInfCTCapPrivate +{ + SmlDevInfContentType* content_type; + GList* properties; +}; + +static void +sml_dev_inf_ctcap_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_CONTENT_TYPE: + g_value_set_object (value, SML_DEV_INF_CTCAP (object)->priv->content_type); + break; + case PROP_PROPERTIES: + g_value_set_pointer (value, SML_DEV_INF_CTCAP (object)->priv->properties); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +sml_dev_inf_ctcap_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_CONTENT_TYPE: + if (SML_DEV_INF_CTCAP (object)->priv->content_type) + g_object_unref (SML_DEV_INF_CTCAP (object)->priv->content_type); + g_object_ref(SML_DEV_INF_CONTENT_TYPE (value)); + break; + SML_DEV_INF_CTCAP (object)->priv->content_type = SML_DEV_INF_CONTENT_TYPE (value); + break; + case PROP_PROPERTIES: + SML_DEV_INF_CTCAP (object)->priv->properties = (GList *) g_value_get_pointer(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +sml_dev_inf_ctcap_finalize (GObject *object) +{ + SmlDevInfCTCap *self = SML_DEV_INF_CTCAP (object); + g_object_unref(self->priv->content_type); + while(self->priv->properties) { + SmlDevInfProperty *prop = self->priv->properties->data; + self->priv->properties = g_list_remove(self->priv->properties, prop); + g_object_unref(prop); + } + G_OBJECT_CLASS (sml_dev_inf_ctcap_parent_class)->finalize (object); +} + +static void +sml_dev_inf_ctcap_class_init (SmlDevInfCTCapClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (SmlDevInfCTCapPrivate)); + + object_class->get_property = sml_dev_inf_ctcap_get_property; + object_class->set_property = sml_dev_inf_ctcap_set_property; + object_class->finalize = sml_dev_inf_ctcap_finalize; + + /** + * SmlDevInfCTCap:ContentType: + * + * The The versioned content type of the content type capabilities property. + */ + g_object_class_install_property (object_class, + PROP_CONTENT_TYPE, + g_param_spec_object ("ContentType", + "", + "The versioned content type of the content type capabilities", + G_TYPE_OBJECT, + G_PARAM_READWRITE)); + /** + * SmlDevInfCTCap:Properties: + * + * The A list of SmlDevInfProperty objects property. + */ + g_object_class_install_property (object_class, + PROP_PROPERTIES, + g_param_spec_pointer ("Properties", + "Properties", + "A list of SmlDevInfProperty objects", + G_PARAM_PRIVATE)); + +} + +static void +sml_dev_inf_ctcap_init (SmlDevInfCTCap *self) +{ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + SML_TYPE_DEV_INF_CTCAP, + SmlDevInfCTCapPrivate); +} + +/** + * sml_dev_inf_ctcap_new: + * + * Creates a new instance of #SmlDevInfCTCap. + * + * Return value: the newly created #SmlDevInfCTCap instance + */ +SmlDevInfCTCap* +sml_dev_inf_ctcap_new (SmlDevInfContentType *ct, GError **error) +{ + if (ct == NULL) { + *error = g_error_new(SML_ERROR, SML_ERROR_GENERIC, "Every CTCap must have a content type."); + return NULL; + } + SmlDevInfCTCap *self = g_object_new (SML_TYPE_DEV_INF_CTCAP, NULL); + g_object_ref(ct); + self->priv->content_type = ct; + return self; +} + +/** + * sml_dev_inf_ctcap_get_content_type: + * @self: A #SmlDevInfCTCap + * + * Gets the property. + * + * Return value: + */ +SmlDevInfContentType* +sml_dev_inf_ctcap_get_content_type (SmlDevInfCTCap *self) +{ + g_return_val_if_fail (SML_IS_DEV_INF_CTCAP (self), NULL); + return self->priv->content_type; +} + +/** + * sml_dev_inf_ctcap_set_content_type: + * @self: A #SmlDevInfCTCap + * @contenttype: + * + * Sets the property. + */ +gboolean +sml_dev_inf_ctcap_set_content_type (SmlDevInfCTCap *self, + SmlDevInfContentType *content_type, + GError **error) +{ + g_return_val_if_fail (SML_IS_DEV_INF_CTCAP (self), FALSE); + + if (content_type == NULL) { + *error = g_error_new(SML_ERROR, SML_ERROR_GENERIC, "The content type cannot be deleted only replace is allowed."); + return FALSE; + } + g_return_val_if_fail (SML_IS_DEV_INF_CONTENT_TYPE (content_type), FALSE); + + if (self->priv->content_type) + g_object_unref (self->priv->content_type); + self->priv->content_type = g_object_ref (content_type); + + return TRUE; +} + +/** + * sml_dev_inf_ctcap_num_properties: + * @self: A #SmlDevInfCTCap + * + * + */ +gsize +sml_dev_inf_ctcap_num_properties (SmlDevInfCTCap *self) +{ + g_return_val_if_fail (SML_IS_DEV_INF_CTCAP (self), 0); + return g_list_length(self->priv->properties); +} + +/** + * sml_dev_inf_ctcap_get_nth_property: + * @self: A #SmlDevInfCTCap + * + * + */ +SmlDevInfProperty* +sml_dev_inf_ctcap_get_nth_property (SmlDevInfCTCap *self, + gsize n) +{ + g_return_val_if_fail (SML_IS_DEV_INF_CTCAP (self), NULL); + return (SmlDevInfProperty *) g_list_nth_data(self->priv->properties, n); +} + +/** + * sml_dev_inf_ctcap_add_property: + * @self: A #SmlDevInfCTCap + * + * + */ +gboolean +sml_dev_inf_ctcap_add_property (SmlDevInfCTCap *self, + SmlDevInfProperty *property, + GError **error) +{ + g_return_val_if_fail (SML_IS_DEV_INF_CTCAP (self), FALSE); + if (!property) { + *error = g_error_new(SML_ERROR, SML_ERROR_GENERIC, "The SmlDevInfProperty object is missing."); + return FALSE; + } + g_object_ref(property); + self->priv->properties = g_list_append(self->priv->properties, property); + if (!self->priv->properties) { + *error = g_error_new(SML_ERROR, SML_ERROR_GENERIC, "Cannot add Property to Property list of CTCap."); + return FALSE; + } + return TRUE; +} Added: trunk/libsyncml/dev_inf_api/sml_dev_inf_ctcap.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ trunk/libsyncml/dev_inf_api/sml_dev_inf_ctcap.h Fri Jun 19 16:32:59 2009 (r1098) @@ -0,0 +1,65 @@ +/* sml_dev_inf_ctcap.h + * + * Copyright (C) 2009 Michael Bell <mic...@op...> + * + * 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 __SML_DEV_INF_CTCAP_H__ +#define __SML_DEV_INF_CTCAP_H__ + +#include <glib-object.h> +#include <libsyncml/dev_inf_api/sml_dev_inf_content_type.h> +#include <libsyncml/dev_inf_api/sml_dev_inf_property.h> + +G_BEGIN_DECLS + +#define SML_TYPE_DEV_INF_CTCAP (sml_dev_inf_ctcap_get_type()) +#define SML_DEV_INF_CTCAP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SML_TYPE_DEV_INF_CTCAP, SmlDevInfCTCap)) +#define SML_DEV_INF_CTCAP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SML_TYPE_DEV_INF_CTCAP, SmlDevInfCTCapClass)) +#define SML_IS_DEV_INF_CTCAP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SML_TYPE_DEV_INF_CTCAP)) +#define SML_IS_DEV_INF_CTCAP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SML_TYPE_DEV_INF_CTCAP)) +#define SML_DEV_INF_CTCAP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SML_TYPE_DEV_INF_CTCAP, SmlDevInfCTCapClass)) + +typedef struct _SmlDevInfCTCap SmlDevInfCTCap; +typedef struct _SmlDevInfCTCapClass SmlDevInfCTCapClass; +typedef struct _SmlDevInfCTCapPrivate SmlDevInfCTCapPrivate; + +struct _SmlDevInfCTCap +{ + GObject parent; + + /*< private >*/ + SmlDevInfCTCapPrivate *priv; +}; + +struct _SmlDevInfCTCapClass +{ + GObjectClass parent_class; + +}; + +GType sml_dev_inf_ctcap_get_type (void); +SmlDevInfCTCap* sml_dev_inf_ctcap_new (SmlDevInfContentType *contenttype, GError **error); +SmlDevInfContentType* sml_dev_inf_ctcap_get_content_type (SmlDevInfCTCap *self); +gboolean sml_dev_inf_ctcap_set_content_type (SmlDevInfCTCap *self, SmlDevInfContentType *content_type, GError **error); +gsize sml_dev_inf_ctcap_num_properties (SmlDevInfCTCap *self); +SmlDevInfProperty* sml_dev_inf_ctcap_get_nth_property (SmlDevInfCTCap *self, gsize n); +gboolean sml_dev_inf_ctcap_add_property (SmlDevInfCTCap *self, SmlDevInfProperty *property, GError **error); + +G_END_DECLS + +#endif /* __SML_DEV_INF_CTCAP_H__ */ Modified: trunk/libsyncml/parser/sml_xml_assm.c ============================================================================== --- trunk/libsyncml/parser/sml_xml_assm.c Fri Jun 19 12:59:56 2009 (r1097) +++ trunk/libsyncml/parser/sml_xml_assm.c Fri Jun 19 16:32:59 2009 (r1098) @@ -2046,7 +2046,7 @@ static SmlBool _smlXmlDevInfDataStoreAssembleCTCap( SmlXmlAssembler *assm, - const SmlDevInfCTCap *ctcap, + SmlDevInfCTCap *ctcap, SmlBool flat, SmlError **error) { @@ -2063,7 +2063,7 @@ } // add CTType - if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_CTTYPE, sml_dev_inf_content_type_get_cttype(ctcap->ct), error)) + if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_CTTYPE, sml_dev_inf_content_type_get_cttype(sml_dev_inf_ctcap_get_content_type(ctcap)), error)) goto error; // add VerCT @@ -2071,15 +2071,16 @@ // because this info is in the VERSION property. if (!flat) { - if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_VERCT, sml_dev_inf_content_type_get_verct(ctcap->ct), error)) + if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_VERCT, sml_dev_inf_content_type_get_verct(sml_dev_inf_ctcap_get_content_type(ctcap)), error)) goto error; } // add properties - GList *hprop = NULL; - for (hprop = ctcap->properties; hprop; hprop = hprop->next) + gsize ctcapPropCount = sml_dev_inf_ctcap_num_properties(ctcap); + gsize n; + for (n = 0; n < ctcapPropCount; n++) { - SmlDevInfProperty *property = hprop->data; + SmlDevInfProperty *property = sml_dev_inf_ctcap_get_nth_property(ctcap, n); if (!flat) { @@ -2334,7 +2335,7 @@ GList *hct = NULL; for (hct = contentTypes; hct; hct = hct->next) { SmlDevInfContentType *ct = hct->data; - const SmlDevInfCTCap *ctcap = smlDevInfGetCTCap(devinf, ct); + SmlDevInfCTCap *ctcap = smlDevInfGetCTCap(devinf, ct); if (ctcap != NULL) { // we found a matching CTCap Modified: trunk/libsyncml/parser/sml_xml_parse.c ============================================================================== --- trunk/libsyncml/parser/sml_xml_parse.c Fri Jun 19 12:59:56 2009 (r1097) +++ trunk/libsyncml/parser/sml_xml_parse.c Fri Jun 19 16:32:59 2009 (r1098) @@ -2659,6 +2659,7 @@ goto error; } + SmlDevInfContentType *ct = NULL; SmlDevInfCTCap *ctcap = NULL; SmlDevInfProperty *property = NULL; SmlDevInfPropParam *param = NULL; @@ -2707,21 +2708,27 @@ goto error; param = NULL; } - smlDevInfCTCapAddProperty(ctcap, property); + if (!sml_dev_inf_ctcap_add_property(ctcap, property, &gerror)) + goto error; property = NULL; } smlDevInfAppendCTCap(devinf, ctcap); ctcap = NULL; + g_object_unref(ct); + ct = NULL; } - ctcap = smlDevInfNewCTCap(error); + ct = sml_dev_inf_content_type_new(value, NULL, &gerror); + if (!ct) + goto error; + ctcap = sml_dev_inf_ctcap_new(ct, &gerror); if (!ctcap) goto error; - smlDevInfCTCapSetCTType(ctcap, value); break; case SML_DEVINF_CTCAP_VERCT: - if (ctcap == NULL) + if (ct == NULL) + goto error; + if (!sml_dev_inf_content_type_set_verct(ct, value, &gerror)) goto error; - smlDevInfCTCapSetVerCT(ctcap, value); break; case SML_DEVINF_CTCAP_PROPNAME: // PropName => new property @@ -2735,7 +2742,8 @@ goto error; param = NULL; } - smlDevInfCTCapAddProperty(ctcap, property); + if (!sml_dev_inf_ctcap_add_property(ctcap, property, &gerror)) + goto error; property = NULL; } property = sml_dev_inf_property_new(); @@ -2829,10 +2837,12 @@ } if (param != NULL && !sml_dev_inf_property_add_param(property, param, &gerror)) goto error; - if (property != NULL) - smlDevInfCTCapAddProperty(ctcap, property); + if (property != NULL && !sml_dev_inf_ctcap_add_property(ctcap, property, &gerror)) + goto error; if (ctcap != NULL) smlDevInfAppendCTCap(devinf, ctcap); + if (ct != NULL) + g_object_unref(ct); smlTrace(TRACE_EXIT, "%s", __func__); return TRUE; @@ -3060,6 +3070,11 @@ smlAssert(parser); smlAssert(devinf); + GError *gerror = NULL; + SmlDevInfContentType *ct = NULL; + SmlDevInfProperty *property = NULL; + SmlDevInfCTCap *ctcap = NULL; + /* This function was designed to parse one CTCap section */ /* which can include only one CTCap definition */ @@ -3068,11 +3083,13 @@ goto error; } - SmlDevInfCTCap *ctcap = smlDevInfNewCTCap(error); + ct = sml_dev_inf_content_type_new(NULL, NULL, &gerror); + if (!ct) + goto error; + ctcap = sml_dev_inf_ctcap_new(ct, &gerror); if (!ctcap) goto error; - SmlDevInfProperty *property; char *value = NULL; while (1) { @@ -3108,16 +3125,21 @@ switch(type) { case SML_DEVINF_CTCAP_CTTYPE: - smlDevInfCTCapSetCTType(ctcap, value); + if (!sml_dev_inf_content_type_set_cttype(ct, value, &gerror)) + goto error; break; case SML_DEVINF_CTCAP_VERCT: - smlDevInfCTCapSetVerCT(ctcap, value); + if (!sml_dev_inf_content_type_set_verct(ct, value, &gerror)) + goto error; break; case SML_DEVINF_CTCAP_PROPERTY: property = _smlXmlDevInfDataStoreParseCTCap12Property(parser, error); if (!property) goto error; - smlDevInfCTCapAddProperty(ctcap, property); + if (!sml_dev_inf_ctcap_add_property(ctcap, property, &gerror)) + goto error; + g_object_unref(property); + property = NULL; break; default: smlErrorSet(error, SML_ERROR_GENERIC, "Unknown CTCapType for CTCap: %s", elem_name); @@ -3130,12 +3152,23 @@ goto error; } } + g_object_unref(ct); smlDevInfAppendCTCap(devinf, ctcap); smlTrace(TRACE_EXIT, "%s", __func__); return TRUE; error: + if (gerror) { + smlErrorSet(error, gerror->code, "%s", gerror->message); + g_error_free(gerror); + } + if (ct) + g_object_unref(ct); + if (ctcap) + g_object_unref(ctcap); + if (property) + g_object_unref(ctcap); smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error)); if (value != NULL) smlSafeCFree(&value); Modified: trunk/libsyncml/sml_devinf.c ============================================================================== --- trunk/libsyncml/sml_devinf.c Fri Jun 19 12:59:56 2009 (r1097) +++ trunk/libsyncml/sml_devinf.c Fri Jun 19 16:32:59 2009 (r1098) @@ -146,18 +146,7 @@ while (devinf->ctcaps) { SmlDevInfCTCap *ctcap = devinf->ctcaps->data; devinf->ctcaps = g_list_remove(devinf->ctcaps, ctcap); - //smlSafeCFree(&(ctcap->ct->cttype)); - //if (ctcap->ct->verct) - // smlSafeCFree(&(ctcap->ct->verct)); - //smlSafeFree((gpointer *)&(ctcap->ct)); - g_object_unref(ctcap->ct); - while (ctcap->properties) { - SmlDevInfProperty *prop = ctcap->properties->data; - ctcap->properties = g_list_remove(ctcap->properties, prop); - g_object_unref(prop); - } - /* don't use ctcap here because the list must be cleaned up */ - smlSafeFree((gpointer *)&ctcap); + g_object_unref(ctcap); } smlSafeFree((gpointer *)&devinf); @@ -805,97 +794,6 @@ return NULL; } -/* CTCap stuff */ - -SmlDevInfCTCap *smlDevInfNewCTCap(SmlError **error) -{ - smlTrace(TRACE_ENTRY, "%s(%p)", __func__, error); - CHECK_ERROR_REF - - SmlDevInfCTCap *ctcap = smlTryMalloc0(sizeof(SmlDevInfCTCap), error); - if (!ctcap) { - smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error)); - return NULL; - } - - GError *gerror = NULL; - ctcap->ct = sml_dev_inf_content_type_new(NULL, NULL, &gerror); - if (!ctcap->ct) { - smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, gerror->message); - smlErrorSet(error, gerror->code, "%s", gerror->message); - g_error_free(gerror); - smlSafeFree((gpointer *)&ctcap); - return NULL; - } - ctcap->properties = NULL; - - smlTrace(TRACE_EXIT, "%s", __func__); - return ctcap; -} - -void smlDevInfCTCapSetCTType( - SmlDevInfCTCap *ctcap, - const char *cttype) -{ - smlTrace(TRACE_ENTRY, "%s(%p, %s)", __func__, ctcap, VA_STRING(cttype)); - smlAssert(ctcap); - smlAssert(cttype); - - GError *gerror = NULL; - sml_dev_inf_content_type_set_cttype(ctcap->ct, cttype, &gerror); - - smlTrace(TRACE_EXIT, "%s", __func__); -} - -void smlDevInfCTCapSetVerCT( - SmlDevInfCTCap *ctcap, - const char *verct) -{ - smlTrace(TRACE_ENTRY, "%s(%p, %s)", __func__, ctcap, VA_STRING(verct)); - smlAssert(ctcap); - smlAssert(verct); - - GError *gerror = NULL; - sml_dev_inf_content_type_set_verct(ctcap->ct, verct, &gerror); - - smlTrace(TRACE_EXIT, "%s", __func__); -} - -char *smlDevInfCTCapGetCTType(const SmlDevInfCTCap *ctcap) -{ - smlTrace(TRACE_ENTRY, "%s(%p)", __func__, ctcap); - smlAssert(ctcap); - char *cttype; - - cttype = g_strdup(sml_dev_inf_content_type_get_cttype(ctcap->ct)); - - smlTrace(TRACE_EXIT, "%s - %s", __func__, VA_STRING(cttype)); - return cttype; -} - -char *smlDevInfCTCapGetVerCT(const SmlDevInfCTCap *ctcap) -{ - smlTrace(TRACE_ENTRY, "%s(%p)", __func__, ctcap); - smlAssert(ctcap); - char *verct; - - verct = g_strdup(sml_dev_inf_content_type_get_verct(ctcap->ct)); - - smlTrace(TRACE_EXIT, "%s - %s", __func__, VA_STRING(verct)); - return verct; -} - -void smlDevInfCTCapAddProperty( - SmlDevInfCTCap *ctcap, - SmlDevInfProperty *property) -{ - smlTrace(TRACE_ENTRY, "%s(%p, %p)", __func__, ctcap, property); - smlAssert(ctcap); - smlAssert(property); - ctcap->properties = g_list_append(ctcap->properties, property); - smlTrace(TRACE_EXIT, "%s", __func__); -} - void smlDevInfAppendCTCap(SmlDevInf *devinf, SmlDevInfCTCap *ctcap) { smlTrace(TRACE_ENTRY, "%s(%p, %p)", __func__, devinf, ctcap); @@ -921,9 +819,9 @@ SmlDevInfCTCap *ctcap = h->data; // check that CTType matches if (!strcmp(sml_dev_inf_content_type_get_cttype(ct), - sml_dev_inf_content_type_get_cttype(ctcap->ct)) && + sml_dev_inf_content_type_get_cttype(sml_dev_inf_ctcap_get_content_type(ctcap))) && !strcmp(sml_dev_inf_content_type_get_verct(ct), - sml_dev_inf_content_type_get_verct(ctcap->ct))) + sml_dev_inf_content_type_get_verct(sml_dev_inf_ctcap_get_content_type(ctcap)))) { smlTrace(TRACE_EXIT, "%s - succeeded", __func__); return ctcap; @@ -953,26 +851,6 @@ return ctcap; } -unsigned int smlDevInfCTCapNumProperties(const SmlDevInfCTCap *ctcap) -{ - smlTrace(TRACE_ENTRY, "%s(%p)", __func__, ctcap); - smlAssert(ctcap); - unsigned int num = g_list_length(ctcap->properties); - smlTrace(TRACE_EXIT, "%s - %d", __func__, num); - return num; -} - -const SmlDevInfProperty *smlDevInfCTCapGetNthProperty( - const SmlDevInfCTCap *ctcap, - unsigned int n) -{ - smlTrace(TRACE_ENTRY, "%s(%p, %d)", __func__, ctcap, n); - smlAssert(ctcap); - SmlDevInfProperty *property = g_list_nth_data(ctcap->properties, n); - smlTrace(TRACE_EXIT, "%s - %p", __func__, property); - return property; -} - SmlDevInfSyncCap smlDevInfSyncCapConvert(unsigned int id, SmlError **error) { smlTrace(TRACE_ENTRY, "%s(%u, %p)", __func__, id, error); Modified: trunk/libsyncml/sml_devinf.h ============================================================================== --- trunk/libsyncml/sml_devinf.h Fri Jun 19 12:59:56 2009 (r1097) +++ trunk/libsyncml/sml_devinf.h Fri Jun 19 16:32:59 2009 (r1098) @@ -33,6 +33,7 @@ #include <libsyncml/dev_inf_api/sml_dev_inf_content_type.h> #include <libsyncml/dev_inf_api/sml_dev_inf_prop_param.h> #include <libsyncml/dev_inf_api/sml_dev_inf_property.h> +#include <libsyncml/dev_inf_api/sml_dev_inf_ctcap.h> SmlDevInfDevTyp smlDevInfDevTypeFromString(const char *name, SmlError **error); const char *smlDevInfDevTypeToString(SmlDevInfDevTyp type, SmlError **error); @@ -112,20 +113,8 @@ /* so we can generate SyncML 1.0, 1.1 and 1.2 devinf from this structure */ /* the CTCap will be assigned to a datastore if CTType and VerCT match */ -/* CTCap stuff */ +/* DevInf */ -SmlDevInfCTCap *smlDevInfNewCTCap(SmlError **error); -void smlDevInfCTCapSetCTType( - SmlDevInfCTCap *ctcap, - const char *cttype); // REQUIRED => NOT NULL -void smlDevInfCTCapSetVerCT( - SmlDevInfCTCap *ctcap, - const char *verct); // REQUIRED => NOT NULL -char *smlDevInfCTCapGetCTType(const SmlDevInfCTCap *ctcap); -char *smlDevInfCTCapGetVerCT(const SmlDevInfCTCap *ctcap); -void smlDevInfCTCapAddProperty( - SmlDevInfCTCap *ctcap, - SmlDevInfProperty *property); void smlDevInfAppendCTCap(SmlDevInf *devinf, SmlDevInfCTCap *ctcap); const SmlDevInfCTCap *smlDevInfGetCTCap( @@ -135,10 +124,6 @@ const SmlDevInfCTCap *smlDevInfGetNthCTCap( const SmlDevInf *devinf, unsigned int n); -unsigned int smlDevInfCTCapNumProperties(const SmlDevInfCTCap *ctcap); -const SmlDevInfProperty *smlDevInfCTCapGetNthProperty( - const SmlDevInfCTCap *ctcap, - unsigned int n); #endif //_SML_DEVINF_H_ Modified: trunk/libsyncml/syncml.h ============================================================================== --- trunk/libsyncml/syncml.h Fri Jun 19 12:59:56 2009 (r1097) +++ trunk/libsyncml/syncml.h Fri Jun 19 16:32:59 2009 (r1098) @@ -78,7 +78,7 @@ typedef struct SmlDevInf SmlDevInf; typedef struct SmlDevInfDataStore SmlDevInfDataStore; //typedef struct SmlDevInfContentType SmlDevInfContentType; -typedef struct SmlDevInfCTCap SmlDevInfCTCap; +//typedef struct SmlDevInfCTCap SmlDevInfCTCap; //typedef struct SmlDevInfProperty SmlDevInfProperty; //typedef struct SmlDevInfPropParam SmlDevInfPropParam; typedef struct SmlNotification SmlNotification; Modified: trunk/tests/CMakeLists.txt ============================================================================== --- trunk/tests/CMakeLists.txt Fri Jun 19 12:59:56 2009 (r1097) +++ trunk/tests/CMakeLists.txt Fri Jun 19 16:32:59 2009 (r1098) @@ -287,6 +287,15 @@ SML_ADD_TESTCASE( dev_inf_property_references ) SML_END_TEST() + SML_START_TEST( "DevInfCTCap" dev_inf_ctcap check_dev_inf_ctcap.c ${TEST_TARGET_LIBRARIES} ) + SML_ADD_TESTCASE( dev_inf_ctcap_create ) + SML_ADD_TESTCASE( dev_inf_ctcap_empty_set ) + SML_ADD_TESTCASE( dev_inf_ctcap_empty_get ) + SML_ADD_TESTCASE( dev_inf_ctcap_filled_set ) + SML_ADD_TESTCASE( dev_inf_ctcap_filled_get ) + SML_ADD_TESTCASE( dev_inf_ctcap_references ) + SML_END_TEST() + SML_START_TEST( "Sync" sync check_sync.c ${TEST_TARGET_LIBRARIES} ) IF ( ENABLE_HTTP ) SML_ADD_TESTCASE( sync_multi_start ) Added: trunk/tests/check_dev_inf_ctcap.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ trunk/tests/check_dev_inf_ctcap.c Fri Jun 19 16:32:59 2009 (r1098) @@ -0,0 +1,249 @@ +/* + * libsyncml - A syncml protocol implementation + * Copyright (C) 2009 Michael Bell <mic...@op...> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "tests/support.h" + +#include <libsyncml/dev_inf_api/sml_dev_inf_ctcap.h> + +START_TEST (dev_inf_ctcap_create) +{ + GError *error = NULL; + + SmlDevInfCTCap *ctcap = sml_dev_inf_ctcap_new(NULL, &error); + sml_fail_unless(ctcap == NULL, NULL); + sml_fail_unless(error != NULL, "No GError set."); + g_error_free(error); + error = NULL; + + SmlDevInfContentType *ct = sml_dev_inf_content_type_new(NULL, NULL, &error); + sml_fail_unless(ct != NULL, "%s", error?error->message:"No GError set."); + + ctcap = sml_dev_inf_ctcap_new(ct, &error); + sml_fail_unless(ctcap != NULL, "%s", error?error->message:"No GError set."); + sml_fail_unless(error == NULL, "%s", error?error->message:"No GError set."); + g_object_unref(ct); + g_object_unref(ctcap); +} +END_TEST + +START_TEST (dev_inf_ctcap_empty_set) +{ + GError *error = NULL; + SmlDevInfContentType *ct = sml_dev_inf_content_type_new(NULL, NULL, &error); + sml_fail_unless(ct != NULL, "%s", error?error->message:"No GError set."); + sml_fail_unless(error == NULL, "%s", error?error->message:"No GError set."); + SmlDevInfCTCap *ctcap = sml_dev_inf_ctcap_new(ct, &error); + sml_fail_unless(ctcap != NULL, "%s", error?error->message:"No GError set."); + sml_fail_unless(error == NULL, "%s", error?error->message:"No GError set."); + g_object_unref(ct); + ct = NULL; + + /* test enforcement of content type */ + + sml_fail_unless(sml_dev_inf_ctcap_set_content_type(ctcap, NULL, &error) == FALSE, NULL); + sml_fail_unless(error != NULL, "No GError set."); + g_error_free(error); + error = NULL; + + /* property checks must be a little bit more careful */ + + sml_fail_unless(sml_dev_inf_ctcap_add_property(ctcap, NULL, &error) == FALSE, "Empty properties must fail."); + sml_fail_unless(error != NULL, "No GError set."); + g_error_free(error); + error = NULL; + + SmlDevInfProperty *prop = sml_dev_inf_property_new(); + sml_fail_unless(prop != NULL, NULL); + sml_fail_unless(sml_dev_inf_ctcap_add_property(ctcap, prop, &error) == TRUE, "%s", error?error->message:"No GError set."); + g_object_unref(prop); + prop = NULL; + + sml_fail_unless(sml_dev_inf_ctcap_add_property(ctcap, NULL, &error) == FALSE, "Empty properties must fail."); + sml_fail_unless(error != NULL, "No GError set."); + g_error_free(error); + error = NULL; + + g_object_unref(ctcap); +} +END_TEST + +START_TEST (dev_inf_ctcap_empty_get) +{ + GError *error = NULL; + SmlDevInfContentType *ct = sml_dev_inf_content_type_new(NULL, NULL, &error); + sml_fail_unless(ct != NULL, "%s", error?error->message:"No GError set."); + sml_fail_unless(error == NULL, "%s", error?error->message:"No GError set."); + SmlDevInfCTCap *ctcap = sml_dev_inf_ctcap_new(ct, &error); + sml_fail_unless(ctcap != NULL, "%s", error?error->message:"No GError set."); + sml_fail_unless(error == NULL, "%s", error?error->message:"No GError set."); + + /* test enforcement of content type */ + + sml_fail_unless(sml_dev_inf_ctcap_set_content_type(ctcap, NULL, &error) == FALSE, NULL); + sml_fail_unless(error != NULL, "No GError set."); + g_error_free(error); + error = NULL; + sml_fail_unless(sml_dev_inf_ctcap_get_content_type(ctcap) == ct, "The original content type was replaced."); + g_object_unref(ct); + ct = NULL; + + /* property checks must be a little bit more careful */ + + sml_fail_unless(sml_dev_inf_ctcap_add_property(ctcap, NULL, &error) == FALSE, "Empty properties must fail."); + sml_fail_unless(error != NULL, "No GError set."); + g_error_free(error); + error = NULL; + sml_fail_unless(sml_dev_inf_ctcap_num_properties(ctcap) == 0, NULL); + + SmlDevInfProperty *prop = sml_dev_inf_property_new(); + sml_fail_unless(prop != NULL, NULL); + sml_fail_unless(sml_dev_inf_ctcap_add_property(ctcap, prop, &error) == TRUE, "%s", error?error->message:"No GError set."); + g_object_unref(prop); + prop = NULL; + sml_fail_unless(sml_dev_inf_ctcap_num_properties(ctcap) == 1, NULL); + + sml_fail_unless(sml_dev_inf_ctcap_add_property(ctcap, NULL, &error) == FALSE, "Empty properties must fail."); + sml_fail_unless(error != NULL, "No GError set."); + g_error_free(error); + error = NULL; + sml_fail_unless(sml_dev_inf_ctcap_num_properties(ctcap) == 1, NULL); + + g_object_unref(ctcap); +} +END_TEST + +START_TEST (dev_inf_ctcap_filled_set) +{ + GError *error = NULL; + SmlDevInfContentType *ct = sml_dev_inf_content_type_new(NULL, NULL, &error); + sml_fail_unless(ct != NULL, "%s", error?error->message:"No GError set."); + sml_fail_unless(error == NULL, "%s", error?error->message:"No GError set."); + SmlDevInfCTCap *ctcap = sml_dev_inf_ctcap_new(ct, &error); + sml_fail_unless(ctcap != NULL, "%s", error?error->message:"No GError set."); + sml_fail_unless(error == NULL, "%s", error?error->message:"No GError set."); + g_object_unref(ct); + ct = NULL; + + /* content type related tests */ + + ct = sml_dev_inf_content_type_new(NULL, NULL, &error); + sml_fail_unless(ct != NULL, "%s", error?error->message:"No GError set."); + + sml_fail_unless(sml_dev_inf_ctcap_set_content_type(ctcap, ct, &error), "%s", error?error->message:"No GError set."); + + g_object_unref(ct); + ct = NULL; + + /* property related tests */ + + SmlDevInfProperty *prop = sml_dev_inf_property_new(); + sml_fail_unless(prop != NULL, NULL); + sml_fail_unless(sml_dev_inf_ctcap_add_property(ctcap, prop, &error) == TRUE, "%s", error?error->message:"No GError set."); + g_object_unref(prop); + prop = NULL; + + prop = sml_dev_inf_property_new(); + sml_fail_unless(prop != NULL, NULL); + sml_fail_unless(sml_dev_inf_ctcap_add_property(ctcap, prop, &error) == TRUE, "%s", error?error->message:"No GError set."); + g_object_unref(prop); + prop = NULL; + + g_object_unref(ctcap); +} +END_TEST + +START_TEST (dev_inf_ctcap_filled_get) +{ + GError *error = NULL; + SmlDevInfContentType *ct = sml_dev_inf_content_type_new(NULL, NULL, &error); + sml_fail_unless(ct != NULL, "%s", error?error->message:"No GError set."); + sml_fail_unless(error == NULL, "%s", error?error->message:"No GError set."); + SmlDevInfCTCap *ctcap = sml_dev_inf_ctcap_new(ct, &error); + sml_fail_unless(ctcap != NULL, "%s", error?error->message:"No GError set."); + sml_fail_unless(error == NULL, "%s", error?error->message:"No GError set."); + + /* content type related tests */ + + sml_fail_unless(sml_dev_inf_ctcap_get_content_type(ctcap) == ct, "The original content type is missing."); + g_object_unref(ct); + ct = NULL; + + ct = sml_dev_inf_content_type_new(NULL, NULL, &error); + sml_fail_unless(ct != NULL, "%s", error?error->message:"No GError set."); + sml_fail_unless(sml_dev_inf_ctcap_set_content_type(ctcap, ct, &error), "%s", error?error->message:"No GError set."); + sml_fail_unless(sml_dev_inf_ctcap_get_content_type(ctcap) != NULL, NULL); + sml_fail_unless(sml_dev_inf_ctcap_get_content_type(ctcap) == ct, NULL); + g_object_unref(ct); + ct = NULL; + + /* property related tests */ + + sml_fail_unless(sml_dev_inf_ctcap_num_properties(ctcap) == 0, NULL); + + SmlDevInfProperty *prop = sml_dev_inf_property_new(); + sml_fail_unless(prop != NULL, NULL); + sml_fail_unless(sml_dev_inf_ctcap_add_property(ctcap, prop, &error) == TRUE, "%s", error?error->message:"No GError set."); + g_object_unref(prop); + prop = NULL; + sml_fail_unless(sml_dev_inf_ctcap_num_properties(ctcap) == 1, NULL); + + sml_fail_unless(sml_dev_inf_ctcap_add_property(ctcap, NULL, &error) == FALSE, "Empty properties must fail."); + sml_fail_unless(error != NULL, "No GError set."); + g_error_free(error); + error = NULL; + sml_fail_unless(sml_dev_inf_ctcap_num_properties(ctcap) == 1, NULL); + + prop = sml_dev_inf_property_new(); + sml_fail_unless(prop != NULL, NULL); + sml_fail_unless(sml_dev_inf_ctcap_add_property(ctcap, prop, &error) == TRUE, "%s", error?error->message:"No GError set."); + g_object_unref(prop); + prop = NULL; + sml_fail_unless(sml_dev_inf_ctcap_num_properties(ctcap) == 2, NULL); + + g_object_unref(prop); +} +END_TEST + +START_TEST (dev_inf_ctcap_references) +{ + GError *error = NULL; + SmlDevInfContentType *ct = sml_dev_inf_content_type_new(NULL, NULL, &error); + sml_fail_unless(ct != NULL, "%s", error?error->message:"No GError set."); + sml_fail_unless(error == NULL, "%s", error?error->message:"No GError set."); + SmlDevInfCTCap *ctcap = sml_dev_inf_ctcap_new(ct, &error); + sml_fail_unless(ctcap != NULL, "%s", error?error->message:"No GError set."); + sml_fail_unless(error == NULL, "%s", error?error->message:"No GError set."); + g_object_unref(ct); + ct = NULL; + + g_object_ref(ctcap); + + sml_fail_unless(sml_dev_inf_ctcap_get_content_type(ctcap) != NULL, "The content type was not set."); + + g_object_unref(ctcap); + + sml_fail_unless(sml_dev_inf_ctcap_get_content_type(ctcap) != NULL, "The content type is already cleaned up."); + + g_object_unref(ctcap); +} +END_TEST + +@SML_TESTCASE_CODE@ + |