summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--library/backend/vobject.cpp26
1 files changed, 26 insertions, 0 deletions
diff --git a/library/backend/vobject.cpp b/library/backend/vobject.cpp
index 2f22c20..2c5b577 100644
--- a/library/backend/vobject.cpp
+++ b/library/backend/vobject.cpp
@@ -936,254 +936,280 @@ static void appendcOFile(OFile *fp, char c)
if (c == '\n') {
/* write out as <CR><LF> */
appendcOFile_(fp,0xd);
appendcOFile_(fp,0xa);
}
else
appendcOFile_(fp,c);
}
static void appendsOFile(OFile *fp, const char *s)
{
int i, slen;
slen = strlen(s);
for (i=0; i<slen; i++) {
appendcOFile(fp,s[i]);
}
}
#endif
static void initOFile(OFile *fp, FILE *ofp)
{
fp->fp = ofp;
fp->s = 0;
fp->len = 0;
fp->limit = 0;
fp->alloc = 0;
fp->fail = 0;
}
static int writeBase64(OFile *fp, unsigned char *s, long len)
{
long cur = 0;
int i, numQuads = 0;
unsigned long trip;
unsigned char b;
char quad[5];
#define MAXQUADS 16
quad[4] = 0;
while (cur < len) {
// collect the triplet of bytes into 'trip'
trip = 0;
for (i = 0; i < 3; i++) {
b = (cur < len) ? *(s + cur) : 0;
cur++;
trip = trip << 8 | b;
}
// fill in 'quad' with the appropriate four characters
for (i = 3; i >= 0; i--) {
b = (unsigned char)(trip & 0x3F);
trip = trip >> 6;
if ((3 - i) < (cur - len))
quad[i] = '='; // pad char
else if (b < 26) quad[i] = (char)b + 'A';
else if (b < 52) quad[i] = (char)(b - 26) + 'a';
else if (b < 62) quad[i] = (char)(b - 52) + '0';
else if (b == 62) quad[i] = '+';
else quad[i] = '/';
}
// now output 'quad' with appropriate whitespace and line ending
appendsOFile(fp, (numQuads == 0 ? " " : ""));
appendsOFile(fp, quad);
appendsOFile(fp, ((cur >= len)?"\n" :(numQuads==MAXQUADS-1?"\n" : "")));
numQuads = (numQuads + 1) % MAXQUADS;
}
appendcOFile(fp,'\n');
return 1;
}
static const char *replaceChar(unsigned char c)
{
if (c == '\n') {
return "=0A=\n";
} else if (
(c >= 'A' && c <= 'Z')
||
(c >= 'a' && c <= 'z')
||
(c >= '0' && c <= '9')
||
(c >= '\'' && c <= ')')
||
(c >= '+' && c <= '-')
||
(c == '/')
||
(c == '?')
||
(c == ' '))
{
return 0;
}
+#warning "Bug-Workaround must be fixed !"
+ // IF THIS FUNCTION RETURNES TRUE, THE DATA IS EXPORTED
+ // AS QUOTED PRINTABLE.
+ // BUT THE PARSER IS UNABLE TO IMPORT THIS, THEREFORE
+ // I DECIDED TO DISABLE IT UNTIL TROLLTECH FIXES THIS BUG
+ // SEE ALSO includesUnprintable(VObject *o)
+ // (se)
+
+ return 0;
+
+#if 0
static char trans[4];
trans[0] = '=';
trans[3] = '\0';
int rem = c % 16;
int div = c / 16;
if (div < 10)
trans[1] = '0' + div;
else
trans[1] = 'A' + (div - 10);
if (rem < 10)
trans[2] = '0' + rem;
else
trans[2] = 'A' + (rem - 10);
return trans;
+#endif
}
static void writeQPString(OFile *fp, const char *s)
{
/*
only A-Z, 0-9 and
"'" (ASCII code 39)
"(" (ASCII code 40)
")" (ASCII code 41)
"+" (ASCII code 43)
"," (ASCII code 44)
"-" (ASCII code 45)
"/" (ASCII code 47)
"?" (ASCII code 63)
should remain un-encoded.
'=' needs to be encoded as it is the escape character.
';' needs to be as it is a field separator.
*/
const char *p = s;
while (*p) {
const char *rep = replaceChar(*p);
if (rep)
appendsOFile(fp, rep);
else
appendcOFile(fp, *p);
p++;
}
}
static bool includesUnprintable(VObject *o)
{
+
+#if 0
+
+ // IF THIS FUNCTION RETURNES TRUE, THE DATA IS EXPORTED
+ // AS QUOTED PRINTABLE.
+ // BUT THE PARSER IS UNABLE TO IMPORT THIS, THEREFORE
+ // I DECIDED TO DISABLE IT UNTIL TROLLTECH FIXES THIS BUG
+ // SEE ALSO *replaceChar(unsigned char c)
+ // (se)
+
if (o) {
if (VALUE_TYPE(o) == VCVT_STRINGZ) {
const char *p = STRINGZ_VALUE_OF(o);
if (p) {
while (*p) {
if (replaceChar(*p))
return TRUE;
p++;
}
}
}
}
+
+#endif
+#warning "Bug-Workaround must be fixed !"
+
return FALSE;
}
static void writeVObject_(OFile *fp, VObject *o);
static void writeValue(OFile *fp, VObject *o, unsigned long size)
{
if (o == 0) return;
switch (VALUE_TYPE(o)) {
case VCVT_STRINGZ: {
writeQPString(fp, STRINGZ_VALUE_OF(o));
break;
}
case VCVT_UINT: {
char buf[16];
sprintf(buf,"%u", INTEGER_VALUE_OF(o));
appendsOFile(fp,buf);
break;
}
case VCVT_ULONG: {
char buf[16];
sprintf(buf,"%lu", LONG_VALUE_OF(o));
appendsOFile(fp,buf);
break;
}
case VCVT_RAW: {
appendcOFile(fp,'\n');
writeBase64(fp,(unsigned char*)(ANY_VALUE_OF(o)),size);
break;
}
case VCVT_VOBJECT:
appendcOFile(fp,'\n');
writeVObject_(fp,VOBJECT_VALUE_OF(o));
break;
}
}
static void writeAttrValue(OFile *fp, VObject *o)
{
if (NAME_OF(o)) {
struct PreDefProp *pi;
pi = lookupPropInfo(NAME_OF(o));
if (pi && ((pi->flags & PD_INTERNAL) != 0)) return;
if ( includesUnprintable(o) ) {
appendsOFile(fp, ";" VCEncodingProp "=" VCQuotedPrintableProp);
appendsOFile(fp, ";" VCCharSetProp "=" "UTF-8");
}
appendcOFile(fp,';');
appendsOFile(fp,NAME_OF(o));
}
else
appendcOFile(fp,';');
if (VALUE_TYPE(o)) {
appendcOFile(fp,'=');
writeValue(fp,o,0);
}
}
static void writeGroup(OFile *fp, VObject *o)
{
char buf1[256];
char buf2[256];
strcpy(buf1,NAME_OF(o));
while ((o=isAPropertyOf(o,VCGroupingProp)) != 0) {
strcpy(buf2,STRINGZ_VALUE_OF(o));
strcat(buf2,".");
strcat(buf2,buf1);
strcpy(buf1,buf2);
}
appendsOFile(fp,buf1);
}
static int inList(const char **list, const char *s)
{
if (list == 0) return 0;
while (*list) {
if (qstricmp(*list,s) == 0) return 1;
list++;
}
return 0;
}
static void writeProp(OFile *fp, VObject *o)
{
if (NAME_OF(o)) {
struct PreDefProp *pi;
VObjectIterator t;
const char **fields_ = 0;
pi = lookupPropInfo(NAME_OF(o));
if (pi && ((pi->flags & PD_BEGIN) != 0)) {
writeVObject_(fp,o);
return;
}
if (isAPropertyOf(o,VCGroupingProp))
writeGroup(fp,o);
else