From 2be48d88552a96878124e71efdbd00e8601da4fe Mon Sep 17 00:00:00 2001 From: Federico Mena Quintero Date: Mon, 10 Sep 2001 21:54:44 +0000 Subject: Replace struct icalattachtype by an opaque icalattach that is properly 2001-09-10 Federico Mena Quintero Replace struct icalattachtype by an opaque icalattach that is properly reference-counted. * src/libical/icalvalueimpl.h (struct icalattach_impl): Private declaration for the icalattach type. (struct icalvalue_impl): Make the v_attach field be an icalattach *. * src/libical/icaltypes.h: Added declaration for icalattach. This is now an opaque type; the implementation is in icalvalueimpl.h. (struct icalattachtype): Removed. * src/libical/icaltypes.c (icalattach_new_from_url): New function. (icalattach_new_from_data): New function. (icalattach_ref): New function. (icalattach_unref): New function. (icalattach_get_is_url): New function. (icalattach_get_url): New function. (icalattach_get_data): New function. (icalattachtype_new): Removed. (icalattachtype_free): Removed. (icalattachtype_add_reference): Removed. (icalattachtype_set_url): Removed. (icalattachtype_get_url): Removed. (icalattachtype_set_base64): Removed. (icalattachtype_get_base64): Removed. (icalattachtype_set_binary): Removed. (icalattachtype_get_binary): Removed. * src/libical/icalderivedvalue.c.in (icalvalue_new_attach): New function; we implement it ourselves. (icalvalue_set_attach): New function. (icalvalue_get_attach): New function. * src/libical/icalvalue.c (icalmemory_strdup_and_dequote): Made static. (icalvalue_new_clone): Clone BINARY and ATTACH values by refing the old attach value. (icalvalue_free): Free BINARY and ATTACH values. (icalvalue_attach_as_ical_string): Handle the new icalattachtype. (icalvalue_compare): Ditto. * src/libical/Makefile.am (CLEANFILES): Added ical.h. * design-data/*: Mark ATTACH as a custom value. svn path=/trunk/; revision=12745 --- libical/ChangeLog | 47 +++++++++ libical/design-data/value-c-types.txt | 2 +- libical/design-data/value-mem-semantics.txt | 2 +- libical/design-data/value-types.csv | 2 +- libical/src/libical/Makefile.am | 4 +- libical/src/libical/icalderivedvalue.c.in | 44 ++++++++- libical/src/libical/icalderivedvalue.h.in | 7 +- libical/src/libical/icaltypes.c | 146 +++++++++++++--------------- libical/src/libical/icaltypes.h | 25 +++-- libical/src/libical/icalvalue.c | 65 ++++++++----- libical/src/libical/icalvalueimpl.h | 30 +++++- 11 files changed, 249 insertions(+), 125 deletions(-) (limited to 'libical') diff --git a/libical/ChangeLog b/libical/ChangeLog index bd481341ce..984e40cfc7 100644 --- a/libical/ChangeLog +++ b/libical/ChangeLog @@ -1,3 +1,50 @@ +2001-09-10 Federico Mena Quintero + + Replace struct icalattachtype by an opaque icalattach that is + properly reference-counted. + + * src/libical/icalvalueimpl.h (struct icalattach_impl): Private + declaration for the icalattach type. + (struct icalvalue_impl): Make the v_attach field be an icalattach *. + + * src/libical/icaltypes.h: Added declaration for icalattach. This + is now an opaque type; the implementation is in icalvalueimpl.h. + (struct icalattachtype): Removed. + + * src/libical/icaltypes.c (icalattach_new_from_url): New function. + (icalattach_new_from_data): New function. + (icalattach_ref): New function. + (icalattach_unref): New function. + (icalattach_get_is_url): New function. + (icalattach_get_url): New function. + (icalattach_get_data): New function. + (icalattachtype_new): Removed. + (icalattachtype_free): Removed. + (icalattachtype_add_reference): Removed. + (icalattachtype_set_url): Removed. + (icalattachtype_get_url): Removed. + (icalattachtype_set_base64): Removed. + (icalattachtype_get_base64): Removed. + (icalattachtype_set_binary): Removed. + (icalattachtype_get_binary): Removed. + + * src/libical/icalderivedvalue.c.in (icalvalue_new_attach): New + function; we implement it ourselves. + (icalvalue_set_attach): New function. + (icalvalue_get_attach): New function. + + * src/libical/icalvalue.c (icalmemory_strdup_and_dequote): Made + static. + (icalvalue_new_clone): Clone BINARY and ATTACH values by refing + the old attach value. + (icalvalue_free): Free BINARY and ATTACH values. + (icalvalue_attach_as_ical_string): Handle the new icalattachtype. + (icalvalue_compare): Ditto. + + * src/libical/Makefile.am (CLEANFILES): Added ical.h. + + * design-data/*: Mark ATTACH as a custom value. + 2001-09-06 Damon Chaplin * src/libical/icalcomponent.c (icalcomponent_merge_vtimezone): pass diff --git a/libical/design-data/value-c-types.txt b/libical/design-data/value-c-types.txt index a171b31171..9b445655d9 100644 --- a/libical/design-data/value-c-types.txt +++ b/libical/design-data/value-c-types.txt @@ -1,4 +1,4 @@ -ATTACH autogen struct icalattachtype # Non-std +ATTACH nogen icalattach * BINARY autogen const char* BOOLEAN autogen int CAL-ADDRESS autogen const char* diff --git a/libical/design-data/value-mem-semantics.txt b/libical/design-data/value-mem-semantics.txt index 5948e244f6..ce085ede80 100644 --- a/libical/design-data/value-mem-semantics.txt +++ b/libical/design-data/value-mem-semantics.txt @@ -1,4 +1,4 @@ -ATTACH struct icalattachtype +ATTACH icalattach * BINARY char* BOOLEAN int CAL-ADDRESS char* diff --git a/libical/design-data/value-types.csv b/libical/design-data/value-types.csv index cbe6bd9969..654307097e 100644 --- a/libical/design-data/value-types.csv +++ b/libical/design-data/value-types.csv @@ -15,7 +15,7 @@ "UTC-OFFSET","(a)int","integer","unitary", "QUERY","(a)const char*","string","unitary", "#Non-standard multi-valued types",,,, -"ATTACH","(a)struct icalattachtype","none","URI;BINARY", +"ATTACH","(m)icalattach *","none","URI;BINARY", "DATE-TIME-DATE","(a)struct icaltimetype","none","DATE-TIME;DATE", "DATE-TIME-PERIOD","(m)struct icaldatetimeperiodtype","none","DATE-TIME;PERIOD", "TRIGGER","(m)struct icaltriggertype","string","DURATION;DATE-TIME", diff --git a/libical/src/libical/Makefile.am b/libical/src/libical/Makefile.am index 9e1a6da9ca..e27f77e5ba 100644 --- a/libical/src/libical/Makefile.am +++ b/libical/src/libical/Makefile.am @@ -2,7 +2,7 @@ # FILE: Makefile.am # CREATOR: eric # -# $Id: Makefile.am,v 1.30 2001/06/14 02:50:46 damon Exp $ +# $Id: Makefile.am,v 1.31 2001/09/10 21:54:44 federico Exp $ # # # (C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org @@ -217,7 +217,7 @@ icalderivedvalue.c: $(VALUEDEPS) $(BUILT_COMBINEDHEADERS) # housekeeping CONFIG_CLEAN_FILES = y.output -CLEANFILES += $(BUILT_SOURCES) +CLEANFILES += $(BUILT_SOURCES) ical.h dist-hook: cd $(distdir); rm -f $(BUILT_SOURCES) diff --git a/libical/src/libical/icalderivedvalue.c.in b/libical/src/libical/icalderivedvalue.c.in index 420ffb9ef0..8dac43a788 100644 --- a/libical/src/libical/icalderivedvalue.c.in +++ b/libical/src/libical/icalderivedvalue.c.in @@ -3,7 +3,7 @@ FILE: icalvalue.c CREATOR: eric 02 May 1999 - $Id: icalderivedvalue.c.in,v 1.1 2001/04/17 17:23:17 jpr Exp $ + $Id: icalderivedvalue.c.in,v 1.2 2001/09/10 21:54:44 federico Exp $ (C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org @@ -284,12 +284,54 @@ icalvalue_get_datetimeperiod(icalvalue* value) return dtp; } +icalvalue * +icalvalue_new_attach (icalattach *attach) +{ + struct icalvalue_impl *impl; + + icalerror_check_arg_rz ((attach != NULL), "attach"); + + impl = icalvalue_new_impl (ICAL_ATTACH_VALUE); + if (!impl) { + errno = ENOMEM; + return NULL; + } + icalvalue_set_attach ((icalvalue *) impl, attach); + return (icalvalue *) impl; +} + +void +icalvalue_set_attach (icalvalue *value, icalattach *attach) +{ + struct icalvalue_impl *impl; + icalerror_check_arg_rv ((value != NULL), "value"); + icalerror_check_value_type (value, ICAL_ATTACH_VALUE); + icalerror_check_arg_rv ((attach != NULL), "attach"); + impl = (struct icalvalue_impl *) value; + icalattach_ref (attach); + if (impl->data.v_attach) + icalattach_unref (impl->data.v_attach); + impl->data.v_attach = attach; +} + +icalattach * +icalvalue_get_attach (icalvalue *value) +{ + struct icalvalue_impl *impl; + + icalerror_check_arg_rz ((value != NULL), "value"); + icalerror_check_value_type (value, ICAL_ATTACH_VALUE); + + impl = (struct icalvalue_impl *) value; + + return impl->data.v_attach; +} /* The remaining interfaces are 'new', 'set' and 'get' for each of the value diff --git a/libical/src/libical/icalderivedvalue.h.in b/libical/src/libical/icalderivedvalue.h.in index 640dd86821..d043ac4048 100644 --- a/libical/src/libical/icalderivedvalue.h.in +++ b/libical/src/libical/icalderivedvalue.h.in @@ -4,7 +4,7 @@ CREATOR: eric 20 March 1999 - $Id: icalderivedvalue.h.in,v 1.1 2001/04/17 17:23:17 jpr Exp $ + $Id: icalderivedvalue.h.in,v 1.2 2001/09/10 21:54:44 federico Exp $ $Locker: $ @@ -38,7 +38,6 @@ typedef void icalvalue; - void icalvalue_set_x(icalvalue* value, const char* v); icalvalue* icalvalue_new_x(const char* v); const char* icalvalue_get_x(icalvalue* value); @@ -55,4 +54,8 @@ icalvalue* icalvalue_new_datetimeperiod (struct icaldatetimeperiodtype v); void icalvalue_set_datetimeperiod(icalvalue* value, struct icaldatetimeperiodtype v); struct icaldatetimeperiodtype icalvalue_get_datetimeperiod(icalvalue* value); +icalvalue *icalvalue_new_attach (icalattach *attach); +void icalvalue_set_attach (icalvalue *value, icalattach *attach); +icalattach *icalvalue_get_attach (icalvalue *value); + /* Everything below this line is machine generated. Do not edit. */ diff --git a/libical/src/libical/icaltypes.c b/libical/src/libical/icaltypes.c index c6c388a978..cbb574992b 100644 --- a/libical/src/libical/icaltypes.c +++ b/libical/src/libical/icaltypes.c @@ -30,6 +30,7 @@ #include "icaltypes.h" #include "icalerror.h" #include "icalmemory.h" +#include "icalvalueimpl.h" #include /* for malloc and abs() */ #include /* for errno */ #include /* for icalmemory_strdup */ @@ -37,115 +38,106 @@ #define TEMP_MAX 1024 -void* -icalattachtype_get_data (struct icalattachtype* type); - -struct icalattachtype* -icalattachtype_new() +icalattach * +icalattach_new_from_url (const char *url) { - struct icalattachtype* v; + icalattach *attach; + char *url_copy; + + icalerror_check_arg_rz ((url != NULL), "url"); - if ( ( v = (struct icalattachtype*) - malloc(sizeof(struct icalattachtype))) == 0) { + if ((attach = malloc (sizeof (icalattach))) == NULL) { errno = ENOMEM; - return 0; + return NULL; } - v->refcount = 1; - - v->binary = 0; - v->owns_binary = 0; - - v->base64 = 0; - v->owns_base64 = 0; + if ((url_copy = strdup (url)) == NULL) { + free (attach); + errno = ENOMEM; + return NULL; + } - v->url = 0; + attach->refcount = 1; + attach->is_url = 1; + attach->u.url.url = url_copy; - return v; + return attach; } - -void -icalattachtype_free(struct icalattachtype* v) +icalattach * +icalattach_new_from_data (const unsigned char *data, icalattach_free_fn_t free_fn, + void *free_fn_data) { - icalerror_check_arg( (v!=0),"v"); - - v->refcount--; - - if (v->refcount <= 0){ - - if (v->base64 != 0 && v->owns_base64 != 0){ - free(v->base64); - } - - if (v->binary != 0 && v->owns_binary != 0){ - free(v->binary); - } - - if (v->url != 0){ - free(v->url); - } - - free(v); - } -} + icalattach *attach; -void icalattachtype_add_reference(struct icalattachtype* v) -{ - icalerror_check_arg( (v!=0),"v"); - v->refcount++; -} + icalerror_check_arg_rz ((data != NULL), "data"); -void icalattachtype_set_url(struct icalattachtype* v, char* url) -{ - icalerror_check_arg( (v!=0),"v"); - - if (v->url != 0){ - free (v->url); + if ((attach = malloc (sizeof (icalattach))) == NULL) { + errno = ENOMEM; + return NULL; } - v->url = icalmemory_strdup(url); - - /* HACK This routine should do something if icalmemory_strdup returns NULL */ + attach->refcount = 1; + attach->is_url = 0; + attach->u.data.data = (unsigned char *) data; + attach->u.data.free_fn = free_fn; + attach->u.data.free_fn_data = free_fn_data; + return attach; } -char* icalattachtype_get_url(struct icalattachtype* v) +void +icalattach_ref (icalattach *attach) { - icalerror_check_arg( (v!=0),"v"); - return v->url; + icalerror_check_arg_rv ((attach != NULL), "attach"); + icalerror_check_arg_rv ((attach->refcount > 0), "attach->refcount > 0"); + + attach->refcount++; } -void icalattachtype_set_base64(struct icalattachtype* v, char* base64, - int owns) +void +icalattach_unref (icalattach *attach) { - icalerror_check_arg( (v!=0),"v"); + icalerror_check_arg_rv ((attach != NULL), "attach"); + icalerror_check_arg_rv ((attach->refcount > 0), "attach->refcount > 0"); - v->base64 = base64; - v->owns_base64 = !(owns != 0 ); - + attach->refcount--; + + if (attach->refcount != 0) + return; + + if (attach->is_url) + free (attach->u.url.url); + else if (attach->u.data.free_fn) + (* attach->u.data.free_fn) (attach->u.data.data, attach->u.data.free_fn_data); + + free (attach); } -char* icalattachtype_get_base64(struct icalattachtype* v) +int +icalattach_get_is_url (icalattach *attach) { - icalerror_check_arg( (v!=0),"v"); - return v->base64; + icalerror_check_arg_rz ((attach != NULL), "attach"); + + return attach->is_url ? 1 : 0; } -void icalattachtype_set_binary(struct icalattachtype* v, char* binary, - int owns) +const char * +icalattach_get_url (icalattach *attach) { - icalerror_check_arg( (v!=0),"v"); - - v->binary = binary; - v->owns_binary = !(owns != 0 ); + icalerror_check_arg_rz ((attach != NULL), "attach"); + icalerror_check_arg_rz ((attach->is_url), "attach->is_url"); + return attach->u.url.url; } -void* icalattachtype_get_binary(struct icalattachtype* v) +unsigned char * +icalattach_get_data (icalattach *attach) { - icalerror_check_arg( (v!=0),"v"); - return v->binary; + icalerror_check_arg_rz ((attach != NULL), "attach"); + icalerror_check_arg_rz ((!attach->is_url), "!attach->is_url"); + + return attach->u.data.data; } diff --git a/libical/src/libical/icaltypes.h b/libical/src/libical/icaltypes.h index 04e04c9dc3..916fef7323 100644 --- a/libical/src/libical/icaltypes.h +++ b/libical/src/libical/icaltypes.h @@ -30,24 +30,23 @@ #include "icalduration.h" #include "icalperiod.h" +typedef struct icalattach_impl icalattach; -/* This type type should probably be an opaque type... */ -struct icalattachtype -{ - void* binary; - int owns_binary; +typedef void (* icalattach_free_fn_t) (unsigned char *data, void *user_data); - char* base64; - int owns_base64; +/* converts base64 to binary, fetches url and stores as binary, or + just returns data */ - char* url; +icalattach *icalattach_new_from_url (const char *url); +icalattach *icalattach_new_from_data (const unsigned char *data, icalattach_free_fn_t free_fn, + void *free_fn_data); - int refcount; +void icalattach_ref (icalattach *attach); +void icalattach_unref (icalattach *attach); -}; - -/* converts base64 to binary, fetches url and stores as binary, or - just returns data */ +int icalattach_get_is_url (icalattach *attach); +const char *icalattach_get_url (icalattach *attach); +unsigned char *icalattach_get_data (icalattach *attach); struct icalattachtype* icalattachtype_new(void); void icalattachtype_add_reference(struct icalattachtype* v); diff --git a/libical/src/libical/icalvalue.c b/libical/src/libical/icalvalue.c index 0010c391f6..6b887d3be5 100644 --- a/libical/src/libical/icalvalue.c +++ b/libical/src/libical/icalvalue.c @@ -88,8 +88,9 @@ icalvalue_new (icalvalue_kind kind) return (icalvalue*)icalvalue_new_impl(kind); } -icalvalue* icalvalue_new_clone(icalvalue* value){ - +icalvalue* +icalvalue_new_clone(icalvalue* value) +{ struct icalvalue_impl* new; struct icalvalue_impl* old = (struct icalvalue_impl*)value; @@ -105,13 +106,18 @@ icalvalue* icalvalue_new_clone(icalvalue* value){ new->size = old->size; switch (new->kind){ - - /* The contents of the attach value may or may not be owned by the - * library. */ case ICAL_ATTACH_VALUE: case ICAL_BINARY_VALUE: { - /* HACK ugh. I don't feel like impleenting this */ + /* Hmm. We just ref the attach value, which may not be the right + * thing to do. We cannot quite copy the data, anyways, since we + * don't know how long it is. + */ + new->data.v_attach = old->data.v_attach; + if (new->data.v_attach) + icalattach_ref (new->data.v_attach); + + break; } case ICAL_STRING_VALUE: @@ -156,7 +162,7 @@ icalvalue* icalvalue_new_clone(icalvalue* value){ return new; } -char* icalmemory_strdup_and_dequote(const char* str) +static char* icalmemory_strdup_and_dequote(const char* str) { const char* p; char* out = (char*)malloc(sizeof(char) * strlen(str) +1); @@ -257,7 +263,8 @@ icalvalue* icalvalue_new_enum(icalvalue_kind kind, int x_type, const char* str) } -icalvalue* icalvalue_new_from_string_with_error(icalvalue_kind kind,const char* str,icalproperty** error) +icalvalue* +icalvalue_new_from_string_with_error(icalvalue_kind kind,const char* str,icalproperty** error) { struct icalvalue_impl *value = 0; @@ -511,7 +518,12 @@ icalvalue_free (icalvalue* value) switch (v->kind){ case ICAL_BINARY_VALUE: case ICAL_ATTACH_VALUE: { - /* HACK ugh. This will be tough to implement */ + if (v->data.v_attach) { + icalattach_unref (v->data.v_attach); + v->data.v_attach = NULL; + } + + break; } case ICAL_TEXT_VALUE: case ICAL_CALADDRESS_VALUE: @@ -734,27 +746,25 @@ char* icalvalue_text_as_ical_string(icalvalue* value) { } -char* icalvalue_attach_as_ical_string(icalvalue* value) { - - struct icalattachtype a; +char* +icalvalue_attach_as_ical_string(icalvalue* value) +{ + icalattach *a; char * str; icalerror_check_arg_rz( (value!=0),"value"); a = icalvalue_get_attach(value); - if (a.binary != 0) { - return icalvalue_binary_as_ical_string(value); - } else if (a.base64 != 0) { - str = (char*)icalmemory_tmp_buffer(strlen(a.base64)+1); - strcpy(str,a.base64); + if (icalattach_get_is_url (a)) { + const char *url; + + url = icalattach_get_url (a); + str = icalmemory_tmp_buffer (strlen (url) + 1); + strcpy (str, url); return str; - } else if (a.url != 0){ - return icalvalue_string_as_ical_string(value); - } else { - icalerrno = ICAL_MALFORMEDDATA_ERROR; - return 0; - } + } else + return icalvalue_binary_as_ical_string (value); } @@ -1081,9 +1091,14 @@ icalvalue_compare(icalvalue* a, icalvalue *b) } switch (icalvalue_isa(a)){ - case ICAL_ATTACH_VALUE: - case ICAL_BINARY_VALUE: + case ICAL_BINARY_VALUE: + { + if (impla->data.v_attach == implb->data.v_attach) + return ICAL_XLICCOMPARETYPE_EQUAL; + else + return ICAL_XLICCOMPARETYPE_NOTEQUAL; + } case ICAL_BOOLEAN_VALUE: { diff --git a/libical/src/libical/icalvalueimpl.h b/libical/src/libical/icalvalueimpl.h index b103c9cb3f..8d39e6ca7f 100644 --- a/libical/src/libical/icalvalueimpl.h +++ b/libical/src/libical/icalvalueimpl.h @@ -35,7 +35,31 @@ #define ICALVALUEIMPL_H #include "icalenums.h" - +#include "icalderivedvalue.h" +#include "icalderivedproperty.h" + +/* Private structure for ATTACH values */ +struct icalattach_impl { + /* Reference count */ + int refcount; + + union { + /* URL attachment data */ + struct { + char *url; + } url; + + /* Inline data */ + struct { + unsigned char *data; + icalattach_free_fn_t free_fn; + void *free_fn_data; + } data; + } u; + + /* TRUE if URL, FALSE if inline data */ + unsigned int is_url : 1; +}; struct icalvalue_impl { icalvalue_kind kind; /*this is the kind that is visible from the outside*/ @@ -46,7 +70,7 @@ struct icalvalue_impl { const char* x_value; union data { - struct icalattachtype v_attach; + icalattach *v_attach; /* void *v_binary; */ /* use v_attach */ const char *v_string; /*char *v_text;*/ @@ -88,4 +112,6 @@ struct icalvalue_impl { } data; }; +struct icalvalue_impl *icalvalue_new_impl(icalvalue_kind kind); + #endif -- cgit v1.2.3