summaryrefslogtreecommitdiff
path: root/library/backend/vobject.cpp
Unidiff
Diffstat (limited to 'library/backend/vobject.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--library/backend/vobject.cpp273
1 files changed, 146 insertions, 127 deletions
diff --git a/library/backend/vobject.cpp b/library/backend/vobject.cpp
index 2c5b577..b6d17dc 100644
--- a/library/backend/vobject.cpp
+++ b/library/backend/vobject.cpp
@@ -1,113 +1,118 @@
1/*************************************************************************** 1/***************************************************************************
2(C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International 2(C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International
3Business Machines Corporation and Siemens Rolm Communications Inc. 3Business Machines Corporation and Siemens Rolm Communications Inc.
4 4
5For purposes of this license notice, the term Licensors shall mean, 5For purposes of this license notice, the term Licensors shall mean,
6collectively, Apple Computer, Inc., AT&T Corp., International 6collectively, Apple Computer, Inc., AT&T Corp., International
7Business Machines Corporation and Siemens Rolm Communications Inc. 7Business Machines Corporation and Siemens Rolm Communications Inc.
8The term Licensor shall mean any of the Licensors. 8The term Licensor shall mean any of the Licensors.
9 9
10Subject to acceptance of the following conditions, permission is hereby 10Subject to acceptance of the following conditions, permission is hereby
11granted by Licensors without the need for written agreement and without 11granted by Licensors without the need for written agreement and without
12license or royalty fees, to use, copy, modify and distribute this 12license or royalty fees, to use, copy, modify and distribute this
13software for any purpose. 13software for any purpose.
14 14
15The above copyright notice and the following four paragraphs must be 15The above copyright notice and the following four paragraphs must be
16reproduced in all copies of this software and any software including 16reproduced in all copies of this software and any software including
17this software. 17this software.
18 18
19THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE 19THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE
20ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR 20ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR
21MODIFICATIONS. 21MODIFICATIONS.
22 22
23IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT, 23IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT,
24INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT 24INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT
25OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 25OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26DAMAGE. 26DAMAGE.
27 27
28EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, 28EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED,
29INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE 29INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE
30IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31PURPOSE. 31PURPOSE.
32 32
33The software is provided with RESTRICTED RIGHTS. Use, duplication, or 33The software is provided with RESTRICTED RIGHTS. Use, duplication, or
34disclosure by the government are subject to restrictions set forth in 34disclosure by the government are subject to restrictions set forth in
35DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. 35DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable.
36 36
37***************************************************************************/ 37***************************************************************************/
38 38
39/* 39/*
40 * src: vobject.c 40 * src: vobject.c
41 * doc: vobject and APIs to construct vobject, APIs pretty print 41 * doc: vobject and APIs to construct vobject, APIs pretty print
42 * vobject, and convert a vobject into its textual representation. 42 * vobject, and convert a vobject into its textual representation.
43 */ 43 */
44 44
45 #ifndef MWERKS 45 #ifndef MWERKS
46#include <malloc.h> 46#include <malloc.h>
47#endif 47#endif
48 48
49#include <qtopia/private/vobject_p.h> 49#include <qtopia/config.h>
50#include <qtopia/private/qfiledirect_p.h> 50#include "vobject_p.h"
51#include "qfiledirect_p.h"
51#include <string.h> 52#include <string.h>
52#include <stdio.h> 53#include <stdio.h>
53#include <fcntl.h> 54#include <fcntl.h>
54//#include <io.h> 55//#include <io.h>
55 56
56 57
57 #define NAME_OF(o) o->id 58 #define NAME_OF(o) o->id
58 #define VALUE_TYPE(o) o->valType 59 #define VALUE_TYPE(o) o->valType
59 #define STRINGZ_VALUE_OF(o) o->val.strs 60 #define STRINGZ_VALUE_OF(o) o->val.strs
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
66static char vobj_cs[10];
67static enum { EightBit, QuotedPrintable, Base64 } vobj_enc=EightBit;
68static const char *vobj_enc_s=0;
69
65typedef union ValueItem { 70typedef union ValueItem {
66 const char *strs; 71 const char *strs;
67 unsigned int i; 72 unsigned int i;
68 unsigned long l; 73 unsigned long l;
69 void *any; 74 void *any;
70 VObject *vobj; 75 VObject *vobj;
71 } ValueItem; 76 } ValueItem;
72 77
73struct VObject { 78struct VObject {
74 VObject *next; 79 VObject *next;
75 const char *id; 80 const char *id;
76 VObject *prop; 81 VObject *prop;
77 unsigned short valType; 82 unsigned short valType;
78 ValueItem val; 83 ValueItem val;
79 }; 84 };
80 85
81typedef struct StrItem StrItem; 86typedef struct StrItem StrItem;
82 87
83struct StrItem { 88struct StrItem {
84 StrItem *next; 89 StrItem *next;
85 const char *s; 90 const char *s;
86 unsigned int refCnt; 91 unsigned int refCnt;
87 }; 92 };
88 93
89const char** fieldedProp; 94DLLEXPORT(const char**) fieldedProp;
90 95
91 96
92 97
93/*---------------------------------------------------------------------- 98/*----------------------------------------------------------------------
94 The following functions involve with memory allocation: 99 The following functions involve with memory allocation:
95 newVObject 100 newVObject
96 deleteVObject 101 deleteVObject
97 dupStr 102 dupStr
98 deleteStr 103 deleteStr
99 newStrItem 104 newStrItem
100 deleteStrItem 105 deleteStrItem
101 ----------------------------------------------------------------------*/ 106 ----------------------------------------------------------------------*/
102 107
103DLLEXPORT(VObject*) newVObject_(const char *id) 108DLLEXPORT(VObject*) newVObject_(const char *id)
104{ 109{
105 VObject *p = (VObject*)malloc(sizeof(VObject)); 110 VObject *p = (VObject*)malloc(sizeof(VObject));
106 p->next = 0; 111 p->next = 0;
107 p->id = id; 112 p->id = id;
108 p->prop = 0; 113 p->prop = 0;
109 VALUE_TYPE(p) = 0; 114 VALUE_TYPE(p) = 0;
110 ANY_VALUE_OF(p) = 0; 115 ANY_VALUE_OF(p) = 0;
111 return p; 116 return p;
112} 117}
113 118
@@ -306,60 +311,60 @@ DLLEXPORT(void) addList(VObject **o, VObject *p)
306} 311}
307 312
308DLLEXPORT(VObject*) nextVObjectInList(VObject *o) 313DLLEXPORT(VObject*) nextVObjectInList(VObject *o)
309{ 314{
310 return o->next; 315 return o->next;
311} 316}
312 317
313DLLEXPORT(VObject*) setValueWithSize_(VObject *prop, void *val, unsigned int size) 318DLLEXPORT(VObject*) setValueWithSize_(VObject *prop, void *val, unsigned int size)
314{ 319{
315 VObject *sizeProp; 320 VObject *sizeProp;
316 setVObjectAnyValue(prop, val); 321 setVObjectAnyValue(prop, val);
317 sizeProp = addProp(prop,VCDataSizeProp); 322 sizeProp = addProp(prop,VCDataSizeProp);
318 setVObjectLongValue(sizeProp, size); 323 setVObjectLongValue(sizeProp, size);
319 return prop; 324 return prop;
320} 325}
321 326
322DLLEXPORT(VObject*) setValueWithSize(VObject *prop, void *val, unsigned int size) 327DLLEXPORT(VObject*) setValueWithSize(VObject *prop, void *val, unsigned int size)
323{ 328{
324 void *p = dupStr((const char *)val,size); 329 void *p = dupStr((const char *)val,size);
325 return setValueWithSize_(prop,p,p?size:0); 330 return setValueWithSize_(prop,p,p?size:0);
326} 331}
327 332
328DLLEXPORT(void) initPropIterator(VObjectIterator *i, VObject *o) 333DLLEXPORT(void) initPropIterator(VObjectIterator *i, VObject *o)
329{ 334{
330 i->start = o->prop; 335 i->start = o->prop;
331 i->next = 0; 336 i->next = 0;
332} 337}
333 338
334DLLEXPORT(void) initVObjectIterator(VObjectIterator *i, VObject *o) 339DLLEXPORT(void) initVObjectIterator(VObjectIterator *i, VObject *o)
335{ 340{
336 i->start = o->next; 341 i->start = o->next;
337 i->next = 0; 342 i->next = 0;
338} 343}
339 344
340DLLEXPORT(int) moreIteration(VObjectIterator *i) 345DLLEXPORT(int) moreIteration(VObjectIterator *i)
341{ 346{
342 return (i->start && (i->next==0 || i->next!=i->start)); 347 return (i->start && (i->next==0 || i->next!=i->start));
343} 348}
344 349
345DLLEXPORT(VObject*) nextVObject(VObjectIterator *i) 350DLLEXPORT(VObject*) nextVObject(VObjectIterator *i)
346{ 351{
347 if (i->start && i->next != i->start) { 352 if (i->start && i->next != i->start) {
348 if (i->next == 0) { 353 if (i->next == 0) {
349 i->next = i->start->next; 354 i->next = i->start->next;
350 return i->next; 355 return i->next;
351 } 356 }
352 else { 357 else {
353 i->next = i->next->next; 358 i->next = i->next->next;
354 return i->next; 359 return i->next;
355 } 360 }
356 } 361 }
357 else return (VObject*)0; 362 else return (VObject*)0;
358} 363}
359 364
360DLLEXPORT(VObject*) isAPropertyOf(VObject *o, const char *id) 365DLLEXPORT(VObject*) isAPropertyOf(VObject *o, const char *id)
361{ 366{
362 VObjectIterator i; 367 VObjectIterator i;
363 initPropIterator(&i,o); 368 initPropIterator(&i,o);
364 while (moreIteration(&i)) { 369 while (moreIteration(&i)) {
365 VObject *each = nextVObject(&i); 370 VObject *each = nextVObject(&i);
@@ -382,49 +387,49 @@ DLLEXPORT(VObject*) addGroup(VObject *o, const char *g)
382 if (dot) { 387 if (dot) {
383 VObject *p, *t; 388 VObject *p, *t;
384 char *gs, *n = dot+1; 389 char *gs, *n = dot+1;
385 gs = dupStr(g,0);/* so we can write to it. */ 390 gs = dupStr(g,0);/* so we can write to it. */
386 /* used to be 391 /* used to be
387 * t = p = addProp_(o,lookupProp_(n)); 392 * t = p = addProp_(o,lookupProp_(n));
388 */ 393 */
389 t = p = addProp_(o,lookupProp(n)); 394 t = p = addProp_(o,lookupProp(n));
390 dot = strrchr(gs,'.'); 395 dot = strrchr(gs,'.');
391 *dot = 0; 396 *dot = 0;
392 do { 397 do {
393 dot = strrchr(gs,'.'); 398 dot = strrchr(gs,'.');
394 if (dot) { 399 if (dot) {
395 n = dot+1; 400 n = dot+1;
396 *dot=0; 401 *dot=0;
397 } 402 }
398 else 403 else
399 n = gs; 404 n = gs;
400 /* property(VCGroupingProp=n); 405 /* property(VCGroupingProp=n);
401 *and the value may have VCGrouping property 406 *and the value may have VCGrouping property
402 */ 407 */
403 t = addProp(t,VCGroupingProp); 408 t = addProp(t,VCGroupingProp);
404 setVObjectStringZValue(t,lookupProp_(n)); 409 setVObjectStringZValue(t,lookupProp_(n));
405 } while (n != gs); 410 } while (n != gs);
406 deleteStr(gs); 411 deleteStr(gs);
407 return p; 412 return p;
408 } 413 }
409 else 414 else
410 return addProp_(o,lookupProp(g)); 415 return addProp_(o,lookupProp(g));
411} 416}
412 417
413DLLEXPORT(VObject*) addPropValue(VObject *o, const char *p, const char *v) 418DLLEXPORT(VObject*) addPropValue(VObject *o, const char *p, const char *v)
414{ 419{
415 VObject *prop; 420 VObject *prop;
416 prop = addProp(o,p); 421 prop = addProp(o,p);
417 setVObjectStringZValue_(prop, strdup( v ) ); 422 setVObjectStringZValue_(prop, strdup( v ) );
418 return prop; 423 return prop;
419} 424}
420 425
421DLLEXPORT(VObject*) addPropSizedValue_(VObject *o, const char *p, const char *v, 426DLLEXPORT(VObject*) addPropSizedValue_(VObject *o, const char *p, const char *v,
422 unsigned int size) 427 unsigned int size)
423{ 428{
424 VObject *prop; 429 VObject *prop;
425 prop = addProp(o,p); 430 prop = addProp(o,p);
426 setValueWithSize_(prop, (void*)v, size); 431 setValueWithSize_(prop, (void*)v, size);
427 return prop; 432 return prop;
428} 433}
429 434
430DLLEXPORT(VObject*) addPropSizedValue(VObject *o, const char *p, const char *v, 435DLLEXPORT(VObject*) addPropSizedValue(VObject *o, const char *p, const char *v,
@@ -778,76 +783,76 @@ static struct PreDefProp propNames[] = {
778 { VCTLXProp, 0, 0, 0 }, 783 { VCTLXProp, 0, 0, 0 },
779 { VCTodoProp, 0, 0, PD_BEGIN }, 784 { VCTodoProp, 0, 0, PD_BEGIN },
780 { VCTranspProp, 0, 0, 0 }, 785 { VCTranspProp, 0, 0, 0 },
781 { VCUniqueStringProp, 0, 0, 0 }, 786 { VCUniqueStringProp, 0, 0, 0 },
782 { VCURLProp, 0, 0, 0 }, 787 { VCURLProp, 0, 0, 0 },
783 { VCURLValueProp, 0, 0, 0 }, 788 { VCURLValueProp, 0, 0, 0 },
784 { VCValueProp, 0, 0, 0 }, 789 { VCValueProp, 0, 0, 0 },
785 { VCVersionProp, 0, 0, 0 }, 790 { VCVersionProp, 0, 0, 0 },
786 { VCVideoProp, 0, 0, 0 }, 791 { VCVideoProp, 0, 0, 0 },
787 { VCVoiceProp, 0, 0, 0 }, 792 { VCVoiceProp, 0, 0, 0 },
788 { VCWAVEProp, 0, 0, 0 }, 793 { VCWAVEProp, 0, 0, 0 },
789 { VCWMFProp, 0, 0, 0 }, 794 { VCWMFProp, 0, 0, 0 },
790 { VCWorkProp, 0, 0, 0 }, 795 { VCWorkProp, 0, 0, 0 },
791 { VCX400Prop, 0, 0, 0 }, 796 { VCX400Prop, 0, 0, 0 },
792 { VCX509Prop, 0, 0, 0 }, 797 { VCX509Prop, 0, 0, 0 },
793 { VCXRuleProp, 0, 0, 0 }, 798 { VCXRuleProp, 0, 0, 0 },
794 { 0,0,0,0 } 799 { 0,0,0,0 }
795 }; 800 };
796 801
797 802
798static struct PreDefProp* lookupPropInfo(const char* str) 803static struct PreDefProp* lookupPropInfo(const char* str)
799{ 804{
800 /* brute force for now, could use a hash table here. */ 805 /* brute force for now, could use a hash table here. */
801 int i; 806 int i;
802 807
803 for (i = 0; propNames[i].name; i++) 808 for (i = 0; propNames[i].name; i++)
804 if (qstricmp(str, propNames[i].name) == 0) { 809 if (qstricmp(str, propNames[i].name) == 0) {
805 return &propNames[i]; 810 return &propNames[i];
806 } 811 }
807 812
808 return 0; 813 return 0;
809} 814}
810 815
811 816
812DLLEXPORT(const char*) lookupProp_(const char* str) 817DLLEXPORT(const char*) lookupProp_(const char* str)
813{ 818{
814 int i; 819 int i;
815 820
816 for (i = 0; propNames[i].name; i++) 821 for (i = 0; propNames[i].name; i++)
817 if (qstricmp(str, propNames[i].name) == 0) { 822 if (qstricmp(str, propNames[i].name) == 0) {
818 const char* s; 823 const char* s;
819 s = propNames[i].alias?propNames[i].alias:propNames[i].name; 824 s = propNames[i].alias?propNames[i].alias:propNames[i].name;
820 return lookupStr(s); 825 return lookupStr(s);
821 } 826 }
822 return lookupStr(str); 827 return lookupStr(str);
823} 828}
824 829
825 830
826DLLEXPORT(const char*) lookupProp(const char* str) 831DLLEXPORT(const char*) lookupProp(const char* str)
827{ 832{
828 int i; 833 int i;
829 834
830 for (i = 0; propNames[i].name; i++) 835 for (i = 0; propNames[i].name; i++)
831 if (qstricmp(str, propNames[i].name) == 0) { 836 if (qstricmp(str, propNames[i].name) == 0) {
832 const char *s; 837 const char *s;
833 fieldedProp = propNames[i].fields; 838 fieldedProp = propNames[i].fields;
834 s = propNames[i].alias?propNames[i].alias:propNames[i].name; 839 s = propNames[i].alias?propNames[i].alias:propNames[i].name;
835 return lookupStr(s); 840 return lookupStr(s);
836 } 841 }
837 fieldedProp = 0; 842 fieldedProp = 0;
838 return lookupStr(str); 843 return lookupStr(str);
839} 844}
840 845
841 846
842/*---------------------------------------------------------------------- 847/*----------------------------------------------------------------------
843 APIs to Output text form. 848 APIs to Output text form.
844 ----------------------------------------------------------------------*/ 849 ----------------------------------------------------------------------*/
845#define OFILE_REALLOC_SIZE 256 850#define OFILE_REALLOC_SIZE 256
846typedef struct OFile { 851typedef struct OFile {
847 FILE *fp; 852 FILE *fp;
848 char *s; 853 char *s;
849 int len; 854 int len;
850 int limit; 855 int limit;
851 int alloc:1; 856 int alloc:1;
852 int fail:1; 857 int fail:1;
853 } OFile; 858 } OFile;
@@ -932,48 +937,59 @@ stuff:
932} 937}
933 938
934static void appendcOFile(OFile *fp, char c) 939static void appendcOFile(OFile *fp, char c)
935{ 940{
936 if (c == '\n') { 941 if (c == '\n') {
937 /* write out as <CR><LF> */ 942 /* write out as <CR><LF> */
938 appendcOFile_(fp,0xd); 943 appendcOFile_(fp,0xd);
939 appendcOFile_(fp,0xa); 944 appendcOFile_(fp,0xa);
940 } 945 }
941 else 946 else
942 appendcOFile_(fp,c); 947 appendcOFile_(fp,c);
943} 948}
944 949
945static void appendsOFile(OFile *fp, const char *s) 950static void appendsOFile(OFile *fp, const char *s)
946{ 951{
947 int i, slen; 952 int i, slen;
948 slen = strlen(s); 953 slen = strlen(s);
949 for (i=0; i<slen; i++) { 954 for (i=0; i<slen; i++) {
950 appendcOFile(fp,s[i]); 955 appendcOFile(fp,s[i]);
951 } 956 }
952} 957}
953 958
954#endif 959#endif
955 960
961static void appendsOFileEncCs(OFile *fp)
962{
963 if ( vobj_enc_s ) {
964 appendsOFile(fp, ";" VCEncodingProp "=");
965 appendsOFile(fp, vobj_enc_s);
966 }
967 appendsOFile(fp, ";" VCCharSetProp "=");
968 appendsOFile(fp, vobj_cs);
969}
970
971
956static void initOFile(OFile *fp, FILE *ofp) 972static void initOFile(OFile *fp, FILE *ofp)
957{ 973{
958 fp->fp = ofp; 974 fp->fp = ofp;
959 fp->s = 0; 975 fp->s = 0;
960 fp->len = 0; 976 fp->len = 0;
961 fp->limit = 0; 977 fp->limit = 0;
962 fp->alloc = 0; 978 fp->alloc = 0;
963 fp->fail = 0; 979 fp->fail = 0;
964} 980}
965 981
966static int writeBase64(OFile *fp, unsigned char *s, long len) 982static int writeBase64(OFile *fp, unsigned char *s, long len)
967{ 983{
968 long cur = 0; 984 long cur = 0;
969 int i, numQuads = 0; 985 int i, numQuads = 0;
970 unsigned long trip; 986 unsigned long trip;
971 unsigned char b; 987 unsigned char b;
972 char quad[5]; 988 char quad[5];
973#define MAXQUADS 16 989#define MAXQUADS 16
974 990
975 quad[4] = 0; 991 quad[4] = 0;
976 992
977 while (cur < len) { 993 while (cur < len) {
978 // collect the triplet of bytes into 'trip' 994 // collect the triplet of bytes into 'trip'
979 trip = 0; 995 trip = 0;
@@ -984,216 +1000,201 @@ static int writeBase64(OFile *fp, unsigned char *s, long len)
984 } 1000 }
985 // fill in 'quad' with the appropriate four characters 1001 // fill in 'quad' with the appropriate four characters
986 for (i = 3; i >= 0; i--) { 1002 for (i = 3; i >= 0; i--) {
987 b = (unsigned char)(trip & 0x3F); 1003 b = (unsigned char)(trip & 0x3F);
988 trip = trip >> 6; 1004 trip = trip >> 6;
989 if ((3 - i) < (cur - len)) 1005 if ((3 - i) < (cur - len))
990 quad[i] = '='; // pad char 1006 quad[i] = '='; // pad char
991 else if (b < 26) quad[i] = (char)b + 'A'; 1007 else if (b < 26) quad[i] = (char)b + 'A';
992 else if (b < 52) quad[i] = (char)(b - 26) + 'a'; 1008 else if (b < 52) quad[i] = (char)(b - 26) + 'a';
993 else if (b < 62) quad[i] = (char)(b - 52) + '0'; 1009 else if (b < 62) quad[i] = (char)(b - 52) + '0';
994 else if (b == 62) quad[i] = '+'; 1010 else if (b == 62) quad[i] = '+';
995 else quad[i] = '/'; 1011 else quad[i] = '/';
996 } 1012 }
997 // now output 'quad' with appropriate whitespace and line ending 1013 // now output 'quad' with appropriate whitespace and line ending
998 appendsOFile(fp, (numQuads == 0 ? " " : "")); 1014 appendsOFile(fp, (numQuads == 0 ? " " : ""));
999 appendsOFile(fp, quad); 1015 appendsOFile(fp, quad);
1000 appendsOFile(fp, ((cur >= len)?"\n" :(numQuads==MAXQUADS-1?"\n" : ""))); 1016 appendsOFile(fp, ((cur >= len)?"\n" :(numQuads==MAXQUADS-1?"\n" : "")));
1001 numQuads = (numQuads + 1) % MAXQUADS; 1017 numQuads = (numQuads + 1) % MAXQUADS;
1002 } 1018 }
1003 appendcOFile(fp,'\n'); 1019 appendcOFile(fp,'\n');
1004 1020
1005 return 1; 1021 return 1;
1006} 1022}
1007 1023
1008static const char *replaceChar(unsigned char c) 1024static const char *qpReplaceChar(unsigned char c)
1009{ 1025{
1010 if (c == '\n') { 1026 if (c == '\n') {
1011 return "=0A=\n"; 1027 return "=0A=\n";
1012 } else if ( 1028 } else if (
1013 (c >= 'A' && c <= 'Z') 1029 // RFC 1521
1014 || 1030 (c >= 32 && c <= 60) // Note: " " not allowed at EOL
1015 (c >= 'a' && c <= 'z')
1016 ||
1017 (c >= '0' && c <= '9')
1018 ||
1019 (c >= '\'' && c <= ')')
1020 ||
1021 (c >= '+' && c <= '-')
1022 ||
1023 (c == '/')
1024 ||
1025 (c == '?')
1026 || 1031 ||
1027 (c == ' ')) 1032 (c >= 62 && c <= 126)
1028 { 1033 )
1034 {
1029 return 0; 1035 return 0;
1030 } 1036 }
1031 1037
1032#warning "Bug-Workaround must be fixed !"
1033 // IF THIS FUNCTION RETURNES TRUE, THE DATA IS EXPORTED
1034 // AS QUOTED PRINTABLE.
1035 // BUT THE PARSER IS UNABLE TO IMPORT THIS, THEREFORE
1036 // I DECIDED TO DISABLE IT UNTIL TROLLTECH FIXES THIS BUG
1037 // SEE ALSO includesUnprintable(VObject *o)
1038 // (se)
1039
1040 return 0;
1041
1042#if 0
1043 static char trans[4]; 1038 static char trans[4];
1044 trans[0] = '='; 1039 trans[0] = '=';
1045 trans[3] = '\0'; 1040 trans[3] = '\0';
1046 int rem = c % 16; 1041 int rem = c % 16;
1047 int div = c / 16; 1042 int div = c / 16;
1048 1043
1049 if (div < 10) 1044 if (div < 10)
1050 trans[1] = '0' + div; 1045 trans[1] = '0' + div;
1051 else 1046 else
1052 trans[1] = 'A' + (div - 10); 1047 trans[1] = 'A' + (div - 10);
1053 1048
1054 if (rem < 10) 1049 if (rem < 10)
1055 trans[2] = '0' + rem; 1050 trans[2] = '0' + rem;
1056 else 1051 else
1057 trans[2] = 'A' + (rem - 10); 1052 trans[2] = 'A' + (rem - 10);
1058 1053
1059 return trans; 1054 return trans;
1060#endif
1061} 1055}
1062 1056
1063static void writeQPString(OFile *fp, const char *s) 1057static void writeEncString(OFile *fp, const char *s, bool nosemi)
1064{ 1058{
1065 /* 1059 /*
1066 only A-Z, 0-9 and 1060 only A-Z, 0-9 and
1067 "'" (ASCII code 39) 1061 "'" (ASCII code 39)
1068 "(" (ASCII code 40) 1062 "(" (ASCII code 40)
1069 ")" (ASCII code 41) 1063 ")" (ASCII code 41)
1070 "+" (ASCII code 43) 1064 "+" (ASCII code 43)
1071 "," (ASCII code 44) 1065 "," (ASCII code 44)
1072 "-" (ASCII code 45) 1066 "-" (ASCII code 45)
1073 "/" (ASCII code 47) 1067 "/" (ASCII code 47)
1074 "?" (ASCII code 63) 1068 "?" (ASCII code 63)
1075 1069
1076 should remain un-encoded. 1070 should remain un-encoded.
1077 '=' needs to be encoded as it is the escape character. 1071 '=' needs to be encoded as it is the escape character.
1078 ';' needs to be as it is a field separator. 1072 ';' needs to be as it is a field separator.
1079 1073
1080 */ 1074 */
1081 const char *p = s; 1075 const char *p = s;
1082 while (*p) { 1076 switch ( vobj_enc ) {
1083 const char *rep = replaceChar(*p); 1077 case EightBit:
1084 if (rep) 1078 while (*p) {
1085 appendsOFile(fp, rep); 1079 if ( *p == '\n' || nosemi && ( *p == '\\' || *p == ';' ) )
1086 else 1080 appendcOFile(fp, '\\');
1087 appendcOFile(fp, *p); 1081 appendcOFile(fp, *p);
1088 p++; 1082 p++;
1083 }
1084 break;
1085 case QuotedPrintable:
1086 while (*p) {
1087 const char *rep = qpReplaceChar(*p);
1088 if (rep)
1089 appendsOFile(fp, rep);
1090 else if ( *p == ';' && nosemi )
1091 appendsOFile(fp, "=3B");
1092 else if ( *p == ' ' ) {
1093 if ( !p[1] || p[1] == '\n' ) // RFC 1521
1094 appendsOFile(fp, "=20");
1095 else
1096 appendcOFile(fp, *p);
1097 } else
1098 appendcOFile(fp, *p);
1099 p++;
1100 }
1101 break;
1102 case Base64:
1103 writeBase64(fp, (unsigned char*)p, strlen(p));
1104 break;
1089 } 1105 }
1090} 1106}
1091 1107
1092static bool includesUnprintable(VObject *o) 1108static bool includesUnprintable(VObject *o)
1093{ 1109{
1094
1095#if 0
1096
1097 // IF THIS FUNCTION RETURNES TRUE, THE DATA IS EXPORTED
1098 // AS QUOTED PRINTABLE.
1099 // BUT THE PARSER IS UNABLE TO IMPORT THIS, THEREFORE
1100 // I DECIDED TO DISABLE IT UNTIL TROLLTECH FIXES THIS BUG
1101 // SEE ALSO *replaceChar(unsigned char c)
1102 // (se)
1103
1104 if (o) { 1110 if (o) {
1105 if (VALUE_TYPE(o) == VCVT_STRINGZ) { 1111 if (VALUE_TYPE(o) == VCVT_STRINGZ) {
1106 const char *p = STRINGZ_VALUE_OF(o); 1112 const char *p = STRINGZ_VALUE_OF(o);
1107 if (p) { 1113 if (p) {
1108 while (*p) { 1114 while (*p) {
1109 if (replaceChar(*p)) 1115 if (*p==' ' && (!p[1] || p[1]=='\n') // RFC 1521: spaces at ends need quoting
1116 || qpReplaceChar(*p) )
1110 return TRUE; 1117 return TRUE;
1111 p++; 1118 p++;
1112 } 1119 }
1113 } 1120 }
1114 } 1121 }
1115 } 1122 }
1116
1117#endif
1118#warning "Bug-Workaround must be fixed !"
1119
1120 return FALSE; 1123 return FALSE;
1121} 1124}
1122 1125
1123static void writeVObject_(OFile *fp, VObject *o); 1126static void writeVObject_(OFile *fp, VObject *o);
1124 1127
1125static void writeValue(OFile *fp, VObject *o, unsigned long size) 1128static void writeValue(OFile *fp, VObject *o, unsigned long size, bool nosemi)
1126{ 1129{
1127 if (o == 0) return; 1130 if (o == 0) return;
1128 switch (VALUE_TYPE(o)) { 1131 switch (VALUE_TYPE(o)) {
1129 case VCVT_STRINGZ: { 1132 case VCVT_STRINGZ: {
1130 writeQPString(fp, STRINGZ_VALUE_OF(o)); 1133 writeEncString(fp, STRINGZ_VALUE_OF(o), nosemi);
1131 break; 1134 break;
1132 } 1135 }
1133 case VCVT_UINT: { 1136 case VCVT_UINT: {
1134 char buf[16]; 1137 char buf[16];
1135 sprintf(buf,"%u", INTEGER_VALUE_OF(o)); 1138 sprintf(buf,"%u", INTEGER_VALUE_OF(o));
1136 appendsOFile(fp,buf); 1139 appendsOFile(fp,buf);
1137 break; 1140 break;
1138 } 1141 }
1139 case VCVT_ULONG: { 1142 case VCVT_ULONG: {
1140 char buf[16]; 1143 char buf[16];
1141 sprintf(buf,"%lu", LONG_VALUE_OF(o)); 1144 sprintf(buf,"%lu", LONG_VALUE_OF(o));
1142 appendsOFile(fp,buf); 1145 appendsOFile(fp,buf);
1143 break; 1146 break;
1144 } 1147 }
1145 case VCVT_RAW: { 1148 case VCVT_RAW: {
1146 appendcOFile(fp,'\n'); 1149 appendcOFile(fp,'\n');
1147 writeBase64(fp,(unsigned char*)(ANY_VALUE_OF(o)),size); 1150 writeBase64(fp,(unsigned char*)(ANY_VALUE_OF(o)),size);
1148 break; 1151 break;
1149 } 1152 }
1150 case VCVT_VOBJECT: 1153 case VCVT_VOBJECT:
1151 appendcOFile(fp,'\n'); 1154 appendcOFile(fp,'\n');
1152 writeVObject_(fp,VOBJECT_VALUE_OF(o)); 1155 writeVObject_(fp,VOBJECT_VALUE_OF(o));
1153 break; 1156 break;
1154 } 1157 }
1155} 1158}
1156 1159
1157static void writeAttrValue(OFile *fp, VObject *o) 1160static void writeAttrValue(OFile *fp, VObject *o)
1158{ 1161{
1159 if (NAME_OF(o)) { 1162 if (NAME_OF(o)) {
1160 struct PreDefProp *pi; 1163 struct PreDefProp *pi;
1161 pi = lookupPropInfo(NAME_OF(o)); 1164 pi = lookupPropInfo(NAME_OF(o));
1162 if (pi && ((pi->flags & PD_INTERNAL) != 0)) return; 1165 if (pi && ((pi->flags & PD_INTERNAL) != 0)) return;
1163 if ( includesUnprintable(o) ) { 1166 if ( includesUnprintable(o) )
1164 appendsOFile(fp, ";" VCEncodingProp "=" VCQuotedPrintableProp); 1167 appendsOFileEncCs(fp);
1165 appendsOFile(fp, ";" VCCharSetProp "=" "UTF-8");
1166 }
1167 appendcOFile(fp,';'); 1168 appendcOFile(fp,';');
1168 appendsOFile(fp,NAME_OF(o)); 1169 appendsOFile(fp,NAME_OF(o));
1169 } 1170 } else {
1170 else
1171 appendcOFile(fp,';'); 1171 appendcOFile(fp,';');
1172 }
1172 if (VALUE_TYPE(o)) { 1173 if (VALUE_TYPE(o)) {
1173 appendcOFile(fp,'='); 1174 appendcOFile(fp,'=');
1174 writeValue(fp,o,0); 1175 writeValue(fp,o,0,TRUE);
1175 } 1176 }
1176} 1177}
1177 1178
1178static void writeGroup(OFile *fp, VObject *o) 1179static void writeGroup(OFile *fp, VObject *o)
1179{ 1180{
1180 char buf1[256]; 1181 char buf1[256];
1181 char buf2[256]; 1182 char buf2[256];
1182 strcpy(buf1,NAME_OF(o)); 1183 strcpy(buf1,NAME_OF(o));
1183 while ((o=isAPropertyOf(o,VCGroupingProp)) != 0) { 1184 while ((o=isAPropertyOf(o,VCGroupingProp)) != 0) {
1184 strcpy(buf2,STRINGZ_VALUE_OF(o)); 1185 strcpy(buf2,STRINGZ_VALUE_OF(o));
1185 strcat(buf2,"."); 1186 strcat(buf2,".");
1186 strcat(buf2,buf1); 1187 strcat(buf2,buf1);
1187 strcpy(buf1,buf2); 1188 strcpy(buf1,buf2);
1188 } 1189 }
1189 appendsOFile(fp,buf1); 1190 appendsOFile(fp,buf1);
1190} 1191}
1191 1192
1192static int inList(const char **list, const char *s) 1193static int inList(const char **list, const char *s)
1193{ 1194{
1194 if (list == 0) return 0; 1195 if (list == 0) return 0;
1195 while (*list) { 1196 while (*list) {
1196 if (qstricmp(*list,s) == 0) return 1; 1197 if (qstricmp(*list,s) == 0) return 1;
1197 list++; 1198 list++;
1198 } 1199 }
1199 return 0; 1200 return 0;
@@ -1214,133 +1215,151 @@ static void writeProp(OFile *fp, VObject *o)
1214 writeGroup(fp,o); 1215 writeGroup(fp,o);
1215 else 1216 else
1216 appendsOFile(fp,NAME_OF(o)); 1217 appendsOFile(fp,NAME_OF(o));
1217 if (pi) fields_ = pi->fields; 1218 if (pi) fields_ = pi->fields;
1218 initPropIterator(&t,o); 1219 initPropIterator(&t,o);
1219 while (moreIteration(&t)) { 1220 while (moreIteration(&t)) {
1220 const char *s; 1221 const char *s;
1221 VObject *eachProp = nextVObject(&t); 1222 VObject *eachProp = nextVObject(&t);
1222 s = NAME_OF(eachProp); 1223 s = NAME_OF(eachProp);
1223 if (qstricmp(VCGroupingProp,s) && !inList(fields_,s)) 1224 if (qstricmp(VCGroupingProp,s) && !inList(fields_,s))
1224 writeAttrValue(fp,eachProp); 1225 writeAttrValue(fp,eachProp);
1225 } 1226 }
1226 if (fields_) { 1227 if (fields_) {
1227 int i = 0, n = 0; 1228 int i = 0, n = 0;
1228 const char** fields = fields_; 1229 const char** fields = fields_;
1229 /* output prop as fields */ 1230 /* output prop as fields */
1230 bool printable = TRUE; 1231 bool printable = TRUE;
1231 while (*fields && printable) { 1232 while (*fields && printable) {
1232 VObject *t = isAPropertyOf(o,*fields); 1233 VObject *t = isAPropertyOf(o,*fields);
1233 if (includesUnprintable(t)) 1234 if (includesUnprintable(t))
1234 printable = FALSE; 1235 printable = FALSE;
1235 fields++; 1236 fields++;
1236 } 1237 }
1237 fields = fields_; 1238 fields = fields_;
1238 if (!printable) { 1239 if (!printable)
1239 appendsOFile(fp, ";" VCEncodingProp "=" VCQuotedPrintableProp); 1240 appendsOFileEncCs(fp);
1240 appendsOFile(fp, ";" VCCharSetProp "=" "UTF-8");
1241 }
1242 appendcOFile(fp,':'); 1241 appendcOFile(fp,':');
1243 while (*fields) { 1242 while (*fields) {
1244 VObject *t = isAPropertyOf(o,*fields); 1243 VObject *t = isAPropertyOf(o,*fields);
1245 i++; 1244 i++;
1246 if (t) n = i; 1245 if (t) n = i;
1247 fields++; 1246 fields++;
1248 } 1247 }
1249 fields = fields_; 1248 fields = fields_;
1250 for (i=0;i<n;i++) { 1249 for (i=0;i<n;i++) {
1251 writeValue(fp,isAPropertyOf(o,*fields),0); 1250 writeValue(fp,isAPropertyOf(o,*fields),0,TRUE);
1252 fields++; 1251 fields++;
1253 if (i<(n-1)) appendcOFile(fp,';'); 1252 if (i<(n-1)) appendcOFile(fp,';');
1254 } 1253 }
1255 } 1254 }
1256 } 1255 }
1257 1256
1258 1257
1259 if (VALUE_TYPE(o)) { 1258 if (VALUE_TYPE(o)) {
1260 if ( includesUnprintable(o) ) { 1259 if ( includesUnprintable(o) )
1261 appendsOFile(fp, ";" VCEncodingProp "=" VCQuotedPrintableProp); 1260 appendsOFileEncCs(fp);
1262 appendsOFile(fp, ";" VCCharSetProp "=" "UTF-8");
1263 }
1264 unsigned long size = 0; 1261 unsigned long size = 0;
1265 VObject *p = isAPropertyOf(o,VCDataSizeProp); 1262 VObject *p = isAPropertyOf(o,VCDataSizeProp);
1266 if (p) size = LONG_VALUE_OF(p); 1263 if (p) size = LONG_VALUE_OF(p);
1267 appendcOFile(fp,':'); 1264 appendcOFile(fp,':');
1268 writeValue(fp,o,size); 1265 writeValue(fp,o,size,FALSE);
1269 } 1266 }
1270 1267
1271 appendcOFile(fp,'\n'); 1268 appendcOFile(fp,'\n');
1272} 1269}
1273 1270
1274static void writeVObject_(OFile *fp, VObject *o) 1271static void writeVObject_(OFile *fp, VObject *o)
1275{ 1272{
1276 if (NAME_OF(o)) { 1273 if (NAME_OF(o)) {
1277 struct PreDefProp *pi; 1274 struct PreDefProp *pi;
1278 pi = lookupPropInfo(NAME_OF(o)); 1275 pi = lookupPropInfo(NAME_OF(o));
1279 1276
1280 if (pi && ((pi->flags & PD_BEGIN) != 0)) { 1277 if (pi && ((pi->flags & PD_BEGIN) != 0)) {
1281 VObjectIterator t; 1278 VObjectIterator t;
1282 const char *begin = NAME_OF(o); 1279 const char *begin = NAME_OF(o);
1283 appendsOFile(fp,"BEGIN:"); 1280 appendsOFile(fp,"BEGIN:");
1284 appendsOFile(fp,begin); 1281 appendsOFile(fp,begin);
1285 appendcOFile(fp,'\n'); 1282 appendcOFile(fp,'\n');
1286 initPropIterator(&t,o); 1283 initPropIterator(&t,o);
1287 while (moreIteration(&t)) { 1284 while (moreIteration(&t)) {
1288 VObject *eachProp = nextVObject(&t); 1285 VObject *eachProp = nextVObject(&t);
1289 writeProp(fp, eachProp); 1286 writeProp(fp, eachProp);
1290 } 1287 }
1291 appendsOFile(fp,"END:"); 1288 appendsOFile(fp,"END:");
1292 appendsOFile(fp,begin); 1289 appendsOFile(fp,begin);
1293 appendsOFile(fp,"\n\n"); 1290 appendsOFile(fp,"\n\n");
1294 } 1291 }
1295 } 1292 }
1296} 1293}
1297 1294
1295static void initVObjectEncoding()
1296{
1297 Config pimConfig( "Beam" );
1298 pimConfig.setGroup("Send");
1299 Config devcfg(pimConfig.readEntry("DeviceConfig"),Config::File);
1300 QString enc = "QP";
1301 QString cs = "UTF-8";
1302 if ( devcfg.isValid() ) {
1303 devcfg.setGroup("Send");
1304 enc = devcfg.readEntry("Encoding","QP");
1305 cs = devcfg.readEntry("CharSet","UTF-8");
1306 }
1307 strncpy(vobj_cs,cs.latin1(),10);
1308 if ( enc == "QP" ) {
1309 vobj_enc = QuotedPrintable;
1310 vobj_enc_s = VCQuotedPrintableProp;
1311 } else if ( enc == "B64" ) {
1312 vobj_enc = Base64;
1313 vobj_enc_s = VCBase64Prop;
1314 } else {
1315 vobj_enc = EightBit;
1316 vobj_enc_s = 0;
1317 }
1318}
1319
1298void writeVObject(FILE *fp, VObject *o) 1320void writeVObject(FILE *fp, VObject *o)
1299{ 1321{
1322 initVObjectEncoding();
1323
1300 OFile ofp; 1324 OFile ofp;
1301 // ##### 1325 // #####
1302 //_setmode(_fileno(fp), _O_BINARY); 1326 //_setmode(_fileno(fp), _O_BINARY);
1303 initOFile(&ofp,fp); 1327 initOFile(&ofp,fp);
1304 writeVObject_(&ofp,o); 1328 writeVObject_(&ofp,o);
1305} 1329}
1306 1330
1307DLLEXPORT(void) writeVObjectToFile(char *fname, VObject *o) 1331DLLEXPORT(void) writeVObjectToFile(char *fname, VObject *o)
1308{ 1332{
1309 QFileDirect f( fname); 1333 QFileDirect f( fname);
1310 if ( !f.open( IO_WriteOnly ) ) { 1334 if ( !f.open( IO_WriteOnly ) ) {
1311 qWarning("Unable to open vobject write %s", fname); 1335 qWarning("Unable to open vobject write %s", fname);
1312 return; 1336 return;
1313 } 1337 }
1314 1338
1315 writeVObject( f.directHandle(),o ); 1339 writeVObject( f.directHandle(),o );
1316} 1340}
1317 1341
1318DLLEXPORT(void) writeVObjectsToFile(char *fname, VObject *list) 1342DLLEXPORT(void) writeVObjectsToFile(char *fname, VObject *list)
1319{ 1343{
1320 QFileDirect f( fname); 1344 QFileDirect f( fname);
1321 if ( !f.open( IO_WriteOnly ) ) { 1345 if ( !f.open( IO_WriteOnly ) ) {
1322 qWarning("Unable to open vobject write %s", fname); 1346 qWarning("Unable to open vobject write %s", fname);
1323 return; 1347 return;
1324 } 1348 }
1325 1349
1326 while (list) { 1350 while (list) {
1327 writeVObject(f.directHandle(),list); 1351 writeVObject(f.directHandle(),list);
1328 list = nextVObjectInList(list); 1352 list = nextVObjectInList(list);
1329 } 1353 }
1330} 1354}
1331 1355
1332#ifndef __SHARP_COMP_
1333
1334// This function is not available in the Sharp ROM for SL 5500 !
1335// Therefore I have to move it into the header file.. (se)
1336
1337DLLEXPORT(const char *) vObjectTypeInfo(VObject *o) 1356DLLEXPORT(const char *) vObjectTypeInfo(VObject *o)
1338{ 1357{
1339 const char *type = vObjectName( o ); 1358 const char *type = vObjectName( o );
1340 if ( strcmp( type, "TYPE" ) == 0 ) 1359 if ( strcmp( type, "TYPE" ) == 0 )
1341 type = vObjectStringZValue( o ); 1360 type = vObjectStringZValue( o );
1342 return type; 1361 return type;
1343} 1362}
1344#endif 1363
1345 1364
1346// end of source file vobject.c 1365// end of source file vobject.c