summaryrefslogtreecommitdiffabout
path: root/libkcal/versit/vobject.c
authorzautrix <zautrix>2004-06-29 11:59:46 (UTC)
committer zautrix <zautrix>2004-06-29 11:59:46 (UTC)
commitda43dbdc6c82453228f34766fc74585615cba938 (patch) (unidiff)
tree16576932cea08bf117b2d0320b0d5f66ee8ad093 /libkcal/versit/vobject.c
parent627489ea2669d3997676bc3cee0f5d0d0c16c4d4 (diff)
downloadkdepimpi-da43dbdc6c82453228f34766fc74585615cba938.zip
kdepimpi-da43dbdc6c82453228f34766fc74585615cba938.tar.gz
kdepimpi-da43dbdc6c82453228f34766fc74585615cba938.tar.bz2
New lib ical.Some minor changes as well.
Diffstat (limited to 'libkcal/versit/vobject.c') (more/less context) (ignore whitespace changes)
-rw-r--r--libkcal/versit/vobject.c363
1 files changed, 192 insertions, 171 deletions
diff --git a/libkcal/versit/vobject.c b/libkcal/versit/vobject.c
index 637efb2..3fac63e 100644
--- a/libkcal/versit/vobject.c
+++ b/libkcal/versit/vobject.c
@@ -41,28 +41,54 @@ DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable.
41 * doc: vobject and APIs to construct vobject, APIs pretty print 41 * doc: vobject and APIs to construct vobject, APIs pretty print
42 * vobject, and convert a vobject into its textual representation. 42 * vobject, and convert a vobject into its textual representation.
43 */ 43 */
44 44
45#include <stdlib.h> 45#ifdef WIN32
46#define snprintf _snprintf
47#define strcasecmp stricmp
48#endif
46 49
47#include "vobject.h" 50#include "vobject.h"
51#include <stdlib.h>
48#include <string.h> 52#include <string.h>
49#include <stdio.h> 53#include <stdio.h>
50#ifdef _WIN32_ 54#include <fcntl.h>
51 55
52 #define strcasecmp _stricmp
53 56
54#endif 57 #define NAME_OF(o) o->id
55
56 #define NAME_OF(o) o->id
57 #define VALUE_TYPE(o) o->valType 58 #define VALUE_TYPE(o) o->valType
58 #define STRINGZ_VALUE_OF(o) o->val.strs 59 #define STRINGZ_VALUE_OF(o) o->val.strs
59 #define USTRINGZ_VALUE_OF(o)o->val.ustrs 60 #define USTRINGZ_VALUE_OF(o)o->val.ustrs
60 #define INTEGER_VALUE_OF(o) o->val.i 61 #define INTEGER_VALUE_OF(o) o->val.i
61 #define LONG_VALUE_OF(o) o->val.l 62 #define LONG_VALUE_OF(o) o->val.l
62 #define ANY_VALUE_OF(o) o->val.any 63 #define ANY_VALUE_OF(o) o->val.any
63 #define VOBJECT_VALUE_OF(o) o->val.vobj 64 #define VOBJECT_VALUE_OF(o) o->val.vobj
64 65
66typedef union ValueItem {
67 const char *strs;
68 const wchar_t *ustrs;
69 unsigned int i;
70 unsigned long l;
71 void *any;
72 VObject *vobj;
73 } ValueItem;
74
75struct VObject {
76 VObject *next;
77 const char *id;
78 VObject *prop;
79 unsigned short valType;
80 ValueItem val;
81 };
82
83typedef struct StrItem StrItem;
84
85struct StrItem {
86 StrItem *next;
87 const char *s;
88 unsigned int refCnt;
89 };
90
65const char** fieldedProp; 91const char** fieldedProp;
66 92
67 93
68 94
@@ -75,9 +101,9 @@ const char** fieldedProp;
75 newStrItem 101 newStrItem
76 deleteStrItem 102 deleteStrItem
77 ----------------------------------------------------------------------*/ 103 ----------------------------------------------------------------------*/
78 104
79VObject* newVObject_(const char *id) 105DLLEXPORT(VObject*) newVObject_(const char *id)
80{ 106{
81 VObject *p = (VObject*)malloc(sizeof(VObject)); 107 VObject *p = (VObject*)malloc(sizeof(VObject));
82 p->next = 0; 108 p->next = 0;
83 p->id = id; 109 p->id = id;
@@ -86,23 +112,20 @@ VObject* newVObject_(const char *id)
86 ANY_VALUE_OF(p) = 0; 112 ANY_VALUE_OF(p) = 0;
87 return p; 113 return p;
88} 114}
89 115
90VObject* newVObject(const char *id) 116DLLEXPORT(VObject*) newVObject(const char *id)
91{ 117{
92 return newVObject_(lookupStr(id)); 118 return newVObject_(lookupStr(id));
93} 119}
94 120
95void deleteVObject(VObject *p) 121DLLEXPORT(void) deleteVObject(VObject *p)
96{ 122{
97 if (p->id)
98 unUseStr(p->id); 123 unUseStr(p->id);
99 if (p)
100 free(p); 124 free(p);
101 p = NULL;
102} 125}
103 126
104char* dupStr(const char *s, unsigned int size) 127DLLEXPORT(char*) dupStr(const char *s, unsigned int size)
105{ 128{
106 char *t; 129 char *t;
107 if (size == 0) { 130 if (size == 0) {
108 size = strlen(s); 131 size = strlen(s);
@@ -117,13 +140,11 @@ char* dupStr(const char *s, unsigned int size)
117 return (char*)0; 140 return (char*)0;
118 } 141 }
119} 142}
120 143
121void deleteStr(const char *p) 144DLLEXPORT(void) deleteStr(const char *p)
122{ 145{
123 if (p) 146 if (p) free((void*)p);
124 free((void*)p);
125 p = NULL;
126} 147}
127 148
128 149
129static StrItem* newStrItem(const char *s, StrItem *next) 150static StrItem* newStrItem(const char *s, StrItem *next)
@@ -136,107 +157,105 @@ static StrItem* newStrItem(const char *s, StrItem *next)
136} 157}
137 158
138static void deleteStrItem(StrItem *p) 159static void deleteStrItem(StrItem *p)
139{ 160{
140 if (p) 161 free((void*)p);
141 free((void*)p);
142 p = NULL;
143} 162}
144 163
145 164
146/*---------------------------------------------------------------------- 165/*----------------------------------------------------------------------
147 The following function provide accesses to VObject's value. 166 The following function provide accesses to VObject's value.
148 ----------------------------------------------------------------------*/ 167 ----------------------------------------------------------------------*/
149 168
150const char* vObjectName(VObject *o) 169DLLEXPORT(const char*) vObjectName(VObject *o)
151{ 170{
152 return NAME_OF(o); 171 return NAME_OF(o);
153} 172}
154 173
155void setVObjectName(VObject *o, const char* id) 174DLLEXPORT(void) setVObjectName(VObject *o, const char* id)
156{ 175{
157 NAME_OF(o) = id; 176 NAME_OF(o) = id;
158} 177}
159 178
160const char* vObjectStringZValue(VObject *o) 179DLLEXPORT(const char*) vObjectStringZValue(VObject *o)
161{ 180{
162 return STRINGZ_VALUE_OF(o); 181 return STRINGZ_VALUE_OF(o);
163} 182}
164 183
165void setVObjectStringZValue(VObject *o, const char *s) 184DLLEXPORT(void) setVObjectStringZValue(VObject *o, const char *s)
166{ 185{
167 STRINGZ_VALUE_OF(o) = dupStr(s,0); 186 STRINGZ_VALUE_OF(o) = dupStr(s,0);
168 VALUE_TYPE(o) = VCVT_STRINGZ; 187 VALUE_TYPE(o) = VCVT_STRINGZ;
169} 188}
170 189
171void setVObjectStringZValue_(VObject *o, const char *s) 190DLLEXPORT(void) setVObjectStringZValue_(VObject *o, const char *s)
172{ 191{
173 STRINGZ_VALUE_OF(o) = s; 192 STRINGZ_VALUE_OF(o) = s;
174 VALUE_TYPE(o) = VCVT_STRINGZ; 193 VALUE_TYPE(o) = VCVT_STRINGZ;
175} 194}
176 195
177const wchar_t* vObjectUStringZValue(VObject *o) 196DLLEXPORT(const wchar_t*) vObjectUStringZValue(VObject *o)
178{ 197{
179 return USTRINGZ_VALUE_OF(o); 198 return USTRINGZ_VALUE_OF(o);
180} 199}
181 200
182void setVObjectUStringZValue(VObject *o, const wchar_t *s) 201DLLEXPORT(void) setVObjectUStringZValue(VObject *o, const wchar_t *s)
183{ 202{
184 USTRINGZ_VALUE_OF(o) = (wchar_t*) dupStr((char*)s,(uStrLen(s)+1)*2); 203 USTRINGZ_VALUE_OF(o) = (wchar_t*) dupStr((char*)s,(uStrLen(s)+1)*2);
185 VALUE_TYPE(o) = VCVT_USTRINGZ; 204 VALUE_TYPE(o) = VCVT_USTRINGZ;
186} 205}
187 206
188void setVObjectUStringZValue_(VObject *o, const wchar_t *s) 207DLLEXPORT(void) setVObjectUStringZValue_(VObject *o, const wchar_t *s)
189{ 208{
190 USTRINGZ_VALUE_OF(o) = s; 209 USTRINGZ_VALUE_OF(o) = s;
191 VALUE_TYPE(o) = VCVT_USTRINGZ; 210 VALUE_TYPE(o) = VCVT_USTRINGZ;
192} 211}
193 212
194unsigned int vObjectIntegerValue(VObject *o) 213DLLEXPORT(unsigned int) vObjectIntegerValue(VObject *o)
195{ 214{
196 return INTEGER_VALUE_OF(o); 215 return INTEGER_VALUE_OF(o);
197} 216}
198 217
199void setVObjectIntegerValue(VObject *o, unsigned int i) 218DLLEXPORT(void) setVObjectIntegerValue(VObject *o, unsigned int i)
200{ 219{
201 INTEGER_VALUE_OF(o) = i; 220 INTEGER_VALUE_OF(o) = i;
202 VALUE_TYPE(o) = VCVT_UINT; 221 VALUE_TYPE(o) = VCVT_UINT;
203} 222}
204 223
205unsigned long vObjectLongValue(VObject *o) 224DLLEXPORT(unsigned long) vObjectLongValue(VObject *o)
206{ 225{
207 return LONG_VALUE_OF(o); 226 return LONG_VALUE_OF(o);
208} 227}
209 228
210void setVObjectLongValue(VObject *o, unsigned long l) 229DLLEXPORT(void) setVObjectLongValue(VObject *o, unsigned long l)
211{ 230{
212 LONG_VALUE_OF(o) = l; 231 LONG_VALUE_OF(o) = l;
213 VALUE_TYPE(o) = VCVT_ULONG; 232 VALUE_TYPE(o) = VCVT_ULONG;
214} 233}
215 234
216void* vObjectAnyValue(VObject *o) 235DLLEXPORT(void*) vObjectAnyValue(VObject *o)
217{ 236{
218 return ANY_VALUE_OF(o); 237 return ANY_VALUE_OF(o);
219} 238}
220 239
221void setVObjectAnyValue(VObject *o, void *t) 240DLLEXPORT(void) setVObjectAnyValue(VObject *o, void *t)
222{ 241{
223 ANY_VALUE_OF(o) = t; 242 ANY_VALUE_OF(o) = t;
224 VALUE_TYPE(o) = VCVT_RAW; 243 VALUE_TYPE(o) = VCVT_RAW;
225} 244}
226 245
227VObject* vObjectVObjectValue(VObject *o) 246DLLEXPORT(VObject*) vObjectVObjectValue(VObject *o)
228{ 247{
229 return VOBJECT_VALUE_OF(o); 248 return VOBJECT_VALUE_OF(o);
230} 249}
231 250
232void setVObjectVObjectValue(VObject *o, VObject *p) 251DLLEXPORT(void) setVObjectVObjectValue(VObject *o, VObject *p)
233{ 252{
234 VOBJECT_VALUE_OF(o) = p; 253 VOBJECT_VALUE_OF(o) = p;
235 VALUE_TYPE(o) = VCVT_VOBJECT; 254 VALUE_TYPE(o) = VCVT_VOBJECT;
236} 255}
237 256
238int vObjectValueType(VObject *o) 257DLLEXPORT(int) vObjectValueType(VObject *o)
239{ 258{
240 return VALUE_TYPE(o); 259 return VALUE_TYPE(o);
241} 260}
242 261
@@ -244,9 +263,9 @@ int vObjectValueType(VObject *o)
244/*---------------------------------------------------------------------- 263/*----------------------------------------------------------------------
245 The following functions can be used to build VObject. 264 The following functions can be used to build VObject.
246 ----------------------------------------------------------------------*/ 265 ----------------------------------------------------------------------*/
247 266
248VObject* addVObjectProp(VObject *o, VObject *p) 267DLLEXPORT(VObject*) addVObjectProp(VObject *o, VObject *p)
249{ 268{
250 /* circular link list pointed to tail */ 269 /* circular link list pointed to tail */
251 /* 270 /*
252 o {next,id,prop,val} 271 o {next,id,prop,val}
@@ -279,19 +298,19 @@ VObject* addVObjectProp(VObject *o, VObject *p)
279 } 298 }
280 return p; 299 return p;
281} 300}
282 301
283VObject* addProp(VObject *o, const char *id) 302DLLEXPORT(VObject*) addProp(VObject *o, const char *id)
284{ 303{
285 return addVObjectProp(o,newVObject(id)); 304 return addVObjectProp(o,newVObject(id));
286} 305}
287 306
288VObject* addProp_(VObject *o, const char *id) 307DLLEXPORT(VObject*) addProp_(VObject *o, const char *id)
289{ 308{
290 return addVObjectProp(o,newVObject_(id)); 309 return addVObjectProp(o,newVObject_(id));
291} 310}
292 311
293void addList(VObject **o, VObject *p) 312DLLEXPORT(void) addList(VObject **o, VObject *p)
294{ 313{
295 p->next = 0; 314 p->next = 0;
296 if (*o == 0) { 315 if (*o == 0) {
297 *o = p; 316 *o = p;
@@ -304,46 +323,46 @@ void addList(VObject **o, VObject *p)
304 t->next = p; 323 t->next = p;
305 } 324 }
306} 325}
307 326
308VObject* nextVObjectInList(VObject *o) 327DLLEXPORT(VObject*) nextVObjectInList(VObject *o)
309{ 328{
310 return o->next; 329 return o->next;
311} 330}
312 331
313VObject* setValueWithSize_(VObject *prop, void *val, unsigned int size) 332DLLEXPORT(VObject*) setValueWithSize_(VObject *prop, void *val, unsigned int size)
314{ 333{
315 VObject *sizeProp; 334 VObject *sizeProp;
316 setVObjectAnyValue(prop, val); 335 setVObjectAnyValue(prop, val);
317 sizeProp = addProp(prop,VCDataSizeProp); 336 sizeProp = addProp(prop,VCDataSizeProp);
318 setVObjectLongValue(sizeProp, size); 337 setVObjectLongValue(sizeProp, size);
319 return prop; 338 return prop;
320} 339}
321 340
322VObject* setValueWithSize(VObject *prop, void *val, unsigned int size) 341DLLEXPORT(VObject*) setValueWithSize(VObject *prop, void *val, unsigned int size)
323{ 342{
324 void *p = dupStr(val,size); 343 void *p = dupStr((const char *)val,size);
325 return setValueWithSize_(prop,p,p?size:0); 344 return setValueWithSize_(prop,p,p?size:0);
326} 345}
327 346
328void initPropIterator(VObjectIterator *i, VObject *o) 347DLLEXPORT(void) initPropIterator(VObjectIterator *i, VObject *o)
329{ 348{
330 i->start = o->prop; 349 i->start = o->prop;
331 i->next = 0; 350 i->next = 0;
332} 351}
333 352
334void initVObjectIterator(VObjectIterator *i, VObject *o) 353DLLEXPORT(void) initVObjectIterator(VObjectIterator *i, VObject *o)
335{ 354{
336 i->start = o->next; 355 i->start = o->next;
337 i->next = 0; 356 i->next = 0;
338} 357}
339 358
340int moreIteration(VObjectIterator *i) 359DLLEXPORT(int) moreIteration(VObjectIterator *i)
341{ 360{
342 return (i->start && (i->next==0 || i->next!=i->start)); 361 return (i->start && (i->next==0 || i->next!=i->start));
343} 362}
344 363
345VObject* nextVObject(VObjectIterator *i) 364DLLEXPORT(VObject*) nextVObject(VObjectIterator *i)
346{ 365{
347 if (i->start && i->next != i->start) { 366 if (i->start && i->next != i->start) {
348 if (i->next == 0) { 367 if (i->next == 0) {
349 i->next = i->start->next; 368 i->next = i->start->next;
@@ -356,21 +375,21 @@ VObject* nextVObject(VObjectIterator *i)
356 } 375 }
357 else return (VObject*)0; 376 else return (VObject*)0;
358} 377}
359 378
360VObject* isAPropertyOf(VObject *o, const char *id) 379DLLEXPORT(VObject*) isAPropertyOf(VObject *o, const char *id)
361{ 380{
362 VObjectIterator i; 381 VObjectIterator i;
363 initPropIterator(&i,o); 382 initPropIterator(&i,o);
364 while (moreIteration(&i)) { 383 while (moreIteration(&i)) {
365 VObject *each = nextVObject(&i); 384 VObject *each = nextVObject(&i);
366 if (!strcasecmp(id,each->id)) 385 if (!stricmp(id,each->id))
367 return each; 386 return each;
368 } 387 }
369 return (VObject*)0; 388 return (VObject*)0;
370} 389}
371 390
372VObject* addGroup(VObject *o, const char *g) 391DLLEXPORT(VObject*) addGroup(VObject *o, const char *g)
373{ 392{
374 /* 393 /*
375 a.b.c 394 a.b.c
376 --> 395 -->
@@ -409,26 +428,26 @@ VObject* addGroup(VObject *o, const char *g)
409 else 428 else
410 return addProp_(o,lookupProp(g)); 429 return addProp_(o,lookupProp(g));
411} 430}
412 431
413VObject* addPropValue(VObject *o, const char *p, const char *v) 432DLLEXPORT(VObject*) addPropValue(VObject *o, const char *p, const char *v)
414{ 433{
415 VObject *prop; 434 VObject *prop;
416 prop = addProp(o,p); 435 prop = addProp(o,p);
417 setVObjectUStringZValue_(prop, fakeUnicode(v,0)); 436 setVObjectUStringZValue_(prop, fakeUnicode(v,0));
418 return prop; 437 return prop;
419} 438}
420 439
421VObject* addPropSizedValue_(VObject *o, const char *p, const char *v, 440DLLEXPORT(VObject*) addPropSizedValue_(VObject *o, const char *p, const char *v,
422 unsigned int size) 441 unsigned int size)
423{ 442{
424 VObject *prop; 443 VObject *prop;
425 prop = addProp(o,p); 444 prop = addProp(o,p);
426 setValueWithSize_(prop, (void*)v, size); 445 setValueWithSize_(prop, (void*)v, size);
427 return prop; 446 return prop;
428} 447}
429 448
430VObject* addPropSizedValue(VObject *o, const char *p, const char *v, 449DLLEXPORT(VObject*) addPropSizedValue(VObject *o, const char *p, const char *v,
431 unsigned int size) 450 unsigned int size)
432{ 451{
433 return addPropSizedValue_(o,p,dupStr(v,size),size); 452 return addPropSizedValue_(o,p,dupStr(v,size),size);
434} 453}
@@ -527,18 +546,18 @@ void printVObject(FILE *fp,VObject *o)
527{ 546{
528 printVObject_(fp,o,0); 547 printVObject_(fp,o,0);
529} 548}
530 549
531void printVObjectToFile(char *fname,VObject *o) 550DLLEXPORT(void) printVObjectToFile(char *fname,VObject *o)
532{ 551{
533 FILE *fp = fopen(fname,"w"); 552 FILE *fp = fopen(fname,"w");
534 if (fp) { 553 if (fp) {
535 printVObject(fp,o); 554 printVObject(fp,o);
536 fclose(fp); 555 fclose(fp);
537 } 556 }
538} 557}
539 558
540void printVObjectsToFile(char *fname,VObject *list) 559DLLEXPORT(void) printVObjectsToFile(char *fname,VObject *list)
541{ 560{
542 FILE *fp = fopen(fname,"w"); 561 FILE *fp = fopen(fname,"w");
543 if (fp) { 562 if (fp) {
544 while (list) { 563 while (list) {
@@ -548,9 +567,9 @@ void printVObjectsToFile(char *fname,VObject *list)
548 fclose(fp); 567 fclose(fp);
549 } 568 }
550} 569}
551 570
552void cleanVObject(VObject *o) 571DLLEXPORT(void) cleanVObject(VObject *o)
553{ 572{
554 if (o == 0) return; 573 if (o == 0) return;
555 if (o->prop) { 574 if (o->prop) {
556 /* destroy time: cannot use the iterator here. 575 /* destroy time: cannot use the iterator here.
@@ -572,9 +591,9 @@ void cleanVObject(VObject *o)
572 switch (VALUE_TYPE(o)) { 591 switch (VALUE_TYPE(o)) {
573 case VCVT_USTRINGZ: 592 case VCVT_USTRINGZ:
574 case VCVT_STRINGZ: 593 case VCVT_STRINGZ:
575 case VCVT_RAW: 594 case VCVT_RAW:
576 /* assume they are all allocated by malloc. */ 595 /* assume they are all allocated by malloc. */
577 free((char*)STRINGZ_VALUE_OF(o)); 596 free((char*)STRINGZ_VALUE_OF(o));
578 break; 597 break;
579 case VCVT_VOBJECT: 598 case VCVT_VOBJECT:
580 cleanVObject(VOBJECT_VALUE_OF(o)); 599 cleanVObject(VOBJECT_VALUE_OF(o));
@@ -582,9 +601,9 @@ void cleanVObject(VObject *o)
582 } 601 }
583 deleteVObject(o); 602 deleteVObject(o);
584} 603}
585 604
586void cleanVObjects(VObject *list) 605DLLEXPORT(void) cleanVObjects(VObject *list)
587{ 606{
588 while (list) { 607 while (list) {
589 VObject *t = list; 608 VObject *t = list;
590 list = nextVObjectInList(list); 609 list = nextVObjectInList(list);
@@ -609,71 +628,67 @@ static unsigned int hashStr(const char *s)
609 } 628 }
610 return h % STRTBLSIZE; 629 return h % STRTBLSIZE;
611} 630}
612 631
613const char* lookupStr(const char *s) 632DLLEXPORT(const char*) lookupStr(const char *s)
614{ 633{
615 char *newS; 634 StrItem *t;
616 635 unsigned int h = hashStr(s);
617 StrItem *t; 636 if ((t = strTbl[h]) != 0) {
618 unsigned int h = hashStr(s); 637 do {
619 if ((t = strTbl[h]) != 0) { 638 if (stricmp(t->s,s) == 0) {
620 do { 639 t->refCnt++;
621 if (strcasecmp(t->s,s) == 0) { 640 return t->s;
622 t->refCnt++; 641 }
623 return t->s; 642 t = t->next;
624 } 643 } while (t);
625 t = t->next; 644 }
626 } while (t); 645 s = dupStr(s,0);
627 } 646 strTbl[h] = newStrItem(s,strTbl[h]);
628 newS = dupStr(s,0); 647 return s;
629 strTbl[h] = newStrItem(newS,strTbl[h]);
630 return newS;
631} 648}
632 649
633void unUseStr(const char *s) 650DLLEXPORT(void) unUseStr(const char *s)
634{ 651{
635 StrItem *cur, *prev; 652 StrItem *t, *p;
636
637 unsigned int h = hashStr(s); 653 unsigned int h = hashStr(s);
638 cur = strTbl[h]; 654 if ((t = strTbl[h]) != 0) {
639 prev = cur; 655 p = t;
640 while (cur != 0) { 656 do {
641 if (strcasecmp(cur->s,s) == 0) { 657 if (stricmp(t->s,s) == 0) {
642 cur->refCnt--; 658 t->refCnt--;
643 /* if that was the last reference to this string, kill it. */ 659 if (t->refCnt == 0) {
644 if (cur->refCnt == 0) { 660 if (p == strTbl[h]) {
645 if (cur == strTbl[h]) { 661 strTbl[h] = t->next;
646 strTbl[h] = cur->next; 662 }
647 deleteStr(prev->s); 663 else {
648 deleteStrItem(prev); 664 p->next = t->next;
649 } else { 665 }
650 prev->next = cur->next; 666 deleteStr(t->s);
651 deleteStr(cur->s); 667 deleteStrItem(t);
652 deleteStrItem(cur); 668 return;
653 } 669 }
654 return; 670 }
671 p = t;
672 t = t->next;
673 } while (t);
655 } 674 }
656 }
657 prev = cur;
658 cur = cur->next;
659 }
660} 675}
661 676
662void cleanStrTbl() 677DLLEXPORT(void) cleanStrTbl()
663{ 678{
664 int i; 679 int i;
665 for (i=0; i<STRTBLSIZE;i++) { 680 for (i=0; i<STRTBLSIZE;i++) {
666 StrItem *t = strTbl[i]; 681 StrItem *t = strTbl[i];
667 while (t) { 682 while (t) {
668 StrItem *p; 683 StrItem *p;
669 deleteStr(t->s); 684 deleteStr(t->s);
670 p = t; 685 p = t;
671 t = t->next; 686 t = t->next;
672 deleteStrItem(p); 687 deleteStrItem(p);
673 } 688 } while (t);
674 strTbl[i] = 0; 689 strTbl[i] = 0;
675 } 690 }
676} 691}
677 692
678 693
679struct PreDefProp { 694struct PreDefProp {
@@ -806,9 +821,9 @@ static struct PreDefProp propNames[] = {
806 { VCEndProp, 0, 0, 0 }, 821 { VCEndProp, 0, 0, 0 },
807 { VCEventProp, 0, 0, PD_BEGIN }, 822 { VCEventProp, 0, 0, PD_BEGIN },
808 { VCEWorldProp, 0, 0, 0 }, 823 { VCEWorldProp, 0, 0, 0 },
809 { VCExNumProp, 0, 0, 0 }, 824 { VCExNumProp, 0, 0, 0 },
810 { VCExDateProp, 0, 0, 0 }, 825 { VCExpDateProp, 0, 0, 0 },
811 { VCExpectProp, 0, 0, 0 }, 826 { VCExpectProp, 0, 0, 0 },
812 { VCExtAddressProp, 0, 0, 0 }, 827 { VCExtAddressProp, 0, 0, 0 },
813 { VCFamilyNameProp, 0, 0, 0 }, 828 { VCFamilyNameProp, 0, 0, 0 },
814 { VCFaxProp, 0, 0, 0 }, 829 { VCFaxProp, 0, 0, 0 },
@@ -920,36 +935,36 @@ static struct PreDefProp* lookupPropInfo(const char* str)
920 /* brute force for now, could use a hash table here. */ 935 /* brute force for now, could use a hash table here. */
921 int i; 936 int i;
922 937
923 for (i = 0; propNames[i].name; i++) 938 for (i = 0; propNames[i].name; i++)
924 if (strcasecmp(str, propNames[i].name) == 0) { 939 if (stricmp(str, propNames[i].name) == 0) {
925 return &propNames[i]; 940 return &propNames[i];
926 } 941 }
927 942
928 return 0; 943 return 0;
929} 944}
930 945
931 946
932const char* lookupProp_(const char* str) 947DLLEXPORT(const char*) lookupProp_(const char* str)
933{ 948{
934 int i; 949 int i;
935 950
936 for (i = 0; propNames[i].name; i++) 951 for (i = 0; propNames[i].name; i++)
937 if (strcasecmp(str, propNames[i].name) == 0) { 952 if (stricmp(str, propNames[i].name) == 0) {
938 const char* s; 953 const char* s;
939 s = propNames[i].alias?propNames[i].alias:propNames[i].name; 954 s = propNames[i].alias?propNames[i].alias:propNames[i].name;
940 return lookupStr(s); 955 return lookupStr(s);
941 } 956 }
942 return lookupStr(str); 957 return lookupStr(str);
943} 958}
944 959
945 960
946const char* lookupProp(const char* str) 961DLLEXPORT(const char*) lookupProp(const char* str)
947{ 962{
948 int i; 963 int i;
949 964
950 for (i = 0; propNames[i].name; i++) 965 for (i = 0; propNames[i].name; i++)
951 if (strcasecmp(str, propNames[i].name) == 0) { 966 if (stricmp(str, propNames[i].name) == 0) {
952 const char *s; 967 const char *s;
953 fieldedProp = propNames[i].fields; 968 fieldedProp = propNames[i].fields;
954 s = propNames[i].alias?propNames[i].alias:propNames[i].name; 969 s = propNames[i].alias?propNames[i].alias:propNames[i].name;
955 return lookupStr(s); 970 return lookupStr(s);
@@ -971,13 +986,9 @@ typedef struct OFile {
971 int alloc:1; 986 int alloc:1;
972 int fail:1; 987 int fail:1;
973 } OFile; 988 } OFile;
974 989
975
976/* vCalendar files need crlf linebreaks. The disabled functions didn't provide
977 that. */
978#if 0 990#if 0
979
980static void appendsOFile(OFile *fp, const char *s) 991static void appendsOFile(OFile *fp, const char *s)
981{ 992{
982 int slen; 993 int slen;
983 if (fp->fail) return; 994 if (fp->fail) return;
@@ -994,12 +1005,9 @@ stuff:
994 } 1005 }
995 else if (fp->alloc) { 1006 else if (fp->alloc) {
996 fp->limit = fp->limit + OFILE_REALLOC_SIZE; 1007 fp->limit = fp->limit + OFILE_REALLOC_SIZE;
997 if (OFILE_REALLOC_SIZE <= slen) fp->limit += slen; 1008 if (OFILE_REALLOC_SIZE <= slen) fp->limit += slen;
998 if (fp->s) 1009 fp->s = (char *) realloc(fp->s,fp->limit);
999 fp->s = realloc(fp->s,fp->limit);
1000 else
1001 fp->s = malloc(fp->limit);
1002 if (fp->s) goto stuff; 1010 if (fp->s) goto stuff;
1003 } 1011 }
1004 if (fp->alloc) 1012 if (fp->alloc)
1005 free(fp->s); 1013 free(fp->s);
@@ -1022,20 +1030,18 @@ stuff:
1022 return; 1030 return;
1023 } 1031 }
1024 else if (fp->alloc) { 1032 else if (fp->alloc) {
1025 fp->limit = fp->limit + OFILE_REALLOC_SIZE; 1033 fp->limit = fp->limit + OFILE_REALLOC_SIZE;
1026 fp->s = realloc(fp->s,fp->limit); 1034 fp->s = (char *) realloc(fp->s,fp->limit);
1027 if (fp->s) goto stuff; 1035 if (fp->s) goto stuff;
1028 } 1036 }
1029 if (fp->alloc) 1037 if (fp->alloc)
1030 free(fp->s); 1038 free(fp->s);
1031 fp->s = 0; 1039 fp->s = 0;
1032 fp->fail = 1; 1040 fp->fail = 1;
1033 } 1041 }
1034} 1042}
1035
1036#else 1043#else
1037
1038static void appendcOFile_(OFile *fp, char c) 1044static void appendcOFile_(OFile *fp, char c)
1039{ 1045{
1040 if (fp->fail) return; 1046 if (fp->fail) return;
1041 if (fp->fp) { 1047 if (fp->fp) {
@@ -1114,9 +1120,9 @@ static int writeBase64(OFile *fp, unsigned char *s, long len)
1114 1120
1115 quad[4] = 0; 1121 quad[4] = 0;
1116 1122
1117 while (cur < len) { 1123 while (cur < len) {
1118 /* collect the triplet of bytes into 'trip' */ 1124 /* collect the triplet of bytes into 'trip' */
1119 trip = 0; 1125 trip = 0;
1120 for (i = 0; i < 3; i++) { 1126 for (i = 0; i < 3; i++) {
1121 b = (cur < len) ? *(s + cur) : 0; 1127 b = (cur < len) ? *(s + cur) : 0;
1122 cur++; 1128 cur++;
@@ -1126,9 +1132,9 @@ static int writeBase64(OFile *fp, unsigned char *s, long len)
1126 for (i = 3; i >= 0; i--) { 1132 for (i = 3; i >= 0; i--) {
1127 b = (unsigned char)(trip & 0x3F); 1133 b = (unsigned char)(trip & 0x3F);
1128 trip = trip >> 6; 1134 trip = trip >> 6;
1129 if ((3 - i) < (cur - len)) 1135 if ((3 - i) < (cur - len))
1130 quad[i] = '='; /* pad char */ 1136 quad[i] = '='; /* pad char */
1131 else if (b < 26) quad[i] = (char)b + 'A'; 1137 else if (b < 26) quad[i] = (char)b + 'A';
1132 else if (b < 52) quad[i] = (char)(b - 26) + 'a'; 1138 else if (b < 52) quad[i] = (char)(b - 26) + 'a';
1133 else if (b < 62) quad[i] = (char)(b - 52) + '0'; 1139 else if (b < 62) quad[i] = (char)(b - 52) + '0';
1134 else if (b == 62) quad[i] = '+'; 1140 else if (b == 62) quad[i] = '+';
@@ -1144,44 +1150,57 @@ static int writeBase64(OFile *fp, unsigned char *s, long len)
1144 1150
1145 return 1; 1151 return 1;
1146} 1152}
1147 1153
1148/* this function really sucks. Too basic. */ 1154static void writeString(OFile *fp, const char *s)
1149static void writeQPString(OFile *fp, const char *s, int qp) 1155{
1156 appendsOFile(fp,s);
1157}
1158
1159static void writeQPString(OFile *fp, const char *s)
1150{ 1160{
1161 char buf[4];
1162 int count=0;
1151 const char *p = s; 1163 const char *p = s;
1164
1152 while (*p) { 1165 while (*p) {
1153 if (*p == '\n') { 1166 /* break up lines biggger than 75 chars */
1154 if (p[1]) appendsOFile(fp,"=0A="); 1167 if(count >=74){
1155 } 1168 count=0;
1156 if (*p == '=' && qp) 1169 appendsOFile(fp,"=\n");
1157 appendsOFile(fp,"=3D"); 1170 }
1158 else 1171
1159 appendcOFile(fp,*p); 1172 /* escape any non ASCII characters and '=' as per rfc1521 */
1160 p++; 1173 if (*p<= 0x1f || *p >=0x7f || *p == '=' ) {
1174 sprintf(buf,"=%02X",(unsigned char)*p);
1175 appendsOFile(fp,buf);
1176 count+=3;
1177 } else {
1178 appendcOFile(fp,*p);
1179 count++;
1180 }
1181 p++;
1161 } 1182 }
1162} 1183}
1163 1184
1185
1186
1164static void writeVObject_(OFile *fp, VObject *o); 1187static void writeVObject_(OFile *fp, VObject *o);
1165 1188
1166static void writeValue(OFile *fp, VObject *o, unsigned long size) 1189static void writeValue(OFile *fp, VObject *o, unsigned long size,int quote)
1167{ 1190{
1168 if (o == 0) return; 1191 if (o == 0) return;
1169 switch (VALUE_TYPE(o)) { 1192 switch (VALUE_TYPE(o)) {
1170 case VCVT_USTRINGZ: { 1193 case VCVT_USTRINGZ: {
1171 char *s = fakeCString(USTRINGZ_VALUE_OF(o)); 1194 char *s = fakeCString(USTRINGZ_VALUE_OF(o));
1172 if (isAPropertyOf(o, VCQuotedPrintableProp)) 1195 if(quote) writeQPString(fp, s);
1173 writeQPString(fp, s, 1); 1196 else writeString(fp,s);
1174 else
1175 writeQPString(fp, s, 0);
1176 deleteStr(s); 1197 deleteStr(s);
1177 break; 1198 break;
1178 } 1199 }
1179 case VCVT_STRINGZ: { 1200 case VCVT_STRINGZ: {
1180 if (isAPropertyOf(o, VCQuotedPrintableProp)) 1201 if(quote) writeQPString(fp, STRINGZ_VALUE_OF(o));
1181 writeQPString(fp, STRINGZ_VALUE_OF(o), 1); 1202 else writeString(fp,STRINGZ_VALUE_OF(o));
1182 else
1183 writeQPString(fp, STRINGZ_VALUE_OF(o), 0);
1184 break; 1203 break;
1185 } 1204 }
1186 case VCVT_UINT: { 1205 case VCVT_UINT: {
1187 char buf[16]; 1206 char buf[16];
@@ -1219,9 +1238,9 @@ static void writeAttrValue(OFile *fp, VObject *o)
1219 else 1238 else
1220 appendcOFile(fp,';'); 1239 appendcOFile(fp,';');
1221 if (VALUE_TYPE(o)) { 1240 if (VALUE_TYPE(o)) {
1222 appendcOFile(fp,'='); 1241 appendcOFile(fp,'=');
1223 writeValue(fp,o,0); 1242 writeValue(fp,o,0,0);
1224 } 1243 }
1225} 1244}
1226 1245
1227static void writeGroup(OFile *fp, VObject *o) 1246static void writeGroup(OFile *fp, VObject *o)
@@ -1229,12 +1248,11 @@ static void writeGroup(OFile *fp, VObject *o)
1229 char buf1[256]; 1248 char buf1[256];
1230 char buf2[256]; 1249 char buf2[256];
1231 strcpy(buf1,NAME_OF(o)); 1250 strcpy(buf1,NAME_OF(o));
1232 while ((o=isAPropertyOf(o,VCGroupingProp)) != 0) { 1251 while ((o=isAPropertyOf(o,VCGroupingProp)) != 0) {
1233 strncpy(buf2,STRINGZ_VALUE_OF(o),sizeof(buf2)); 1252 strcpy(buf2,STRINGZ_VALUE_OF(o));
1234 buf2[sizeof(buf2)] = '\0'; 1253 strcat(buf2,".");
1235 strncat(buf2,".",sizeof(buf2)-strlen(buf2)-1); 1254 strcat(buf2,buf1);
1236 strncat(buf2,buf1,sizeof(buf2)-strlen(buf2)-1);
1237 strcpy(buf1,buf2); 1255 strcpy(buf1,buf2);
1238 } 1256 }
1239 appendsOFile(fp,buf1); 1257 appendsOFile(fp,buf1);
1240} 1258}
@@ -1242,16 +1260,17 @@ static void writeGroup(OFile *fp, VObject *o)
1242static int inList(const char **list, const char *s) 1260static int inList(const char **list, const char *s)
1243{ 1261{
1244 if (list == 0) return 0; 1262 if (list == 0) return 0;
1245 while (*list) { 1263 while (*list) {
1246 if (strcasecmp(*list,s) == 0) return 1; 1264 if (stricmp(*list,s) == 0) return 1;
1247 list++; 1265 list++;
1248 } 1266 }
1249 return 0; 1267 return 0;
1250} 1268}
1251 1269
1252static void writeProp(OFile *fp, VObject *o) 1270static void writeProp(OFile *fp, VObject *o)
1253{ 1271{
1272 int isQuoted=0;
1254 if (NAME_OF(o)) { 1273 if (NAME_OF(o)) {
1255 struct PreDefProp *pi; 1274 struct PreDefProp *pi;
1256 VObjectIterator t; 1275 VObjectIterator t;
1257 const char **fields_ = 0; 1276 const char **fields_ = 0;
@@ -1269,25 +1288,27 @@ static void writeProp(OFile *fp, VObject *o)
1269 while (moreIteration(&t)) { 1288 while (moreIteration(&t)) {
1270 const char *s; 1289 const char *s;
1271 VObject *eachProp = nextVObject(&t); 1290 VObject *eachProp = nextVObject(&t);
1272 s = NAME_OF(eachProp); 1291 s = NAME_OF(eachProp);
1273 if (strcasecmp(VCGroupingProp,s) && !inList(fields_,s)) 1292 if (stricmp(VCGroupingProp,s) && !inList(fields_,s))
1274 writeAttrValue(fp,eachProp); 1293 writeAttrValue(fp,eachProp);
1294 if (stricmp(VCQPProp,s)==0 || stricmp(VCQuotedPrintableProp,s)==0)
1295 isQuoted=1;
1275 } 1296 }
1276 if (fields_) { 1297 if (fields_) {
1277 int i = 0, n = 0; 1298 int i = 0, n = 0;
1278 const char** fields = fields_; 1299 const char** fields = fields_;
1279 /* output prop as fields */ 1300 /* output prop as fields */
1280 appendcOFile(fp,':'); 1301 appendcOFile(fp,':');
1281 while (*fields) { 1302 while (*fields) {
1282 VObject *tl = isAPropertyOf(o,*fields); 1303 VObject *t = isAPropertyOf(o,*fields);
1283 i++; 1304 i++;
1284 if (tl) n = i; 1305 if (t) n = i;
1285 fields++; 1306 fields++;
1286 } 1307 }
1287 fields = fields_; 1308 fields = fields_;
1288 for (i=0;i<n;i++) { 1309 for (i=0;i<n;i++) {
1289 writeValue(fp,isAPropertyOf(o,*fields),0); 1310 writeValue(fp,isAPropertyOf(o,*fields),0,isQuoted);
1290 fields++; 1311 fields++;
1291 if (i<(n-1)) appendcOFile(fp,';'); 1312 if (i<(n-1)) appendcOFile(fp,';');
1292 } 1313 }
1293 } 1314 }
@@ -1297,9 +1318,9 @@ static void writeProp(OFile *fp, VObject *o)
1297 unsigned long size = 0; 1318 unsigned long size = 0;
1298 VObject *p = isAPropertyOf(o,VCDataSizeProp); 1319 VObject *p = isAPropertyOf(o,VCDataSizeProp);
1299 if (p) size = LONG_VALUE_OF(p); 1320 if (p) size = LONG_VALUE_OF(p);
1300 appendcOFile(fp,':'); 1321 appendcOFile(fp,':');
1301 writeValue(fp,o,size); 1322 writeValue(fp,o,size,isQuoted);
1302 } 1323 }
1303 1324
1304 appendcOFile(fp,'\n'); 1325 appendcOFile(fp,'\n');
1305} 1326}
@@ -1334,18 +1355,18 @@ void writeVObject(FILE *fp, VObject *o)
1334 initOFile(&ofp,fp); 1355 initOFile(&ofp,fp);
1335 writeVObject_(&ofp,o); 1356 writeVObject_(&ofp,o);
1336} 1357}
1337 1358
1338void writeVObjectToFile(char *fname, VObject *o) 1359DLLEXPORT(void) writeVObjectToFile(char *fname, VObject *o)
1339{ 1360{
1340 FILE *fp = fopen(fname,"w"); 1361 FILE *fp = fopen(fname,"w");
1341 if (fp) { 1362 if (fp) {
1342 writeVObject(fp,o); 1363 writeVObject(fp,o);
1343 fclose(fp); 1364 fclose(fp);
1344 } 1365 }
1345} 1366}
1346 1367
1347void writeVObjectsToFile(char *fname, VObject *list) 1368DLLEXPORT(void) writeVObjectsToFile(char *fname, VObject *list)
1348{ 1369{
1349 FILE *fp = fopen(fname,"w"); 1370 FILE *fp = fopen(fname,"w");
1350 if (fp) { 1371 if (fp) {
1351 while (list) { 1372 while (list) {
@@ -1355,9 +1376,9 @@ void writeVObjectsToFile(char *fname, VObject *list)
1355 fclose(fp); 1376 fclose(fp);
1356 } 1377 }
1357} 1378}
1358 1379
1359char* writeMemVObject(char *s, int *len, VObject *o) 1380DLLEXPORT(char*) writeMemVObject(char *s, int *len, VObject *o)
1360{ 1381{
1361 OFile ofp; 1382 OFile ofp;
1362 initMemOFile(&ofp,s,len?*len:0); 1383 initMemOFile(&ofp,s,len?*len:0);
1363 writeVObject_(&ofp,o); 1384 writeVObject_(&ofp,o);
@@ -1365,9 +1386,9 @@ char* writeMemVObject(char *s, int *len, VObject *o)
1365 appendcOFile(&ofp,0); 1386 appendcOFile(&ofp,0);
1366 return ofp.s; 1387 return ofp.s;
1367} 1388}
1368 1389
1369char* writeMemVObjects(char *s, int *len, VObject *list) 1390DLLEXPORT(char*) writeMemVObjects(char *s, int *len, VObject *list)
1370{ 1391{
1371 OFile ofp; 1392 OFile ofp;
1372 initMemOFile(&ofp,s,len?*len:0); 1393 initMemOFile(&ofp,s,len?*len:0);
1373 while (list) { 1394 while (list) {
@@ -1381,9 +1402,9 @@ char* writeMemVObjects(char *s, int *len, VObject *list)
1381 1402
1382/*---------------------------------------------------------------------- 1403/*----------------------------------------------------------------------
1383 APIs to do fake Unicode stuff. 1404 APIs to do fake Unicode stuff.
1384 ----------------------------------------------------------------------*/ 1405 ----------------------------------------------------------------------*/
1385wchar_t* fakeUnicode(const char *ps, int *bytes) 1406DLLEXPORT(wchar_t*) fakeUnicode(const char *ps, int *bytes)
1386{ 1407{
1387 wchar_t *r, *pw; 1408 wchar_t *r, *pw;
1388 int len = strlen(ps)+1; 1409 int len = strlen(ps)+1;
1389 1410
@@ -1404,20 +1425,20 @@ wchar_t* fakeUnicode(const char *ps, int *bytes)
1404 1425
1405 return r; 1426 return r;
1406} 1427}
1407 1428
1408int uStrLen(const wchar_t *u) 1429DLLEXPORT(int) uStrLen(const wchar_t *u)
1409{ 1430{
1410 int i = 0; 1431 int i = 0;
1411 while (*u != (wchar_t)0) { u++; i++; } 1432 while (*u != (wchar_t)0) { u++; i++; }
1412 return i; 1433 return i;
1413} 1434}
1414 1435
1415char* fakeCString(const wchar_t *u) 1436DLLEXPORT(char*) fakeCString(const wchar_t *u)
1416{ 1437{
1417 char *s, *t; 1438 char *s, *t;
1418 int len = uStrLen(u) + 1; 1439 int len = uStrLen(u) + 1;
1419 t = s = (char*)malloc(len+1); 1440 t = s = (char*)malloc(len);
1420 while (*u) { 1441 while (*u) {
1421 if (*u == (wchar_t)0x2028) 1442 if (*u == (wchar_t)0x2028)
1422 *t = '\n'; 1443 *t = '\n';
1423 else if (*u == (wchar_t)0x2029) 1444 else if (*u == (wchar_t)0x2029)