Replace struct icalattachtype by an opaque icalattach that is properly

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.

svn path=/trunk/; revision=12745
This commit is contained in:
Federico Mena Quintero
2001-09-10 21:54:44 +00:00
committed by Federico Mena Quintero
parent 3240dc4afc
commit 2be48d8855
11 changed files with 254 additions and 130 deletions

View File

@ -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

View File

@ -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*

View File

@ -1,4 +1,4 @@
ATTACH struct icalattachtype
ATTACH icalattach *
BINARY char*
BOOLEAN int
CAL-ADDRESS char*

View File

@ -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",

1 #Name C type& gen flag Python Component Values Enum Values
15 UTC-OFFSET (a)int integer unitary
16 QUERY (a)const char* string unitary
17 #Non-standard multi-valued types
18 ATTACH (a)struct icalattachtype (m)icalattach * none URI;BINARY
19 DATE-TIME-DATE (a)struct icaltimetype none DATE-TIME;DATE
20 DATE-TIME-PERIOD (m)struct icaldatetimeperiodtype none DATE-TIME;PERIOD
21 TRIGGER (m)struct icaltriggertype string DURATION;DATE-TIME

View File

@ -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)

View File

@ -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

View File

@ -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. */

View File

@ -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;
if ( ( v = (struct icalattachtype*)
malloc(sizeof(struct icalattachtype))) == 0) {
icalerror_check_arg_rz ((url != NULL), "url");
if ((attach = malloc (sizeof (icalattach))) == NULL) {
errno = ENOMEM;
return 0;
return NULL;
}
v->refcount = 1;
if ((url_copy = strdup (url)) == NULL) {
free (attach);
errno = ENOMEM;
return NULL;
}
v->binary = 0;
v->owns_binary = 0;
attach->refcount = 1;
attach->is_url = 1;
attach->u.url.url = url_copy;
v->base64 = 0;
v->owns_base64 = 0;
v->url = 0;
return v;
return attach;
}
icalattach *
icalattach_new_from_data (const unsigned char *data, icalattach_free_fn_t free_fn,
void *free_fn_data)
{
icalattach *attach;
icalerror_check_arg_rz ((data != NULL), "data");
if ((attach = malloc (sizeof (icalattach))) == NULL) {
errno = ENOMEM;
return 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;
}
void
icalattachtype_free(struct icalattachtype* v)
icalattach_ref (icalattach *attach)
{
icalerror_check_arg( (v!=0),"v");
v->refcount--;
icalerror_check_arg_rv ((attach != NULL), "attach");
icalerror_check_arg_rv ((attach->refcount > 0), "attach->refcount > 0");
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);
}
attach->refcount++;
}
void icalattachtype_add_reference(struct icalattachtype* v)
void
icalattach_unref (icalattach *attach)
{
icalerror_check_arg( (v!=0),"v");
v->refcount++;
icalerror_check_arg_rv ((attach != NULL), "attach");
icalerror_check_arg_rv ((attach->refcount > 0), "attach->refcount > 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);
}
void icalattachtype_set_url(struct icalattachtype* v, char* url)
int
icalattach_get_is_url (icalattach *attach)
{
icalerror_check_arg( (v!=0),"v");
if (v->url != 0){
free (v->url);
}
v->url = icalmemory_strdup(url);
/* HACK This routine should do something if icalmemory_strdup returns NULL */
icalerror_check_arg_rz ((attach != NULL), "attach");
return attach->is_url ? 1 : 0;
}
char* icalattachtype_get_url(struct icalattachtype* v)
const char *
icalattach_get_url (icalattach *attach)
{
icalerror_check_arg( (v!=0),"v");
return v->url;
icalerror_check_arg_rz ((attach != NULL), "attach");
icalerror_check_arg_rz ((attach->is_url), "attach->is_url");
return attach->u.url.url;
}
void icalattachtype_set_base64(struct icalattachtype* v, char* base64,
int owns)
unsigned char *
icalattach_get_data (icalattach *attach)
{
icalerror_check_arg( (v!=0),"v");
icalerror_check_arg_rz ((attach != NULL), "attach");
icalerror_check_arg_rz ((!attach->is_url), "!attach->is_url");
v->base64 = base64;
v->owns_base64 = !(owns != 0 );
}
char* icalattachtype_get_base64(struct icalattachtype* v)
{
icalerror_check_arg( (v!=0),"v");
return v->base64;
}
void icalattachtype_set_binary(struct icalattachtype* v, char* binary,
int owns)
{
icalerror_check_arg( (v!=0),"v");
v->binary = binary;
v->owns_binary = !(owns != 0 );
}
void* icalattachtype_get_binary(struct icalattachtype* v)
{
icalerror_check_arg( (v!=0),"v");
return v->binary;
return attach->u.data.data;
}

View File

@ -30,25 +30,24 @@
#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;
char* base64;
int owns_base64;
char* url;
int refcount;
};
typedef void (* icalattach_free_fn_t) (unsigned char *data, void *user_data);
/* converts base64 to binary, fetches url and stores as binary, or
just returns data */
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);
void icalattach_ref (icalattach *attach);
void icalattach_unref (icalattach *attach);
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);
void icalattachtype_free(struct icalattachtype* v);

View File

@ -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:
{

View File

@ -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