bump to 1.0.0 and clean up spec file
[platform/upstream/libical.git] / src / libical / icalparameter.c
1 /* -*- Mode: C -*-
2   ======================================================================
3   FILE: icalderivedparameters.{c,h}
4   CREATOR: eric 09 May 1999
5   
6   $Id: icalparameter.c,v 1.15 2008-01-15 23:17:40 dothebart Exp $
7   $Locker:  $
8     
9
10  (C) COPYRIGHT 2000, Eric Busboom <eric@softwarestudio.org>
11      http://www.softwarestudio.org
12
13  This program is free software; you can redistribute it and/or modify
14  it under the terms of either: 
15
16     The LGPL as published by the Free Software Foundation, version
17     2.1, available at: http://www.fsf.org/copyleft/lesser.html
18
19   Or:
20
21     The Mozilla Public License Version 1.0. You may obtain a copy of
22     the License at http://www.mozilla.org/MPL/
23
24   The original code is icalderivedparameters.{c,h}
25
26   Contributions from:
27      Graham Davison <g.m.davison@computer.org>
28
29  ======================================================================*/
30 #ifdef HAVE_CONFIG_H
31 #include <config.h>
32 #endif
33
34
35 #include "icalparameter.h"
36 #include "icalproperty.h"
37 #include "icalerror.h"
38 #include "icalmemory.h"
39 #include "icalparameterimpl.h"
40
41 #include <stdlib.h> /* for malloc() */
42 #include <errno.h>
43 #include <string.h> /* for memset() */
44
45 #if defined(_MSC_VER)
46 #define snprintf _snprintf
47 #define strcasecmp stricmp
48 #endif
49
50 /* In icalderivedparameter */
51 icalparameter* icalparameter_new_from_value_string(icalparameter_kind kind,const  char* val);
52
53
54 struct icalparameter_impl* icalparameter_new_impl(icalparameter_kind kind)
55 {
56     struct icalparameter_impl* v;
57
58     if ( ( v = (struct icalparameter_impl*)
59            malloc(sizeof(struct icalparameter_impl))) == 0) {
60         icalerror_set_errno(ICAL_NEWFAILED_ERROR);
61         return 0;
62     }
63     
64     strcpy(v->id,"para");
65
66     v->kind = kind;
67     v->size = 0;
68     v->string = 0;
69     v->x_name = 0;
70     v->parent = 0;
71     v->data = 0;
72
73     return v;
74 }
75
76 icalparameter*
77 icalparameter_new (icalparameter_kind kind)
78 {
79     struct icalparameter_impl* v = icalparameter_new_impl(kind);
80
81     return (icalparameter*) v;
82
83 }
84
85 void
86 icalparameter_free (icalparameter* param)
87 {
88
89 /*  HACK. This always triggers, even when parameter is non-zero
90     icalerror_check_arg_rv((parameter==0),"parameter");*/
91
92
93 #ifdef ICAL_FREE_ON_LIST_IS_ERROR
94     icalerror_assert( (param->parent ==0),"Tried to free a parameter that is still attached to a component. ");
95     
96 #else
97     if(param->parent !=0){
98         return;
99     }
100 #endif
101
102     
103     if (param->string != 0){
104         free ((void*)param->string);
105     }
106     
107     if (param->x_name != 0){
108         free ((void*)param->x_name);
109     }
110     
111     memset(param,0,sizeof(icalparameter));
112
113     param->parent = 0;
114     param->id[0] = 'X';
115     free(param);
116 }
117
118
119
120 icalparameter* 
121 icalparameter_new_clone(icalparameter* old)
122 {
123     struct icalparameter_impl *new;
124
125     new = icalparameter_new_impl(old->kind);
126
127     icalerror_check_arg_rz((old!=0),"param");
128
129     if (new == 0){
130         return 0;
131     }
132
133     memcpy(new,old,sizeof(struct icalparameter_impl));
134
135     if (old->string != 0){
136         new->string = icalmemory_strdup(old->string);
137         if (new->string == 0){
138             icalparameter_free(new);
139             return 0;
140         }
141     }
142
143     if (old->x_name != 0){
144         new->x_name = icalmemory_strdup(old->x_name);
145         if (new->x_name == 0){
146             icalparameter_free(new);
147             return 0;
148         }
149     }
150
151     return new;
152 }
153
154 icalparameter* icalparameter_new_from_string(const char *str)
155 {
156     char* eq;
157     char* cpy;
158     icalparameter_kind kind;
159     icalparameter *param;
160
161     icalerror_check_arg_rz(str != 0,"str");
162
163     cpy = icalmemory_strdup(str);
164
165     if (cpy == 0){
166         icalerror_set_errno(ICAL_NEWFAILED_ERROR);
167         return 0;
168     }
169
170     eq = strchr(cpy,'=');
171
172     if(eq == 0){
173         icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);
174         free(cpy);
175         return 0;
176     }
177
178     *eq = '\0';
179
180     eq++;
181
182     kind = icalparameter_string_to_kind(cpy);
183
184     if(kind == ICAL_NO_PARAMETER){
185         icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);
186         free(cpy);
187         return 0;
188     }
189
190     param = icalparameter_new_from_value_string(kind,eq);
191
192     if(kind == ICAL_X_PARAMETER){
193         icalparameter_set_xname(param,cpy);
194     } else if(kind == ICAL_IANA_PARAMETER) {
195         icalparameter_set_iana_name(param, cpy);
196     }
197
198     free(cpy);
199
200     return param;
201     
202 }
203
204 char*
205 icalparameter_as_ical_string(icalparameter* param)
206 {
207         char *buf;
208         buf = icalparameter_as_ical_string_r(param);
209         icalmemory_add_tmp_buffer(buf);
210         return buf;
211 }
212
213
214 /**
215  * Return a string representation of the parameter according to RFC2445.
216  *
217  * param        = param-name "=" param-value
218  * param-name   = iana-token / x-token
219  * param-value  = paramtext /quoted-string
220  * paramtext    = *SAFE-SHARE
221  * quoted-string= DQUOTE *QSAFE-CHARE DQUOTE
222  * QSAFE-CHAR   = any character except CTLs and DQUOTE
223  * SAFE-CHAR    = any character except CTLs, DQUOTE. ";", ":", ","
224  */
225 char*
226 icalparameter_as_ical_string_r(icalparameter* param)
227 {
228     size_t buf_size = 1024;
229     char* buf; 
230     char* buf_ptr;
231     const char *kind_string;
232
233     icalerror_check_arg_rz( (param!=0), "parameter");
234
235     /* Create new buffer that we can append names, parameters and a
236      * value to, and reallocate as needed.
237      */
238
239     buf = icalmemory_new_buffer(buf_size);
240     buf_ptr = buf;
241
242     if(param->kind == ICAL_X_PARAMETER) {
243         icalmemory_append_string(&buf, &buf_ptr, &buf_size, 
244                      icalparameter_get_xname(param));
245     } else if (param->kind == ICAL_IANA_PARAMETER) {
246         icalmemory_append_string(&buf, &buf_ptr, &buf_size, 
247                      icalparameter_get_iana_name(param));
248     } else {
249
250         kind_string = icalparameter_kind_to_string(param->kind);
251         
252         if (param->kind == ICAL_NO_PARAMETER || 
253             param->kind == ICAL_ANY_PARAMETER || 
254             kind_string == 0)
255         {
256             icalerror_set_errno(ICAL_BADARG_ERROR);
257             free(buf);
258             return 0;
259         }
260         
261         
262         /* Put the parameter name into the string */
263         icalmemory_append_string(&buf, &buf_ptr, &buf_size, kind_string);
264
265     }
266
267     icalmemory_append_string(&buf, &buf_ptr, &buf_size, "=");
268
269     if(param->string !=0){
270         int qm = 0;
271
272         /* Encapsulate the property in quotes if necessary */
273         if (strpbrk(param->string, ";:,") != 0) {
274                 icalmemory_append_char (&buf, &buf_ptr, &buf_size, '"');
275                 qm = 1;
276         }
277         icalmemory_append_string(&buf, &buf_ptr, &buf_size, param->string); 
278         if (qm == 1) {
279                 icalmemory_append_char (&buf, &buf_ptr, &buf_size, '"');
280         }
281     } else if (param->data != 0){
282         const char* str = icalparameter_enum_to_string(param->data);
283         icalmemory_append_string(&buf, &buf_ptr, &buf_size, str); 
284     } else {
285         icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);
286         free(buf);
287         return 0;
288     }
289
290     return buf;
291 }
292
293
294 int
295 icalparameter_is_valid (icalparameter* parameter);
296
297
298 icalparameter_kind
299 icalparameter_isa (icalparameter* parameter)
300 {
301     if(parameter == 0){
302         return ICAL_NO_PARAMETER;
303     }
304
305     return parameter->kind;
306 }
307
308
309 int
310 icalparameter_isa_parameter (void* parameter)
311 {
312     struct icalparameter_impl *impl = (struct icalparameter_impl *)parameter;
313
314     if (parameter == 0){
315         return 0;
316     }
317
318     if (strcmp(impl->id,"para") == 0) {
319         return 1;
320     } else {
321         return 0;
322     }
323 }
324
325
326 void
327 icalparameter_set_xname (icalparameter* param, const char* v)
328 {
329     icalerror_check_arg_rv( (param!=0),"param");
330     icalerror_check_arg_rv( (v!=0),"v");
331
332     if (param->x_name != 0){
333         free((void*)param->x_name);
334     }
335
336     param->x_name = icalmemory_strdup(v);
337
338     if (param->x_name == 0){
339         errno = ENOMEM;
340     }
341
342 }
343
344 const char*
345 icalparameter_get_xname (icalparameter* param)
346 {
347     icalerror_check_arg_rz( (param!=0),"param");
348
349     return param->x_name;
350 }
351
352 void
353 icalparameter_set_xvalue (icalparameter* param, const char* v)
354 {
355     icalerror_check_arg_rv( (param!=0),"param");
356     icalerror_check_arg_rv( (v!=0),"v");
357
358     if (param->string != 0){
359         free((void*)param->string);
360     }
361
362     param->string = icalmemory_strdup(v);
363
364     if (param->string == 0){
365         errno = ENOMEM;
366     }
367
368 }
369
370 const char*
371 icalparameter_get_xvalue (icalparameter* param)
372 {
373     icalerror_check_arg_rz( (param!=0),"param");
374
375     return param->string;
376 }
377
378 void icalparameter_set_iana_value (icalparameter* param, const char* v)
379 {
380     icalparameter_set_xvalue(param, v);
381 }
382
383 const char* icalparameter_get_iana_value(icalparameter* param)
384 {
385     return icalparameter_get_xvalue(param);
386 }
387
388 void icalparameter_set_iana_name (icalparameter* param, const char* v)
389 {
390     icalparameter_set_xname(param, v);
391 }
392
393 const char* icalparameter_get_iana_name (icalparameter* param)
394 {
395     return icalparameter_get_xname(param);
396 }
397
398 void icalparameter_set_parent(icalparameter* param,
399                              icalproperty* property)
400 {
401     icalerror_check_arg_rv( (param!=0),"param");
402
403     param->parent = property;
404 }
405
406 icalproperty* icalparameter_get_parent(icalparameter* param)
407 {
408     icalerror_check_arg_rz( (param!=0),"param");
409
410     return param->parent;
411 }
412
413 /* returns 1 if parameters have same name in ICAL, otherwise 0 */
414 int icalparameter_has_same_name(icalparameter* param1, icalparameter* param2)
415 {
416     icalparameter_kind kind1;
417     icalparameter_kind kind2;
418     const char *name1;
419     const char *name2;
420
421     icalerror_check_arg_rz( (param1!=0),"param1");
422     icalerror_check_arg_rz( (param2!=0),"param2");
423
424     kind1 = icalparameter_isa(param1);
425     kind2 = icalparameter_isa(param2);
426
427     if (kind1 != kind2)
428         return 0;
429
430     if  (kind1 == ICAL_X_PARAMETER) {
431         name1 = icalparameter_get_xname(param1);
432         name2 = icalparameter_get_xname(param2);
433         if (strcasecmp(name1, name2) != 0)
434             return 0;
435     } else if  (kind1 == ICAL_IANA_PARAMETER) {
436         name1 = icalparameter_get_iana_name(param1);
437         name2 = icalparameter_get_iana_name(param2);
438         if (strcasecmp(name1, name2) != 0)
439             return 0;
440     }
441         return 1;
442 }
443
444 /* Everything below this line is machine generated. Do not edit. */
445 /* ALTREP */