summaryrefslogtreecommitdiff
path: root/library/backend
authoreilers <eilers>2004-11-19 11:05:19 (UTC)
committer eilers <eilers>2004-11-19 11:05:19 (UTC)
commit362e353e4ee43a5aa37fd4c264ad0b40bbd0098b (patch) (unidiff)
tree52de09cbe81e5105cfdef9b606c10e4239cef814 /library/backend
parent6b1a6e3bf5d012e517c9668501f030d8c660b537 (diff)
downloadopie-362e353e4ee43a5aa37fd4c264ad0b40bbd0098b.zip
opie-362e353e4ee43a5aa37fd4c264ad0b40bbd0098b.tar.gz
opie-362e353e4ee43a5aa37fd4c264ad0b40bbd0098b.tar.bz2
Don't just allow "TYPE=<value>".. This makes the vcard import filter more
robust against unexpected typos..
Diffstat (limited to 'library/backend') (more/less context) (ignore whitespace changes)
-rw-r--r--library/backend/vobject.cpp6
1 files changed, 4 insertions, 2 deletions
diff --git a/library/backend/vobject.cpp b/library/backend/vobject.cpp
index 592d116..28b8bae 100644
--- a/library/backend/vobject.cpp
+++ b/library/backend/vobject.cpp
@@ -334,1031 +334,1033 @@ DLLEXPORT(void) initPropIterator(VObjectIterator *i, VObject *o)
334 i->next = 0; 334 i->next = 0;
335} 335}
336 336
337DLLEXPORT(void) initVObjectIterator(VObjectIterator *i, VObject *o) 337DLLEXPORT(void) initVObjectIterator(VObjectIterator *i, VObject *o)
338{ 338{
339 i->start = o->next; 339 i->start = o->next;
340 i->next = 0; 340 i->next = 0;
341} 341}
342 342
343DLLEXPORT(int) moreIteration(VObjectIterator *i) 343DLLEXPORT(int) moreIteration(VObjectIterator *i)
344{ 344{
345 return (i->start && (i->next==0 || i->next!=i->start)); 345 return (i->start && (i->next==0 || i->next!=i->start));
346} 346}
347 347
348DLLEXPORT(VObject*) nextVObject(VObjectIterator *i) 348DLLEXPORT(VObject*) nextVObject(VObjectIterator *i)
349{ 349{
350 if (i->start && i->next != i->start) { 350 if (i->start && i->next != i->start) {
351 if (i->next == 0) { 351 if (i->next == 0) {
352 i->next = i->start->next; 352 i->next = i->start->next;
353 return i->next; 353 return i->next;
354 } 354 }
355 else { 355 else {
356 i->next = i->next->next; 356 i->next = i->next->next;
357 return i->next; 357 return i->next;
358 } 358 }
359 } 359 }
360 else return (VObject*)0; 360 else return (VObject*)0;
361} 361}
362 362
363DLLEXPORT(VObject*) isAPropertyOf(VObject *o, const char *id) 363DLLEXPORT(VObject*) isAPropertyOf(VObject *o, const char *id)
364{ 364{
365 VObjectIterator i; 365 VObjectIterator i;
366 initPropIterator(&i,o); 366 initPropIterator(&i,o);
367 while (moreIteration(&i)) { 367 while (moreIteration(&i)) {
368 VObject *each = nextVObject(&i); 368 VObject *each = nextVObject(&i);
369 if (!qstricmp(id,each->id)) 369 if (!qstricmp(id,each->id))
370 return each; 370 return each;
371 } 371 }
372 return (VObject*)0; 372 return (VObject*)0;
373} 373}
374 374
375DLLEXPORT(VObject*) addGroup(VObject *o, const char *g) 375DLLEXPORT(VObject*) addGroup(VObject *o, const char *g)
376{ 376{
377 /* 377 /*
378 a.b.c 378 a.b.c
379 --> 379 -->
380 prop(c) 380 prop(c)
381 prop(VCGrouping=b) 381 prop(VCGrouping=b)
382 prop(VCGrouping=a) 382 prop(VCGrouping=a)
383 */ 383 */
384 char *dot = strrchr(g,'.'); 384 char *dot = strrchr(g,'.');
385 if (dot) { 385 if (dot) {
386 VObject *p, *t; 386 VObject *p, *t;
387 char *gs, *n = dot+1; 387 char *gs, *n = dot+1;
388 gs = dupStr(g,0);/* so we can write to it. */ 388 gs = dupStr(g,0);/* so we can write to it. */
389 /* used to be 389 /* used to be
390 * t = p = addProp_(o,lookupProp_(n)); 390 * t = p = addProp_(o,lookupProp_(n));
391 */ 391 */
392 t = p = addProp_(o,lookupProp(n)); 392 t = p = addProp_(o,lookupProp(n));
393 dot = strrchr(gs,'.'); 393 dot = strrchr(gs,'.');
394 *dot = 0; 394 *dot = 0;
395 do { 395 do {
396 dot = strrchr(gs,'.'); 396 dot = strrchr(gs,'.');
397 if (dot) { 397 if (dot) {
398 n = dot+1; 398 n = dot+1;
399 *dot=0; 399 *dot=0;
400 } 400 }
401 else 401 else
402 n = gs; 402 n = gs;
403 /* property(VCGroupingProp=n); 403 /* property(VCGroupingProp=n);
404 *and the value may have VCGrouping property 404 *and the value may have VCGrouping property
405 */ 405 */
406 t = addProp(t,VCGroupingProp); 406 t = addProp(t,VCGroupingProp);
407 setVObjectStringZValue(t,lookupProp_(n)); 407 setVObjectStringZValue(t,lookupProp_(n));
408 } while (n != gs); 408 } while (n != gs);
409 deleteStr(gs); 409 deleteStr(gs);
410 return p; 410 return p;
411 } 411 }
412 else 412 else
413 return addProp_(o,lookupProp(g)); 413 return addProp_(o,lookupProp(g));
414} 414}
415 415
416DLLEXPORT(VObject*) addPropValue(VObject *o, const char *p, const char *v) 416DLLEXPORT(VObject*) addPropValue(VObject *o, const char *p, const char *v)
417{ 417{
418 VObject *prop; 418 VObject *prop;
419 prop = addProp(o,p); 419 prop = addProp(o,p);
420 setVObjectStringZValue_(prop, strdup( v ) ); 420 setVObjectStringZValue_(prop, strdup( v ) );
421 return prop; 421 return prop;
422} 422}
423 423
424DLLEXPORT(VObject*) addPropSizedValue_(VObject *o, const char *p, const char *v, 424DLLEXPORT(VObject*) addPropSizedValue_(VObject *o, const char *p, const char *v,
425 unsigned int size) 425 unsigned int size)
426{ 426{
427 VObject *prop; 427 VObject *prop;
428 prop = addProp(o,p); 428 prop = addProp(o,p);
429 setValueWithSize_(prop, (void*)v, size); 429 setValueWithSize_(prop, (void*)v, size);
430 return prop; 430 return prop;
431} 431}
432 432
433DLLEXPORT(VObject*) addPropSizedValue(VObject *o, const char *p, const char *v, 433DLLEXPORT(VObject*) addPropSizedValue(VObject *o, const char *p, const char *v,
434 unsigned int size) 434 unsigned int size)
435{ 435{
436 return addPropSizedValue_(o,p,dupStr(v,size),size); 436 return addPropSizedValue_(o,p,dupStr(v,size),size);
437} 437}
438 438
439 439
440DLLEXPORT(void) cleanVObject(VObject *o) 440DLLEXPORT(void) cleanVObject(VObject *o)
441{ 441{
442 if (o == 0) return; 442 if (o == 0) return;
443 if (o->prop) { 443 if (o->prop) {
444 /* destroy time: cannot use the iterator here. 444 /* destroy time: cannot use the iterator here.
445 Have to break the cycle in the circular link 445 Have to break the cycle in the circular link
446 list and turns it into regular NULL-terminated 446 list and turns it into regular NULL-terminated
447 list -- since at some point of destruction, 447 list -- since at some point of destruction,
448 the reference entry for the iterator to work 448 the reference entry for the iterator to work
449 will not longer be valid. 449 will not longer be valid.
450 */ 450 */
451 VObject *p; 451 VObject *p;
452 p = o->prop->next; 452 p = o->prop->next;
453 o->prop->next = 0; 453 o->prop->next = 0;
454 do { 454 do {
455 VObject *t = p->next; 455 VObject *t = p->next;
456 cleanVObject(p); 456 cleanVObject(p);
457 p = t; 457 p = t;
458 } while (p); 458 } while (p);
459 } 459 }
460 switch (VALUE_TYPE(o)) { 460 switch (VALUE_TYPE(o)) {
461 case VCVT_STRINGZ: 461 case VCVT_STRINGZ:
462 case VCVT_RAW: 462 case VCVT_RAW:
463 // assume they are all allocated by malloc. 463 // assume they are all allocated by malloc.
464 free((char*)STRINGZ_VALUE_OF(o)); 464 free((char*)STRINGZ_VALUE_OF(o));
465 break; 465 break;
466 case VCVT_VOBJECT: 466 case VCVT_VOBJECT:
467 cleanVObject(VOBJECT_VALUE_OF(o)); 467 cleanVObject(VOBJECT_VALUE_OF(o));
468 break; 468 break;
469 } 469 }
470 deleteVObject(o); 470 deleteVObject(o);
471} 471}
472 472
473DLLEXPORT(void) cleanVObjects(VObject *list) 473DLLEXPORT(void) cleanVObjects(VObject *list)
474{ 474{
475 while (list) { 475 while (list) {
476 VObject *t = list; 476 VObject *t = list;
477 list = nextVObjectInList(list); 477 list = nextVObjectInList(list);
478 cleanVObject(t); 478 cleanVObject(t);
479 } 479 }
480} 480}
481 481
482/*---------------------------------------------------------------------- 482/*----------------------------------------------------------------------
483 The following is a String Table Facilities. 483 The following is a String Table Facilities.
484 ----------------------------------------------------------------------*/ 484 ----------------------------------------------------------------------*/
485 485
486#define STRTBLSIZE 255 486#define STRTBLSIZE 255
487 487
488static StrItem *strTbl[STRTBLSIZE]; 488static StrItem *strTbl[STRTBLSIZE];
489 489
490static unsigned int hashStr(const char *s) 490static unsigned int hashStr(const char *s)
491{ 491{
492 unsigned int h = 0; 492 unsigned int h = 0;
493 int i; 493 int i;
494 for (i=0;s[i];i++) { 494 for (i=0;s[i];i++) {
495 h += s[i]*i; 495 h += s[i]*i;
496 } 496 }
497 return h % STRTBLSIZE; 497 return h % STRTBLSIZE;
498} 498}
499 499
500DLLEXPORT(const char*) lookupStr(const char *s) 500DLLEXPORT(const char*) lookupStr(const char *s)
501{ 501{
502 StrItem *t; 502 StrItem *t;
503 unsigned int h = hashStr(s); 503 unsigned int h = hashStr(s);
504 if ((t = strTbl[h]) != 0) { 504 if ((t = strTbl[h]) != 0) {
505 do { 505 do {
506 if (qstricmp(t->s,s) == 0) { 506 if (qstricmp(t->s,s) == 0) {
507 t->refCnt++; 507 t->refCnt++;
508 return t->s; 508 return t->s;
509 } 509 }
510 t = t->next; 510 t = t->next;
511 } while (t); 511 } while (t);
512 } 512 }
513 s = dupStr(s,0); 513 s = dupStr(s,0);
514 strTbl[h] = newStrItem(s,strTbl[h]); 514 strTbl[h] = newStrItem(s,strTbl[h]);
515 return s; 515 return s;
516} 516}
517 517
518DLLEXPORT(void) unUseStr(const char *s) 518DLLEXPORT(void) unUseStr(const char *s)
519{ 519{
520 StrItem *t, *p; 520 StrItem *t, *p;
521 unsigned int h = hashStr(s); 521 unsigned int h = hashStr(s);
522 if ((t = strTbl[h]) != 0) { 522 if ((t = strTbl[h]) != 0) {
523 p = t; 523 p = t;
524 do { 524 do {
525 if (qstricmp(t->s,s) == 0) { 525 if (qstricmp(t->s,s) == 0) {
526 t->refCnt--; 526 t->refCnt--;
527 if (t->refCnt == 0) { 527 if (t->refCnt == 0) {
528 if (p == strTbl[h]) { 528 if (p == strTbl[h]) {
529 strTbl[h] = t->next; 529 strTbl[h] = t->next;
530 } 530 }
531 else { 531 else {
532 p->next = t->next; 532 p->next = t->next;
533 } 533 }
534 deleteStr(t->s); 534 deleteStr(t->s);
535 deleteStrItem(t); 535 deleteStrItem(t);
536 return; 536 return;
537 } 537 }
538 } 538 }
539 p = t; 539 p = t;
540 t = t->next; 540 t = t->next;
541 } while (t); 541 } while (t);
542 } 542 }
543} 543}
544 544
545DLLEXPORT(void) cleanStrTbl() 545DLLEXPORT(void) cleanStrTbl()
546{ 546{
547 int i; 547 int i;
548 for (i=0; i<STRTBLSIZE;i++) { 548 for (i=0; i<STRTBLSIZE;i++) {
549 StrItem *t = strTbl[i]; 549 StrItem *t = strTbl[i];
550 while (t) { 550 while (t) {
551 StrItem *p; 551 StrItem *p;
552 deleteStr(t->s); 552 deleteStr(t->s);
553 p = t; 553 p = t;
554 t = t->next; 554 t = t->next;
555 deleteStrItem(p); 555 deleteStrItem(p);
556 } while (t); 556 } while (t);
557 strTbl[i] = 0; 557 strTbl[i] = 0;
558 } 558 }
559} 559}
560 560
561 561
562struct PreDefProp { 562struct PreDefProp {
563 const char *name; 563 const char *name;
564 const char *alias; 564 const char *alias;
565 const char** fields; 565 const char** fields;
566 unsigned int flags; 566 unsigned int flags;
567 }; 567 };
568 568
569/* flags in PreDefProp */ 569/* flags in PreDefProp */
570 #define PD_BEGIN0x1 570 #define PD_BEGIN0x1
571 #define PD_INTERNAL0x2 571 #define PD_INTERNAL0x2
572 572
573static const char *adrFields[] = { 573static const char *adrFields[] = {
574 VCPostalBoxProp, 574 VCPostalBoxProp,
575 VCExtAddressProp, 575 VCExtAddressProp,
576 VCStreetAddressProp, 576 VCStreetAddressProp,
577 VCCityProp, 577 VCCityProp,
578 VCRegionProp, 578 VCRegionProp,
579 VCPostalCodeProp, 579 VCPostalCodeProp,
580 VCCountryNameProp, 580 VCCountryNameProp,
581 0 581 0
582}; 582};
583 583
584static const char *nameFields[] = { 584static const char *nameFields[] = {
585 VCFamilyNameProp, 585 VCFamilyNameProp,
586 VCGivenNameProp, 586 VCGivenNameProp,
587 VCAdditionalNamesProp, 587 VCAdditionalNamesProp,
588 VCNamePrefixesProp, 588 VCNamePrefixesProp,
589 VCNameSuffixesProp, 589 VCNameSuffixesProp,
590 NULL 590 NULL
591 }; 591 };
592 592
593static const char *orgFields[] = { 593static const char *orgFields[] = {
594 VCOrgNameProp, 594 VCOrgNameProp,
595 VCOrgUnitProp, 595 VCOrgUnitProp,
596 VCOrgUnit2Prop, 596 VCOrgUnit2Prop,
597 VCOrgUnit3Prop, 597 VCOrgUnit3Prop,
598 VCOrgUnit4Prop, 598 VCOrgUnit4Prop,
599 NULL 599 NULL
600 }; 600 };
601 601
602static const char *AAlarmFields[] = { 602static const char *AAlarmFields[] = {
603 VCRunTimeProp, 603 VCRunTimeProp,
604 VCSnoozeTimeProp, 604 VCSnoozeTimeProp,
605 VCRepeatCountProp, 605 VCRepeatCountProp,
606 VCAudioContentProp, 606 VCAudioContentProp,
607 0 607 0
608 }; 608 };
609 609
610/* ExDate -- has unamed fields */ 610/* ExDate -- has unamed fields */
611/* RDate -- has unamed fields */ 611/* RDate -- has unamed fields */
612 612
613static const char *DAlarmFields[] = { 613static const char *DAlarmFields[] = {
614 VCRunTimeProp, 614 VCRunTimeProp,
615 VCSnoozeTimeProp, 615 VCSnoozeTimeProp,
616 VCRepeatCountProp, 616 VCRepeatCountProp,
617 VCDisplayStringProp, 617 VCDisplayStringProp,
618 0 618 0
619 }; 619 };
620 620
621static const char *MAlarmFields[] = { 621static const char *MAlarmFields[] = {
622 VCRunTimeProp, 622 VCRunTimeProp,
623 VCSnoozeTimeProp, 623 VCSnoozeTimeProp,
624 VCRepeatCountProp, 624 VCRepeatCountProp,
625 VCEmailAddressProp, 625 VCEmailAddressProp,
626 VCNoteProp, 626 VCNoteProp,
627 0 627 0
628 }; 628 };
629 629
630static const char *PAlarmFields[] = { 630static const char *PAlarmFields[] = {
631 VCRunTimeProp, 631 VCRunTimeProp,
632 VCSnoozeTimeProp, 632 VCSnoozeTimeProp,
633 VCRepeatCountProp, 633 VCRepeatCountProp,
634 VCProcedureNameProp, 634 VCProcedureNameProp,
635 0 635 0
636 }; 636 };
637 637
638static struct PreDefProp propNames[] = { 638static struct PreDefProp propNames[] = {
639 { VC7bitProp, 0, 0, 0 }, 639 { VC7bitProp, 0, 0, 0 },
640 { VC8bitProp, 0, 0, 0 }, 640 { VC8bitProp, 0, 0, 0 },
641 { VCAAlarmProp, 0, AAlarmFields, 0 }, 641 { VCAAlarmProp, 0, AAlarmFields, 0 },
642 { VCAdditionalNamesProp, 0, 0, 0 }, 642 { VCAdditionalNamesProp, 0, 0, 0 },
643 { VCAdrProp, 0, adrFields, 0 }, 643 { VCAdrProp, 0, adrFields, 0 },
644 { VCAgentProp, 0, 0, 0 }, 644 { VCAgentProp, 0, 0, 0 },
645 { VCAIFFProp, 0, 0, 0 }, 645 { VCAIFFProp, 0, 0, 0 },
646 { VCAOLProp, 0, 0, 0 }, 646 { VCAOLProp, 0, 0, 0 },
647 { VCAppleLinkProp, 0, 0, 0 }, 647 { VCAppleLinkProp, 0, 0, 0 },
648 { VCAttachProp, 0, 0, 0 }, 648 { VCAttachProp, 0, 0, 0 },
649 { VCAttendeeProp, 0, 0, 0 }, 649 { VCAttendeeProp, 0, 0, 0 },
650 { VCATTMailProp, 0, 0, 0 }, 650 { VCATTMailProp, 0, 0, 0 },
651 { VCAudioContentProp, 0, 0, 0 }, 651 { VCAudioContentProp, 0, 0, 0 },
652 { VCAVIProp, 0, 0, 0 }, 652 { VCAVIProp, 0, 0, 0 },
653 { VCBase64Prop, 0, 0, 0 }, 653 { VCBase64Prop, 0, 0, 0 },
654 { VCBBSProp, 0, 0, 0 }, 654 { VCBBSProp, 0, 0, 0 },
655 { VCBirthDateProp, 0, 0, 0 }, 655 { VCBirthDateProp, 0, 0, 0 },
656 { VCBMPProp, 0, 0, 0 }, 656 { VCBMPProp, 0, 0, 0 },
657 { VCBodyProp, 0, 0, 0 }, 657 { VCBodyProp, 0, 0, 0 },
658 { VCBusinessRoleProp, 0, 0, 0 }, 658 { VCBusinessRoleProp, 0, 0, 0 },
659 { VCCalProp, 0, 0, PD_BEGIN }, 659 { VCCalProp, 0, 0, PD_BEGIN },
660 { VCCaptionProp, 0, 0, 0 }, 660 { VCCaptionProp, 0, 0, 0 },
661 { VCCardProp, 0, 0, PD_BEGIN }, 661 { VCCardProp, 0, 0, PD_BEGIN },
662 { VCCarProp, 0, 0, 0 }, 662 { VCCarProp, 0, 0, 0 },
663 { VCCategoriesProp, 0, 0, 0 }, 663 { VCCategoriesProp, 0, 0, 0 },
664 { VCCellularProp, 0, 0, 0 }, 664 { VCCellularProp, 0, 0, 0 },
665 { VCCGMProp, 0, 0, 0 }, 665 { VCCGMProp, 0, 0, 0 },
666 { VCCharSetProp, 0, 0, 0 }, 666 { VCCharSetProp, 0, 0, 0 },
667 { VCCIDProp, VCContentIDProp, 0, 0 }, 667 { VCCIDProp, VCContentIDProp, 0, 0 },
668 { VCCISProp, 0, 0, 0 }, 668 { VCCISProp, 0, 0, 0 },
669 { VCCityProp, 0, 0, 0 }, 669 { VCCityProp, 0, 0, 0 },
670 { VCClassProp, 0, 0, 0 }, 670 { VCClassProp, 0, 0, 0 },
671 { VCCommentProp, 0, 0, 0 }, 671 { VCCommentProp, 0, 0, 0 },
672 { VCCompletedProp, 0, 0, 0 }, 672 { VCCompletedProp, 0, 0, 0 },
673 { VCContentIDProp, 0, 0, 0 }, 673 { VCContentIDProp, 0, 0, 0 },
674 { VCCountryNameProp, 0, 0, 0 }, 674 { VCCountryNameProp, 0, 0, 0 },
675 { VCDAlarmProp, 0, DAlarmFields, 0 }, 675 { VCDAlarmProp, 0, DAlarmFields, 0 },
676 { VCDataSizeProp, 0, 0, PD_INTERNAL }, 676 { VCDataSizeProp, 0, 0, PD_INTERNAL },
677 { VCDayLightProp, 0, 0, 0 }, 677 { VCDayLightProp, 0, 0, 0 },
678 { VCDCreatedProp, 0, 0, 0 }, 678 { VCDCreatedProp, 0, 0, 0 },
679 { VCDeliveryLabelProp, 0, 0, 0 }, 679 { VCDeliveryLabelProp, 0, 0, 0 },
680 { VCDescriptionProp, 0, 0, 0 }, 680 { VCDescriptionProp, 0, 0, 0 },
681 { VCDIBProp, 0, 0, 0 }, 681 { VCDIBProp, 0, 0, 0 },
682 { VCDisplayStringProp, 0, 0, 0 }, 682 { VCDisplayStringProp, 0, 0, 0 },
683 { VCDomesticProp, 0, 0, 0 }, 683 { VCDomesticProp, 0, 0, 0 },
684 { VCDTendProp, 0, 0, 0 }, 684 { VCDTendProp, 0, 0, 0 },
685 { VCDTstartProp, 0, 0, 0 }, 685 { VCDTstartProp, 0, 0, 0 },
686 { VCDueProp, 0, 0, 0 }, 686 { VCDueProp, 0, 0, 0 },
687 { VCEmailAddressProp, 0, 0, 0 }, 687 { VCEmailAddressProp, 0, 0, 0 },
688 { VCEncodingProp, 0, 0, 0 }, 688 { VCEncodingProp, 0, 0, 0 },
689 { VCEndProp, 0, 0, 0 }, 689 { VCEndProp, 0, 0, 0 },
690 { VCEventProp, 0, 0, PD_BEGIN }, 690 { VCEventProp, 0, 0, PD_BEGIN },
691 { VCEWorldProp, 0, 0, 0 }, 691 { VCEWorldProp, 0, 0, 0 },
692 { VCExNumProp, 0, 0, 0 }, 692 { VCExNumProp, 0, 0, 0 },
693 { VCExpDateProp, 0, 0, 0 }, 693 { VCExpDateProp, 0, 0, 0 },
694 { VCExpectProp, 0, 0, 0 }, 694 { VCExpectProp, 0, 0, 0 },
695 { VCExtAddressProp, 0, 0, 0 }, 695 { VCExtAddressProp, 0, 0, 0 },
696 { VCFamilyNameProp, 0, 0, 0 }, 696 { VCFamilyNameProp, 0, 0, 0 },
697 { VCFaxProp, 0, 0, 0 }, 697 { VCFaxProp, 0, 0, 0 },
698 { VCFullNameProp, 0, 0, 0 }, 698 { VCFullNameProp, 0, 0, 0 },
699 { VCGeoLocationProp, 0, 0, 0 }, 699 { VCGeoLocationProp, 0, 0, 0 },
700 { VCGeoProp, 0, 0, 0 }, 700 { VCGeoProp, 0, 0, 0 },
701 { VCGIFProp, 0, 0, 0 }, 701 { VCGIFProp, 0, 0, 0 },
702 { VCGivenNameProp, 0, 0, 0 }, 702 { VCGivenNameProp, 0, 0, 0 },
703 { VCGroupingProp, 0, 0, 0 }, 703 { VCGroupingProp, 0, 0, 0 },
704 { VCHomeProp, 0, 0, 0 }, 704 { VCHomeProp, 0, 0, 0 },
705 { VCIBMMailProp, 0, 0, 0 }, 705 { VCIBMMailProp, 0, 0, 0 },
706 { VCInlineProp, 0, 0, 0 }, 706 { VCInlineProp, 0, 0, 0 },
707 { VCInternationalProp, 0, 0, 0 }, 707 { VCInternationalProp, 0, 0, 0 },
708 { VCInternetProp, 0, 0, 0 }, 708 { VCInternetProp, 0, 0, 0 },
709 { VCISDNProp, 0, 0, 0 }, 709 { VCISDNProp, 0, 0, 0 },
710 { VCJPEGProp, 0, 0, 0 }, 710 { VCJPEGProp, 0, 0, 0 },
711 { VCLanguageProp, 0, 0, 0 }, 711 { VCLanguageProp, 0, 0, 0 },
712 { VCLastModifiedProp, 0, 0, 0 }, 712 { VCLastModifiedProp, 0, 0, 0 },
713 { VCLastRevisedProp, 0, 0, 0 }, 713 { VCLastRevisedProp, 0, 0, 0 },
714 { VCLocationProp, 0, 0, 0 }, 714 { VCLocationProp, 0, 0, 0 },
715 { VCLogoProp, 0, 0, 0 }, 715 { VCLogoProp, 0, 0, 0 },
716 { VCMailerProp, 0, 0, 0 }, 716 { VCMailerProp, 0, 0, 0 },
717 { VCMAlarmProp, 0, MAlarmFields, 0 }, 717 { VCMAlarmProp, 0, MAlarmFields, 0 },
718 { VCMCIMailProp, 0, 0, 0 }, 718 { VCMCIMailProp, 0, 0, 0 },
719 { VCMessageProp, 0, 0, 0 }, 719 { VCMessageProp, 0, 0, 0 },
720 { VCMETProp, 0, 0, 0 }, 720 { VCMETProp, 0, 0, 0 },
721 { VCModemProp, 0, 0, 0 }, 721 { VCModemProp, 0, 0, 0 },
722 { VCMPEG2Prop, 0, 0, 0 }, 722 { VCMPEG2Prop, 0, 0, 0 },
723 { VCMPEGProp, 0, 0, 0 }, 723 { VCMPEGProp, 0, 0, 0 },
724 { VCMSNProp, 0, 0, 0 }, 724 { VCMSNProp, 0, 0, 0 },
725 { VCNamePrefixesProp, 0, 0, 0 }, 725 { VCNamePrefixesProp, 0, 0, 0 },
726 { VCNameProp, 0, nameFields, 0 }, 726 { VCNameProp, 0, nameFields, 0 },
727 { VCNameSuffixesProp, 0, 0, 0 }, 727 { VCNameSuffixesProp, 0, 0, 0 },
728 { VCNoteProp, 0, 0, 0 }, 728 { VCNoteProp, 0, 0, 0 },
729 { VCOrgNameProp, 0, 0, 0 }, 729 { VCOrgNameProp, 0, 0, 0 },
730 { VCOrgProp, 0, orgFields, 0 }, 730 { VCOrgProp, 0, orgFields, 0 },
731 { VCOrgUnit2Prop, 0, 0, 0 }, 731 { VCOrgUnit2Prop, 0, 0, 0 },
732 { VCOrgUnit3Prop, 0, 0, 0 }, 732 { VCOrgUnit3Prop, 0, 0, 0 },
733 { VCOrgUnit4Prop, 0, 0, 0 }, 733 { VCOrgUnit4Prop, 0, 0, 0 },
734 { VCOrgUnitProp, 0, 0, 0 }, 734 { VCOrgUnitProp, 0, 0, 0 },
735 { VCPagerProp, 0, 0, 0 }, 735 { VCPagerProp, 0, 0, 0 },
736 { VCPAlarmProp, 0, PAlarmFields, 0 }, 736 { VCPAlarmProp, 0, PAlarmFields, 0 },
737 { VCParcelProp, 0, 0, 0 }, 737 { VCParcelProp, 0, 0, 0 },
738 { VCPartProp, 0, 0, 0 }, 738 { VCPartProp, 0, 0, 0 },
739 { VCPCMProp, 0, 0, 0 }, 739 { VCPCMProp, 0, 0, 0 },
740 { VCPDFProp, 0, 0, 0 }, 740 { VCPDFProp, 0, 0, 0 },
741 { VCPGPProp, 0, 0, 0 }, 741 { VCPGPProp, 0, 0, 0 },
742 { VCPhotoProp, 0, 0, 0 }, 742 { VCPhotoProp, 0, 0, 0 },
743 { VCPICTProp, 0, 0, 0 }, 743 { VCPICTProp, 0, 0, 0 },
744 { VCPMBProp, 0, 0, 0 }, 744 { VCPMBProp, 0, 0, 0 },
745 { VCPostalBoxProp, 0, 0, 0 }, 745 { VCPostalBoxProp, 0, 0, 0 },
746 { VCPostalCodeProp, 0, 0, 0 }, 746 { VCPostalCodeProp, 0, 0, 0 },
747 { VCPostalProp, 0, 0, 0 }, 747 { VCPostalProp, 0, 0, 0 },
748 { VCPowerShareProp, 0, 0, 0 }, 748 { VCPowerShareProp, 0, 0, 0 },
749 { VCPreferredProp, 0, 0, 0 }, 749 { VCPreferredProp, 0, 0, 0 },
750 { VCPriorityProp, 0, 0, 0 }, 750 { VCPriorityProp, 0, 0, 0 },
751 { VCProcedureNameProp, 0, 0, 0 }, 751 { VCProcedureNameProp, 0, 0, 0 },
752 { VCProdIdProp, 0, 0, 0 }, 752 { VCProdIdProp, 0, 0, 0 },
753 { VCProdigyProp, 0, 0, 0 }, 753 { VCProdigyProp, 0, 0, 0 },
754 { VCPronunciationProp, 0, 0, 0 }, 754 { VCPronunciationProp, 0, 0, 0 },
755 { VCPSProp, 0, 0, 0 }, 755 { VCPSProp, 0, 0, 0 },
756 { VCPublicKeyProp, 0, 0, 0 }, 756 { VCPublicKeyProp, 0, 0, 0 },
757 { VCQPProp, VCQuotedPrintableProp, 0, 0 }, 757 { VCQPProp, VCQuotedPrintableProp, 0, 0 },
758 { VCQuickTimeProp, 0, 0, 0 }, 758 { VCQuickTimeProp, 0, 0, 0 },
759 { VCQuotedPrintableProp, 0, 0, 0 }, 759 { VCQuotedPrintableProp, 0, 0, 0 },
760 { VCRDateProp, 0, 0, 0 }, 760 { VCRDateProp, 0, 0, 0 },
761 { VCRegionProp, 0, 0, 0 }, 761 { VCRegionProp, 0, 0, 0 },
762 { VCRelatedToProp, 0, 0, 0 }, 762 { VCRelatedToProp, 0, 0, 0 },
763 { VCRepeatCountProp, 0, 0, 0 }, 763 { VCRepeatCountProp, 0, 0, 0 },
764 { VCResourcesProp, 0, 0, 0 }, 764 { VCResourcesProp, 0, 0, 0 },
765 { VCRNumProp, 0, 0, 0 }, 765 { VCRNumProp, 0, 0, 0 },
766 { VCRoleProp, 0, 0, 0 }, 766 { VCRoleProp, 0, 0, 0 },
767 { VCRRuleProp, 0, 0, 0 }, 767 { VCRRuleProp, 0, 0, 0 },
768 { VCRSVPProp, 0, 0, 0 }, 768 { VCRSVPProp, 0, 0, 0 },
769 { VCRunTimeProp, 0, 0, 0 }, 769 { VCRunTimeProp, 0, 0, 0 },
770 { VCSequenceProp, 0, 0, 0 }, 770 { VCSequenceProp, 0, 0, 0 },
771 { VCSnoozeTimeProp, 0, 0, 0 }, 771 { VCSnoozeTimeProp, 0, 0, 0 },
772 { VCStartProp, 0, 0, 0 }, 772 { VCStartProp, 0, 0, 0 },
773 { VCStatusProp, 0, 0, 0 }, 773 { VCStatusProp, 0, 0, 0 },
774 { VCStreetAddressProp, 0, 0, 0 }, 774 { VCStreetAddressProp, 0, 0, 0 },
775 { VCSubTypeProp, 0, 0, 0 }, 775 { VCSubTypeProp, 0, 0, 0 },
776 { VCSummaryProp, 0, 0, 0 }, 776 { VCSummaryProp, 0, 0, 0 },
777 { VCTelephoneProp, 0, 0, 0 }, 777 { VCTelephoneProp, 0, 0, 0 },
778 { VCTIFFProp, 0, 0, 0 }, 778 { VCTIFFProp, 0, 0, 0 },
779 { VCTimeZoneProp, 0, 0, 0 }, 779 { VCTimeZoneProp, 0, 0, 0 },
780 { VCTitleProp, 0, 0, 0 }, 780 { VCTitleProp, 0, 0, 0 },
781 { VCTLXProp, 0, 0, 0 }, 781 { VCTLXProp, 0, 0, 0 },
782 { VCTodoProp, 0, 0, PD_BEGIN }, 782 { VCTodoProp, 0, 0, PD_BEGIN },
783 { VCTranspProp, 0, 0, 0 }, 783 { VCTranspProp, 0, 0, 0 },
784 { VCUniqueStringProp, 0, 0, 0 }, 784 { VCUniqueStringProp, 0, 0, 0 },
785 { VCURLProp, 0, 0, 0 }, 785 { VCURLProp, 0, 0, 0 },
786 { VCURLValueProp, 0, 0, 0 }, 786 { VCURLValueProp, 0, 0, 0 },
787 { VCValueProp, 0, 0, 0 }, 787 { VCValueProp, 0, 0, 0 },
788 { VCVersionProp, 0, 0, 0 }, 788 { VCVersionProp, 0, 0, 0 },
789 { VCVideoProp, 0, 0, 0 }, 789 { VCVideoProp, 0, 0, 0 },
790 { VCVoiceProp, 0, 0, 0 }, 790 { VCVoiceProp, 0, 0, 0 },
791 { VCWAVEProp, 0, 0, 0 }, 791 { VCWAVEProp, 0, 0, 0 },
792 { VCWMFProp, 0, 0, 0 }, 792 { VCWMFProp, 0, 0, 0 },
793 { VCWorkProp, 0, 0, 0 }, 793 { VCWorkProp, 0, 0, 0 },
794 { VCX400Prop, 0, 0, 0 }, 794 { VCX400Prop, 0, 0, 0 },
795 { VCX509Prop, 0, 0, 0 }, 795 { VCX509Prop, 0, 0, 0 },
796 { VCXRuleProp, 0, 0, 0 }, 796 { VCXRuleProp, 0, 0, 0 },
797 { 0,0,0,0 } 797 { 0,0,0,0 }
798 }; 798 };
799 799
800 800
801static struct PreDefProp* lookupPropInfo(const char* str) 801static struct PreDefProp* lookupPropInfo(const char* str)
802{ 802{
803 /* brute force for now, could use a hash table here. */ 803 /* brute force for now, could use a hash table here. */
804 int i; 804 int i;
805 805
806 for (i = 0; propNames[i].name; i++) 806 for (i = 0; propNames[i].name; i++)
807 if (qstricmp(str, propNames[i].name) == 0) { 807 if (qstricmp(str, propNames[i].name) == 0) {
808 return &propNames[i]; 808 return &propNames[i];
809 } 809 }
810 810
811 return 0; 811 return 0;
812} 812}
813 813
814 814
815DLLEXPORT(const char*) lookupProp_(const char* str) 815DLLEXPORT(const char*) lookupProp_(const char* str)
816{ 816{
817 int i; 817 int i;
818 818
819 for (i = 0; propNames[i].name; i++) 819 for (i = 0; propNames[i].name; i++)
820 if (qstricmp(str, propNames[i].name) == 0) { 820 if (qstricmp(str, propNames[i].name) == 0) {
821 const char* s; 821 const char* s;
822 s = propNames[i].alias?propNames[i].alias:propNames[i].name; 822 s = propNames[i].alias?propNames[i].alias:propNames[i].name;
823 return lookupStr(s); 823 return lookupStr(s);
824 } 824 }
825 return lookupStr(str); 825 return lookupStr(str);
826} 826}
827 827
828 828
829DLLEXPORT(const char*) lookupProp(const char* str) 829DLLEXPORT(const char*) lookupProp(const char* str)
830{ 830{
831 int i; 831 int i;
832 832
833 for (i = 0; propNames[i].name; i++) 833 for (i = 0; propNames[i].name; i++)
834 if (qstricmp(str, propNames[i].name) == 0) { 834 if (qstricmp(str, propNames[i].name) == 0) {
835 const char *s; 835 const char *s;
836 fieldedProp = propNames[i].fields; 836 fieldedProp = propNames[i].fields;
837 s = propNames[i].alias?propNames[i].alias:propNames[i].name; 837 s = propNames[i].alias?propNames[i].alias:propNames[i].name;
838 return lookupStr(s); 838 return lookupStr(s);
839 } 839 }
840 fieldedProp = 0; 840 fieldedProp = 0;
841 return lookupStr(str); 841 return lookupStr(str);
842} 842}
843 843
844 844
845/*---------------------------------------------------------------------- 845/*----------------------------------------------------------------------
846 APIs to Output text form. 846 APIs to Output text form.
847 ----------------------------------------------------------------------*/ 847 ----------------------------------------------------------------------*/
848#define OFILE_REALLOC_SIZE 256 848#define OFILE_REALLOC_SIZE 256
849typedef struct OFile { 849typedef struct OFile {
850 FILE *fp; 850 FILE *fp;
851 char *s; 851 char *s;
852 int len; 852 int len;
853 int limit; 853 int limit;
854 int alloc:1; 854 int alloc:1;
855 int fail:1; 855 int fail:1;
856 } OFile; 856 } OFile;
857 857
858#if 0 858#if 0
859static void appendsOFile(OFile *fp, const char *s) 859static void appendsOFile(OFile *fp, const char *s)
860{ 860{
861 int slen; 861 int slen;
862 if (fp->fail) return; 862 if (fp->fail) return;
863 slen = strlen(s); 863 slen = strlen(s);
864 if (fp->fp) { 864 if (fp->fp) {
865 fwrite(s,1,slen,fp->fp); 865 fwrite(s,1,slen,fp->fp);
866 } 866 }
867 else { 867 else {
868stuff: 868stuff:
869 if (fp->len + slen < fp->limit) { 869 if (fp->len + slen < fp->limit) {
870 memcpy(fp->s+fp->len,s,slen); 870 memcpy(fp->s+fp->len,s,slen);
871 fp->len += slen; 871 fp->len += slen;
872 return; 872 return;
873 } 873 }
874 else if (fp->alloc) { 874 else if (fp->alloc) {
875 fp->limit = fp->limit + OFILE_REALLOC_SIZE; 875 fp->limit = fp->limit + OFILE_REALLOC_SIZE;
876 if (OFILE_REALLOC_SIZE <= slen) fp->limit += slen; 876 if (OFILE_REALLOC_SIZE <= slen) fp->limit += slen;
877 fp->s = (char *) realloc(fp->s,fp->limit); 877 fp->s = (char *) realloc(fp->s,fp->limit);
878 if (fp->s) goto stuff; 878 if (fp->s) goto stuff;
879 } 879 }
880 if (fp->alloc) 880 if (fp->alloc)
881 free(fp->s); 881 free(fp->s);
882 fp->s = 0; 882 fp->s = 0;
883 fp->fail = 1; 883 fp->fail = 1;
884 } 884 }
885} 885}
886 886
887static void appendcOFile(OFile *fp, char c) 887static void appendcOFile(OFile *fp, char c)
888{ 888{
889 if (fp->fail) return; 889 if (fp->fail) return;
890 if (fp->fp) { 890 if (fp->fp) {
891 fputc(c,fp->fp); 891 fputc(c,fp->fp);
892 } 892 }
893 else { 893 else {
894stuff: 894stuff:
895 if (fp->len+1 < fp->limit) { 895 if (fp->len+1 < fp->limit) {
896 fp->s[fp->len] = c; 896 fp->s[fp->len] = c;
897 fp->len++; 897 fp->len++;
898 return; 898 return;
899 } 899 }
900 else if (fp->alloc) { 900 else if (fp->alloc) {
901 fp->limit = fp->limit + OFILE_REALLOC_SIZE; 901 fp->limit = fp->limit + OFILE_REALLOC_SIZE;
902 fp->s = (char *) realloc(fp->s,fp->limit); 902 fp->s = (char *) realloc(fp->s,fp->limit);
903 if (fp->s) goto stuff; 903 if (fp->s) goto stuff;
904 } 904 }
905 if (fp->alloc) 905 if (fp->alloc)
906 free(fp->s); 906 free(fp->s);
907 fp->s = 0; 907 fp->s = 0;
908 fp->fail = 1; 908 fp->fail = 1;
909 } 909 }
910} 910}
911#else 911#else
912static void appendcOFile_(OFile *fp, char c) 912static void appendcOFile_(OFile *fp, char c)
913{ 913{
914 if (fp->fail) return; 914 if (fp->fail) return;
915 if (fp->fp) { 915 if (fp->fp) {
916 fputc(c,fp->fp); 916 fputc(c,fp->fp);
917 } 917 }
918 else { 918 else {
919stuff: 919stuff:
920 if (fp->len+1 < fp->limit) { 920 if (fp->len+1 < fp->limit) {
921 fp->s[fp->len] = c; 921 fp->s[fp->len] = c;
922 fp->len++; 922 fp->len++;
923 return; 923 return;
924 } 924 }
925 else if (fp->alloc) { 925 else if (fp->alloc) {
926 fp->limit = fp->limit + OFILE_REALLOC_SIZE; 926 fp->limit = fp->limit + OFILE_REALLOC_SIZE;
927 fp->s = (char *)realloc(fp->s,fp->limit); 927 fp->s = (char *)realloc(fp->s,fp->limit);
928 if (fp->s) goto stuff; 928 if (fp->s) goto stuff;
929 } 929 }
930 if (fp->alloc) 930 if (fp->alloc)
931 free(fp->s); 931 free(fp->s);
932 fp->s = 0; 932 fp->s = 0;
933 fp->fail = 1; 933 fp->fail = 1;
934 } 934 }
935} 935}
936 936
937static void appendcOFile(OFile *fp, char c) 937static void appendcOFile(OFile *fp, char c)
938{ 938{
939 if (c == '\n') { 939 if (c == '\n') {
940 /* write out as <CR><LF> */ 940 /* write out as <CR><LF> */
941 appendcOFile_(fp,0xd); 941 appendcOFile_(fp,0xd);
942 appendcOFile_(fp,0xa); 942 appendcOFile_(fp,0xa);
943 } 943 }
944 else 944 else
945 appendcOFile_(fp,c); 945 appendcOFile_(fp,c);
946} 946}
947 947
948static void appendsOFile(OFile *fp, const char *s) 948static void appendsOFile(OFile *fp, const char *s)
949{ 949{
950 int i, slen; 950 int i, slen;
951 slen = strlen(s); 951 slen = strlen(s);
952 for (i=0; i<slen; i++) { 952 for (i=0; i<slen; i++) {
953 appendcOFile(fp,s[i]); 953 appendcOFile(fp,s[i]);
954 } 954 }
955} 955}
956 956
957#endif 957#endif
958 958
959static void appendsOFileEncCs(OFile *fp) 959static void appendsOFileEncCs(OFile *fp)
960{ 960{
961 if ( vobj_enc_s ) { 961 if ( vobj_enc_s ) {
962 appendsOFile(fp, ";" VCEncodingProp "="); 962 appendsOFile(fp, ";" VCEncodingProp "=");
963 appendsOFile(fp, vobj_enc_s); 963 appendsOFile(fp, vobj_enc_s);
964 } 964 }
965 appendsOFile(fp, ";" VCCharSetProp "="); 965 appendsOFile(fp, ";" VCCharSetProp "=");
966 appendsOFile(fp, vobj_cs); 966 appendsOFile(fp, vobj_cs);
967} 967}
968 968
969 969
970static void initOFile(OFile *fp, FILE *ofp) 970static void initOFile(OFile *fp, FILE *ofp)
971{ 971{
972 fp->fp = ofp; 972 fp->fp = ofp;
973 fp->s = 0; 973 fp->s = 0;
974 fp->len = 0; 974 fp->len = 0;
975 fp->limit = 0; 975 fp->limit = 0;
976 fp->alloc = 0; 976 fp->alloc = 0;
977 fp->fail = 0; 977 fp->fail = 0;
978} 978}
979 979
980static int writeBase64(OFile *fp, unsigned char *s, long len) 980static int writeBase64(OFile *fp, unsigned char *s, long len)
981{ 981{
982 long cur = 0; 982 long cur = 0;
983 int i, numQuads = 0; 983 int i, numQuads = 0;
984 unsigned long trip; 984 unsigned long trip;
985 unsigned char b; 985 unsigned char b;
986 char quad[5]; 986 char quad[5];
987#define MAXQUADS 16 987#define MAXQUADS 16
988 988
989 quad[4] = 0; 989 quad[4] = 0;
990 990
991 while (cur < len) { 991 while (cur < len) {
992 // collect the triplet of bytes into 'trip' 992 // collect the triplet of bytes into 'trip'
993 trip = 0; 993 trip = 0;
994 for (i = 0; i < 3; i++) { 994 for (i = 0; i < 3; i++) {
995 b = (cur < len) ? *(s + cur) : 0; 995 b = (cur < len) ? *(s + cur) : 0;
996 cur++; 996 cur++;
997 trip = trip << 8 | b; 997 trip = trip << 8 | b;
998 } 998 }
999 // fill in 'quad' with the appropriate four characters 999 // fill in 'quad' with the appropriate four characters
1000 for (i = 3; i >= 0; i--) { 1000 for (i = 3; i >= 0; i--) {
1001 b = (unsigned char)(trip & 0x3F); 1001 b = (unsigned char)(trip & 0x3F);
1002 trip = trip >> 6; 1002 trip = trip >> 6;
1003 if ((3 - i) < (cur - len)) 1003 if ((3 - i) < (cur - len))
1004 quad[i] = '='; // pad char 1004 quad[i] = '='; // pad char
1005 else if (b < 26) quad[i] = (char)b + 'A'; 1005 else if (b < 26) quad[i] = (char)b + 'A';
1006 else if (b < 52) quad[i] = (char)(b - 26) + 'a'; 1006 else if (b < 52) quad[i] = (char)(b - 26) + 'a';
1007 else if (b < 62) quad[i] = (char)(b - 52) + '0'; 1007 else if (b < 62) quad[i] = (char)(b - 52) + '0';
1008 else if (b == 62) quad[i] = '+'; 1008 else if (b == 62) quad[i] = '+';
1009 else quad[i] = '/'; 1009 else quad[i] = '/';
1010 } 1010 }
1011 // now output 'quad' with appropriate whitespace and line ending 1011 // now output 'quad' with appropriate whitespace and line ending
1012 appendsOFile(fp, (numQuads == 0 ? " " : "")); 1012 appendsOFile(fp, (numQuads == 0 ? " " : ""));
1013 appendsOFile(fp, quad); 1013 appendsOFile(fp, quad);
1014 appendsOFile(fp, ((cur >= len)?"\n" :(numQuads==MAXQUADS-1?"\n" : ""))); 1014 appendsOFile(fp, ((cur >= len)?"\n" :(numQuads==MAXQUADS-1?"\n" : "")));
1015 numQuads = (numQuads + 1) % MAXQUADS; 1015 numQuads = (numQuads + 1) % MAXQUADS;
1016 } 1016 }
1017 appendcOFile(fp,'\n'); 1017 appendcOFile(fp,'\n');
1018 1018
1019 return 1; 1019 return 1;
1020} 1020}
1021 1021
1022static const char *qpReplaceChar(unsigned char c) 1022static const char *qpReplaceChar(unsigned char c)
1023{ 1023{
1024 if (c == '\n') { 1024 if (c == '\n') {
1025 return "=0A=\n"; 1025 return "=0A=\n";
1026 } else if ( 1026 } else if (
1027 // RFC 1521 1027 // RFC 1521
1028 (c >= 32 && c <= 60) // Note: " " not allowed at EOL 1028 (c >= 32 && c <= 60) // Note: " " not allowed at EOL
1029 || 1029 ||
1030 (c >= 62 && c <= 126) 1030 (c >= 62 && c <= 126)
1031 ) 1031 )
1032 { 1032 {
1033 return 0; 1033 return 0;
1034 } 1034 }
1035 1035
1036 static char trans[4]; 1036 static char trans[4];
1037 trans[0] = '='; 1037 trans[0] = '=';
1038 trans[3] = '\0'; 1038 trans[3] = '\0';
1039 int rem = c % 16; 1039 int rem = c % 16;
1040 int div = c / 16; 1040 int div = c / 16;
1041 1041
1042 if (div < 10) 1042 if (div < 10)
1043 trans[1] = '0' + div; 1043 trans[1] = '0' + div;
1044 else 1044 else
1045 trans[1] = 'A' + (div - 10); 1045 trans[1] = 'A' + (div - 10);
1046 1046
1047 if (rem < 10) 1047 if (rem < 10)
1048 trans[2] = '0' + rem; 1048 trans[2] = '0' + rem;
1049 else 1049 else
1050 trans[2] = 'A' + (rem - 10); 1050 trans[2] = 'A' + (rem - 10);
1051 1051
1052 return trans; 1052 return trans;
1053} 1053}
1054 1054
1055static void writeEncString(OFile *fp, const char *s, bool nosemi) 1055static void writeEncString(OFile *fp, const char *s, bool nosemi)
1056{ 1056{
1057 /* 1057 /*
1058 only A-Z, 0-9 and 1058 only A-Z, 0-9 and
1059 "'" (ASCII code 39) 1059 "'" (ASCII code 39)
1060 "(" (ASCII code 40) 1060 "(" (ASCII code 40)
1061 ")" (ASCII code 41) 1061 ")" (ASCII code 41)
1062 "+" (ASCII code 43) 1062 "+" (ASCII code 43)
1063 "," (ASCII code 44) 1063 "," (ASCII code 44)
1064 "-" (ASCII code 45) 1064 "-" (ASCII code 45)
1065 "/" (ASCII code 47) 1065 "/" (ASCII code 47)
1066 "?" (ASCII code 63) 1066 "?" (ASCII code 63)
1067 1067
1068 should remain un-encoded. 1068 should remain un-encoded.
1069 '=' needs to be encoded as it is the escape character. 1069 '=' needs to be encoded as it is the escape character.
1070 ';' needs to be as it is a field separator. 1070 ';' needs to be as it is a field separator.
1071 1071
1072 */ 1072 */
1073 const char *p = s; 1073 const char *p = s;
1074 switch ( vobj_enc ) { 1074 switch ( vobj_enc ) {
1075 case EightBit: 1075 case EightBit:
1076 while (*p) { 1076 while (*p) {
1077 if ( *p == '\n' || nosemi && ( *p == '\\' || *p == ';' ) ) 1077 if ( *p == '\n' || nosemi && ( *p == '\\' || *p == ';' ) )
1078 appendcOFile(fp, '\\'); 1078 appendcOFile(fp, '\\');
1079 appendcOFile(fp, *p); 1079 appendcOFile(fp, *p);
1080 p++; 1080 p++;
1081 } 1081 }
1082 break; 1082 break;
1083 case QuotedPrintable: 1083 case QuotedPrintable:
1084 while (*p) { 1084 while (*p) {
1085 const char *rep = qpReplaceChar(*p); 1085 const char *rep = qpReplaceChar(*p);
1086 if (rep) 1086 if (rep)
1087 appendsOFile(fp, rep); 1087 appendsOFile(fp, rep);
1088 else if ( *p == ';' && nosemi ) 1088 else if ( *p == ';' && nosemi )
1089 appendsOFile(fp, "=3B"); 1089 appendsOFile(fp, "=3B");
1090 else if ( *p == ' ' ) { 1090 else if ( *p == ' ' ) {
1091 if ( !p[1] || p[1] == '\n' ) // RFC 1521 1091 if ( !p[1] || p[1] == '\n' ) // RFC 1521
1092 appendsOFile(fp, "=20"); 1092 appendsOFile(fp, "=20");
1093 else 1093 else
1094 appendcOFile(fp, *p); 1094 appendcOFile(fp, *p);
1095 } else 1095 } else
1096 appendcOFile(fp, *p); 1096 appendcOFile(fp, *p);
1097 p++; 1097 p++;
1098 } 1098 }
1099 break; 1099 break;
1100 case Base64: 1100 case Base64:
1101 writeBase64(fp, (unsigned char*)p, strlen(p)); 1101 writeBase64(fp, (unsigned char*)p, strlen(p));
1102 break; 1102 break;
1103 } 1103 }
1104} 1104}
1105 1105
1106static bool includesUnprintable(VObject *o, bool nosemi) 1106static bool includesUnprintable(VObject *o, bool nosemi)
1107{ 1107{
1108 if (o) { 1108 if (o) {
1109 if (VALUE_TYPE(o) == VCVT_STRINGZ) { 1109 if (VALUE_TYPE(o) == VCVT_STRINGZ) {
1110 const char *p = STRINGZ_VALUE_OF(o); 1110 const char *p = STRINGZ_VALUE_OF(o);
1111 if (p) { 1111 if (p) {
1112 while (*p) { 1112 while (*p) {
1113 if (*p==' ' && (!p[1] || p[1]=='\n') // RFC 1521: spaces at ends need quoting 1113 if (*p==' ' && (!p[1] || p[1]=='\n') // RFC 1521: spaces at ends need quoting
1114 || qpReplaceChar(*p) 1114 || qpReplaceChar(*p)
1115 || *p==';' && nosemi ) 1115 || *p==';' && nosemi )
1116 return TRUE; 1116 return TRUE;
1117 p++; 1117 p++;
1118 } 1118 }
1119 } 1119 }
1120 } 1120 }
1121 } 1121 }
1122 return FALSE; 1122 return FALSE;
1123} 1123}
1124 1124
1125static void writeVObject_(OFile *fp, VObject *o); 1125static void writeVObject_(OFile *fp, VObject *o);
1126 1126
1127static void writeValue(OFile *fp, VObject *o, unsigned long size, bool nosemi) 1127static void writeValue(OFile *fp, VObject *o, unsigned long size, bool nosemi)
1128{ 1128{
1129 if (o == 0) return; 1129 if (o == 0) return;
1130 switch (VALUE_TYPE(o)) { 1130 switch (VALUE_TYPE(o)) {
1131 case VCVT_STRINGZ: { 1131 case VCVT_STRINGZ: {
1132 writeEncString(fp, STRINGZ_VALUE_OF(o), nosemi); 1132 writeEncString(fp, STRINGZ_VALUE_OF(o), nosemi);
1133 break; 1133 break;
1134 } 1134 }
1135 case VCVT_UINT: { 1135 case VCVT_UINT: {
1136 char buf[16]; 1136 char buf[16];
1137 sprintf(buf,"%u", INTEGER_VALUE_OF(o)); 1137 sprintf(buf,"%u", INTEGER_VALUE_OF(o));
1138 appendsOFile(fp,buf); 1138 appendsOFile(fp,buf);
1139 break; 1139 break;
1140 } 1140 }
1141 case VCVT_ULONG: { 1141 case VCVT_ULONG: {
1142 char buf[16]; 1142 char buf[16];
1143 sprintf(buf,"%lu", LONG_VALUE_OF(o)); 1143 sprintf(buf,"%lu", LONG_VALUE_OF(o));
1144 appendsOFile(fp,buf); 1144 appendsOFile(fp,buf);
1145 break; 1145 break;
1146 } 1146 }
1147 case VCVT_RAW: { 1147 case VCVT_RAW: {
1148 appendcOFile(fp,'\n'); 1148 appendcOFile(fp,'\n');
1149 writeBase64(fp,(unsigned char*)(ANY_VALUE_OF(o)),size); 1149 writeBase64(fp,(unsigned char*)(ANY_VALUE_OF(o)),size);
1150 break; 1150 break;
1151 } 1151 }
1152 case VCVT_VOBJECT: 1152 case VCVT_VOBJECT:
1153 appendcOFile(fp,'\n'); 1153 appendcOFile(fp,'\n');
1154 writeVObject_(fp,VOBJECT_VALUE_OF(o)); 1154 writeVObject_(fp,VOBJECT_VALUE_OF(o));
1155 break; 1155 break;
1156 } 1156 }
1157} 1157}
1158 1158
1159static void writeAttrValue(OFile *fp, VObject *o) 1159static void writeAttrValue(OFile *fp, VObject *o)
1160{ 1160{
1161 if (NAME_OF(o)) { 1161 if (NAME_OF(o)) {
1162 struct PreDefProp *pi; 1162 struct PreDefProp *pi;
1163 pi = lookupPropInfo(NAME_OF(o)); 1163 pi = lookupPropInfo(NAME_OF(o));
1164 if (pi && ((pi->flags & PD_INTERNAL) != 0)) return; 1164 if (pi && ((pi->flags & PD_INTERNAL) != 0)) return;
1165 if ( includesUnprintable(o,TRUE) ) 1165 if ( includesUnprintable(o,TRUE) )
1166 appendsOFileEncCs(fp); 1166 appendsOFileEncCs(fp);
1167 appendcOFile(fp,';'); 1167 appendcOFile(fp,';');
1168 appendsOFile(fp,NAME_OF(o)); 1168 appendsOFile(fp,NAME_OF(o));
1169 } else { 1169 } else {
1170 appendcOFile(fp,';'); 1170 appendcOFile(fp,';');
1171 } 1171 }
1172 if (VALUE_TYPE(o)) { 1172 if (VALUE_TYPE(o)) {
1173 appendcOFile(fp,'='); 1173 appendcOFile(fp,'=');
1174 writeValue(fp,o,0,TRUE); 1174 writeValue(fp,o,0,TRUE);
1175 } 1175 }
1176} 1176}
1177 1177
1178static void writeGroup(OFile *fp, VObject *o) 1178static void writeGroup(OFile *fp, VObject *o)
1179{ 1179{
1180 char buf1[256]; 1180 char buf1[256];
1181 char buf2[256]; 1181 char buf2[256];
1182 strcpy(buf1,NAME_OF(o)); 1182 strcpy(buf1,NAME_OF(o));
1183 while ((o=isAPropertyOf(o,VCGroupingProp)) != 0) { 1183 while ((o=isAPropertyOf(o,VCGroupingProp)) != 0) {
1184 strcpy(buf2,STRINGZ_VALUE_OF(o)); 1184 strcpy(buf2,STRINGZ_VALUE_OF(o));
1185 strcat(buf2,"."); 1185 strcat(buf2,".");
1186 strcat(buf2,buf1); 1186 strcat(buf2,buf1);
1187 strcpy(buf1,buf2); 1187 strcpy(buf1,buf2);
1188 } 1188 }
1189 appendsOFile(fp,buf1); 1189 appendsOFile(fp,buf1);
1190} 1190}
1191 1191
1192static int inList(const char **list, const char *s) 1192static int inList(const char **list, const char *s)
1193{ 1193{
1194 if (list == 0) return 0; 1194 if (list == 0) return 0;
1195 while (*list) { 1195 while (*list) {
1196 if (qstricmp(*list,s) == 0) return 1; 1196 if (qstricmp(*list,s) == 0) return 1;
1197 list++; 1197 list++;
1198 } 1198 }
1199 return 0; 1199 return 0;
1200} 1200}
1201 1201
1202static void writeProp(OFile *fp, VObject *o) 1202static void writeProp(OFile *fp, VObject *o)
1203{ 1203{
1204 if (NAME_OF(o)) { 1204 if (NAME_OF(o)) {
1205 struct PreDefProp *pi; 1205 struct PreDefProp *pi;
1206 VObjectIterator t; 1206 VObjectIterator t;
1207 const char **fields_ = 0; 1207 const char **fields_ = 0;
1208 pi = lookupPropInfo(NAME_OF(o)); 1208 pi = lookupPropInfo(NAME_OF(o));
1209 if (pi && ((pi->flags & PD_BEGIN) != 0)) { 1209 if (pi && ((pi->flags & PD_BEGIN) != 0)) {
1210 writeVObject_(fp,o); 1210 writeVObject_(fp,o);
1211 return; 1211 return;
1212 } 1212 }
1213 if (isAPropertyOf(o,VCGroupingProp)) 1213 if (isAPropertyOf(o,VCGroupingProp))
1214 writeGroup(fp,o); 1214 writeGroup(fp,o);
1215 else 1215 else
1216 appendsOFile(fp,NAME_OF(o)); 1216 appendsOFile(fp,NAME_OF(o));
1217 if (pi) fields_ = pi->fields; 1217 if (pi) fields_ = pi->fields;
1218 initPropIterator(&t,o); 1218 initPropIterator(&t,o);
1219 while (moreIteration(&t)) { 1219 while (moreIteration(&t)) {
1220 const char *s; 1220 const char *s;
1221 VObject *eachProp = nextVObject(&t); 1221 VObject *eachProp = nextVObject(&t);
1222 s = NAME_OF(eachProp); 1222 s = NAME_OF(eachProp);
1223 if (qstricmp(VCGroupingProp,s) && !inList(fields_,s)) 1223 if (qstricmp(VCGroupingProp,s) && !inList(fields_,s))
1224 writeAttrValue(fp,eachProp); 1224 writeAttrValue(fp,eachProp);
1225 } 1225 }
1226 if (fields_) { 1226 if (fields_) {
1227 int i = 0, n = 0; 1227 int i = 0, n = 0;
1228 const char** fields = fields_; 1228 const char** fields = fields_;
1229 /* output prop as fields */ 1229 /* output prop as fields */
1230 bool printable = TRUE; 1230 bool printable = TRUE;
1231 while (*fields && printable) { 1231 while (*fields && printable) {
1232 VObject *t = isAPropertyOf(o,*fields); 1232 VObject *t = isAPropertyOf(o,*fields);
1233 if (includesUnprintable(t,TRUE)) 1233 if (includesUnprintable(t,TRUE))
1234 printable = FALSE; 1234 printable = FALSE;
1235 fields++; 1235 fields++;
1236 } 1236 }
1237 fields = fields_; 1237 fields = fields_;
1238 if (!printable) 1238 if (!printable)
1239 appendsOFileEncCs(fp); 1239 appendsOFileEncCs(fp);
1240 appendcOFile(fp,':'); 1240 appendcOFile(fp,':');
1241 while (*fields) { 1241 while (*fields) {
1242 VObject *t = isAPropertyOf(o,*fields); 1242 VObject *t = isAPropertyOf(o,*fields);
1243 i++; 1243 i++;
1244 if (t) n = i; 1244 if (t) n = i;
1245 fields++; 1245 fields++;
1246 } 1246 }
1247 fields = fields_; 1247 fields = fields_;
1248 for (i=0;i<n;i++) { 1248 for (i=0;i<n;i++) {
1249 writeValue(fp,isAPropertyOf(o,*fields),0,TRUE); 1249 writeValue(fp,isAPropertyOf(o,*fields),0,TRUE);
1250 fields++; 1250 fields++;
1251 if (i<(n-1)) appendcOFile(fp,';'); 1251 if (i<(n-1)) appendcOFile(fp,';');
1252 } 1252 }
1253 } 1253 }
1254 } 1254 }
1255 1255
1256 1256
1257 if (VALUE_TYPE(o)) { 1257 if (VALUE_TYPE(o)) {
1258 if ( includesUnprintable(o,FALSE) ) 1258 if ( includesUnprintable(o,FALSE) )
1259 appendsOFileEncCs(fp); 1259 appendsOFileEncCs(fp);
1260 unsigned long size = 0; 1260 unsigned long size = 0;
1261 VObject *p = isAPropertyOf(o,VCDataSizeProp); 1261 VObject *p = isAPropertyOf(o,VCDataSizeProp);
1262 if (p) size = LONG_VALUE_OF(p); 1262 if (p) size = LONG_VALUE_OF(p);
1263 appendcOFile(fp,':'); 1263 appendcOFile(fp,':');
1264 writeValue(fp,o,size,FALSE); 1264 writeValue(fp,o,size,FALSE);
1265 } 1265 }
1266 1266
1267 appendcOFile(fp,'\n'); 1267 appendcOFile(fp,'\n');
1268} 1268}
1269 1269
1270static void writeVObject_(OFile *fp, VObject *o) 1270static void writeVObject_(OFile *fp, VObject *o)
1271{ 1271{
1272 if (NAME_OF(o)) { 1272 if (NAME_OF(o)) {
1273 struct PreDefProp *pi; 1273 struct PreDefProp *pi;
1274 pi = lookupPropInfo(NAME_OF(o)); 1274 pi = lookupPropInfo(NAME_OF(o));
1275 1275
1276 if (pi && ((pi->flags & PD_BEGIN) != 0)) { 1276 if (pi && ((pi->flags & PD_BEGIN) != 0)) {
1277 VObjectIterator t; 1277 VObjectIterator t;
1278 const char *begin = NAME_OF(o); 1278 const char *begin = NAME_OF(o);
1279 appendsOFile(fp,"BEGIN:"); 1279 appendsOFile(fp,"BEGIN:");
1280 appendsOFile(fp,begin); 1280 appendsOFile(fp,begin);
1281 appendcOFile(fp,'\n'); 1281 appendcOFile(fp,'\n');
1282 initPropIterator(&t,o); 1282 initPropIterator(&t,o);
1283 while (moreIteration(&t)) { 1283 while (moreIteration(&t)) {
1284 VObject *eachProp = nextVObject(&t); 1284 VObject *eachProp = nextVObject(&t);
1285 writeProp(fp, eachProp); 1285 writeProp(fp, eachProp);
1286 } 1286 }
1287 appendsOFile(fp,"END:"); 1287 appendsOFile(fp,"END:");
1288 appendsOFile(fp,begin); 1288 appendsOFile(fp,begin);
1289 appendsOFile(fp,"\n\n"); 1289 appendsOFile(fp,"\n\n");
1290 } 1290 }
1291 } 1291 }
1292} 1292}
1293 1293
1294static void initVObjectEncoding() 1294static void initVObjectEncoding()
1295{ 1295{
1296 Config pimConfig( "Beam" ); 1296 Config pimConfig( "Beam" );
1297 pimConfig.setGroup("Send"); 1297 pimConfig.setGroup("Send");
1298 Config devcfg(pimConfig.readEntry("DeviceConfig"),Config::File); 1298 Config devcfg(pimConfig.readEntry("DeviceConfig"),Config::File);
1299 QString enc = "QP"; 1299 QString enc = "QP";
1300 QString cs = "UTF-8"; 1300 QString cs = "UTF-8";
1301 if ( devcfg.isValid() ) { 1301 if ( devcfg.isValid() ) {
1302 devcfg.setGroup("Send"); 1302 devcfg.setGroup("Send");
1303 enc = devcfg.readEntry("Encoding","QP"); 1303 enc = devcfg.readEntry("Encoding","QP");
1304 cs = devcfg.readEntry("CharSet","UTF-8"); 1304 cs = devcfg.readEntry("CharSet","UTF-8");
1305 } 1305 }
1306 strncpy(vobj_cs,cs.latin1(),10); 1306 strncpy(vobj_cs,cs.latin1(),10);
1307 if ( enc == "QP" ) { 1307 if ( enc == "QP" ) {
1308 vobj_enc = QuotedPrintable; 1308 vobj_enc = QuotedPrintable;
1309 vobj_enc_s = VCQuotedPrintableProp; 1309 vobj_enc_s = VCQuotedPrintableProp;
1310 } else if ( enc == "B64" ) { 1310 } else if ( enc == "B64" ) {
1311 vobj_enc = Base64; 1311 vobj_enc = Base64;
1312 vobj_enc_s = VCBase64Prop; 1312 vobj_enc_s = VCBase64Prop;
1313 } else { 1313 } else {
1314 vobj_enc = EightBit; 1314 vobj_enc = EightBit;
1315 vobj_enc_s = 0; 1315 vobj_enc_s = 0;
1316 } 1316 }
1317} 1317}
1318 1318
1319void writeVObject(FILE *fp, VObject *o) 1319void writeVObject(FILE *fp, VObject *o)
1320{ 1320{
1321 initVObjectEncoding(); 1321 initVObjectEncoding();
1322 1322
1323 OFile ofp; 1323 OFile ofp;
1324 // ##### 1324 // #####
1325 //_setmode(_fileno(fp), _O_BINARY); 1325 //_setmode(_fileno(fp), _O_BINARY);
1326 initOFile(&ofp,fp); 1326 initOFile(&ofp,fp);
1327 writeVObject_(&ofp,o); 1327 writeVObject_(&ofp,o);
1328} 1328}
1329 1329
1330DLLEXPORT(void) writeVObjectToFile(char *fname, VObject *o) 1330DLLEXPORT(void) writeVObjectToFile(char *fname, VObject *o)
1331{ 1331{
1332 QFileDirect f( fname); 1332 QFileDirect f( fname);
1333 if ( !f.open( IO_WriteOnly ) ) { 1333 if ( !f.open( IO_WriteOnly ) ) {
1334 qWarning("Unable to open vobject write %s", fname); 1334 qWarning("Unable to open vobject write %s", fname);
1335 return; 1335 return;
1336 } 1336 }
1337 1337
1338 writeVObject( f.directHandle(),o ); 1338 writeVObject( f.directHandle(),o );
1339} 1339}
1340 1340
1341DLLEXPORT(void) writeVObjectsToFile(char *fname, VObject *list) 1341DLLEXPORT(void) writeVObjectsToFile(char *fname, VObject *list)
1342{ 1342{
1343 QFileDirect f( fname); 1343 QFileDirect f( fname);
1344 if ( !f.open( IO_WriteOnly ) ) { 1344 if ( !f.open( IO_WriteOnly ) ) {
1345 qWarning("Unable to open vobject write %s", fname); 1345 qWarning("Unable to open vobject write %s", fname);
1346 return; 1346 return;
1347 } 1347 }
1348 1348
1349 while (list) { 1349 while (list) {
1350 writeVObject(f.directHandle(),list); 1350 writeVObject(f.directHandle(),list);
1351 list = nextVObjectInList(list); 1351 list = nextVObjectInList(list);
1352 } 1352 }
1353} 1353}
1354 1354
1355DLLEXPORT(const char *) vObjectTypeInfo(VObject *o) 1355DLLEXPORT(const char *) vObjectTypeInfo(VObject *o)
1356{ 1356{
1357 const char *type = vObjectName( o ); 1357 const char *type = vObjectName( o );
1358 if ( strcmp( type, "TYPE" ) == 0 ) 1358 if ( strcmp( type, "type" ) == 0 ||
1359 type = vObjectStringZValue( o ); 1359 strcmp( type, "TYPE" ) == 0 ||
1360 strcmp( type, "Type" ) == 0 )
1361 type = vObjectStringZValue( o );
1360 return type; 1362 return type;
1361} 1363}
1362 1364
1363 1365
1364// end of source file vobject.c 1366// end of source file vobject.c