aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libical/ChangeLog47
-rw-r--r--libical/design-data/value-c-types.txt2
-rw-r--r--libical/design-data/value-mem-semantics.txt2
-rw-r--r--libical/design-data/value-types.csv2
-rw-r--r--libical/src/libical/Makefile.am4
-rw-r--r--libical/src/libical/icalderivedvalue.c.in44
-rw-r--r--libical/src/libical/icalderivedvalue.h.in7
-rw-r--r--libical/src/libical/icaltypes.c146
-rw-r--r--libical/src/libical/icaltypes.h25
-rw-r--r--libical/src/libical/icalvalue.c65
-rw-r--r--libical/src/libical/icalvalueimpl.h30
11 files changed, 249 insertions, 125 deletions
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 <federico@ximian.com>
+
+ 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 <damon@ximian.com>
* 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 <stdlib.h> /* for malloc and abs() */
#include <errno.h> /* for errno */
#include <string.h> /* 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