author | zautrix <zautrix> | 2004-06-29 11:59:46 (UTC) |
---|---|---|
committer | zautrix <zautrix> | 2004-06-29 11:59:46 (UTC) |
commit | da43dbdc6c82453228f34766fc74585615cba938 (patch) (unidiff) | |
tree | 16576932cea08bf117b2d0320b0d5f66ee8ad093 /libkcal/versit/vobject.c | |
parent | 627489ea2669d3997676bc3cee0f5d0d0c16c4d4 (diff) | |
download | kdepimpi-da43dbdc6c82453228f34766fc74585615cba938.zip kdepimpi-da43dbdc6c82453228f34766fc74585615cba938.tar.gz kdepimpi-da43dbdc6c82453228f34766fc74585615cba938.tar.bz2 |
New lib ical.Some minor changes as well.
-rw-r--r-- | libkcal/versit/vobject.c | 363 |
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 | |||
@@ -29,236 +29,255 @@ EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, | |||
29 | INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE | 29 | INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE |
30 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 30 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
31 | PURPOSE. | 31 | PURPOSE. |
32 | 32 | ||
33 | The software is provided with RESTRICTED RIGHTS. Use, duplication, or | 33 | The software is provided with RESTRICTED RIGHTS. Use, duplication, or |
34 | disclosure by the government are subject to restrictions set forth in | 34 | disclosure by the government are subject to restrictions set forth in |
35 | DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. | 35 | DFARS 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 | #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 | ||
66 | typedef 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 | |||
75 | struct VObject { | ||
76 | VObject *next; | ||
77 | const char *id; | ||
78 | VObject *prop; | ||
79 | unsigned short valType; | ||
80 | ValueItem val; | ||
81 | }; | ||
82 | |||
83 | typedef struct StrItem StrItem; | ||
84 | |||
85 | struct StrItem { | ||
86 | StrItem *next; | ||
87 | const char *s; | ||
88 | unsigned int refCnt; | ||
89 | }; | ||
90 | |||
65 | const char** fieldedProp; | 91 | const char** fieldedProp; |
66 | 92 | ||
67 | 93 | ||
68 | 94 | ||
69 | /*---------------------------------------------------------------------- | 95 | /*---------------------------------------------------------------------- |
70 | The following functions involve with memory allocation: | 96 | The following functions involve with memory allocation: |
71 | newVObject | 97 | newVObject |
72 | deleteVObject | 98 | deleteVObject |
73 | dupStr | 99 | dupStr |
74 | deleteStr | 100 | deleteStr |
75 | newStrItem | 101 | newStrItem |
76 | deleteStrItem | 102 | deleteStrItem |
77 | ----------------------------------------------------------------------*/ | 103 | ----------------------------------------------------------------------*/ |
78 | 104 | ||
79 | VObject* newVObject_(const char *id) | 105 | DLLEXPORT(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; |
84 | p->prop = 0; | 110 | p->prop = 0; |
85 | VALUE_TYPE(p) = 0; | 111 | VALUE_TYPE(p) = 0; |
86 | ANY_VALUE_OF(p) = 0; | 112 | ANY_VALUE_OF(p) = 0; |
87 | return p; | 113 | return p; |
88 | } | 114 | } |
89 | 115 | ||
90 | VObject* newVObject(const char *id) | 116 | DLLEXPORT(VObject*) newVObject(const char *id) |
91 | { | 117 | { |
92 | return newVObject_(lookupStr(id)); | 118 | return newVObject_(lookupStr(id)); |
93 | } | 119 | } |
94 | 120 | ||
95 | void deleteVObject(VObject *p) | 121 | DLLEXPORT(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 | ||
104 | char* dupStr(const char *s, unsigned int size) | 127 | DLLEXPORT(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); |
109 | } | 132 | } |
110 | t = (char*)malloc(size+1); | 133 | t = (char*)malloc(size+1); |
111 | if (t) { | 134 | if (t) { |
112 | memcpy(t,s,size); | 135 | memcpy(t,s,size); |
113 | t[size] = 0; | 136 | t[size] = 0; |
114 | return t; | 137 | return t; |
115 | } | 138 | } |
116 | else { | 139 | else { |
117 | return (char*)0; | 140 | return (char*)0; |
118 | } | 141 | } |
119 | } | 142 | } |
120 | 143 | ||
121 | void deleteStr(const char *p) | 144 | DLLEXPORT(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 | ||
129 | static StrItem* newStrItem(const char *s, StrItem *next) | 150 | static StrItem* newStrItem(const char *s, StrItem *next) |
130 | { | 151 | { |
131 | StrItem *p = (StrItem*)malloc(sizeof(StrItem)); | 152 | StrItem *p = (StrItem*)malloc(sizeof(StrItem)); |
132 | p->next = next; | 153 | p->next = next; |
133 | p->s = s; | 154 | p->s = s; |
134 | p->refCnt = 1; | 155 | p->refCnt = 1; |
135 | return p; | 156 | return p; |
136 | } | 157 | } |
137 | 158 | ||
138 | static void deleteStrItem(StrItem *p) | 159 | static 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 | ||
150 | const char* vObjectName(VObject *o) | 169 | DLLEXPORT(const char*) vObjectName(VObject *o) |
151 | { | 170 | { |
152 | return NAME_OF(o); | 171 | return NAME_OF(o); |
153 | } | 172 | } |
154 | 173 | ||
155 | void setVObjectName(VObject *o, const char* id) | 174 | DLLEXPORT(void) setVObjectName(VObject *o, const char* id) |
156 | { | 175 | { |
157 | NAME_OF(o) = id; | 176 | NAME_OF(o) = id; |
158 | } | 177 | } |
159 | 178 | ||
160 | const char* vObjectStringZValue(VObject *o) | 179 | DLLEXPORT(const char*) vObjectStringZValue(VObject *o) |
161 | { | 180 | { |
162 | return STRINGZ_VALUE_OF(o); | 181 | return STRINGZ_VALUE_OF(o); |
163 | } | 182 | } |
164 | 183 | ||
165 | void setVObjectStringZValue(VObject *o, const char *s) | 184 | DLLEXPORT(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 | ||
171 | void setVObjectStringZValue_(VObject *o, const char *s) | 190 | DLLEXPORT(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 | ||
177 | const wchar_t* vObjectUStringZValue(VObject *o) | 196 | DLLEXPORT(const wchar_t*) vObjectUStringZValue(VObject *o) |
178 | { | 197 | { |
179 | return USTRINGZ_VALUE_OF(o); | 198 | return USTRINGZ_VALUE_OF(o); |
180 | } | 199 | } |
181 | 200 | ||
182 | void setVObjectUStringZValue(VObject *o, const wchar_t *s) | 201 | DLLEXPORT(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 | ||
188 | void setVObjectUStringZValue_(VObject *o, const wchar_t *s) | 207 | DLLEXPORT(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 | ||
194 | unsigned int vObjectIntegerValue(VObject *o) | 213 | DLLEXPORT(unsigned int) vObjectIntegerValue(VObject *o) |
195 | { | 214 | { |
196 | return INTEGER_VALUE_OF(o); | 215 | return INTEGER_VALUE_OF(o); |
197 | } | 216 | } |
198 | 217 | ||
199 | void setVObjectIntegerValue(VObject *o, unsigned int i) | 218 | DLLEXPORT(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 | ||
205 | unsigned long vObjectLongValue(VObject *o) | 224 | DLLEXPORT(unsigned long) vObjectLongValue(VObject *o) |
206 | { | 225 | { |
207 | return LONG_VALUE_OF(o); | 226 | return LONG_VALUE_OF(o); |
208 | } | 227 | } |
209 | 228 | ||
210 | void setVObjectLongValue(VObject *o, unsigned long l) | 229 | DLLEXPORT(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 | ||
216 | void* vObjectAnyValue(VObject *o) | 235 | DLLEXPORT(void*) vObjectAnyValue(VObject *o) |
217 | { | 236 | { |
218 | return ANY_VALUE_OF(o); | 237 | return ANY_VALUE_OF(o); |
219 | } | 238 | } |
220 | 239 | ||
221 | void setVObjectAnyValue(VObject *o, void *t) | 240 | DLLEXPORT(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 | ||
227 | VObject* vObjectVObjectValue(VObject *o) | 246 | DLLEXPORT(VObject*) vObjectVObjectValue(VObject *o) |
228 | { | 247 | { |
229 | return VOBJECT_VALUE_OF(o); | 248 | return VOBJECT_VALUE_OF(o); |
230 | } | 249 | } |
231 | 250 | ||
232 | void setVObjectVObjectValue(VObject *o, VObject *p) | 251 | DLLEXPORT(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 | ||
238 | int vObjectValueType(VObject *o) | 257 | DLLEXPORT(int) vObjectValueType(VObject *o) |
239 | { | 258 | { |
240 | return VALUE_TYPE(o); | 259 | return VALUE_TYPE(o); |
241 | } | 260 | } |
242 | 261 | ||
243 | 262 | ||
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 | ||
248 | VObject* addVObjectProp(VObject *o, VObject *p) | 267 | DLLEXPORT(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} |
253 | V | 272 | V |
254 | pn {next,id,prop,val} | 273 | pn {next,id,prop,val} |
255 | V | 274 | V |
256 | ... | 275 | ... |
257 | p1 {next,id,prop,val} | 276 | p1 {next,id,prop,val} |
258 | V | 277 | V |
259 | pn | 278 | pn |
260 | --> | 279 | --> |
261 | o {next,id,prop,val} | 280 | o {next,id,prop,val} |
262 | V | 281 | V |
263 | pn {next,id,prop,val} | 282 | pn {next,id,prop,val} |
264 | V | 283 | V |
@@ -267,122 +286,122 @@ VObject* addVObjectProp(VObject *o, VObject *p) | |||
267 | p1 {next,id,prop,val} | 286 | p1 {next,id,prop,val} |
268 | V | 287 | V |
269 | pn | 288 | pn |
270 | */ | 289 | */ |
271 | 290 | ||
272 | VObject *tail = o->prop; | 291 | VObject *tail = o->prop; |
273 | if (tail) { | 292 | if (tail) { |
274 | p->next = tail->next; | 293 | p->next = tail->next; |
275 | o->prop = tail->next = p; | 294 | o->prop = tail->next = p; |
276 | } | 295 | } |
277 | else { | 296 | else { |
278 | o->prop = p->next = p; | 297 | o->prop = p->next = p; |
279 | } | 298 | } |
280 | return p; | 299 | return p; |
281 | } | 300 | } |
282 | 301 | ||
283 | VObject* addProp(VObject *o, const char *id) | 302 | DLLEXPORT(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 | ||
288 | VObject* addProp_(VObject *o, const char *id) | 307 | DLLEXPORT(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 | ||
293 | void addList(VObject **o, VObject *p) | 312 | DLLEXPORT(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; |
298 | } | 317 | } |
299 | else { | 318 | else { |
300 | VObject *t = *o; | 319 | VObject *t = *o; |
301 | while (t->next) { | 320 | while (t->next) { |
302 | t = t->next; | 321 | t = t->next; |
303 | } | 322 | } |
304 | t->next = p; | 323 | t->next = p; |
305 | } | 324 | } |
306 | } | 325 | } |
307 | 326 | ||
308 | VObject* nextVObjectInList(VObject *o) | 327 | DLLEXPORT(VObject*) nextVObjectInList(VObject *o) |
309 | { | 328 | { |
310 | return o->next; | 329 | return o->next; |
311 | } | 330 | } |
312 | 331 | ||
313 | VObject* setValueWithSize_(VObject *prop, void *val, unsigned int size) | 332 | DLLEXPORT(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 | ||
322 | VObject* setValueWithSize(VObject *prop, void *val, unsigned int size) | 341 | DLLEXPORT(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 | ||
328 | void initPropIterator(VObjectIterator *i, VObject *o) | 347 | DLLEXPORT(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 | ||
334 | void initVObjectIterator(VObjectIterator *i, VObject *o) | 353 | DLLEXPORT(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 | ||
340 | int moreIteration(VObjectIterator *i) | 359 | DLLEXPORT(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 | ||
345 | VObject* nextVObject(VObjectIterator *i) | 364 | DLLEXPORT(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; |
350 | return i->next; | 369 | return i->next; |
351 | } | 370 | } |
352 | else { | 371 | else { |
353 | i->next = i->next->next; | 372 | i->next = i->next->next; |
354 | return i->next; | 373 | return i->next; |
355 | } | 374 | } |
356 | } | 375 | } |
357 | else return (VObject*)0; | 376 | else return (VObject*)0; |
358 | } | 377 | } |
359 | 378 | ||
360 | VObject* isAPropertyOf(VObject *o, const char *id) | 379 | DLLEXPORT(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 | ||
372 | VObject* addGroup(VObject *o, const char *g) | 391 | DLLEXPORT(VObject*) addGroup(VObject *o, const char *g) |
373 | { | 392 | { |
374 | /* | 393 | /* |
375 | a.b.c | 394 | a.b.c |
376 | --> | 395 | --> |
377 | prop(c) | 396 | prop(c) |
378 | prop(VCGrouping=b) | 397 | prop(VCGrouping=b) |
379 | prop(VCGrouping=a) | 398 | prop(VCGrouping=a) |
380 | */ | 399 | */ |
381 | char *dot = strrchr(g,'.'); | 400 | char *dot = strrchr(g,'.'); |
382 | if (dot) { | 401 | if (dot) { |
383 | VObject *p, *t; | 402 | VObject *p, *t; |
384 | char *gs, *n = dot+1; | 403 | char *gs, *n = dot+1; |
385 | gs = dupStr(g,0);/* so we can write to it. */ | 404 | gs = dupStr(g,0);/* so we can write to it. */ |
386 | /* used to be | 405 | /* used to be |
387 | * t = p = addProp_(o,lookupProp_(n)); | 406 | * t = p = addProp_(o,lookupProp_(n)); |
388 | */ | 407 | */ |
@@ -397,50 +416,50 @@ VObject* addGroup(VObject *o, const char *g) | |||
397 | } | 416 | } |
398 | else | 417 | else |
399 | n = gs; | 418 | n = gs; |
400 | /* property(VCGroupingProp=n); | 419 | /* property(VCGroupingProp=n); |
401 | *and the value may have VCGrouping property | 420 | *and the value may have VCGrouping property |
402 | */ | 421 | */ |
403 | t = addProp(t,VCGroupingProp); | 422 | t = addProp(t,VCGroupingProp); |
404 | setVObjectStringZValue(t,lookupProp_(n)); | 423 | setVObjectStringZValue(t,lookupProp_(n)); |
405 | } while (n != gs); | 424 | } while (n != gs); |
406 | deleteStr(gs); | 425 | deleteStr(gs); |
407 | return p; | 426 | return p; |
408 | } | 427 | } |
409 | else | 428 | else |
410 | return addProp_(o,lookupProp(g)); | 429 | return addProp_(o,lookupProp(g)); |
411 | } | 430 | } |
412 | 431 | ||
413 | VObject* addPropValue(VObject *o, const char *p, const char *v) | 432 | DLLEXPORT(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 | ||
421 | VObject* addPropSizedValue_(VObject *o, const char *p, const char *v, | 440 | DLLEXPORT(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 | ||
430 | VObject* addPropSizedValue(VObject *o, const char *p, const char *v, | 449 | DLLEXPORT(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 | } |
435 | 454 | ||
436 | 455 | ||
437 | 456 | ||
438 | /*---------------------------------------------------------------------- | 457 | /*---------------------------------------------------------------------- |
439 | The following pretty print a VObject | 458 | The following pretty print a VObject |
440 | ----------------------------------------------------------------------*/ | 459 | ----------------------------------------------------------------------*/ |
441 | 460 | ||
442 | static void printVObject_(FILE *fp, VObject *o, int level); | 461 | static void printVObject_(FILE *fp, VObject *o, int level); |
443 | 462 | ||
444 | static void indent(FILE *fp, int level) | 463 | static void indent(FILE *fp, int level) |
445 | { | 464 | { |
446 | int i; | 465 | int i; |
@@ -515,177 +534,173 @@ static void printVObject_(FILE *fp, VObject *o, int level) | |||
515 | fprintf(fp,"[NULL]\n"); | 534 | fprintf(fp,"[NULL]\n"); |
516 | return; | 535 | return; |
517 | } | 536 | } |
518 | printNameValue(fp,o,level); | 537 | printNameValue(fp,o,level); |
519 | initPropIterator(&t,o); | 538 | initPropIterator(&t,o); |
520 | while (moreIteration(&t)) { | 539 | while (moreIteration(&t)) { |
521 | VObject *eachProp = nextVObject(&t); | 540 | VObject *eachProp = nextVObject(&t); |
522 | printVObject_(fp,eachProp,level+1); | 541 | printVObject_(fp,eachProp,level+1); |
523 | } | 542 | } |
524 | } | 543 | } |
525 | 544 | ||
526 | void printVObject(FILE *fp,VObject *o) | 545 | void printVObject(FILE *fp,VObject *o) |
527 | { | 546 | { |
528 | printVObject_(fp,o,0); | 547 | printVObject_(fp,o,0); |
529 | } | 548 | } |
530 | 549 | ||
531 | void printVObjectToFile(char *fname,VObject *o) | 550 | DLLEXPORT(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 | ||
540 | void printVObjectsToFile(char *fname,VObject *list) | 559 | DLLEXPORT(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) { |
545 | printVObject(fp,list); | 564 | printVObject(fp,list); |
546 | list = nextVObjectInList(list); | 565 | list = nextVObjectInList(list); |
547 | } | 566 | } |
548 | fclose(fp); | 567 | fclose(fp); |
549 | } | 568 | } |
550 | } | 569 | } |
551 | 570 | ||
552 | void cleanVObject(VObject *o) | 571 | DLLEXPORT(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. |
557 | Have to break the cycle in the circular link | 576 | Have to break the cycle in the circular link |
558 | list and turns it into regular NULL-terminated | 577 | list and turns it into regular NULL-terminated |
559 | list -- since at some point of destruction, | 578 | list -- since at some point of destruction, |
560 | the reference entry for the iterator to work | 579 | the reference entry for the iterator to work |
561 | will not longer be valid. | 580 | will not longer be valid. |
562 | */ | 581 | */ |
563 | VObject *p; | 582 | VObject *p; |
564 | p = o->prop->next; | 583 | p = o->prop->next; |
565 | o->prop->next = 0; | 584 | o->prop->next = 0; |
566 | do { | 585 | do { |
567 | VObject *t = p->next; | 586 | VObject *t = p->next; |
568 | cleanVObject(p); | 587 | cleanVObject(p); |
569 | p = t; | 588 | p = t; |
570 | } while (p); | 589 | } while (p); |
571 | } | 590 | } |
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)); |
581 | break; | 600 | break; |
582 | } | 601 | } |
583 | deleteVObject(o); | 602 | deleteVObject(o); |
584 | } | 603 | } |
585 | 604 | ||
586 | void cleanVObjects(VObject *list) | 605 | DLLEXPORT(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); |
591 | cleanVObject(t); | 610 | cleanVObject(t); |
592 | } | 611 | } |
593 | } | 612 | } |
594 | 613 | ||
595 | /*---------------------------------------------------------------------- | 614 | /*---------------------------------------------------------------------- |
596 | The following is a String Table Facilities. | 615 | The following is a String Table Facilities. |
597 | ----------------------------------------------------------------------*/ | 616 | ----------------------------------------------------------------------*/ |
598 | 617 | ||
599 | #define STRTBLSIZE 255 | 618 | #define STRTBLSIZE 255 |
600 | 619 | ||
601 | static StrItem *strTbl[STRTBLSIZE]; | 620 | static StrItem *strTbl[STRTBLSIZE]; |
602 | 621 | ||
603 | static unsigned int hashStr(const char *s) | 622 | static unsigned int hashStr(const char *s) |
604 | { | 623 | { |
605 | unsigned int h = 0; | 624 | unsigned int h = 0; |
606 | int i; | 625 | int i; |
607 | for (i=0;s[i];i++) { | 626 | for (i=0;s[i];i++) { |
608 | h += s[i]*i; | 627 | h += s[i]*i; |
609 | } | 628 | } |
610 | return h % STRTBLSIZE; | 629 | return h % STRTBLSIZE; |
611 | } | 630 | } |
612 | 631 | ||
613 | const char* lookupStr(const char *s) | 632 | DLLEXPORT(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 | ||
633 | void unUseStr(const char *s) | 650 | DLLEXPORT(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 | ||
662 | void cleanStrTbl() | 677 | DLLEXPORT(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 | ||
679 | struct PreDefProp { | 694 | struct PreDefProp { |
680 | const char *name; | 695 | const char *name; |
681 | const char *alias; | 696 | const char *alias; |
682 | const char** fields; | 697 | const char** fields; |
683 | unsigned int flags; | 698 | unsigned int flags; |
684 | }; | 699 | }; |
685 | 700 | ||
686 | /* flags in PreDefProp */ | 701 | /* flags in PreDefProp */ |
687 | #define PD_BEGIN0x1 | 702 | #define PD_BEGIN0x1 |
688 | #define PD_INTERNAL0x2 | 703 | #define PD_INTERNAL0x2 |
689 | 704 | ||
690 | static const char *adrFields[] = { | 705 | static const char *adrFields[] = { |
691 | VCPostalBoxProp, | 706 | VCPostalBoxProp, |
@@ -794,33 +809,33 @@ static struct PreDefProp propNames[] = { | |||
794 | { VCDayLightProp, 0, 0, 0 }, | 809 | { VCDayLightProp, 0, 0, 0 }, |
795 | { VCDCreatedProp, 0, 0, 0 }, | 810 | { VCDCreatedProp, 0, 0, 0 }, |
796 | { VCDeliveryLabelProp, 0, 0, 0 }, | 811 | { VCDeliveryLabelProp, 0, 0, 0 }, |
797 | { VCDescriptionProp, 0, 0, 0 }, | 812 | { VCDescriptionProp, 0, 0, 0 }, |
798 | { VCDIBProp, 0, 0, 0 }, | 813 | { VCDIBProp, 0, 0, 0 }, |
799 | { VCDisplayStringProp, 0, 0, 0 }, | 814 | { VCDisplayStringProp, 0, 0, 0 }, |
800 | { VCDomesticProp, 0, 0, 0 }, | 815 | { VCDomesticProp, 0, 0, 0 }, |
801 | { VCDTendProp, 0, 0, 0 }, | 816 | { VCDTendProp, 0, 0, 0 }, |
802 | { VCDTstartProp, 0, 0, 0 }, | 817 | { VCDTstartProp, 0, 0, 0 }, |
803 | { VCDueProp, 0, 0, 0 }, | 818 | { VCDueProp, 0, 0, 0 }, |
804 | { VCEmailAddressProp, 0, 0, 0 }, | 819 | { VCEmailAddressProp, 0, 0, 0 }, |
805 | { VCEncodingProp, 0, 0, 0 }, | 820 | { VCEncodingProp, 0, 0, 0 }, |
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 }, |
815 | { VCFullNameProp, 0, 0, 0 }, | 830 | { VCFullNameProp, 0, 0, 0 }, |
816 | { VCGeoLocationProp, 0, 0, 0 }, | 831 | { VCGeoLocationProp, 0, 0, 0 }, |
817 | { VCGeoProp, 0, 0, 0 }, | 832 | { VCGeoProp, 0, 0, 0 }, |
818 | { VCGIFProp, 0, 0, 0 }, | 833 | { VCGIFProp, 0, 0, 0 }, |
819 | { VCGivenNameProp, 0, 0, 0 }, | 834 | { VCGivenNameProp, 0, 0, 0 }, |
820 | { VCGroupingProp, 0, 0, 0 }, | 835 | { VCGroupingProp, 0, 0, 0 }, |
821 | { VCHomeProp, 0, 0, 0 }, | 836 | { VCHomeProp, 0, 0, 0 }, |
822 | { VCIBMMailProp, 0, 0, 0 }, | 837 | { VCIBMMailProp, 0, 0, 0 }, |
823 | { VCInlineProp, 0, 0, 0 }, | 838 | { VCInlineProp, 0, 0, 0 }, |
824 | { VCInternationalProp, 0, 0, 0 }, | 839 | { VCInternationalProp, 0, 0, 0 }, |
825 | { VCInternetProp, 0, 0, 0 }, | 840 | { VCInternetProp, 0, 0, 0 }, |
826 | { VCISDNProp, 0, 0, 0 }, | 841 | { VCISDNProp, 0, 0, 0 }, |
@@ -908,146 +923,137 @@ static struct PreDefProp propNames[] = { | |||
908 | { VCWAVEProp, 0, 0, 0 }, | 923 | { VCWAVEProp, 0, 0, 0 }, |
909 | { VCWMFProp, 0, 0, 0 }, | 924 | { VCWMFProp, 0, 0, 0 }, |
910 | { VCWorkProp, 0, 0, 0 }, | 925 | { VCWorkProp, 0, 0, 0 }, |
911 | { VCX400Prop, 0, 0, 0 }, | 926 | { VCX400Prop, 0, 0, 0 }, |
912 | { VCX509Prop, 0, 0, 0 }, | 927 | { VCX509Prop, 0, 0, 0 }, |
913 | { VCXRuleProp, 0, 0, 0 }, | 928 | { VCXRuleProp, 0, 0, 0 }, |
914 | { 0,0,0,0 } | 929 | { 0,0,0,0 } |
915 | }; | 930 | }; |
916 | 931 | ||
917 | 932 | ||
918 | static struct PreDefProp* lookupPropInfo(const char* str) | 933 | static struct PreDefProp* lookupPropInfo(const char* str) |
919 | { | 934 | { |
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 | ||
932 | const char* lookupProp_(const char* str) | 947 | DLLEXPORT(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 | ||
946 | const char* lookupProp(const char* str) | 961 | DLLEXPORT(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); |
956 | } | 971 | } |
957 | fieldedProp = 0; | 972 | fieldedProp = 0; |
958 | return lookupStr(str); | 973 | return lookupStr(str); |
959 | } | 974 | } |
960 | 975 | ||
961 | 976 | ||
962 | /*---------------------------------------------------------------------- | 977 | /*---------------------------------------------------------------------- |
963 | APIs to Output text form. | 978 | APIs to Output text form. |
964 | ----------------------------------------------------------------------*/ | 979 | ----------------------------------------------------------------------*/ |
965 | #define OFILE_REALLOC_SIZE 256 | 980 | #define OFILE_REALLOC_SIZE 256 |
966 | typedef struct OFile { | 981 | typedef struct OFile { |
967 | FILE *fp; | 982 | FILE *fp; |
968 | char *s; | 983 | char *s; |
969 | int len; | 984 | int len; |
970 | int limit; | 985 | int limit; |
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 | |||
980 | static void appendsOFile(OFile *fp, const char *s) | 991 | static 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; |
984 | slen = strlen(s); | 995 | slen = strlen(s); |
985 | if (fp->fp) { | 996 | if (fp->fp) { |
986 | fwrite(s,1,slen,fp->fp); | 997 | fwrite(s,1,slen,fp->fp); |
987 | } | 998 | } |
988 | else { | 999 | else { |
989 | stuff: | 1000 | stuff: |
990 | if (fp->len + slen < fp->limit) { | 1001 | if (fp->len + slen < fp->limit) { |
991 | memcpy(fp->s+fp->len,s,slen); | 1002 | memcpy(fp->s+fp->len,s,slen); |
992 | fp->len += slen; | 1003 | fp->len += slen; |
993 | return; | 1004 | return; |
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); |
1006 | fp->s = 0; | 1014 | fp->s = 0; |
1007 | fp->fail = 1; | 1015 | fp->fail = 1; |
1008 | } | 1016 | } |
1009 | } | 1017 | } |
1010 | 1018 | ||
1011 | static void appendcOFile(OFile *fp, char c) | 1019 | static void appendcOFile(OFile *fp, char c) |
1012 | { | 1020 | { |
1013 | if (fp->fail) return; | 1021 | if (fp->fail) return; |
1014 | if (fp->fp) { | 1022 | if (fp->fp) { |
1015 | fputc(c,fp->fp); | 1023 | fputc(c,fp->fp); |
1016 | } | 1024 | } |
1017 | else { | 1025 | else { |
1018 | stuff: | 1026 | stuff: |
1019 | if (fp->len+1 < fp->limit) { | 1027 | if (fp->len+1 < fp->limit) { |
1020 | fp->s[fp->len] = c; | 1028 | fp->s[fp->len] = c; |
1021 | fp->len++; | 1029 | fp->len++; |
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 | |||
1038 | static void appendcOFile_(OFile *fp, char c) | 1044 | static 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) { |
1042 | fputc(c,fp->fp); | 1048 | fputc(c,fp->fp); |
1043 | } | 1049 | } |
1044 | else { | 1050 | else { |
1045 | stuff: | 1051 | stuff: |
1046 | if (fp->len+1 < fp->limit) { | 1052 | if (fp->len+1 < fp->limit) { |
1047 | fp->s[fp->len] = c; | 1053 | fp->s[fp->len] = c; |
1048 | fp->len++; | 1054 | fp->len++; |
1049 | return; | 1055 | return; |
1050 | } | 1056 | } |
1051 | else if (fp->alloc) { | 1057 | else if (fp->alloc) { |
1052 | fp->limit = fp->limit + OFILE_REALLOC_SIZE; | 1058 | fp->limit = fp->limit + OFILE_REALLOC_SIZE; |
1053 | fp->s = realloc(fp->s,fp->limit); | 1059 | fp->s = realloc(fp->s,fp->limit); |
@@ -1102,98 +1108,111 @@ static void initMemOFile(OFile *fp, char *s, int len) | |||
1102 | fp->fail = 0; | 1108 | fp->fail = 0; |
1103 | } | 1109 | } |
1104 | 1110 | ||
1105 | 1111 | ||
1106 | static int writeBase64(OFile *fp, unsigned char *s, long len) | 1112 | static int writeBase64(OFile *fp, unsigned char *s, long len) |
1107 | { | 1113 | { |
1108 | long cur = 0; | 1114 | long cur = 0; |
1109 | int i, numQuads = 0; | 1115 | int i, numQuads = 0; |
1110 | unsigned long trip; | 1116 | unsigned long trip; |
1111 | unsigned char b; | 1117 | unsigned char b; |
1112 | char quad[5]; | 1118 | char quad[5]; |
1113 | #define MAXQUADS 16 | 1119 | #define MAXQUADS 16 |
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++; |
1123 | trip = trip << 8 | b; | 1129 | trip = trip << 8 | b; |
1124 | } | 1130 | } |
1125 | /* fill in 'quad' with the appropriate four characters */ | 1131 | /* fill in 'quad' with the appropriate four characters */ |
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] = '+'; |
1135 | else quad[i] = '/'; | 1141 | else quad[i] = '/'; |
1136 | } | 1142 | } |
1137 | /* now output 'quad' with appropriate whitespace and line ending */ | 1143 | /* now output 'quad' with appropriate whitespace and line ending */ |
1138 | appendsOFile(fp, (numQuads == 0 ? " " : "")); | 1144 | appendsOFile(fp, (numQuads == 0 ? " " : "")); |
1139 | appendsOFile(fp, quad); | 1145 | appendsOFile(fp, quad); |
1140 | appendsOFile(fp, ((cur >= len)?"\n" :(numQuads==MAXQUADS-1?"\n" : ""))); | 1146 | appendsOFile(fp, ((cur >= len)?"\n" :(numQuads==MAXQUADS-1?"\n" : ""))); |
1141 | numQuads = (numQuads + 1) % MAXQUADS; | 1147 | numQuads = (numQuads + 1) % MAXQUADS; |
1142 | } | 1148 | } |
1143 | appendcOFile(fp,'\n'); | 1149 | appendcOFile(fp,'\n'); |
1144 | 1150 | ||
1145 | return 1; | 1151 | return 1; |
1146 | } | 1152 | } |
1147 | 1153 | ||
1148 | /* this function really sucks. Too basic. */ | 1154 | static void writeString(OFile *fp, const char *s) |
1149 | static void writeQPString(OFile *fp, const char *s, int qp) | 1155 | { |
1156 | appendsOFile(fp,s); | ||
1157 | } | ||
1158 | |||
1159 | static 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 | |||
1164 | static void writeVObject_(OFile *fp, VObject *o); | 1187 | static void writeVObject_(OFile *fp, VObject *o); |
1165 | 1188 | ||
1166 | static void writeValue(OFile *fp, VObject *o, unsigned long size) | 1189 | static 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]; |
1188 | sprintf(buf,"%u", INTEGER_VALUE_OF(o)); | 1207 | sprintf(buf,"%u", INTEGER_VALUE_OF(o)); |
1189 | appendsOFile(fp,buf); | 1208 | appendsOFile(fp,buf); |
1190 | break; | 1209 | break; |
1191 | } | 1210 | } |
1192 | case VCVT_ULONG: { | 1211 | case VCVT_ULONG: { |
1193 | char buf[16]; | 1212 | char buf[16]; |
1194 | sprintf(buf,"%lu", LONG_VALUE_OF(o)); | 1213 | sprintf(buf,"%lu", LONG_VALUE_OF(o)); |
1195 | appendsOFile(fp,buf); | 1214 | appendsOFile(fp,buf); |
1196 | break; | 1215 | break; |
1197 | } | 1216 | } |
1198 | case VCVT_RAW: { | 1217 | case VCVT_RAW: { |
1199 | appendcOFile(fp,'\n'); | 1218 | appendcOFile(fp,'\n'); |
@@ -1207,111 +1226,113 @@ static void writeValue(OFile *fp, VObject *o, unsigned long size) | |||
1207 | } | 1226 | } |
1208 | } | 1227 | } |
1209 | 1228 | ||
1210 | static void writeAttrValue(OFile *fp, VObject *o) | 1229 | static void writeAttrValue(OFile *fp, VObject *o) |
1211 | { | 1230 | { |
1212 | if (NAME_OF(o)) { | 1231 | if (NAME_OF(o)) { |
1213 | struct PreDefProp *pi; | 1232 | struct PreDefProp *pi; |
1214 | pi = lookupPropInfo(NAME_OF(o)); | 1233 | pi = lookupPropInfo(NAME_OF(o)); |
1215 | if (pi && ((pi->flags & PD_INTERNAL) != 0)) return; | 1234 | if (pi && ((pi->flags & PD_INTERNAL) != 0)) return; |
1216 | appendcOFile(fp,';'); | 1235 | appendcOFile(fp,';'); |
1217 | appendsOFile(fp,NAME_OF(o)); | 1236 | appendsOFile(fp,NAME_OF(o)); |
1218 | } | 1237 | } |
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 | ||
1227 | static void writeGroup(OFile *fp, VObject *o) | 1246 | static void writeGroup(OFile *fp, VObject *o) |
1228 | { | 1247 | { |
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 | } |
1241 | 1259 | ||
1242 | static int inList(const char **list, const char *s) | 1260 | static 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 | ||
1252 | static void writeProp(OFile *fp, VObject *o) | 1270 | static 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; |
1258 | pi = lookupPropInfo(NAME_OF(o)); | 1277 | pi = lookupPropInfo(NAME_OF(o)); |
1259 | if (pi && ((pi->flags & PD_BEGIN) != 0)) { | 1278 | if (pi && ((pi->flags & PD_BEGIN) != 0)) { |
1260 | writeVObject_(fp,o); | 1279 | writeVObject_(fp,o); |
1261 | return; | 1280 | return; |
1262 | } | 1281 | } |
1263 | if (isAPropertyOf(o,VCGroupingProp)) | 1282 | if (isAPropertyOf(o,VCGroupingProp)) |
1264 | writeGroup(fp,o); | 1283 | writeGroup(fp,o); |
1265 | else | 1284 | else |
1266 | appendsOFile(fp,NAME_OF(o)); | 1285 | appendsOFile(fp,NAME_OF(o)); |
1267 | if (pi) fields_ = pi->fields; | 1286 | if (pi) fields_ = pi->fields; |
1268 | initPropIterator(&t,o); | 1287 | initPropIterator(&t,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 | } |
1294 | } | 1315 | } |
1295 | 1316 | ||
1296 | if (VALUE_TYPE(o)) { | 1317 | if (VALUE_TYPE(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 | } |
1306 | 1327 | ||
1307 | static void writeVObject_(OFile *fp, VObject *o) | 1328 | static void writeVObject_(OFile *fp, VObject *o) |
1308 | { | 1329 | { |
1309 | if (NAME_OF(o)) { | 1330 | if (NAME_OF(o)) { |
1310 | struct PreDefProp *pi; | 1331 | struct PreDefProp *pi; |
1311 | pi = lookupPropInfo(NAME_OF(o)); | 1332 | pi = lookupPropInfo(NAME_OF(o)); |
1312 | 1333 | ||
1313 | if (pi && ((pi->flags & PD_BEGIN) != 0)) { | 1334 | if (pi && ((pi->flags & PD_BEGIN) != 0)) { |
1314 | VObjectIterator t; | 1335 | VObjectIterator t; |
1315 | const char *begin = NAME_OF(o); | 1336 | const char *begin = NAME_OF(o); |
1316 | appendsOFile(fp,"BEGIN:"); | 1337 | appendsOFile(fp,"BEGIN:"); |
1317 | appendsOFile(fp,begin); | 1338 | appendsOFile(fp,begin); |
@@ -1322,112 +1343,112 @@ static void writeVObject_(OFile *fp, VObject *o) | |||
1322 | writeProp(fp, eachProp); | 1343 | writeProp(fp, eachProp); |
1323 | } | 1344 | } |
1324 | appendsOFile(fp,"END:"); | 1345 | appendsOFile(fp,"END:"); |
1325 | appendsOFile(fp,begin); | 1346 | appendsOFile(fp,begin); |
1326 | appendsOFile(fp,"\n\n"); | 1347 | appendsOFile(fp,"\n\n"); |
1327 | } | 1348 | } |
1328 | } | 1349 | } |
1329 | } | 1350 | } |
1330 | 1351 | ||
1331 | void writeVObject(FILE *fp, VObject *o) | 1352 | void writeVObject(FILE *fp, VObject *o) |
1332 | { | 1353 | { |
1333 | OFile ofp; | 1354 | OFile ofp; |
1334 | initOFile(&ofp,fp); | 1355 | initOFile(&ofp,fp); |
1335 | writeVObject_(&ofp,o); | 1356 | writeVObject_(&ofp,o); |
1336 | } | 1357 | } |
1337 | 1358 | ||
1338 | void writeVObjectToFile(char *fname, VObject *o) | 1359 | DLLEXPORT(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 | ||
1347 | void writeVObjectsToFile(char *fname, VObject *list) | 1368 | DLLEXPORT(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) { |
1352 | writeVObject(fp,list); | 1373 | writeVObject(fp,list); |
1353 | list = nextVObjectInList(list); | 1374 | list = nextVObjectInList(list); |
1354 | } | 1375 | } |
1355 | fclose(fp); | 1376 | fclose(fp); |
1356 | } | 1377 | } |
1357 | } | 1378 | } |
1358 | 1379 | ||
1359 | char* writeMemVObject(char *s, int *len, VObject *o) | 1380 | DLLEXPORT(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); |
1364 | if (len) *len = ofp.len; | 1385 | if (len) *len = ofp.len; |
1365 | appendcOFile(&ofp,0); | 1386 | appendcOFile(&ofp,0); |
1366 | return ofp.s; | 1387 | return ofp.s; |
1367 | } | 1388 | } |
1368 | 1389 | ||
1369 | char* writeMemVObjects(char *s, int *len, VObject *list) | 1390 | DLLEXPORT(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) { |
1374 | writeVObject_(&ofp,list); | 1395 | writeVObject_(&ofp,list); |
1375 | list = nextVObjectInList(list); | 1396 | list = nextVObjectInList(list); |
1376 | } | 1397 | } |
1377 | if (len) *len = ofp.len; | 1398 | if (len) *len = ofp.len; |
1378 | appendcOFile(&ofp,0); | 1399 | appendcOFile(&ofp,0); |
1379 | return ofp.s; | 1400 | return ofp.s; |
1380 | } | 1401 | } |
1381 | 1402 | ||
1382 | /*---------------------------------------------------------------------- | 1403 | /*---------------------------------------------------------------------- |
1383 | APIs to do fake Unicode stuff. | 1404 | APIs to do fake Unicode stuff. |
1384 | ----------------------------------------------------------------------*/ | 1405 | ----------------------------------------------------------------------*/ |
1385 | wchar_t* fakeUnicode(const char *ps, int *bytes) | 1406 | DLLEXPORT(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 | ||
1390 | pw = r = (wchar_t*)malloc(sizeof(wchar_t)*len); | 1411 | pw = r = (wchar_t*)malloc(sizeof(wchar_t)*len); |
1391 | if (bytes) | 1412 | if (bytes) |
1392 | *bytes = len * sizeof(wchar_t); | 1413 | *bytes = len * sizeof(wchar_t); |
1393 | 1414 | ||
1394 | while (*ps) { | 1415 | while (*ps) { |
1395 | if (*ps == '\n') | 1416 | if (*ps == '\n') |
1396 | *pw = (wchar_t)0x2028; | 1417 | *pw = (wchar_t)0x2028; |
1397 | else if (*ps == '\r') | 1418 | else if (*ps == '\r') |
1398 | *pw = (wchar_t)0x2029; | 1419 | *pw = (wchar_t)0x2029; |
1399 | else | 1420 | else |
1400 | *pw = (wchar_t)(unsigned char)*ps; | 1421 | *pw = (wchar_t)(unsigned char)*ps; |
1401 | ps++; pw++; | 1422 | ps++; pw++; |
1402 | } | 1423 | } |
1403 | *pw = (wchar_t)0; | 1424 | *pw = (wchar_t)0; |
1404 | 1425 | ||
1405 | return r; | 1426 | return r; |
1406 | } | 1427 | } |
1407 | 1428 | ||
1408 | int uStrLen(const wchar_t *u) | 1429 | DLLEXPORT(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 | ||
1415 | char* fakeCString(const wchar_t *u) | 1436 | DLLEXPORT(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) |
1424 | *t = '\r'; | 1445 | *t = '\r'; |
1425 | else | 1446 | else |
1426 | *t = (char)*u; | 1447 | *t = (char)*u; |
1427 | u++; t++; | 1448 | u++; t++; |
1428 | } | 1449 | } |
1429 | *t = 0; | 1450 | *t = 0; |
1430 | return s; | 1451 | return s; |
1431 | } | 1452 | } |
1432 | 1453 | ||
1433 | /* end of source file vobject.c */ | 1454 | /* end of source file vobject.c */ |