summaryrefslogtreecommitdiff
path: root/library/backend/vobject.cpp
Unidiff
Diffstat (limited to 'library/backend/vobject.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--library/backend/vobject.cpp2534
1 files changed, 1315 insertions, 1219 deletions
diff --git a/library/backend/vobject.cpp b/library/backend/vobject.cpp
index 9c2ba3b..e6f6b78 100644
--- a/library/backend/vobject.cpp
+++ b/library/backend/vobject.cpp
@@ -1,1219 +1,1315 @@
1/*************************************************************************** 1/***************************************************************************
2(C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International 2(C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International
3Business Machines Corporation and Siemens Rolm Communications Inc. 3Business Machines Corporation and Siemens Rolm Communications Inc.
4 4
5For purposes of this license notice, the term Licensors shall mean, 5For purposes of this license notice, the term Licensors shall mean,
6collectively, Apple Computer, Inc., AT&T Corp., International 6collectively, Apple Computer, Inc., AT&T Corp., International
7Business Machines Corporation and Siemens Rolm Communications Inc. 7Business Machines Corporation and Siemens Rolm Communications Inc.
8The term Licensor shall mean any of the Licensors. 8The term Licensor shall mean any of the Licensors.
9 9
10Subject to acceptance of the following conditions, permission is hereby 10Subject to acceptance of the following conditions, permission is hereby
11granted by Licensors without the need for written agreement and without 11granted by Licensors without the need for written agreement and without
12license or royalty fees, to use, copy, modify and distribute this 12license or royalty fees, to use, copy, modify and distribute this
13software for any purpose. 13software for any purpose.
14 14
15The above copyright notice and the following four paragraphs must be 15The above copyright notice and the following four paragraphs must be
16reproduced in all copies of this software and any software including 16reproduced in all copies of this software and any software including
17this software. 17this software.
18 18
19THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE 19THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE
20ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR 20ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR
21MODIFICATIONS. 21MODIFICATIONS.
22 22
23IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT, 23IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT,
24INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT 24INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT
25OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 25OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26DAMAGE. 26DAMAGE.
27 27
28EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, 28EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED,
29INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE 29INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE
30IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31PURPOSE. 31PURPOSE.
32 32
33The software is provided with RESTRICTED RIGHTS. Use, duplication, or 33The software is provided with RESTRICTED RIGHTS. Use, duplication, or
34disclosure by the government are subject to restrictions set forth in 34disclosure by the government are subject to restrictions set forth in
35DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. 35DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable.
36 36
37***************************************************************************/ 37***************************************************************************/
38 38
39/* 39/*
40 * src: vobject.c 40 * src: vobject.c
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 #ifndef MWERKS 45 #ifndef MWERKS
46#include <malloc.h> 46#include <malloc.h>
47#endif 47#endif
48 48
49#include "vobject_p.h" 49#include "vobject_p.h"
50#include "qfiledirect_p.h" 50#include "qfiledirect_p.h"
51#include <string.h> 51#include <string.h>
52#include <stdio.h> 52#include <stdio.h>
53#include <fcntl.h> 53#include <fcntl.h>
54//#include <io.h> 54//#include <io.h>
55 55
56 56
57 #define NAME_OF(o) o->id 57 #define NAME_OF(o) o->id
58 #define VALUE_TYPE(o) o->valType 58 #define VALUE_TYPE(o) o->valType
59 #define STRINGZ_VALUE_OF(o) o->val.strs 59 #define STRINGZ_VALUE_OF(o) o->val.strs
60 #define INTEGER_VALUE_OF(o) o->val.i 60 #define INTEGER_VALUE_OF(o) o->val.i
61 #define LONG_VALUE_OF(o) o->val.l 61 #define LONG_VALUE_OF(o) o->val.l
62 #define ANY_VALUE_OF(o) o->val.any 62 #define ANY_VALUE_OF(o) o->val.any
63 #define VOBJECT_VALUE_OF(o) o->val.vobj 63 #define VOBJECT_VALUE_OF(o) o->val.vobj
64 64
65typedef union ValueItem { 65typedef union ValueItem {
66 const char *strs; 66 const char *strs;
67 unsigned int i; 67 unsigned int i;
68 unsigned long l; 68 unsigned long l;
69 void *any; 69 void *any;
70 VObject *vobj; 70 VObject *vobj;
71 } ValueItem; 71 } ValueItem;
72 72
73struct VObject { 73struct VObject {
74 VObject *next; 74 VObject *next;
75 const char *id; 75 const char *id;
76 VObject *prop; 76 VObject *prop;
77 unsigned short valType; 77 unsigned short valType;
78 ValueItem val; 78 ValueItem val;
79 }; 79 };
80 80
81typedef struct StrItem StrItem; 81typedef struct StrItem StrItem;
82 82
83struct StrItem { 83struct StrItem {
84 StrItem *next; 84 StrItem *next;
85 const char *s; 85 const char *s;
86 unsigned int refCnt; 86 unsigned int refCnt;
87 }; 87 };
88 88
89const char** fieldedProp; 89const char** fieldedProp;
90 90
91 91
92 92
93/*---------------------------------------------------------------------- 93/*----------------------------------------------------------------------
94 The following functions involve with memory allocation: 94 The following functions involve with memory allocation:
95 newVObject 95 newVObject
96 deleteVObject 96 deleteVObject
97 dupStr 97 dupStr
98 deleteStr 98 deleteStr
99 newStrItem 99 newStrItem
100 deleteStrItem 100 deleteStrItem
101 ----------------------------------------------------------------------*/ 101 ----------------------------------------------------------------------*/
102 102
103DLLEXPORT(VObject*) newVObject_(const char *id) 103DLLEXPORT(VObject*) newVObject_(const char *id)
104{ 104{
105 VObject *p = (VObject*)malloc(sizeof(VObject)); 105 VObject *p = (VObject*)malloc(sizeof(VObject));
106 p->next = 0; 106 p->next = 0;
107 p->id = id; 107 p->id = id;
108 p->prop = 0; 108 p->prop = 0;
109 VALUE_TYPE(p) = 0; 109 VALUE_TYPE(p) = 0;
110 ANY_VALUE_OF(p) = 0; 110 ANY_VALUE_OF(p) = 0;
111 return p; 111 return p;
112} 112}
113 113
114DLLEXPORT(VObject*) newVObject(const char *id) 114DLLEXPORT(VObject*) newVObject(const char *id)
115{ 115{
116 return newVObject_(lookupStr(id)); 116 return newVObject_(lookupStr(id));
117} 117}
118 118
119DLLEXPORT(void) deleteVObject(VObject *p) 119DLLEXPORT(void) deleteVObject(VObject *p)
120{ 120{
121 unUseStr(p->id); 121 unUseStr(p->id);
122 free(p); 122 free(p);
123} 123}
124 124
125DLLEXPORT(char*) dupStr(const char *s, unsigned int size) 125DLLEXPORT(char*) dupStr(const char *s, unsigned int size)
126{ 126{
127 char *t; 127 char *t;
128 if (size == 0) { 128 if (size == 0) {
129 size = strlen(s); 129 size = strlen(s);
130 } 130 }
131 t = (char*)malloc(size+1); 131 t = (char*)malloc(size+1);
132 if (t) { 132 if (t) {
133 memcpy(t,s,size); 133 memcpy(t,s,size);
134 t[size] = 0; 134 t[size] = 0;
135 return t; 135 return t;
136 } 136 }
137 else { 137 else {
138 return (char*)0; 138 return (char*)0;
139 } 139 }
140} 140}
141 141
142DLLEXPORT(void) deleteStr(const char *p) 142DLLEXPORT(void) deleteStr(const char *p)
143{ 143{
144 if (p) free((void*)p); 144 if (p) free((void*)p);
145} 145}
146 146
147 147
148static StrItem* newStrItem(const char *s, StrItem *next) 148static StrItem* newStrItem(const char *s, StrItem *next)
149{ 149{
150 StrItem *p = (StrItem*)malloc(sizeof(StrItem)); 150 StrItem *p = (StrItem*)malloc(sizeof(StrItem));
151 p->next = next; 151 p->next = next;
152 p->s = s; 152 p->s = s;
153 p->refCnt = 1; 153 p->refCnt = 1;
154 return p; 154 return p;
155} 155}
156 156
157static void deleteStrItem(StrItem *p) 157static void deleteStrItem(StrItem *p)
158{ 158{
159 free((void*)p); 159 free((void*)p);
160} 160}
161 161
162 162
163/*---------------------------------------------------------------------- 163/*----------------------------------------------------------------------
164 The following function provide accesses to VObject's value. 164 The following function provide accesses to VObject's value.
165 ----------------------------------------------------------------------*/ 165 ----------------------------------------------------------------------*/
166 166
167DLLEXPORT(const char*) vObjectName(VObject *o) 167DLLEXPORT(const char*) vObjectName(VObject *o)
168{ 168{
169 return NAME_OF(o); 169 return NAME_OF(o);
170} 170}
171 171
172DLLEXPORT(void) setVObjectName(VObject *o, const char* id) 172DLLEXPORT(void) setVObjectName(VObject *o, const char* id)
173{ 173{
174 NAME_OF(o) = id; 174 NAME_OF(o) = id;
175} 175}
176 176
177DLLEXPORT(const char*) vObjectStringZValue(VObject *o) 177DLLEXPORT(const char*) vObjectStringZValue(VObject *o)
178{ 178{
179 return STRINGZ_VALUE_OF(o); 179 return STRINGZ_VALUE_OF(o);
180} 180}
181 181
182DLLEXPORT(void) setVObjectStringZValue(VObject *o, const char *s) 182DLLEXPORT(void) setVObjectStringZValue(VObject *o, const char *s)
183{ 183{
184 STRINGZ_VALUE_OF(o) = dupStr(s,0); 184 STRINGZ_VALUE_OF(o) = dupStr(s,0);
185 VALUE_TYPE(o) = VCVT_STRINGZ; 185 VALUE_TYPE(o) = VCVT_STRINGZ;
186} 186}
187 187
188DLLEXPORT(void) setVObjectStringZValue_(VObject *o, const char *s) 188DLLEXPORT(void) setVObjectStringZValue_(VObject *o, const char *s)
189{ 189{
190 STRINGZ_VALUE_OF(o) = s; 190 STRINGZ_VALUE_OF(o) = s;
191 VALUE_TYPE(o) = VCVT_STRINGZ; 191 VALUE_TYPE(o) = VCVT_STRINGZ;
192} 192}
193 193
194DLLEXPORT(unsigned int) vObjectIntegerValue(VObject *o) 194DLLEXPORT(unsigned int) vObjectIntegerValue(VObject *o)
195{ 195{
196 return INTEGER_VALUE_OF(o); 196 return INTEGER_VALUE_OF(o);
197} 197}
198 198
199DLLEXPORT(void) setVObjectIntegerValue(VObject *o, unsigned int i) 199DLLEXPORT(void) setVObjectIntegerValue(VObject *o, unsigned int i)
200{ 200{
201 INTEGER_VALUE_OF(o) = i; 201 INTEGER_VALUE_OF(o) = i;
202 VALUE_TYPE(o) = VCVT_UINT; 202 VALUE_TYPE(o) = VCVT_UINT;
203} 203}
204 204
205DLLEXPORT(unsigned long) vObjectLongValue(VObject *o) 205DLLEXPORT(unsigned long) vObjectLongValue(VObject *o)
206{ 206{
207 return LONG_VALUE_OF(o); 207 return LONG_VALUE_OF(o);
208} 208}
209 209
210DLLEXPORT(void) setVObjectLongValue(VObject *o, unsigned long l) 210DLLEXPORT(void) setVObjectLongValue(VObject *o, unsigned long l)
211{ 211{
212 LONG_VALUE_OF(o) = l; 212 LONG_VALUE_OF(o) = l;
213 VALUE_TYPE(o) = VCVT_ULONG; 213 VALUE_TYPE(o) = VCVT_ULONG;
214} 214}
215 215
216DLLEXPORT(void*) vObjectAnyValue(VObject *o) 216DLLEXPORT(void*) vObjectAnyValue(VObject *o)
217{ 217{
218 return ANY_VALUE_OF(o); 218 return ANY_VALUE_OF(o);
219} 219}
220 220
221DLLEXPORT(void) setVObjectAnyValue(VObject *o, void *t) 221DLLEXPORT(void) setVObjectAnyValue(VObject *o, void *t)
222{ 222{
223 ANY_VALUE_OF(o) = t; 223 ANY_VALUE_OF(o) = t;
224 VALUE_TYPE(o) = VCVT_RAW; 224 VALUE_TYPE(o) = VCVT_RAW;
225} 225}
226 226
227DLLEXPORT(VObject*) vObjectVObjectValue(VObject *o) 227DLLEXPORT(VObject*) vObjectVObjectValue(VObject *o)
228{ 228{
229 return VOBJECT_VALUE_OF(o); 229 return VOBJECT_VALUE_OF(o);
230} 230}
231 231
232DLLEXPORT(void) setVObjectVObjectValue(VObject *o, VObject *p) 232DLLEXPORT(void) setVObjectVObjectValue(VObject *o, VObject *p)
233{ 233{
234 VOBJECT_VALUE_OF(o) = p; 234 VOBJECT_VALUE_OF(o) = p;
235 VALUE_TYPE(o) = VCVT_VOBJECT; 235 VALUE_TYPE(o) = VCVT_VOBJECT;
236} 236}
237 237
238DLLEXPORT(int) vObjectValueType(VObject *o) 238DLLEXPORT(int) vObjectValueType(VObject *o)
239{ 239{
240 return VALUE_TYPE(o); 240 return VALUE_TYPE(o);
241} 241}
242 242
243 243
244/*---------------------------------------------------------------------- 244/*----------------------------------------------------------------------
245 The following functions can be used to build VObject. 245 The following functions can be used to build VObject.
246 ----------------------------------------------------------------------*/ 246 ----------------------------------------------------------------------*/
247 247
248DLLEXPORT(VObject*) addVObjectProp(VObject *o, VObject *p) 248DLLEXPORT(VObject*) addVObjectProp(VObject *o, VObject *p)
249{ 249{
250 /* circular link list pointed to tail */ 250 /* circular link list pointed to tail */
251 /* 251 /*
252 o {next,id,prop,val} 252 o {next,id,prop,val}
253 V 253 V
254 pn {next,id,prop,val} 254 pn {next,id,prop,val}
255 V 255 V
256 ... 256 ...
257 p1 {next,id,prop,val} 257 p1 {next,id,prop,val}
258 V 258 V
259 pn 259 pn
260 --> 260 -->
261 o {next,id,prop,val} 261 o {next,id,prop,val}
262 V 262 V
263 pn {next,id,prop,val} 263 pn {next,id,prop,val}
264 V 264 V
265 p {next,id,prop,val} 265 p {next,id,prop,val}
266 ... 266 ...
267 p1 {next,id,prop,val} 267 p1 {next,id,prop,val}
268 V 268 V
269 pn 269 pn
270 */ 270 */
271 271
272 VObject *tail = o->prop; 272 VObject *tail = o->prop;
273 if (tail) { 273 if (tail) {
274 p->next = tail->next; 274 p->next = tail->next;
275 o->prop = tail->next = p; 275 o->prop = tail->next = p;
276 } 276 }
277 else { 277 else {
278 o->prop = p->next = p; 278 o->prop = p->next = p;
279 } 279 }
280 return p; 280 return p;
281} 281}
282 282
283DLLEXPORT(VObject*) addProp(VObject *o, const char *id) 283DLLEXPORT(VObject*) addProp(VObject *o, const char *id)
284{ 284{
285 return addVObjectProp(o,newVObject(id)); 285 return addVObjectProp(o,newVObject(id));
286} 286}
287 287
288DLLEXPORT(VObject*) addProp_(VObject *o, const char *id) 288DLLEXPORT(VObject*) addProp_(VObject *o, const char *id)
289{ 289{
290 return addVObjectProp(o,newVObject_(id)); 290 return addVObjectProp(o,newVObject_(id));
291} 291}
292 292
293DLLEXPORT(void) addList(VObject **o, VObject *p) 293DLLEXPORT(void) addList(VObject **o, VObject *p)
294{ 294{
295 p->next = 0; 295 p->next = 0;
296 if (*o == 0) { 296 if (*o == 0) {
297 *o = p; 297 *o = p;
298 } 298 }
299 else { 299 else {
300 VObject *t = *o; 300 VObject *t = *o;
301 while (t->next) { 301 while (t->next) {
302 t = t->next; 302 t = t->next;
303 } 303 }
304 t->next = p; 304 t->next = p;
305 } 305 }
306} 306}
307 307
308DLLEXPORT(VObject*) nextVObjectInList(VObject *o) 308DLLEXPORT(VObject*) nextVObjectInList(VObject *o)
309{ 309{
310 return o->next; 310 return o->next;
311} 311}
312 312
313DLLEXPORT(VObject*) setValueWithSize_(VObject *prop, void *val, unsigned int size) 313DLLEXPORT(VObject*) setValueWithSize_(VObject *prop, void *val, unsigned int size)
314{ 314{
315 VObject *sizeProp; 315 VObject *sizeProp;
316 setVObjectAnyValue(prop, val); 316 setVObjectAnyValue(prop, val);
317 sizeProp = addProp(prop,VCDataSizeProp); 317 sizeProp = addProp(prop,VCDataSizeProp);
318 setVObjectLongValue(sizeProp, size); 318 setVObjectLongValue(sizeProp, size);
319 return prop; 319 return prop;
320} 320}
321 321
322DLLEXPORT(VObject*) setValueWithSize(VObject *prop, void *val, unsigned int size) 322DLLEXPORT(VObject*) setValueWithSize(VObject *prop, void *val, unsigned int size)
323{ 323{
324 void *p = dupStr((const char *)val,size); 324 void *p = dupStr((const char *)val,size);
325 return setValueWithSize_(prop,p,p?size:0); 325 return setValueWithSize_(prop,p,p?size:0);
326} 326}
327 327
328DLLEXPORT(void) initPropIterator(VObjectIterator *i, VObject *o) 328DLLEXPORT(void) initPropIterator(VObjectIterator *i, VObject *o)
329{ 329{
330 i->start = o->prop; 330 i->start = o->prop;
331 i->next = 0; 331 i->next = 0;
332} 332}
333 333
334DLLEXPORT(void) initVObjectIterator(VObjectIterator *i, VObject *o) 334DLLEXPORT(void) initVObjectIterator(VObjectIterator *i, VObject *o)
335{ 335{
336 i->start = o->next; 336 i->start = o->next;
337 i->next = 0; 337 i->next = 0;
338} 338}
339 339
340DLLEXPORT(int) moreIteration(VObjectIterator *i) 340DLLEXPORT(int) moreIteration(VObjectIterator *i)
341{ 341{
342 return (i->start && (i->next==0 || i->next!=i->start)); 342 return (i->start && (i->next==0 || i->next!=i->start));
343} 343}
344 344
345DLLEXPORT(VObject*) nextVObject(VObjectIterator *i) 345DLLEXPORT(VObject*) nextVObject(VObjectIterator *i)
346{ 346{
347 if (i->start && i->next != i->start) { 347 if (i->start && i->next != i->start) {
348 if (i->next == 0) { 348 if (i->next == 0) {
349 i->next = i->start->next; 349 i->next = i->start->next;
350 return i->next; 350 return i->next;
351 } 351 }
352 else { 352 else {
353 i->next = i->next->next; 353 i->next = i->next->next;
354 return i->next; 354 return i->next;
355 } 355 }
356 } 356 }
357 else return (VObject*)0; 357 else return (VObject*)0;
358} 358}
359 359
360DLLEXPORT(VObject*) isAPropertyOf(VObject *o, const char *id) 360DLLEXPORT(VObject*) isAPropertyOf(VObject *o, const char *id)
361{ 361{
362 VObjectIterator i; 362 VObjectIterator i;
363 initPropIterator(&i,o); 363 initPropIterator(&i,o);
364 while (moreIteration(&i)) { 364 while (moreIteration(&i)) {
365 VObject *each = nextVObject(&i); 365 VObject *each = nextVObject(&i);
366 if (!qstricmp(id,each->id)) 366 if (!qstricmp(id,each->id))
367 return each; 367 return each;
368 } 368 }
369 return (VObject*)0; 369 return (VObject*)0;
370} 370}
371 371
372DLLEXPORT(VObject*) addGroup(VObject *o, const char *g) 372DLLEXPORT(VObject*) addGroup(VObject *o, const char *g)
373{ 373{
374 /* 374 /*
375 a.b.c 375 a.b.c
376 --> 376 -->
377 prop(c) 377 prop(c)
378 prop(VCGrouping=b) 378 prop(VCGrouping=b)
379 prop(VCGrouping=a) 379 prop(VCGrouping=a)
380 */ 380 */
381 char *dot = strrchr(g,'.'); 381 char *dot = strrchr(g,'.');
382 if (dot) { 382 if (dot) {
383 VObject *p, *t; 383 VObject *p, *t;
384 char *gs, *n = dot+1; 384 char *gs, *n = dot+1;
385 gs = dupStr(g,0);/* so we can write to it. */ 385 gs = dupStr(g,0);/* so we can write to it. */
386 /* used to be 386 /* used to be
387 * t = p = addProp_(o,lookupProp_(n)); 387 * t = p = addProp_(o,lookupProp_(n));
388 */ 388 */
389 t = p = addProp_(o,lookupProp(n)); 389 t = p = addProp_(o,lookupProp(n));
390 dot = strrchr(gs,'.'); 390 dot = strrchr(gs,'.');
391 *dot = 0; 391 *dot = 0;
392 do { 392 do {
393 dot = strrchr(gs,'.'); 393 dot = strrchr(gs,'.');
394 if (dot) { 394 if (dot) {
395 n = dot+1; 395 n = dot+1;
396 *dot=0; 396 *dot=0;
397 } 397 }
398 else 398 else
399 n = gs; 399 n = gs;
400 /* property(VCGroupingProp=n); 400 /* property(VCGroupingProp=n);
401 *and the value may have VCGrouping property 401 *and the value may have VCGrouping property
402 */ 402 */
403 t = addProp(t,VCGroupingProp); 403 t = addProp(t,VCGroupingProp);
404 setVObjectStringZValue(t,lookupProp_(n)); 404 setVObjectStringZValue(t,lookupProp_(n));
405 } while (n != gs); 405 } while (n != gs);
406 deleteStr(gs); 406 deleteStr(gs);
407 return p; 407 return p;
408 } 408 }
409 else 409 else
410 return addProp_(o,lookupProp(g)); 410 return addProp_(o,lookupProp(g));
411} 411}
412 412
413DLLEXPORT(VObject*) addPropValue(VObject *o, const char *p, const char *v) 413DLLEXPORT(VObject*) addPropValue(VObject *o, const char *p, const char *v)
414{ 414{
415 VObject *prop; 415 VObject *prop;
416 prop = addProp(o,p); 416 prop = addProp(o,p);
417 setVObjectStringZValue_(prop, strdup( v ) ); 417 setVObjectStringZValue_(prop, strdup( v ) );
418 return prop; 418 return prop;
419} 419}
420 420
421DLLEXPORT(VObject*) addPropSizedValue_(VObject *o, const char *p, const char *v, 421DLLEXPORT(VObject*) addPropSizedValue_(VObject *o, const char *p, const char *v,
422 unsigned int size) 422 unsigned int size)
423{ 423{
424 VObject *prop; 424 VObject *prop;
425 prop = addProp(o,p); 425 prop = addProp(o,p);
426 setValueWithSize_(prop, (void*)v, size); 426 setValueWithSize_(prop, (void*)v, size);
427 return prop; 427 return prop;
428} 428}
429 429
430DLLEXPORT(VObject*) addPropSizedValue(VObject *o, const char *p, const char *v, 430DLLEXPORT(VObject*) addPropSizedValue(VObject *o, const char *p, const char *v,
431 unsigned int size) 431 unsigned int size)
432{ 432{
433 return addPropSizedValue_(o,p,dupStr(v,size),size); 433 return addPropSizedValue_(o,p,dupStr(v,size),size);
434} 434}
435 435
436 436
437DLLEXPORT(void) cleanVObject(VObject *o) 437DLLEXPORT(void) cleanVObject(VObject *o)
438{ 438{
439 if (o == 0) return; 439 if (o == 0) return;
440 if (o->prop) { 440 if (o->prop) {
441 /* destroy time: cannot use the iterator here. 441 /* destroy time: cannot use the iterator here.
442 Have to break the cycle in the circular link 442 Have to break the cycle in the circular link
443 list and turns it into regular NULL-terminated 443 list and turns it into regular NULL-terminated
444 list -- since at some point of destruction, 444 list -- since at some point of destruction,
445 the reference entry for the iterator to work 445 the reference entry for the iterator to work
446 will not longer be valid. 446 will not longer be valid.
447 */ 447 */
448 VObject *p; 448 VObject *p;
449 p = o->prop->next; 449 p = o->prop->next;
450 o->prop->next = 0; 450 o->prop->next = 0;
451 do { 451 do {
452 VObject *t = p->next; 452 VObject *t = p->next;
453 cleanVObject(p); 453 cleanVObject(p);
454 p = t; 454 p = t;
455 } while (p); 455 } while (p);
456 } 456 }
457 switch (VALUE_TYPE(o)) { 457 switch (VALUE_TYPE(o)) {
458 case VCVT_STRINGZ: 458 case VCVT_STRINGZ:
459 case VCVT_RAW: 459 case VCVT_RAW:
460 // assume they are all allocated by malloc. 460 // assume they are all allocated by malloc.
461 free((char*)STRINGZ_VALUE_OF(o)); 461 free((char*)STRINGZ_VALUE_OF(o));
462 break; 462 break;
463 case VCVT_VOBJECT: 463 case VCVT_VOBJECT:
464 cleanVObject(VOBJECT_VALUE_OF(o)); 464 cleanVObject(VOBJECT_VALUE_OF(o));
465 break; 465 break;
466 } 466 }
467 deleteVObject(o); 467 deleteVObject(o);
468} 468}
469 469
470DLLEXPORT(void) cleanVObjects(VObject *list) 470DLLEXPORT(void) cleanVObjects(VObject *list)
471{ 471{
472 while (list) { 472 while (list) {
473 VObject *t = list; 473 VObject *t = list;
474 list = nextVObjectInList(list); 474 list = nextVObjectInList(list);
475 cleanVObject(t); 475 cleanVObject(t);
476 } 476 }
477} 477}
478 478
479/*---------------------------------------------------------------------- 479/*----------------------------------------------------------------------
480 The following is a String Table Facilities. 480 The following is a String Table Facilities.
481 ----------------------------------------------------------------------*/ 481 ----------------------------------------------------------------------*/
482 482
483#define STRTBLSIZE 255 483#define STRTBLSIZE 255
484 484
485static StrItem *strTbl[STRTBLSIZE]; 485static StrItem *strTbl[STRTBLSIZE];
486 486
487static unsigned int hashStr(const char *s) 487static unsigned int hashStr(const char *s)
488{ 488{
489 unsigned int h = 0; 489 unsigned int h = 0;
490 int i; 490 int i;
491 for (i=0;s[i];i++) { 491 for (i=0;s[i];i++) {
492 h += s[i]*i; 492 h += s[i]*i;
493 } 493 }
494 return h % STRTBLSIZE; 494 return h % STRTBLSIZE;
495} 495}
496 496
497DLLEXPORT(const char*) lookupStr(const char *s) 497DLLEXPORT(const char*) lookupStr(const char *s)
498{ 498{
499 StrItem *t; 499 StrItem *t;
500 unsigned int h = hashStr(s); 500 unsigned int h = hashStr(s);
501 if ((t = strTbl[h]) != 0) { 501 if ((t = strTbl[h]) != 0) {
502 do { 502 do {
503 if (qstricmp(t->s,s) == 0) { 503 if (qstricmp(t->s,s) == 0) {
504 t->refCnt++; 504 t->refCnt++;
505 return t->s; 505 return t->s;
506 } 506 }
507 t = t->next; 507 t = t->next;
508 } while (t); 508 } while (t);
509 } 509 }
510 s = dupStr(s,0); 510 s = dupStr(s,0);
511 strTbl[h] = newStrItem(s,strTbl[h]); 511 strTbl[h] = newStrItem(s,strTbl[h]);
512 return s; 512 return s;
513} 513}
514 514
515DLLEXPORT(void) unUseStr(const char *s) 515DLLEXPORT(void) unUseStr(const char *s)
516{ 516{
517 StrItem *t, *p; 517 StrItem *t, *p;
518 unsigned int h = hashStr(s); 518 unsigned int h = hashStr(s);
519 if ((t = strTbl[h]) != 0) { 519 if ((t = strTbl[h]) != 0) {
520 p = t; 520 p = t;
521 do { 521 do {
522 if (qstricmp(t->s,s) == 0) { 522 if (qstricmp(t->s,s) == 0) {
523 t->refCnt--; 523 t->refCnt--;
524 if (t->refCnt == 0) { 524 if (t->refCnt == 0) {
525 if (p == strTbl[h]) { 525 if (p == strTbl[h]) {
526 strTbl[h] = t->next; 526 strTbl[h] = t->next;
527 } 527 }
528 else { 528 else {
529 p->next = t->next; 529 p->next = t->next;
530 } 530 }
531 deleteStr(t->s); 531 deleteStr(t->s);
532 deleteStrItem(t); 532 deleteStrItem(t);
533 return; 533 return;
534 } 534 }
535 } 535 }
536 p = t; 536 p = t;
537 t = t->next; 537 t = t->next;
538 } while (t); 538 } while (t);
539 } 539 }
540} 540}
541 541
542DLLEXPORT(void) cleanStrTbl() 542DLLEXPORT(void) cleanStrTbl()
543{ 543{
544 int i; 544 int i;
545 for (i=0; i<STRTBLSIZE;i++) { 545 for (i=0; i<STRTBLSIZE;i++) {
546 StrItem *t = strTbl[i]; 546 StrItem *t = strTbl[i];
547 while (t) { 547 while (t) {
548 StrItem *p; 548 StrItem *p;
549 deleteStr(t->s); 549 deleteStr(t->s);
550 p = t; 550 p = t;
551 t = t->next; 551 t = t->next;
552 deleteStrItem(p); 552 deleteStrItem(p);
553 } while (t); 553 } while (t);
554 strTbl[i] = 0; 554 strTbl[i] = 0;
555 } 555 }
556} 556}
557 557
558 558
559struct PreDefProp { 559struct PreDefProp {
560 const char *name; 560 const char *name;
561 const char *alias; 561 const char *alias;
562 const char** fields; 562 const char** fields;
563 unsigned int flags; 563 unsigned int flags;
564 }; 564 };
565 565
566/* flags in PreDefProp */ 566/* flags in PreDefProp */
567 #define PD_BEGIN0x1 567 #define PD_BEGIN0x1
568 #define PD_INTERNAL0x2 568 #define PD_INTERNAL0x2
569 569
570static const char *adrFields[] = { 570static const char *adrFields[] = {
571 VCPostalBoxProp, 571 VCPostalBoxProp,
572 VCExtAddressProp, 572 VCExtAddressProp,
573 VCStreetAddressProp, 573 VCStreetAddressProp,
574 VCCityProp, 574 VCCityProp,
575 VCRegionProp, 575 VCRegionProp,
576 VCPostalCodeProp, 576 VCPostalCodeProp,
577 VCCountryNameProp, 577 VCCountryNameProp,
578 0 578 0
579}; 579};
580 580
581static const char *nameFields[] = { 581static const char *nameFields[] = {
582 VCFamilyNameProp, 582 VCFamilyNameProp,
583 VCGivenNameProp, 583 VCGivenNameProp,
584 VCAdditionalNamesProp, 584 VCAdditionalNamesProp,
585 VCNamePrefixesProp, 585 VCNamePrefixesProp,
586 VCNameSuffixesProp, 586 VCNameSuffixesProp,
587 NULL 587 NULL
588 }; 588 };
589 589
590static const char *orgFields[] = { 590static const char *orgFields[] = {
591 VCOrgNameProp, 591 VCOrgNameProp,
592 VCOrgUnitProp, 592 VCOrgUnitProp,
593 VCOrgUnit2Prop, 593 VCOrgUnit2Prop,
594 VCOrgUnit3Prop, 594 VCOrgUnit3Prop,
595 VCOrgUnit4Prop, 595 VCOrgUnit4Prop,
596 NULL 596 NULL
597 }; 597 };
598 598
599static const char *AAlarmFields[] = { 599static const char *AAlarmFields[] = {
600 VCRunTimeProp, 600 VCRunTimeProp,
601 VCSnoozeTimeProp, 601 VCSnoozeTimeProp,
602 VCRepeatCountProp, 602 VCRepeatCountProp,
603 VCAudioContentProp, 603 VCAudioContentProp,
604 0 604 0
605 }; 605 };
606 606
607/* ExDate -- has unamed fields */ 607/* ExDate -- has unamed fields */
608/* RDate -- has unamed fields */ 608/* RDate -- has unamed fields */
609 609
610static const char *DAlarmFields[] = { 610static const char *DAlarmFields[] = {
611 VCRunTimeProp, 611 VCRunTimeProp,
612 VCSnoozeTimeProp, 612 VCSnoozeTimeProp,
613 VCRepeatCountProp, 613 VCRepeatCountProp,
614 VCDisplayStringProp, 614 VCDisplayStringProp,
615 0 615 0
616 }; 616 };
617 617
618static const char *MAlarmFields[] = { 618static const char *MAlarmFields[] = {
619 VCRunTimeProp, 619 VCRunTimeProp,
620 VCSnoozeTimeProp, 620 VCSnoozeTimeProp,
621 VCRepeatCountProp, 621 VCRepeatCountProp,
622 VCEmailAddressProp, 622 VCEmailAddressProp,
623 VCNoteProp, 623 VCNoteProp,
624 0 624 0
625 }; 625 };
626 626
627static const char *PAlarmFields[] = { 627static const char *PAlarmFields[] = {
628 VCRunTimeProp, 628 VCRunTimeProp,
629 VCSnoozeTimeProp, 629 VCSnoozeTimeProp,
630 VCRepeatCountProp, 630 VCRepeatCountProp,
631 VCProcedureNameProp, 631 VCProcedureNameProp,
632 0 632 0
633 }; 633 };
634 634
635static struct PreDefProp propNames[] = { 635static struct PreDefProp propNames[] = {
636 { VC7bitProp, 0, 0, 0 }, 636 { VC7bitProp, 0, 0, 0 },
637 { VC8bitProp, 0, 0, 0 }, 637 { VC8bitProp, 0, 0, 0 },
638 { VCAAlarmProp, 0, AAlarmFields, 0 }, 638 { VCAAlarmProp, 0, AAlarmFields, 0 },
639 { VCAdditionalNamesProp, 0, 0, 0 }, 639 { VCAdditionalNamesProp, 0, 0, 0 },
640 { VCAdrProp, 0, adrFields, 0 }, 640 { VCAdrProp, 0, adrFields, 0 },
641 { VCAgentProp, 0, 0, 0 }, 641 { VCAgentProp, 0, 0, 0 },
642 { VCAIFFProp, 0, 0, 0 }, 642 { VCAIFFProp, 0, 0, 0 },
643 { VCAOLProp, 0, 0, 0 }, 643 { VCAOLProp, 0, 0, 0 },
644 { VCAppleLinkProp, 0, 0, 0 }, 644 { VCAppleLinkProp, 0, 0, 0 },
645 { VCAttachProp, 0, 0, 0 }, 645 { VCAttachProp, 0, 0, 0 },
646 { VCAttendeeProp, 0, 0, 0 }, 646 { VCAttendeeProp, 0, 0, 0 },
647 { VCATTMailProp, 0, 0, 0 }, 647 { VCATTMailProp, 0, 0, 0 },
648 { VCAudioContentProp, 0, 0, 0 }, 648 { VCAudioContentProp, 0, 0, 0 },
649 { VCAVIProp, 0, 0, 0 }, 649 { VCAVIProp, 0, 0, 0 },
650 { VCBase64Prop, 0, 0, 0 }, 650 { VCBase64Prop, 0, 0, 0 },
651 { VCBBSProp, 0, 0, 0 }, 651 { VCBBSProp, 0, 0, 0 },
652 { VCBirthDateProp, 0, 0, 0 }, 652 { VCBirthDateProp, 0, 0, 0 },
653 { VCBMPProp, 0, 0, 0 }, 653 { VCBMPProp, 0, 0, 0 },
654 { VCBodyProp, 0, 0, 0 }, 654 { VCBodyProp, 0, 0, 0 },
655 { VCBusinessRoleProp, 0, 0, 0 }, 655 { VCBusinessRoleProp, 0, 0, 0 },
656 { VCCalProp, 0, 0, PD_BEGIN }, 656 { VCCalProp, 0, 0, PD_BEGIN },
657 { VCCaptionProp, 0, 0, 0 }, 657 { VCCaptionProp, 0, 0, 0 },
658 { VCCardProp, 0, 0, PD_BEGIN }, 658 { VCCardProp, 0, 0, PD_BEGIN },
659 { VCCarProp, 0, 0, 0 }, 659 { VCCarProp, 0, 0, 0 },
660 { VCCategoriesProp, 0, 0, 0 }, 660 { VCCategoriesProp, 0, 0, 0 },
661 { VCCellularProp, 0, 0, 0 }, 661 { VCCellularProp, 0, 0, 0 },
662 { VCCGMProp, 0, 0, 0 }, 662 { VCCGMProp, 0, 0, 0 },
663 { VCCharSetProp, 0, 0, 0 }, 663 { VCCharSetProp, 0, 0, 0 },
664 { VCCIDProp, VCContentIDProp, 0, 0 }, 664 { VCCIDProp, VCContentIDProp, 0, 0 },
665 { VCCISProp, 0, 0, 0 }, 665 { VCCISProp, 0, 0, 0 },
666 { VCCityProp, 0, 0, 0 }, 666 { VCCityProp, 0, 0, 0 },
667 { VCClassProp, 0, 0, 0 }, 667 { VCClassProp, 0, 0, 0 },
668 { VCCommentProp, 0, 0, 0 }, 668 { VCCommentProp, 0, 0, 0 },
669 { VCCompletedProp, 0, 0, 0 }, 669 { VCCompletedProp, 0, 0, 0 },
670 { VCContentIDProp, 0, 0, 0 }, 670 { VCContentIDProp, 0, 0, 0 },
671 { VCCountryNameProp, 0, 0, 0 }, 671 { VCCountryNameProp, 0, 0, 0 },
672 { VCDAlarmProp, 0, DAlarmFields, 0 }, 672 { VCDAlarmProp, 0, DAlarmFields, 0 },
673 { VCDataSizeProp, 0, 0, PD_INTERNAL }, 673 { VCDataSizeProp, 0, 0, PD_INTERNAL },
674 { VCDayLightProp, 0, 0, 0 }, 674 { VCDayLightProp, 0, 0, 0 },
675 { VCDCreatedProp, 0, 0, 0 }, 675 { VCDCreatedProp, 0, 0, 0 },
676 { VCDeliveryLabelProp, 0, 0, 0 }, 676 { VCDeliveryLabelProp, 0, 0, 0 },
677 { VCDescriptionProp, 0, 0, 0 }, 677 { VCDescriptionProp, 0, 0, 0 },
678 { VCDIBProp, 0, 0, 0 }, 678 { VCDIBProp, 0, 0, 0 },
679 { VCDisplayStringProp, 0, 0, 0 }, 679 { VCDisplayStringProp, 0, 0, 0 },
680 { VCDomesticProp, 0, 0, 0 }, 680 { VCDomesticProp, 0, 0, 0 },
681 { VCDTendProp, 0, 0, 0 }, 681 { VCDTendProp, 0, 0, 0 },
682 { VCDTstartProp, 0, 0, 0 }, 682 { VCDTstartProp, 0, 0, 0 },
683 { VCDueProp, 0, 0, 0 }, 683 { VCDueProp, 0, 0, 0 },
684 { VCEmailAddressProp, 0, 0, 0 }, 684 { VCEmailAddressProp, 0, 0, 0 },
685 { VCEncodingProp, 0, 0, 0 }, 685 { VCEncodingProp, 0, 0, 0 },
686 { VCEndProp, 0, 0, 0 }, 686 { VCEndProp, 0, 0, 0 },
687 { VCEventProp, 0, 0, PD_BEGIN }, 687 { VCEventProp, 0, 0, PD_BEGIN },
688 { VCEWorldProp, 0, 0, 0 }, 688 { VCEWorldProp, 0, 0, 0 },
689 { VCExNumProp, 0, 0, 0 }, 689 { VCExNumProp, 0, 0, 0 },
690 { VCExpDateProp, 0, 0, 0 }, 690 { VCExpDateProp, 0, 0, 0 },
691 { VCExpectProp, 0, 0, 0 }, 691 { VCExpectProp, 0, 0, 0 },
692 { VCExtAddressProp, 0, 0, 0 }, 692 { VCExtAddressProp, 0, 0, 0 },
693 { VCFamilyNameProp, 0, 0, 0 }, 693 { VCFamilyNameProp, 0, 0, 0 },
694 { VCFaxProp, 0, 0, 0 }, 694 { VCFaxProp, 0, 0, 0 },
695 { VCFullNameProp, 0, 0, 0 }, 695 { VCFullNameProp, 0, 0, 0 },
696 { VCGeoLocationProp, 0, 0, 0 }, 696 { VCGeoLocationProp, 0, 0, 0 },
697 { VCGeoProp, 0, 0, 0 }, 697 { VCGeoProp, 0, 0, 0 },
698 { VCGIFProp, 0, 0, 0 }, 698 { VCGIFProp, 0, 0, 0 },
699 { VCGivenNameProp, 0, 0, 0 }, 699 { VCGivenNameProp, 0, 0, 0 },
700 { VCGroupingProp, 0, 0, 0 }, 700 { VCGroupingProp, 0, 0, 0 },
701 { VCHomeProp, 0, 0, 0 }, 701 { VCHomeProp, 0, 0, 0 },
702 { VCIBMMailProp, 0, 0, 0 }, 702 { VCIBMMailProp, 0, 0, 0 },
703 { VCInlineProp, 0, 0, 0 }, 703 { VCInlineProp, 0, 0, 0 },
704 { VCInternationalProp, 0, 0, 0 }, 704 { VCInternationalProp, 0, 0, 0 },
705 { VCInternetProp, 0, 0, 0 }, 705 { VCInternetProp, 0, 0, 0 },
706 { VCISDNProp, 0, 0, 0 }, 706 { VCISDNProp, 0, 0, 0 },
707 { VCJPEGProp, 0, 0, 0 }, 707 { VCJPEGProp, 0, 0, 0 },
708 { VCLanguageProp, 0, 0, 0 }, 708 { VCLanguageProp, 0, 0, 0 },
709 { VCLastModifiedProp, 0, 0, 0 }, 709 { VCLastModifiedProp, 0, 0, 0 },
710 { VCLastRevisedProp, 0, 0, 0 }, 710 { VCLastRevisedProp, 0, 0, 0 },
711 { VCLocationProp, 0, 0, 0 }, 711 { VCLocationProp, 0, 0, 0 },
712 { VCLogoProp, 0, 0, 0 }, 712 { VCLogoProp, 0, 0, 0 },
713 { VCMailerProp, 0, 0, 0 }, 713 { VCMailerProp, 0, 0, 0 },
714 { VCMAlarmProp, 0, MAlarmFields, 0 }, 714 { VCMAlarmProp, 0, MAlarmFields, 0 },
715 { VCMCIMailProp, 0, 0, 0 }, 715 { VCMCIMailProp, 0, 0, 0 },
716 { VCMessageProp, 0, 0, 0 }, 716 { VCMessageProp, 0, 0, 0 },
717 { VCMETProp, 0, 0, 0 }, 717 { VCMETProp, 0, 0, 0 },
718 { VCModemProp, 0, 0, 0 }, 718 { VCModemProp, 0, 0, 0 },
719 { VCMPEG2Prop, 0, 0, 0 }, 719 { VCMPEG2Prop, 0, 0, 0 },
720 { VCMPEGProp, 0, 0, 0 }, 720 { VCMPEGProp, 0, 0, 0 },
721 { VCMSNProp, 0, 0, 0 }, 721 { VCMSNProp, 0, 0, 0 },
722 { VCNamePrefixesProp, 0, 0, 0 }, 722 { VCNamePrefixesProp, 0, 0, 0 },
723 { VCNameProp, 0, nameFields, 0 }, 723 { VCNameProp, 0, nameFields, 0 },
724 { VCNameSuffixesProp, 0, 0, 0 }, 724 { VCNameSuffixesProp, 0, 0, 0 },
725 { VCNoteProp, 0, 0, 0 }, 725 { VCNoteProp, 0, 0, 0 },
726 { VCOrgNameProp, 0, 0, 0 }, 726 { VCOrgNameProp, 0, 0, 0 },
727 { VCOrgProp, 0, orgFields, 0 }, 727 { VCOrgProp, 0, orgFields, 0 },
728 { VCOrgUnit2Prop, 0, 0, 0 }, 728 { VCOrgUnit2Prop, 0, 0, 0 },
729 { VCOrgUnit3Prop, 0, 0, 0 }, 729 { VCOrgUnit3Prop, 0, 0, 0 },
730 { VCOrgUnit4Prop, 0, 0, 0 }, 730 { VCOrgUnit4Prop, 0, 0, 0 },
731 { VCOrgUnitProp, 0, 0, 0 }, 731 { VCOrgUnitProp, 0, 0, 0 },
732 { VCPagerProp, 0, 0, 0 }, 732 { VCPagerProp, 0, 0, 0 },
733 { VCPAlarmProp, 0, PAlarmFields, 0 }, 733 { VCPAlarmProp, 0, PAlarmFields, 0 },
734 { VCParcelProp, 0, 0, 0 }, 734 { VCParcelProp, 0, 0, 0 },
735 { VCPartProp, 0, 0, 0 }, 735 { VCPartProp, 0, 0, 0 },
736 { VCPCMProp, 0, 0, 0 }, 736 { VCPCMProp, 0, 0, 0 },
737 { VCPDFProp, 0, 0, 0 }, 737 { VCPDFProp, 0, 0, 0 },
738 { VCPGPProp, 0, 0, 0 }, 738 { VCPGPProp, 0, 0, 0 },
739 { VCPhotoProp, 0, 0, 0 }, 739 { VCPhotoProp, 0, 0, 0 },
740 { VCPICTProp, 0, 0, 0 }, 740 { VCPICTProp, 0, 0, 0 },
741 { VCPMBProp, 0, 0, 0 }, 741 { VCPMBProp, 0, 0, 0 },
742 { VCPostalBoxProp, 0, 0, 0 }, 742 { VCPostalBoxProp, 0, 0, 0 },
743 { VCPostalCodeProp, 0, 0, 0 }, 743 { VCPostalCodeProp, 0, 0, 0 },
744 { VCPostalProp, 0, 0, 0 }, 744 { VCPostalProp, 0, 0, 0 },
745 { VCPowerShareProp, 0, 0, 0 }, 745 { VCPowerShareProp, 0, 0, 0 },
746 { VCPreferredProp, 0, 0, 0 }, 746 { VCPreferredProp, 0, 0, 0 },
747 { VCPriorityProp, 0, 0, 0 }, 747 { VCPriorityProp, 0, 0, 0 },
748 { VCProcedureNameProp, 0, 0, 0 }, 748 { VCProcedureNameProp, 0, 0, 0 },
749 { VCProdIdProp, 0, 0, 0 }, 749 { VCProdIdProp, 0, 0, 0 },
750 { VCProdigyProp, 0, 0, 0 }, 750 { VCProdigyProp, 0, 0, 0 },
751 { VCPronunciationProp, 0, 0, 0 }, 751 { VCPronunciationProp, 0, 0, 0 },
752 { VCPSProp, 0, 0, 0 }, 752 { VCPSProp, 0, 0, 0 },
753 { VCPublicKeyProp, 0, 0, 0 }, 753 { VCPublicKeyProp, 0, 0, 0 },
754 { VCQPProp, VCQuotedPrintableProp, 0, 0 }, 754 { VCQPProp, VCQuotedPrintableProp, 0, 0 },
755 { VCQuickTimeProp, 0, 0, 0 }, 755 { VCQuickTimeProp, 0, 0, 0 },
756 { VCQuotedPrintableProp, 0, 0, 0 }, 756 { VCQuotedPrintableProp, 0, 0, 0 },
757 { VCRDateProp, 0, 0, 0 }, 757 { VCRDateProp, 0, 0, 0 },
758 { VCRegionProp, 0, 0, 0 }, 758 { VCRegionProp, 0, 0, 0 },
759 { VCRelatedToProp, 0, 0, 0 }, 759 { VCRelatedToProp, 0, 0, 0 },
760 { VCRepeatCountProp, 0, 0, 0 }, 760 { VCRepeatCountProp, 0, 0, 0 },
761 { VCResourcesProp, 0, 0, 0 }, 761 { VCResourcesProp, 0, 0, 0 },
762 { VCRNumProp, 0, 0, 0 }, 762 { VCRNumProp, 0, 0, 0 },
763 { VCRoleProp, 0, 0, 0 }, 763 { VCRoleProp, 0, 0, 0 },
764 { VCRRuleProp, 0, 0, 0 }, 764 { VCRRuleProp, 0, 0, 0 },
765 { VCRSVPProp, 0, 0, 0 }, 765 { VCRSVPProp, 0, 0, 0 },
766 { VCRunTimeProp, 0, 0, 0 }, 766 { VCRunTimeProp, 0, 0, 0 },
767 { VCSequenceProp, 0, 0, 0 }, 767 { VCSequenceProp, 0, 0, 0 },
768 { VCSnoozeTimeProp, 0, 0, 0 }, 768 { VCSnoozeTimeProp, 0, 0, 0 },
769 { VCStartProp, 0, 0, 0 }, 769 { VCStartProp, 0, 0, 0 },
770 { VCStatusProp, 0, 0, 0 }, 770 { VCStatusProp, 0, 0, 0 },
771 { VCStreetAddressProp, 0, 0, 0 }, 771 { VCStreetAddressProp, 0, 0, 0 },
772 { VCSubTypeProp, 0, 0, 0 }, 772 { VCSubTypeProp, 0, 0, 0 },
773 { VCSummaryProp, 0, 0, 0 }, 773 { VCSummaryProp, 0, 0, 0 },
774 { VCTelephoneProp, 0, 0, 0 }, 774 { VCTelephoneProp, 0, 0, 0 },
775 { VCTIFFProp, 0, 0, 0 }, 775 { VCTIFFProp, 0, 0, 0 },
776 { VCTimeZoneProp, 0, 0, 0 }, 776 { VCTimeZoneProp, 0, 0, 0 },
777 { VCTitleProp, 0, 0, 0 }, 777 { VCTitleProp, 0, 0, 0 },
778 { VCTLXProp, 0, 0, 0 }, 778 { VCTLXProp, 0, 0, 0 },
779 { VCTodoProp, 0, 0, PD_BEGIN }, 779 { VCTodoProp, 0, 0, PD_BEGIN },
780 { VCTranspProp, 0, 0, 0 }, 780 { VCTranspProp, 0, 0, 0 },
781 { VCUniqueStringProp, 0, 0, 0 }, 781 { VCUniqueStringProp, 0, 0, 0 },
782 { VCURLProp, 0, 0, 0 }, 782 { VCURLProp, 0, 0, 0 },
783 { VCURLValueProp, 0, 0, 0 }, 783 { VCURLValueProp, 0, 0, 0 },
784 { VCValueProp, 0, 0, 0 }, 784 { VCValueProp, 0, 0, 0 },
785 { VCVersionProp, 0, 0, 0 }, 785 { VCVersionProp, 0, 0, 0 },
786 { VCVideoProp, 0, 0, 0 }, 786 { VCVideoProp, 0, 0, 0 },
787 { VCVoiceProp, 0, 0, 0 }, 787 { VCVoiceProp, 0, 0, 0 },
788 { VCWAVEProp, 0, 0, 0 }, 788 { VCWAVEProp, 0, 0, 0 },
789 { VCWMFProp, 0, 0, 0 }, 789 { VCWMFProp, 0, 0, 0 },
790 { VCWorkProp, 0, 0, 0 }, 790 { VCWorkProp, 0, 0, 0 },
791 { VCX400Prop, 0, 0, 0 }, 791 { VCX400Prop, 0, 0, 0 },
792 { VCX509Prop, 0, 0, 0 }, 792 { VCX509Prop, 0, 0, 0 },
793 { VCXRuleProp, 0, 0, 0 }, 793 { VCXRuleProp, 0, 0, 0 },
794 { 0,0,0,0 } 794 { 0,0,0,0 }
795 }; 795 };
796 796
797 797
798static struct PreDefProp* lookupPropInfo(const char* str) 798static struct PreDefProp* lookupPropInfo(const char* str)
799{ 799{
800 /* brute force for now, could use a hash table here. */ 800 /* brute force for now, could use a hash table here. */
801 int i; 801 int i;
802 802
803 for (i = 0; propNames[i].name; i++) 803 for (i = 0; propNames[i].name; i++)
804 if (qstricmp(str, propNames[i].name) == 0) { 804 if (qstricmp(str, propNames[i].name) == 0) {
805 return &propNames[i]; 805 return &propNames[i];
806 } 806 }
807 807
808 return 0; 808 return 0;
809} 809}
810 810
811 811
812DLLEXPORT(const char*) lookupProp_(const char* str) 812DLLEXPORT(const char*) lookupProp_(const char* str)
813{ 813{
814 int i; 814 int i;
815 815
816 for (i = 0; propNames[i].name; i++) 816 for (i = 0; propNames[i].name; i++)
817 if (qstricmp(str, propNames[i].name) == 0) { 817 if (qstricmp(str, propNames[i].name) == 0) {
818 const char* s; 818 const char* s;
819 s = propNames[i].alias?propNames[i].alias:propNames[i].name; 819 s = propNames[i].alias?propNames[i].alias:propNames[i].name;
820 return lookupStr(s); 820 return lookupStr(s);
821 } 821 }
822 return lookupStr(str); 822 return lookupStr(str);
823} 823}
824 824
825 825
826DLLEXPORT(const char*) lookupProp(const char* str) 826DLLEXPORT(const char*) lookupProp(const char* str)
827{ 827{
828 int i; 828 int i;
829 829
830 for (i = 0; propNames[i].name; i++) 830 for (i = 0; propNames[i].name; i++)
831 if (qstricmp(str, propNames[i].name) == 0) { 831 if (qstricmp(str, propNames[i].name) == 0) {
832 const char *s; 832 const char *s;
833 fieldedProp = propNames[i].fields; 833 fieldedProp = propNames[i].fields;
834 s = propNames[i].alias?propNames[i].alias:propNames[i].name; 834 s = propNames[i].alias?propNames[i].alias:propNames[i].name;
835 return lookupStr(s); 835 return lookupStr(s);
836 } 836 }
837 fieldedProp = 0; 837 fieldedProp = 0;
838 return lookupStr(str); 838 return lookupStr(str);
839} 839}
840 840
841 841
842/*---------------------------------------------------------------------- 842/*----------------------------------------------------------------------
843 APIs to Output text form. 843 APIs to Output text form.
844 ----------------------------------------------------------------------*/ 844 ----------------------------------------------------------------------*/
845#define OFILE_REALLOC_SIZE 256 845#define OFILE_REALLOC_SIZE 256
846typedef struct OFile { 846typedef struct OFile {
847 FILE *fp; 847 FILE *fp;
848 char *s; 848 char *s;
849 int len; 849 int len;
850 int limit; 850 int limit;
851 int alloc:1; 851 int alloc:1;
852 int fail:1; 852 int fail:1;
853 } OFile; 853 } OFile;
854 854
855#if 0 855#if 0
856static void appendsOFile(OFile *fp, const char *s) 856static void appendsOFile(OFile *fp, const char *s)
857{ 857{
858 int slen; 858 int slen;
859 if (fp->fail) return; 859 if (fp->fail) return;
860 slen = strlen(s); 860 slen = strlen(s);
861 if (fp->fp) { 861 if (fp->fp) {
862 fwrite(s,1,slen,fp->fp); 862 fwrite(s,1,slen,fp->fp);
863 } 863 }
864 else { 864 else {
865stuff: 865stuff:
866 if (fp->len + slen < fp->limit) { 866 if (fp->len + slen < fp->limit) {
867 memcpy(fp->s+fp->len,s,slen); 867 memcpy(fp->s+fp->len,s,slen);
868 fp->len += slen; 868 fp->len += slen;
869 return; 869 return;
870 } 870 }
871 else if (fp->alloc) { 871 else if (fp->alloc) {
872 fp->limit = fp->limit + OFILE_REALLOC_SIZE; 872 fp->limit = fp->limit + OFILE_REALLOC_SIZE;
873 if (OFILE_REALLOC_SIZE <= slen) fp->limit += slen; 873 if (OFILE_REALLOC_SIZE <= slen) fp->limit += slen;
874 fp->s = (char *) realloc(fp->s,fp->limit); 874 fp->s = (char *) realloc(fp->s,fp->limit);
875 if (fp->s) goto stuff; 875 if (fp->s) goto stuff;
876 } 876 }
877 if (fp->alloc) 877 if (fp->alloc)
878 free(fp->s); 878 free(fp->s);
879 fp->s = 0; 879 fp->s = 0;
880 fp->fail = 1; 880 fp->fail = 1;
881 } 881 }
882} 882}
883 883
884static void appendcOFile(OFile *fp, char c) 884static void appendcOFile(OFile *fp, char c)
885{ 885{
886 if (fp->fail) return; 886 if (fp->fail) return;
887 if (fp->fp) { 887 if (fp->fp) {
888 fputc(c,fp->fp); 888 fputc(c,fp->fp);
889 } 889 }
890 else { 890 else {
891stuff: 891stuff:
892 if (fp->len+1 < fp->limit) { 892 if (fp->len+1 < fp->limit) {
893 fp->s[fp->len] = c; 893 fp->s[fp->len] = c;
894 fp->len++; 894 fp->len++;
895 return; 895 return;
896 } 896 }
897 else if (fp->alloc) { 897 else if (fp->alloc) {
898 fp->limit = fp->limit + OFILE_REALLOC_SIZE; 898 fp->limit = fp->limit + OFILE_REALLOC_SIZE;
899 fp->s = (char *) realloc(fp->s,fp->limit); 899 fp->s = (char *) realloc(fp->s,fp->limit);
900 if (fp->s) goto stuff; 900 if (fp->s) goto stuff;
901 } 901 }
902 if (fp->alloc) 902 if (fp->alloc)
903 free(fp->s); 903 free(fp->s);
904 fp->s = 0; 904 fp->s = 0;
905 fp->fail = 1; 905 fp->fail = 1;
906 } 906 }
907} 907}
908#else 908#else
909static void appendcOFile_(OFile *fp, char c) 909static void appendcOFile_(OFile *fp, char c)
910{ 910{
911 if (fp->fail) return; 911 if (fp->fail) return;
912 if (fp->fp) { 912 if (fp->fp) {
913 fputc(c,fp->fp); 913 fputc(c,fp->fp);
914 } 914 }
915 else { 915 else {
916stuff: 916stuff:
917 if (fp->len+1 < fp->limit) { 917 if (fp->len+1 < fp->limit) {
918 fp->s[fp->len] = c; 918 fp->s[fp->len] = c;
919 fp->len++; 919 fp->len++;
920 return; 920 return;
921 } 921 }
922 else if (fp->alloc) { 922 else if (fp->alloc) {
923 fp->limit = fp->limit + OFILE_REALLOC_SIZE; 923 fp->limit = fp->limit + OFILE_REALLOC_SIZE;
924 fp->s = (char *)realloc(fp->s,fp->limit); 924 fp->s = (char *)realloc(fp->s,fp->limit);
925 if (fp->s) goto stuff; 925 if (fp->s) goto stuff;
926 } 926 }
927 if (fp->alloc) 927 if (fp->alloc)
928 free(fp->s); 928 free(fp->s);
929 fp->s = 0; 929 fp->s = 0;
930 fp->fail = 1; 930 fp->fail = 1;
931 } 931 }
932} 932}
933 933
934static void appendcOFile(OFile *fp, char c) 934static void appendcOFile(OFile *fp, char c)
935{ 935{
936 if (c == '\n') { 936 if (c == '\n') {
937 /* write out as <CR><LF> */ 937 /* write out as <CR><LF> */
938 appendcOFile_(fp,0xd); 938 appendcOFile_(fp,0xd);
939 appendcOFile_(fp,0xa); 939 appendcOFile_(fp,0xa);
940 } 940 }
941 else 941 else
942 appendcOFile_(fp,c); 942 appendcOFile_(fp,c);
943} 943}
944 944
945static void appendsOFile(OFile *fp, const char *s) 945static void appendsOFile(OFile *fp, const char *s)
946{ 946{
947 int i, slen; 947 int i, slen;
948 slen = strlen(s); 948 slen = strlen(s);
949 for (i=0; i<slen; i++) { 949 for (i=0; i<slen; i++) {
950 appendcOFile(fp,s[i]); 950 appendcOFile(fp,s[i]);
951 } 951 }
952} 952}
953 953
954#endif 954#endif
955 955
956static void initOFile(OFile *fp, FILE *ofp) 956static void initOFile(OFile *fp, FILE *ofp)
957{ 957{
958 fp->fp = ofp; 958 fp->fp = ofp;
959 fp->s = 0; 959 fp->s = 0;
960 fp->len = 0; 960 fp->len = 0;
961 fp->limit = 0; 961 fp->limit = 0;
962 fp->alloc = 0; 962 fp->alloc = 0;
963 fp->fail = 0; 963 fp->fail = 0;
964} 964}
965 965
966static int writeBase64(OFile *fp, unsigned char *s, long len) 966static int writeBase64(OFile *fp, unsigned char *s, long len)
967{ 967{
968 long cur = 0; 968 long cur = 0;
969 int i, numQuads = 0; 969 int i, numQuads = 0;
970 unsigned long trip; 970 unsigned long trip;
971 unsigned char b; 971 unsigned char b;
972 char quad[5]; 972 char quad[5];
973#define MAXQUADS 16 973#define MAXQUADS 16
974 974
975 quad[4] = 0; 975 quad[4] = 0;
976 976
977 while (cur < len) { 977 while (cur < len) {
978 // collect the triplet of bytes into 'trip' 978 // collect the triplet of bytes into 'trip'
979 trip = 0; 979 trip = 0;
980 for (i = 0; i < 3; i++) { 980 for (i = 0; i < 3; i++) {
981 b = (cur < len) ? *(s + cur) : 0; 981 b = (cur < len) ? *(s + cur) : 0;
982 cur++; 982 cur++;
983 trip = trip << 8 | b; 983 trip = trip << 8 | b;
984 } 984 }
985 // fill in 'quad' with the appropriate four characters 985 // fill in 'quad' with the appropriate four characters
986 for (i = 3; i >= 0; i--) { 986 for (i = 3; i >= 0; i--) {
987 b = (unsigned char)(trip & 0x3F); 987 b = (unsigned char)(trip & 0x3F);
988 trip = trip >> 6; 988 trip = trip >> 6;
989 if ((3 - i) < (cur - len)) 989 if ((3 - i) < (cur - len))
990 quad[i] = '='; // pad char 990 quad[i] = '='; // pad char
991 else if (b < 26) quad[i] = (char)b + 'A'; 991 else if (b < 26) quad[i] = (char)b + 'A';
992 else if (b < 52) quad[i] = (char)(b - 26) + 'a'; 992 else if (b < 52) quad[i] = (char)(b - 26) + 'a';
993 else if (b < 62) quad[i] = (char)(b - 52) + '0'; 993 else if (b < 62) quad[i] = (char)(b - 52) + '0';
994 else if (b == 62) quad[i] = '+'; 994 else if (b == 62) quad[i] = '+';
995 else quad[i] = '/'; 995 else quad[i] = '/';
996 } 996 }
997 // now output 'quad' with appropriate whitespace and line ending 997 // now output 'quad' with appropriate whitespace and line ending
998 appendsOFile(fp, (numQuads == 0 ? " " : "")); 998 appendsOFile(fp, (numQuads == 0 ? " " : ""));
999 appendsOFile(fp, quad); 999 appendsOFile(fp, quad);
1000 appendsOFile(fp, ((cur >= len)?"\n" :(numQuads==MAXQUADS-1?"\n" : ""))); 1000 appendsOFile(fp, ((cur >= len)?"\n" :(numQuads==MAXQUADS-1?"\n" : "")));
1001 numQuads = (numQuads + 1) % MAXQUADS; 1001 numQuads = (numQuads + 1) % MAXQUADS;
1002 } 1002 }
1003 appendcOFile(fp,'\n'); 1003 appendcOFile(fp,'\n');
1004 1004
1005 return 1; 1005 return 1;
1006} 1006}
1007 1007
1008static void writeQPString(OFile *fp, const char *s) 1008static const char *replaceChar(unsigned char c)
1009{ 1009{
1010 const char *p = s; 1010 if (c == '\n') {
1011 while (*p) { 1011 return "=0A=\n";
1012 if (*p == '\n') { 1012 } else if (
1013 if (p[1]) appendsOFile(fp,"=0A="); 1013 (c >= 'A' && c <= 'Z')
1014 } 1014 ||
1015 appendcOFile(fp,*p); 1015 (c >= 'a' && c <= 'z')
1016 p++; 1016 ||
1017 } 1017 (c >= '0' && c <= '9')
1018} 1018 ||
1019 1019 (c >= '\'' && c <= ')')
1020 1020 ||
1021 1021 (c >= '+' && c <= '-')
1022static void writeVObject_(OFile *fp, VObject *o); 1022 ||
1023 1023 (c == '/')
1024static void writeValue(OFile *fp, VObject *o, unsigned long size) 1024 ||
1025{ 1025 (c == '?')
1026 if (o == 0) return; 1026 ||
1027 switch (VALUE_TYPE(o)) { 1027 (c == ' '))
1028 case VCVT_STRINGZ: { 1028 {
1029 writeQPString(fp, STRINGZ_VALUE_OF(o)); 1029 return 0;
1030 break; 1030 }
1031 } 1031
1032 case VCVT_UINT: { 1032 static char trans[4];
1033 char buf[16]; 1033 trans[0] = '=';
1034 sprintf(buf,"%u", INTEGER_VALUE_OF(o)); 1034 trans[3] = '\0';
1035 appendsOFile(fp,buf); 1035 int rem = c % 16;
1036 break; 1036 int div = c / 16;
1037 } 1037
1038 case VCVT_ULONG: { 1038 if (div < 10)
1039 char buf[16]; 1039 trans[1] = '0' + div;
1040 sprintf(buf,"%lu", LONG_VALUE_OF(o)); 1040 else
1041 appendsOFile(fp,buf); 1041 trans[1] = 'A' + (div - 10);
1042 break; 1042
1043 } 1043 if (rem < 10)
1044 case VCVT_RAW: { 1044 trans[2] = '0' + rem;
1045 appendcOFile(fp,'\n'); 1045 else
1046 writeBase64(fp,(unsigned char*)(ANY_VALUE_OF(o)),size); 1046 trans[2] = 'A' + (rem - 10);
1047 break; 1047
1048 } 1048 return trans;
1049 case VCVT_VOBJECT: 1049}
1050 appendcOFile(fp,'\n'); 1050
1051 writeVObject_(fp,VOBJECT_VALUE_OF(o)); 1051static void writeQPString(OFile *fp, const char *s)
1052 break; 1052{
1053 } 1053 /*
1054} 1054 only A-Z, 0-9 and
1055 1055 "'" (ASCII code 39)
1056static void writeAttrValue(OFile *fp, VObject *o) 1056 "(" (ASCII code 40)
1057{ 1057 ")" (ASCII code 41)
1058 if (NAME_OF(o)) { 1058 "+" (ASCII code 43)
1059 struct PreDefProp *pi; 1059 "," (ASCII code 44)
1060 pi = lookupPropInfo(NAME_OF(o)); 1060 "-" (ASCII code 45)
1061 if (pi && ((pi->flags & PD_INTERNAL) != 0)) return; 1061 "/" (ASCII code 47)
1062 appendcOFile(fp,';'); 1062 "?" (ASCII code 63)
1063 appendsOFile(fp,NAME_OF(o)); 1063
1064 } 1064 should remain un-encoded.
1065 else 1065 '=' needs to be encoded as it is the escape character.
1066 appendcOFile(fp,';'); 1066 ';' needs to be as it is a field separator.
1067 if (VALUE_TYPE(o)) { 1067
1068 appendcOFile(fp,'='); 1068 */
1069 writeValue(fp,o,0); 1069 const char *p = s;
1070 } 1070 while (*p) {
1071} 1071 const char *rep = replaceChar(*p);
1072 1072 if (rep)
1073static void writeGroup(OFile *fp, VObject *o) 1073 appendsOFile(fp, rep);
1074{ 1074 else
1075 char buf1[256]; 1075 appendcOFile(fp, *p);
1076 char buf2[256]; 1076 p++;
1077 strcpy(buf1,NAME_OF(o)); 1077 }
1078 while ((o=isAPropertyOf(o,VCGroupingProp)) != 0) { 1078}
1079 strcpy(buf2,STRINGZ_VALUE_OF(o)); 1079
1080 strcat(buf2,"."); 1080static bool includesUnprintable(VObject *o)
1081 strcat(buf2,buf1); 1081{
1082 strcpy(buf1,buf2); 1082 if (o) {
1083 } 1083 if (VALUE_TYPE(o) == VCVT_STRINGZ) {
1084 appendsOFile(fp,buf1); 1084 const char *p = STRINGZ_VALUE_OF(o);
1085} 1085 if (p) {
1086 1086 while (*p) {
1087static int inList(const char **list, const char *s) 1087 if (replaceChar(*p))
1088{ 1088 return TRUE;
1089 if (list == 0) return 0; 1089 p++;
1090 while (*list) { 1090 }
1091 if (qstricmp(*list,s) == 0) return 1; 1091 }
1092 list++; 1092 }
1093 } 1093 }
1094 return 0; 1094 return FALSE;
1095} 1095}
1096 1096
1097static void writeProp(OFile *fp, VObject *o) 1097static void writeVObject_(OFile *fp, VObject *o);
1098{ 1098
1099 if (NAME_OF(o)) { 1099static void writeValue(OFile *fp, VObject *o, unsigned long size)
1100 struct PreDefProp *pi; 1100{
1101 VObjectIterator t; 1101 if (o == 0) return;
1102 const char **fields_ = 0; 1102 switch (VALUE_TYPE(o)) {
1103 pi = lookupPropInfo(NAME_OF(o)); 1103 case VCVT_STRINGZ: {
1104 if (pi && ((pi->flags & PD_BEGIN) != 0)) { 1104 writeQPString(fp, STRINGZ_VALUE_OF(o));
1105 writeVObject_(fp,o); 1105 break;
1106 return; 1106 }
1107 } 1107 case VCVT_UINT: {
1108 if (isAPropertyOf(o,VCGroupingProp)) 1108 char buf[16];
1109 writeGroup(fp,o); 1109 sprintf(buf,"%u", INTEGER_VALUE_OF(o));
1110 else 1110 appendsOFile(fp,buf);
1111 appendsOFile(fp,NAME_OF(o)); 1111 break;
1112 if (pi) fields_ = pi->fields; 1112 }
1113 initPropIterator(&t,o); 1113 case VCVT_ULONG: {
1114 while (moreIteration(&t)) { 1114 char buf[16];
1115 const char *s; 1115 sprintf(buf,"%lu", LONG_VALUE_OF(o));
1116 VObject *eachProp = nextVObject(&t); 1116 appendsOFile(fp,buf);
1117 s = NAME_OF(eachProp); 1117 break;
1118 if (qstricmp(VCGroupingProp,s) && !inList(fields_,s)) 1118 }
1119 writeAttrValue(fp,eachProp); 1119 case VCVT_RAW: {
1120 } 1120 appendcOFile(fp,'\n');
1121 if (fields_) { 1121 writeBase64(fp,(unsigned char*)(ANY_VALUE_OF(o)),size);
1122 int i = 0, n = 0; 1122 break;
1123 const char** fields = fields_; 1123 }
1124 /* output prop as fields */ 1124 case VCVT_VOBJECT:
1125 appendcOFile(fp,':'); 1125 appendcOFile(fp,'\n');
1126 while (*fields) { 1126 writeVObject_(fp,VOBJECT_VALUE_OF(o));
1127 VObject *t = isAPropertyOf(o,*fields); 1127 break;
1128 i++; 1128 }
1129 if (t) n = i; 1129}
1130 fields++; 1130
1131 } 1131static void writeAttrValue(OFile *fp, VObject *o)
1132 fields = fields_; 1132{
1133 for (i=0;i<n;i++) { 1133 if (NAME_OF(o)) {
1134 writeValue(fp,isAPropertyOf(o,*fields),0); 1134 struct PreDefProp *pi;
1135 fields++; 1135 pi = lookupPropInfo(NAME_OF(o));
1136 if (i<(n-1)) appendcOFile(fp,';'); 1136 if (pi && ((pi->flags & PD_INTERNAL) != 0)) return;
1137 } 1137 if ( includesUnprintable(o) ) {
1138 } 1138 appendsOFile(fp, ";" VCEncodingProp "=" VCQuotedPrintableProp);
1139 } 1139 appendsOFile(fp, ";" VCCharSetProp "=" "UTF-8");
1140 1140 }
1141 if (VALUE_TYPE(o)) { 1141 appendcOFile(fp,';');
1142 unsigned long size = 0; 1142 appendsOFile(fp,NAME_OF(o));
1143 VObject *p = isAPropertyOf(o,VCDataSizeProp); 1143 }
1144 if (p) size = LONG_VALUE_OF(p); 1144 else
1145 appendcOFile(fp,':'); 1145 appendcOFile(fp,';');
1146 writeValue(fp,o,size); 1146 if (VALUE_TYPE(o)) {
1147 } 1147 appendcOFile(fp,'=');
1148 1148 writeValue(fp,o,0);
1149 appendcOFile(fp,'\n'); 1149 }
1150} 1150}
1151 1151
1152static void writeVObject_(OFile *fp, VObject *o) 1152static void writeGroup(OFile *fp, VObject *o)
1153{ 1153{
1154 if (NAME_OF(o)) { 1154 char buf1[256];
1155 struct PreDefProp *pi; 1155 char buf2[256];
1156 pi = lookupPropInfo(NAME_OF(o)); 1156 strcpy(buf1,NAME_OF(o));
1157 1157 while ((o=isAPropertyOf(o,VCGroupingProp)) != 0) {
1158 if (pi && ((pi->flags & PD_BEGIN) != 0)) { 1158 strcpy(buf2,STRINGZ_VALUE_OF(o));
1159 VObjectIterator t; 1159 strcat(buf2,".");
1160 const char *begin = NAME_OF(o); 1160 strcat(buf2,buf1);
1161 appendsOFile(fp,"BEGIN:"); 1161 strcpy(buf1,buf2);
1162 appendsOFile(fp,begin); 1162 }
1163 appendcOFile(fp,'\n'); 1163 appendsOFile(fp,buf1);
1164 initPropIterator(&t,o); 1164}
1165 while (moreIteration(&t)) { 1165
1166 VObject *eachProp = nextVObject(&t); 1166static int inList(const char **list, const char *s)
1167 writeProp(fp, eachProp); 1167{
1168 } 1168 if (list == 0) return 0;
1169 appendsOFile(fp,"END:"); 1169 while (*list) {
1170 appendsOFile(fp,begin); 1170 if (qstricmp(*list,s) == 0) return 1;
1171 appendsOFile(fp,"\n\n"); 1171 list++;
1172 } 1172 }
1173 } 1173 return 0;
1174} 1174}
1175 1175
1176void writeVObject(FILE *fp, VObject *o) 1176static void writeProp(OFile *fp, VObject *o)
1177{ 1177{
1178 OFile ofp; 1178 if (NAME_OF(o)) {
1179 // ##### 1179 struct PreDefProp *pi;
1180 //_setmode(_fileno(fp), _O_BINARY); 1180 VObjectIterator t;
1181 initOFile(&ofp,fp); 1181 const char **fields_ = 0;
1182 writeVObject_(&ofp,o); 1182 pi = lookupPropInfo(NAME_OF(o));
1183} 1183 if (pi && ((pi->flags & PD_BEGIN) != 0)) {
1184 1184 writeVObject_(fp,o);
1185DLLEXPORT(void) writeVObjectToFile(char *fname, VObject *o) 1185 return;
1186{ 1186 }
1187 QFileDirect f( fname); 1187 if (isAPropertyOf(o,VCGroupingProp))
1188 if ( !f.open( IO_WriteOnly ) ) { 1188 writeGroup(fp,o);
1189 qWarning("Unable to open vobject write %s", fname); 1189 else
1190 return; 1190 appendsOFile(fp,NAME_OF(o));
1191 } 1191 if (pi) fields_ = pi->fields;
1192 1192 initPropIterator(&t,o);
1193 writeVObject( f.directHandle(),o ); 1193 while (moreIteration(&t)) {
1194} 1194 const char *s;
1195 1195 VObject *eachProp = nextVObject(&t);
1196DLLEXPORT(void) writeVObjectsToFile(char *fname, VObject *list) 1196 s = NAME_OF(eachProp);
1197{ 1197 if (qstricmp(VCGroupingProp,s) && !inList(fields_,s))
1198 QFileDirect f( fname); 1198 writeAttrValue(fp,eachProp);
1199 if ( !f.open( IO_WriteOnly ) ) { 1199 }
1200 qWarning("Unable to open vobject write %s", fname); 1200 if (fields_) {
1201 return; 1201 int i = 0, n = 0;
1202 } 1202 const char** fields = fields_;
1203 1203 /* output prop as fields */
1204 while (list) { 1204 bool printable = TRUE;
1205 writeVObject(f.directHandle(),list); 1205 while (*fields && printable) {
1206 list = nextVObjectInList(list); 1206 VObject *t = isAPropertyOf(o,*fields);
1207 } 1207 if (includesUnprintable(t))
1208} 1208 printable = FALSE;
1209 1209 fields++;
1210DLLEXPORT(const char *) vObjectTypeInfo(VObject *o) 1210 }
1211{ 1211 fields = fields_;
1212 const char *type = vObjectName( o ); 1212 if (!printable) {
1213 if ( strcmp( type, "TYPE" ) == 0 ) 1213 appendsOFile(fp, ";" VCEncodingProp "=" VCQuotedPrintableProp);
1214 type = vObjectStringZValue( o ); 1214 appendsOFile(fp, ";" VCCharSetProp "=" "UTF-8");
1215 return type; 1215 }
1216} 1216 appendcOFile(fp,':');
1217 1217 while (*fields) {
1218 1218 VObject *t = isAPropertyOf(o,*fields);
1219// end of source file vobject.c 1219 i++;
1220 if (t) n = i;
1221 fields++;
1222 }
1223 fields = fields_;
1224 for (i=0;i<n;i++) {
1225 writeValue(fp,isAPropertyOf(o,*fields),0);
1226 fields++;
1227 if (i<(n-1)) appendcOFile(fp,';');
1228 }
1229 }
1230 }
1231
1232
1233 if (VALUE_TYPE(o)) {
1234 if ( includesUnprintable(o) ) {
1235 appendsOFile(fp, ";" VCEncodingProp "=" VCQuotedPrintableProp);
1236 appendsOFile(fp, ";" VCCharSetProp "=" "UTF-8");
1237 }
1238 unsigned long size = 0;
1239 VObject *p = isAPropertyOf(o,VCDataSizeProp);
1240 if (p) size = LONG_VALUE_OF(p);
1241 appendcOFile(fp,':');
1242 writeValue(fp,o,size);
1243 }
1244
1245 appendcOFile(fp,'\n');
1246}
1247
1248static void writeVObject_(OFile *fp, VObject *o)
1249{
1250 if (NAME_OF(o)) {
1251 struct PreDefProp *pi;
1252 pi = lookupPropInfo(NAME_OF(o));
1253
1254 if (pi && ((pi->flags & PD_BEGIN) != 0)) {
1255 VObjectIterator t;
1256 const char *begin = NAME_OF(o);
1257 appendsOFile(fp,"BEGIN:");
1258 appendsOFile(fp,begin);
1259 appendcOFile(fp,'\n');
1260 initPropIterator(&t,o);
1261 while (moreIteration(&t)) {
1262 VObject *eachProp = nextVObject(&t);
1263 writeProp(fp, eachProp);
1264 }
1265 appendsOFile(fp,"END:");
1266 appendsOFile(fp,begin);
1267 appendsOFile(fp,"\n\n");
1268 }
1269 }
1270}
1271
1272void writeVObject(FILE *fp, VObject *o)
1273{
1274 OFile ofp;
1275 // #####
1276 //_setmode(_fileno(fp), _O_BINARY);
1277 initOFile(&ofp,fp);
1278 writeVObject_(&ofp,o);
1279}
1280
1281DLLEXPORT(void) writeVObjectToFile(char *fname, VObject *o)
1282{
1283 QFileDirect f( fname);
1284 if ( !f.open( IO_WriteOnly ) ) {
1285 qWarning("Unable to open vobject write %s", fname);
1286 return;
1287 }
1288
1289 writeVObject( f.directHandle(),o );
1290}
1291
1292DLLEXPORT(void) writeVObjectsToFile(char *fname, VObject *list)
1293{
1294 QFileDirect f( fname);
1295 if ( !f.open( IO_WriteOnly ) ) {
1296 qWarning("Unable to open vobject write %s", fname);
1297 return;
1298 }
1299
1300 while (list) {
1301 writeVObject(f.directHandle(),list);
1302 list = nextVObjectInList(list);
1303 }
1304}
1305
1306DLLEXPORT(const char *) vObjectTypeInfo(VObject *o)
1307{
1308 const char *type = vObjectName( o );
1309 if ( strcmp( type, "TYPE" ) == 0 )
1310 type = vObjectStringZValue( o );
1311 return type;
1312}
1313
1314
1315// end of source file vobject.c