00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #include <stdlib.h>
00046
00047 #include <qtopia/config.h>
00048 #include "vobject_p.h"
00049 #include "qfiledirect_p.h"
00050 #include <string.h>
00051 #include <stdio.h>
00052 #include <fcntl.h>
00053
00054
00055
00056 #define NAME_OF(o) o->id
00057 #define VALUE_TYPE(o) o->valType
00058 #define STRINGZ_VALUE_OF(o) o->val.strs
00059 #define INTEGER_VALUE_OF(o) o->val.i
00060 #define LONG_VALUE_OF(o) o->val.l
00061 #define ANY_VALUE_OF(o) o->val.any
00062 #define VOBJECT_VALUE_OF(o) o->val.vobj
00063
00064 static char vobj_cs[10];
00065 static enum { EightBit, QuotedPrintable, Base64 } vobj_enc=EightBit;
00066 static const char *vobj_enc_s=0;
00067
00068 typedef union ValueItem {
00069 const char *strs;
00070 unsigned int i;
00071 unsigned long l;
00072 void *any;
00073 VObject *vobj;
00074 } ValueItem;
00075
00076 struct VObject {
00077 VObject *next;
00078 const char *id;
00079 VObject *prop;
00080 unsigned short valType;
00081 ValueItem val;
00082 };
00083
00084 typedef struct StrItem StrItem;
00085
00086 struct StrItem {
00087 StrItem *next;
00088 const char *s;
00089 unsigned int refCnt;
00090 };
00091
00092 DLLEXPORT(const char**) fieldedProp;
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 DLLEXPORT(VObject*) newVObject_(const char *id)
00107 {
00108 VObject *p = (VObject*)malloc(sizeof(VObject));
00109 p->next = 0;
00110 p->id = id;
00111 p->prop = 0;
00112 VALUE_TYPE(p) = 0;
00113 ANY_VALUE_OF(p) = 0;
00114 return p;
00115 }
00116
00117 DLLEXPORT(VObject*) newVObject(const char *id)
00118 {
00119 return newVObject_(lookupStr(id));
00120 }
00121
00122 DLLEXPORT(void) deleteVObject(VObject *p)
00123 {
00124 unUseStr(p->id);
00125 free(p);
00126 }
00127
00128 DLLEXPORT(char*) dupStr(const char *s, unsigned int size)
00129 {
00130 char *t;
00131 if (size == 0) {
00132 size = strlen(s);
00133 }
00134 t = (char*)malloc(size+1);
00135 if (t) {
00136 memcpy(t,s,size);
00137 t[size] = 0;
00138 return t;
00139 }
00140 else {
00141 return (char*)0;
00142 }
00143 }
00144
00145 DLLEXPORT(void) deleteStr(const char *p)
00146 {
00147 if (p) free((void*)p);
00148 }
00149
00150
00151 static StrItem* newStrItem(const char *s, StrItem *next)
00152 {
00153 StrItem *p = (StrItem*)malloc(sizeof(StrItem));
00154 p->next = next;
00155 p->s = s;
00156 p->refCnt = 1;
00157 return p;
00158 }
00159
00160 static void deleteStrItem(StrItem *p)
00161 {
00162 free((void*)p);
00163 }
00164
00165
00166
00167
00168
00169
00170 DLLEXPORT(const char*) vObjectName(VObject *o)
00171 {
00172 return NAME_OF(o);
00173 }
00174
00175 DLLEXPORT(void) setVObjectName(VObject *o, const char* id)
00176 {
00177 NAME_OF(o) = id;
00178 }
00179
00180 DLLEXPORT(const char*) vObjectStringZValue(VObject *o)
00181 {
00182 return STRINGZ_VALUE_OF(o);
00183 }
00184
00185 DLLEXPORT(void) setVObjectStringZValue(VObject *o, const char *s)
00186 {
00187 STRINGZ_VALUE_OF(o) = dupStr(s,0);
00188 VALUE_TYPE(o) = VCVT_STRINGZ;
00189 }
00190
00191 DLLEXPORT(void) setVObjectStringZValue_(VObject *o, const char *s)
00192 {
00193 STRINGZ_VALUE_OF(o) = s;
00194 VALUE_TYPE(o) = VCVT_STRINGZ;
00195 }
00196
00197 DLLEXPORT(unsigned int) vObjectIntegerValue(VObject *o)
00198 {
00199 return INTEGER_VALUE_OF(o);
00200 }
00201
00202 DLLEXPORT(void) setVObjectIntegerValue(VObject *o, unsigned int i)
00203 {
00204 INTEGER_VALUE_OF(o) = i;
00205 VALUE_TYPE(o) = VCVT_UINT;
00206 }
00207
00208 DLLEXPORT(unsigned long) vObjectLongValue(VObject *o)
00209 {
00210 return LONG_VALUE_OF(o);
00211 }
00212
00213 DLLEXPORT(void) setVObjectLongValue(VObject *o, unsigned long l)
00214 {
00215 LONG_VALUE_OF(o) = l;
00216 VALUE_TYPE(o) = VCVT_ULONG;
00217 }
00218
00219 DLLEXPORT(void*) vObjectAnyValue(VObject *o)
00220 {
00221 return ANY_VALUE_OF(o);
00222 }
00223
00224 DLLEXPORT(void) setVObjectAnyValue(VObject *o, void *t)
00225 {
00226 ANY_VALUE_OF(o) = t;
00227 VALUE_TYPE(o) = VCVT_RAW;
00228 }
00229
00230 DLLEXPORT(VObject*) vObjectVObjectValue(VObject *o)
00231 {
00232 return VOBJECT_VALUE_OF(o);
00233 }
00234
00235 DLLEXPORT(void) setVObjectVObjectValue(VObject *o, VObject *p)
00236 {
00237 VOBJECT_VALUE_OF(o) = p;
00238 VALUE_TYPE(o) = VCVT_VOBJECT;
00239 }
00240
00241 DLLEXPORT(int) vObjectValueType(VObject *o)
00242 {
00243 return VALUE_TYPE(o);
00244 }
00245
00246
00247
00248
00249
00250
00251 DLLEXPORT(VObject*) addVObjectProp(VObject *o, VObject *p)
00252 {
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275 VObject *tail = o->prop;
00276 if (tail) {
00277 p->next = tail->next;
00278 o->prop = tail->next = p;
00279 }
00280 else {
00281 o->prop = p->next = p;
00282 }
00283 return p;
00284 }
00285
00286 DLLEXPORT(VObject*) addProp(VObject *o, const char *id)
00287 {
00288 return addVObjectProp(o,newVObject(id));
00289 }
00290
00291 DLLEXPORT(VObject*) addProp_(VObject *o, const char *id)
00292 {
00293 return addVObjectProp(o,newVObject_(id));
00294 }
00295
00296 DLLEXPORT(void) addList(VObject **o, VObject *p)
00297 {
00298 p->next = 0;
00299 if (*o == 0) {
00300 *o = p;
00301 }
00302 else {
00303 VObject *t = *o;
00304 while (t->next) {
00305 t = t->next;
00306 }
00307 t->next = p;
00308 }
00309 }
00310
00311 DLLEXPORT(VObject*) nextVObjectInList(VObject *o)
00312 {
00313 return o->next;
00314 }
00315
00316 DLLEXPORT(VObject*) setValueWithSize_(VObject *prop, void *val, unsigned int size)
00317 {
00318 VObject *sizeProp;
00319 setVObjectAnyValue(prop, val);
00320 sizeProp = addProp(prop,VCDataSizeProp);
00321 setVObjectLongValue(sizeProp, size);
00322 return prop;
00323 }
00324
00325 DLLEXPORT(VObject*) setValueWithSize(VObject *prop, void *val, unsigned int size)
00326 {
00327 void *p = dupStr((const char *)val,size);
00328 return setValueWithSize_(prop,p,p?size:0);
00329 }
00330
00331 DLLEXPORT(void) initPropIterator(VObjectIterator *i, VObject *o)
00332 {
00333 i->start = o->prop;
00334 i->next = 0;
00335 }
00336
00337 DLLEXPORT(void) initVObjectIterator(VObjectIterator *i, VObject *o)
00338 {
00339 i->start = o->next;
00340 i->next = 0;
00341 }
00342
00343 DLLEXPORT(int) moreIteration(VObjectIterator *i)
00344 {
00345 return (i->start && (i->next==0 || i->next!=i->start));
00346 }
00347
00348 DLLEXPORT(VObject*) nextVObject(VObjectIterator *i)
00349 {
00350 if (i->start && i->next != i->start) {
00351 if (i->next == 0) {
00352 i->next = i->start->next;
00353 return i->next;
00354 }
00355 else {
00356 i->next = i->next->next;
00357 return i->next;
00358 }
00359 }
00360 else return (VObject*)0;
00361 }
00362
00363 DLLEXPORT(VObject*) isAPropertyOf(VObject *o, const char *id)
00364 {
00365 VObjectIterator i;
00366 initPropIterator(&i,o);
00367 while (moreIteration(&i)) {
00368 VObject *each = nextVObject(&i);
00369 if (!qstricmp(id,each->id))
00370 return each;
00371 }
00372 return (VObject*)0;
00373 }
00374
00375 DLLEXPORT(VObject*) addGroup(VObject *o, const char *g)
00376 {
00377
00378
00379
00380
00381
00382
00383
00384 char *dot = strrchr(g,'.');
00385 if (dot) {
00386 VObject *p, *t;
00387 char *gs, *n = dot+1;
00388 gs = dupStr(g,0);
00389
00390
00391
00392 t = p = addProp_(o,lookupProp(n));
00393 dot = strrchr(gs,'.');
00394 *dot = 0;
00395 do {
00396 dot = strrchr(gs,'.');
00397 if (dot) {
00398 n = dot+1;
00399 *dot=0;
00400 }
00401 else
00402 n = gs;
00403
00404
00405
00406 t = addProp(t,VCGroupingProp);
00407 setVObjectStringZValue(t,lookupProp_(n));
00408 } while (n != gs);
00409 deleteStr(gs);
00410 return p;
00411 }
00412 else
00413 return addProp_(o,lookupProp(g));
00414 }
00415
00416 DLLEXPORT(VObject*) addPropValue(VObject *o, const char *p, const char *v)
00417 {
00418 VObject *prop;
00419 prop = addProp(o,p);
00420 setVObjectStringZValue_(prop, strdup( v ) );
00421 return prop;
00422 }
00423
00424 DLLEXPORT(VObject*) addPropSizedValue_(VObject *o, const char *p, const char *v,
00425 unsigned int size)
00426 {
00427 VObject *prop;
00428 prop = addProp(o,p);
00429 setValueWithSize_(prop, (void*)v, size);
00430 return prop;
00431 }
00432
00433 DLLEXPORT(VObject*) addPropSizedValue(VObject *o, const char *p, const char *v,
00434 unsigned int size)
00435 {
00436 return addPropSizedValue_(o,p,dupStr(v,size),size);
00437 }
00438
00439
00440 DLLEXPORT(void) cleanVObject(VObject *o)
00441 {
00442 if (o == 0) return;
00443 if (o->prop) {
00444
00445
00446
00447
00448
00449
00450
00451 VObject *p;
00452 p = o->prop->next;
00453 o->prop->next = 0;
00454 do {
00455 VObject *t = p->next;
00456 cleanVObject(p);
00457 p = t;
00458 } while (p);
00459 }
00460 switch (VALUE_TYPE(o)) {
00461 case VCVT_STRINGZ:
00462 case VCVT_RAW:
00463
00464 free((char*)STRINGZ_VALUE_OF(o));
00465 break;
00466 case VCVT_VOBJECT:
00467 cleanVObject(VOBJECT_VALUE_OF(o));
00468 break;
00469 }
00470 deleteVObject(o);
00471 }
00472
00473 DLLEXPORT(void) cleanVObjects(VObject *list)
00474 {
00475 while (list) {
00476 VObject *t = list;
00477 list = nextVObjectInList(list);
00478 cleanVObject(t);
00479 }
00480 }
00481
00482
00483
00484
00485
00486 #define STRTBLSIZE 255
00487
00488 static StrItem *strTbl[STRTBLSIZE];
00489
00490 static unsigned int hashStr(const char *s)
00491 {
00492 unsigned int h = 0;
00493 int i;
00494 for (i=0;s[i];i++) {
00495 h += s[i]*i;
00496 }
00497 return h % STRTBLSIZE;
00498 }
00499
00500 DLLEXPORT(const char*) lookupStr(const char *s)
00501 {
00502 StrItem *t;
00503 unsigned int h = hashStr(s);
00504 if ((t = strTbl[h]) != 0) {
00505 do {
00506 if (qstricmp(t->s,s) == 0) {
00507 t->refCnt++;
00508 return t->s;
00509 }
00510 t = t->next;
00511 } while (t);
00512 }
00513 s = dupStr(s,0);
00514 strTbl[h] = newStrItem(s,strTbl[h]);
00515 return s;
00516 }
00517
00518 DLLEXPORT(void) unUseStr(const char *s)
00519 {
00520 StrItem *t, *p;
00521 unsigned int h = hashStr(s);
00522 if ((t = strTbl[h]) != 0) {
00523 p = t;
00524 do {
00525 if (qstricmp(t->s,s) == 0) {
00526 t->refCnt--;
00527 if (t->refCnt == 0) {
00528 if (p == strTbl[h]) {
00529 strTbl[h] = t->next;
00530 }
00531 else {
00532 p->next = t->next;
00533 }
00534 deleteStr(t->s);
00535 deleteStrItem(t);
00536 return;
00537 }
00538 }
00539 p = t;
00540 t = t->next;
00541 } while (t);
00542 }
00543 }
00544
00545 DLLEXPORT(void) cleanStrTbl()
00546 {
00547 int i;
00548 for (i=0; i<STRTBLSIZE;i++) {
00549 StrItem *t = strTbl[i];
00550 while (t) {
00551 StrItem *p;
00552 deleteStr(t->s);
00553 p = t;
00554 t = t->next;
00555 deleteStrItem(p);
00556 } while (t);
00557 strTbl[i] = 0;
00558 }
00559 }
00560
00561
00562 struct PreDefProp {
00563 const char *name;
00564 const char *alias;
00565 const char** fields;
00566 unsigned int flags;
00567 };
00568
00569
00570 #define PD_BEGIN 0x1
00571 #define PD_INTERNAL 0x2
00572
00573 static const char *adrFields[] = {
00574 VCPostalBoxProp,
00575 VCExtAddressProp,
00576 VCStreetAddressProp,
00577 VCCityProp,
00578 VCRegionProp,
00579 VCPostalCodeProp,
00580 VCCountryNameProp,
00581 0
00582 };
00583
00584 static const char *nameFields[] = {
00585 VCFamilyNameProp,
00586 VCGivenNameProp,
00587 VCAdditionalNamesProp,
00588 VCNamePrefixesProp,
00589 VCNameSuffixesProp,
00590 NULL
00591 };
00592
00593 static const char *orgFields[] = {
00594 VCOrgNameProp,
00595 VCOrgUnitProp,
00596 VCOrgUnit2Prop,
00597 VCOrgUnit3Prop,
00598 VCOrgUnit4Prop,
00599 NULL
00600 };
00601
00602 static const char *AAlarmFields[] = {
00603 VCRunTimeProp,
00604 VCSnoozeTimeProp,
00605 VCRepeatCountProp,
00606 VCAudioContentProp,
00607 0
00608 };
00609
00610
00611
00612
00613 static const char *DAlarmFields[] = {
00614 VCRunTimeProp,
00615 VCSnoozeTimeProp,
00616 VCRepeatCountProp,
00617 VCDisplayStringProp,
00618 0
00619 };
00620
00621 static const char *MAlarmFields[] = {
00622 VCRunTimeProp,
00623 VCSnoozeTimeProp,
00624 VCRepeatCountProp,
00625 VCEmailAddressProp,
00626 VCNoteProp,
00627 0
00628 };
00629
00630 static const char *PAlarmFields[] = {
00631 VCRunTimeProp,
00632 VCSnoozeTimeProp,
00633 VCRepeatCountProp,
00634 VCProcedureNameProp,
00635 0
00636 };
00637
00638 static struct PreDefProp propNames[] = {
00639 { VC7bitProp, 0, 0, 0 },
00640 { VC8bitProp, 0, 0, 0 },
00641 { VCAAlarmProp, 0, AAlarmFields, 0 },
00642 { VCAdditionalNamesProp, 0, 0, 0 },
00643 { VCAdrProp, 0, adrFields, 0 },
00644 { VCAgentProp, 0, 0, 0 },
00645 { VCAIFFProp, 0, 0, 0 },
00646 { VCAOLProp, 0, 0, 0 },
00647 { VCAppleLinkProp, 0, 0, 0 },
00648 { VCAttachProp, 0, 0, 0 },
00649 { VCAttendeeProp, 0, 0, 0 },
00650 { VCATTMailProp, 0, 0, 0 },
00651 { VCAudioContentProp, 0, 0, 0 },
00652 { VCAVIProp, 0, 0, 0 },
00653 { VCBase64Prop, 0, 0, 0 },
00654 { VCBBSProp, 0, 0, 0 },
00655 { VCBirthDateProp, 0, 0, 0 },
00656 { VCBMPProp, 0, 0, 0 },
00657 { VCBodyProp, 0, 0, 0 },
00658 { VCBusinessRoleProp, 0, 0, 0 },
00659 { VCCalProp, 0, 0, PD_BEGIN },
00660 { VCCaptionProp, 0, 0, 0 },
00661 { VCCardProp, 0, 0, PD_BEGIN },
00662 { VCCarProp, 0, 0, 0 },
00663 { VCCategoriesProp, 0, 0, 0 },
00664 { VCCellularProp, 0, 0, 0 },
00665 { VCCGMProp, 0, 0, 0 },
00666 { VCCharSetProp, 0, 0, 0 },
00667 { VCCIDProp, VCContentIDProp, 0, 0 },
00668 { VCCISProp, 0, 0, 0 },
00669 { VCCityProp, 0, 0, 0 },
00670 { VCClassProp, 0, 0, 0 },
00671 { VCCommentProp, 0, 0, 0 },
00672 { VCCompletedProp, 0, 0, 0 },
00673 { VCContentIDProp, 0, 0, 0 },
00674 { VCCountryNameProp, 0, 0, 0 },
00675 { VCDAlarmProp, 0, DAlarmFields, 0 },
00676 { VCDataSizeProp, 0, 0, PD_INTERNAL },
00677 { VCDayLightProp, 0, 0, 0 },
00678 { VCDCreatedProp, 0, 0, 0 },
00679 { VCDeliveryLabelProp, 0, 0, 0 },
00680 { VCDescriptionProp, 0, 0, 0 },
00681 { VCDIBProp, 0, 0, 0 },
00682 { VCDisplayStringProp, 0, 0, 0 },
00683 { VCDomesticProp, 0, 0, 0 },
00684 { VCDTendProp, 0, 0, 0 },
00685 { VCDTstartProp, 0, 0, 0 },
00686 { VCDueProp, 0, 0, 0 },
00687 { VCEmailAddressProp, 0, 0, 0 },
00688 { VCEncodingProp, 0, 0, 0 },
00689 { VCEndProp, 0, 0, 0 },
00690 { VCEventProp, 0, 0, PD_BEGIN },
00691 { VCEWorldProp, 0, 0, 0 },
00692 { VCExNumProp, 0, 0, 0 },
00693 { VCExpDateProp, 0, 0, 0 },
00694 { VCExpectProp, 0, 0, 0 },
00695 { VCExtAddressProp, 0, 0, 0 },
00696 { VCFamilyNameProp, 0, 0, 0 },
00697 { VCFaxProp, 0, 0, 0 },
00698 { VCFullNameProp, 0, 0, 0 },
00699 { VCGeoLocationProp, 0, 0, 0 },
00700 { VCGeoProp, 0, 0, 0 },
00701 { VCGIFProp, 0, 0, 0 },
00702 { VCGivenNameProp, 0, 0, 0 },
00703 { VCGroupingProp, 0, 0, 0 },
00704 { VCHomeProp, 0, 0, 0 },
00705 { VCIBMMailProp, 0, 0, 0 },
00706 { VCInlineProp, 0, 0, 0 },
00707 { VCInternationalProp, 0, 0, 0 },
00708 { VCInternetProp, 0, 0, 0 },
00709 { VCISDNProp, 0, 0, 0 },
00710 { VCJPEGProp, 0, 0, 0 },
00711 { VCLanguageProp, 0, 0, 0 },
00712 { VCLastModifiedProp, 0, 0, 0 },
00713 { VCLastRevisedProp, 0, 0, 0 },
00714 { VCLocationProp, 0, 0, 0 },
00715 { VCLogoProp, 0, 0, 0 },
00716 { VCMailerProp, 0, 0, 0 },
00717 { VCMAlarmProp, 0, MAlarmFields, 0 },
00718 { VCMCIMailProp, 0, 0, 0 },
00719 { VCMessageProp, 0, 0, 0 },
00720 { VCMETProp, 0, 0, 0 },
00721 { VCModemProp, 0, 0, 0 },
00722 { VCMPEG2Prop, 0, 0, 0 },
00723 { VCMPEGProp, 0, 0, 0 },
00724 { VCMSNProp, 0, 0, 0 },
00725 { VCNamePrefixesProp, 0, 0, 0 },
00726 { VCNameProp, 0, nameFields, 0 },
00727 { VCNameSuffixesProp, 0, 0, 0 },
00728 { VCNoteProp, 0, 0, 0 },
00729 { VCOrgNameProp, 0, 0, 0 },
00730 { VCOrgProp, 0, orgFields, 0 },
00731 { VCOrgUnit2Prop, 0, 0, 0 },
00732 { VCOrgUnit3Prop, 0, 0, 0 },
00733 { VCOrgUnit4Prop, 0, 0, 0 },
00734 { VCOrgUnitProp, 0, 0, 0 },
00735 { VCPagerProp, 0, 0, 0 },
00736 { VCPAlarmProp, 0, PAlarmFields, 0 },
00737 { VCParcelProp, 0, 0, 0 },
00738 { VCPartProp, 0, 0, 0 },
00739 { VCPCMProp, 0, 0, 0 },
00740 { VCPDFProp, 0, 0, 0 },
00741 { VCPGPProp, 0, 0, 0 },
00742 { VCPhotoProp, 0, 0, 0 },
00743 { VCPICTProp, 0, 0, 0 },
00744 { VCPMBProp, 0, 0, 0 },
00745 { VCPostalBoxProp, 0, 0, 0 },
00746 { VCPostalCodeProp, 0, 0, 0 },
00747 { VCPostalProp, 0, 0, 0 },
00748 { VCPowerShareProp, 0, 0, 0 },
00749 { VCPreferredProp, 0, 0, 0 },
00750 { VCPriorityProp, 0, 0, 0 },
00751 { VCProcedureNameProp, 0, 0, 0 },
00752 { VCProdIdProp, 0, 0, 0 },
00753 { VCProdigyProp, 0, 0, 0 },
00754 { VCPronunciationProp, 0, 0, 0 },
00755 { VCPSProp, 0, 0, 0 },
00756 { VCPublicKeyProp, 0, 0, 0 },
00757 { VCQPProp, VCQuotedPrintableProp, 0, 0 },
00758 { VCQuickTimeProp, 0, 0, 0 },
00759 { VCQuotedPrintableProp, 0, 0, 0 },
00760 { VCRDateProp, 0, 0, 0 },
00761 { VCRegionProp, 0, 0, 0 },
00762 { VCRelatedToProp, 0, 0, 0 },
00763 { VCRepeatCountProp, 0, 0, 0 },
00764 { VCResourcesProp, 0, 0, 0 },
00765 { VCRNumProp, 0, 0, 0 },
00766 { VCRoleProp, 0, 0, 0 },
00767 { VCRRuleProp, 0, 0, 0 },
00768 { VCRSVPProp, 0, 0, 0 },
00769 { VCRunTimeProp, 0, 0, 0 },
00770 { VCSequenceProp, 0, 0, 0 },
00771 { VCSnoozeTimeProp, 0, 0, 0 },
00772 { VCStartProp, 0, 0, 0 },
00773 { VCStatusProp, 0, 0, 0 },
00774 { VCStreetAddressProp, 0, 0, 0 },
00775 { VCSubTypeProp, 0, 0, 0 },
00776 { VCSummaryProp, 0, 0, 0 },
00777 { VCTelephoneProp, 0, 0, 0 },
00778 { VCTIFFProp, 0, 0, 0 },
00779 { VCTimeZoneProp, 0, 0, 0 },
00780 { VCTitleProp, 0, 0, 0 },
00781 { VCTLXProp, 0, 0, 0 },
00782 { VCTodoProp, 0, 0, PD_BEGIN },
00783 { VCTranspProp, 0, 0, 0 },
00784 { VCUniqueStringProp, 0, 0, 0 },
00785 { VCURLProp, 0, 0, 0 },
00786 { VCURLValueProp, 0, 0, 0 },
00787 { VCValueProp, 0, 0, 0 },
00788 { VCVersionProp, 0, 0, 0 },
00789 { VCVideoProp, 0, 0, 0 },
00790 { VCVoiceProp, 0, 0, 0 },
00791 { VCWAVEProp, 0, 0, 0 },
00792 { VCWMFProp, 0, 0, 0 },
00793 { VCWorkProp, 0, 0, 0 },
00794 { VCX400Prop, 0, 0, 0 },
00795 { VCX509Prop, 0, 0, 0 },
00796 { VCXRuleProp, 0, 0, 0 },
00797 { 0,0,0,0 }
00798 };
00799
00800
00801 static struct PreDefProp* lookupPropInfo(const char* str)
00802 {
00803
00804 int i;
00805
00806 for (i = 0; propNames[i].name; i++)
00807 if (qstricmp(str, propNames[i].name) == 0) {
00808 return &propNames[i];
00809 }
00810
00811 return 0;
00812 }
00813
00814
00815 DLLEXPORT(const char*) lookupProp_(const char* str)
00816 {
00817 int i;
00818
00819 for (i = 0; propNames[i].name; i++)
00820 if (qstricmp(str, propNames[i].name) == 0) {
00821 const char* s;
00822 s = propNames[i].alias?propNames[i].alias:propNames[i].name;
00823 return lookupStr(s);
00824 }
00825 return lookupStr(str);
00826 }
00827
00828
00829 DLLEXPORT(const char*) lookupProp(const char* str)
00830 {
00831 int i;
00832
00833 for (i = 0; propNames[i].name; i++)
00834 if (qstricmp(str, propNames[i].name) == 0) {
00835 const char *s;
00836 fieldedProp = propNames[i].fields;
00837 s = propNames[i].alias?propNames[i].alias:propNames[i].name;
00838 return lookupStr(s);
00839 }
00840 fieldedProp = 0;
00841 return lookupStr(str);
00842 }
00843
00844
00845
00846
00847
00848 #define OFILE_REALLOC_SIZE 256
00849 typedef struct OFile {
00850 FILE *fp;
00851 char *s;
00852 int len;
00853 int limit;
00854 int alloc:1;
00855 int fail:1;
00856 } OFile;
00857
00858 #if 0
00859 static void appendsOFile(OFile *fp, const char *s)
00860 {
00861 int slen;
00862 if (fp->fail) return;
00863 slen = strlen(s);
00864 if (fp->fp) {
00865 fwrite(s,1,slen,fp->fp);
00866 }
00867 else {
00868 stuff:
00869 if (fp->len + slen < fp->limit) {
00870 memcpy(fp->s+fp->len,s,slen);
00871 fp->len += slen;
00872 return;
00873 }
00874 else if (fp->alloc) {
00875 fp->limit = fp->limit + OFILE_REALLOC_SIZE;
00876 if (OFILE_REALLOC_SIZE <= slen) fp->limit += slen;
00877 fp->s = (char *) realloc(fp->s,fp->limit);
00878 if (fp->s) goto stuff;
00879 }
00880 if (fp->alloc)
00881 free(fp->s);
00882 fp->s = 0;
00883 fp->fail = 1;
00884 }
00885 }
00886
00887 static void appendcOFile(OFile *fp, char c)
00888 {
00889 if (fp->fail) return;
00890 if (fp->fp) {
00891 fputc(c,fp->fp);
00892 }
00893 else {
00894 stuff:
00895 if (fp->len+1 < fp->limit) {
00896 fp->s[fp->len] = c;
00897 fp->len++;
00898 return;
00899 }
00900 else if (fp->alloc) {
00901 fp->limit = fp->limit + OFILE_REALLOC_SIZE;
00902 fp->s = (char *) realloc(fp->s,fp->limit);
00903 if (fp->s) goto stuff;
00904 }
00905 if (fp->alloc)
00906 free(fp->s);
00907 fp->s = 0;
00908 fp->fail = 1;
00909 }
00910 }
00911 #else
00912 static void appendcOFile_(OFile *fp, char c)
00913 {
00914 if (fp->fail) return;
00915 if (fp->fp) {
00916 fputc(c,fp->fp);
00917 }
00918 else {
00919 stuff:
00920 if (fp->len+1 < fp->limit) {
00921 fp->s[fp->len] = c;
00922 fp->len++;
00923 return;
00924 }
00925 else if (fp->alloc) {
00926 fp->limit = fp->limit + OFILE_REALLOC_SIZE;
00927 fp->s = (char *)realloc(fp->s,fp->limit);
00928 if (fp->s) goto stuff;
00929 }
00930 if (fp->alloc)
00931 free(fp->s);
00932 fp->s = 0;
00933 fp->fail = 1;
00934 }
00935 }
00936
00937 static void appendcOFile(OFile *fp, char c)
00938 {
00939 if (c == '\n') {
00940
00941 appendcOFile_(fp,0xd);
00942 appendcOFile_(fp,0xa);
00943 }
00944 else
00945 appendcOFile_(fp,c);
00946 }
00947
00948 static void appendsOFile(OFile *fp, const char *s)
00949 {
00950 int i, slen;
00951 slen = strlen(s);
00952 for (i=0; i<slen; i++) {
00953 appendcOFile(fp,s[i]);
00954 }
00955 }
00956
00957 #endif
00958
00959 static void appendsOFileEncCs(OFile *fp)
00960 {
00961 if ( vobj_enc_s ) {
00962 appendsOFile(fp, ";" VCEncodingProp "=");
00963 appendsOFile(fp, vobj_enc_s);
00964 }
00965 appendsOFile(fp, ";" VCCharSetProp "=");
00966 appendsOFile(fp, vobj_cs);
00967 }
00968
00969
00970 static void initOFile(OFile *fp, FILE *ofp)
00971 {
00972 fp->fp = ofp;
00973 fp->s = 0;
00974 fp->len = 0;
00975 fp->limit = 0;
00976 fp->alloc = 0;
00977 fp->fail = 0;
00978 }
00979
00980 static int writeBase64(OFile *fp, unsigned char *s, long len)
00981 {
00982 long cur = 0;
00983 int i, numQuads = 0;
00984 unsigned long trip;
00985 unsigned char b;
00986 char quad[5];
00987 #define MAXQUADS 16
00988
00989 quad[4] = 0;
00990
00991 while (cur < len) {
00992
00993 trip = 0;
00994 for (i = 0; i < 3; i++) {
00995 b = (cur < len) ? *(s + cur) : 0;
00996 cur++;
00997 trip = trip << 8 | b;
00998 }
00999
01000 for (i = 3; i >= 0; i--) {
01001 b = (unsigned char)(trip & 0x3F);
01002 trip = trip >> 6;
01003 if ((3 - i) < (cur - len))
01004 quad[i] = '=';
01005 else if (b < 26) quad[i] = (char)b + 'A';
01006 else if (b < 52) quad[i] = (char)(b - 26) + 'a';
01007 else if (b < 62) quad[i] = (char)(b - 52) + '0';
01008 else if (b == 62) quad[i] = '+';
01009 else quad[i] = '/';
01010 }
01011
01012 appendsOFile(fp, (numQuads == 0 ? " " : ""));
01013 appendsOFile(fp, quad);
01014 appendsOFile(fp, ((cur >= len)?"\n" :(numQuads==MAXQUADS-1?"\n" : "")));
01015 numQuads = (numQuads + 1) % MAXQUADS;
01016 }
01017 appendcOFile(fp,'\n');
01018
01019 return 1;
01020 }
01021
01022 static const char *qpReplaceChar(unsigned char c)
01023 {
01024 if (c == '\n') {
01025 return "=0A=\n";
01026 } else if (
01027
01028 (c >= 32 && c <= 60)
01029 ||
01030 (c >= 62 && c <= 126)
01031 )
01032 {
01033 return 0;
01034 }
01035
01036 static char trans[4];
01037 trans[0] = '=';
01038 trans[3] = '\0';
01039 int rem = c % 16;
01040 int div = c / 16;
01041
01042 if (div < 10)
01043 trans[1] = '0' + div;
01044 else
01045 trans[1] = 'A' + (div - 10);
01046
01047 if (rem < 10)
01048 trans[2] = '0' + rem;
01049 else
01050 trans[2] = 'A' + (rem - 10);
01051
01052 return trans;
01053 }
01054
01055 static void writeEncString(OFile *fp, const char *s, bool nosemi)
01056 {
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073 const char *p = s;
01074 switch ( vobj_enc ) {
01075 case EightBit:
01076 while (*p) {
01077 if ( *p == '\n' || nosemi && ( *p == '\\' || *p == ';' ) )
01078 appendcOFile(fp, '\\');
01079 appendcOFile(fp, *p);
01080 p++;
01081 }
01082 break;
01083 case QuotedPrintable:
01084 while (*p) {
01085 const char *rep = qpReplaceChar(*p);
01086 if (rep)
01087 appendsOFile(fp, rep);
01088 else if ( *p == ';' && nosemi )
01089 appendsOFile(fp, "=3B");
01090 else if ( *p == ' ' ) {
01091 if ( !p[1] || p[1] == '\n' )
01092 appendsOFile(fp, "=20");
01093 else
01094 appendcOFile(fp, *p);
01095 } else
01096 appendcOFile(fp, *p);
01097 p++;
01098 }
01099 break;
01100 case Base64:
01101 writeBase64(fp, (unsigned char*)p, strlen(p));
01102 break;
01103 }
01104 }
01105
01106 static bool includesUnprintable(VObject *o)
01107 {
01108 if (o) {
01109 if (VALUE_TYPE(o) == VCVT_STRINGZ) {
01110 const char *p = STRINGZ_VALUE_OF(o);
01111 if (p) {
01112 while (*p) {
01113 if (*p==' ' && (!p[1] || p[1]=='\n')
01114 || qpReplaceChar(*p) )
01115 return TRUE;
01116 p++;
01117 }
01118 }
01119 }
01120 }
01121 return FALSE;
01122 }
01123
01124 static void writeVObject_(OFile *fp, VObject *o);
01125
01126 static void writeValue(OFile *fp, VObject *o, unsigned long size, bool nosemi)
01127 {
01128 if (o == 0) return;
01129 switch (VALUE_TYPE(o)) {
01130 case VCVT_STRINGZ: {
01131 writeEncString(fp, STRINGZ_VALUE_OF(o), nosemi);
01132 break;
01133 }
01134 case VCVT_UINT: {
01135 char buf[16];
01136 sprintf(buf,"%u", INTEGER_VALUE_OF(o));
01137 appendsOFile(fp,buf);
01138 break;
01139 }
01140 case VCVT_ULONG: {
01141 char buf[16];
01142 sprintf(buf,"%lu", LONG_VALUE_OF(o));
01143 appendsOFile(fp,buf);
01144 break;
01145 }
01146 case VCVT_RAW: {
01147 appendcOFile(fp,'\n');
01148 writeBase64(fp,(unsigned char*)(ANY_VALUE_OF(o)),size);
01149 break;
01150 }
01151 case VCVT_VOBJECT:
01152 appendcOFile(fp,'\n');
01153 writeVObject_(fp,VOBJECT_VALUE_OF(o));
01154 break;
01155 }
01156 }
01157
01158 static void writeAttrValue(OFile *fp, VObject *o)
01159 {
01160 if (NAME_OF(o)) {
01161 struct PreDefProp *pi;
01162 pi = lookupPropInfo(NAME_OF(o));
01163 if (pi && ((pi->flags & PD_INTERNAL) != 0)) return;
01164 if ( includesUnprintable(o) )
01165 appendsOFileEncCs(fp);
01166 appendcOFile(fp,';');
01167 appendsOFile(fp,NAME_OF(o));
01168 } else {
01169 appendcOFile(fp,';');
01170 }
01171 if (VALUE_TYPE(o)) {
01172 appendcOFile(fp,'=');
01173 writeValue(fp,o,0,TRUE);
01174 }
01175 }
01176
01177 static void writeGroup(OFile *fp, VObject *o)
01178 {
01179 char buf1[256];
01180 char buf2[256];
01181 strcpy(buf1,NAME_OF(o));
01182 while ((o=isAPropertyOf(o,VCGroupingProp)) != 0) {
01183 strcpy(buf2,STRINGZ_VALUE_OF(o));
01184 strcat(buf2,".");
01185 strcat(buf2,buf1);
01186 strcpy(buf1,buf2);
01187 }
01188 appendsOFile(fp,buf1);
01189 }
01190
01191 static int inList(const char **list, const char *s)
01192 {
01193 if (list == 0) return 0;
01194 while (*list) {
01195 if (qstricmp(*list,s) == 0) return 1;
01196 list++;
01197 }
01198 return 0;
01199 }
01200
01201 static void writeProp(OFile *fp, VObject *o)
01202 {
01203 if (NAME_OF(o)) {
01204 struct PreDefProp *pi;
01205 VObjectIterator t;
01206 const char **fields_ = 0;
01207 pi = lookupPropInfo(NAME_OF(o));
01208 if (pi && ((pi->flags & PD_BEGIN) != 0)) {
01209 writeVObject_(fp,o);
01210 return;
01211 }
01212 if (isAPropertyOf(o,VCGroupingProp))
01213 writeGroup(fp,o);
01214 else
01215 appendsOFile(fp,NAME_OF(o));
01216 if (pi) fields_ = pi->fields;
01217 initPropIterator(&t,o);
01218 while (moreIteration(&t)) {
01219 const char *s;
01220 VObject *eachProp = nextVObject(&t);
01221 s = NAME_OF(eachProp);
01222 if (qstricmp(VCGroupingProp,s) && !inList(fields_,s))
01223 writeAttrValue(fp,eachProp);
01224 }
01225 if (fields_) {
01226 int i = 0, n = 0;
01227 const char** fields = fields_;
01228
01229 bool printable = TRUE;
01230 while (*fields && printable) {
01231 VObject *t = isAPropertyOf(o,*fields);
01232 if (includesUnprintable(t))
01233 printable = FALSE;
01234 fields++;
01235 }
01236 fields = fields_;
01237 if (!printable)
01238 appendsOFileEncCs(fp);
01239 appendcOFile(fp,':');
01240 while (*fields) {
01241 VObject *t = isAPropertyOf(o,*fields);
01242 i++;
01243 if (t) n = i;
01244 fields++;
01245 }
01246 fields = fields_;
01247 for (i=0;i<n;i++) {
01248 writeValue(fp,isAPropertyOf(o,*fields),0,TRUE);
01249 fields++;
01250 if (i<(n-1)) appendcOFile(fp,';');
01251 }
01252 }
01253 }
01254
01255
01256 if (VALUE_TYPE(o)) {
01257 if ( includesUnprintable(o) )
01258 appendsOFileEncCs(fp);
01259 unsigned long size = 0;
01260 VObject *p = isAPropertyOf(o,VCDataSizeProp);
01261 if (p) size = LONG_VALUE_OF(p);
01262 appendcOFile(fp,':');
01263 writeValue(fp,o,size,FALSE);
01264 }
01265
01266 appendcOFile(fp,'\n');
01267 }
01268
01269 static void writeVObject_(OFile *fp, VObject *o)
01270 {
01271 if (NAME_OF(o)) {
01272 struct PreDefProp *pi;
01273 pi = lookupPropInfo(NAME_OF(o));
01274
01275 if (pi && ((pi->flags & PD_BEGIN) != 0)) {
01276 VObjectIterator t;
01277 const char *begin = NAME_OF(o);
01278 appendsOFile(fp,"BEGIN:");
01279 appendsOFile(fp,begin);
01280 appendcOFile(fp,'\n');
01281 initPropIterator(&t,o);
01282 while (moreIteration(&t)) {
01283 VObject *eachProp = nextVObject(&t);
01284 writeProp(fp, eachProp);
01285 }
01286 appendsOFile(fp,"END:");
01287 appendsOFile(fp,begin);
01288 appendsOFile(fp,"\n\n");
01289 }
01290 }
01291 }
01292
01293 static void initVObjectEncoding()
01294 {
01295 Config pimConfig( "Beam" );
01296 pimConfig.setGroup("Send");
01297 Config devcfg(pimConfig.readEntry("DeviceConfig"),Config::File);
01298 QString enc = "QP";
01299 QString cs = "UTF-8";
01300 if ( devcfg.isValid() ) {
01301 devcfg.setGroup("Send");
01302 enc = devcfg.readEntry("Encoding","QP");
01303 cs = devcfg.readEntry("CharSet","UTF-8");
01304 }
01305 strncpy(vobj_cs,cs.latin1(),10);
01306 if ( enc == "QP" ) {
01307 vobj_enc = QuotedPrintable;
01308 vobj_enc_s = VCQuotedPrintableProp;
01309 } else if ( enc == "B64" ) {
01310 vobj_enc = Base64;
01311 vobj_enc_s = VCBase64Prop;
01312 } else {
01313 vobj_enc = EightBit;
01314 vobj_enc_s = 0;
01315 }
01316 }
01317
01318 void writeVObject(FILE *fp, VObject *o)
01319 {
01320 initVObjectEncoding();
01321
01322 OFile ofp;
01323
01324
01325 initOFile(&ofp,fp);
01326 writeVObject_(&ofp,o);
01327 }
01328
01329 DLLEXPORT(void) writeVObjectToFile(char *fname, VObject *o)
01330 {
01331 QFileDirect f( fname);
01332 if ( !f.open( IO_WriteOnly ) ) {
01333 qWarning("Unable to open vobject write %s", fname);
01334 return;
01335 }
01336
01337 writeVObject( f.directHandle(),o );
01338 }
01339
01340 DLLEXPORT(void) writeVObjectsToFile(char *fname, VObject *list)
01341 {
01342 QFileDirect f( fname);
01343 if ( !f.open( IO_WriteOnly ) ) {
01344 qWarning("Unable to open vobject write %s", fname);
01345 return;
01346 }
01347
01348 while (list) {
01349 writeVObject(f.directHandle(),list);
01350 list = nextVObjectInList(list);
01351 }
01352 }
01353
01354 DLLEXPORT(const char *) vObjectTypeInfo(VObject *o)
01355 {
01356 const char *type = vObjectName( o );
01357 if ( strcmp( type, "TYPE" ) == 0 )
01358 type = vObjectStringZValue( o );
01359 return type;
01360 }
01361
01362
01363