-rw-r--r-- | library/backend/vobject.cpp | 26 |
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 @@ -840,446 +840,472 @@ DLLEXPORT(const char*) lookupProp(const char* str) /*---------------------------------------------------------------------- APIs to Output text form. ----------------------------------------------------------------------*/ #define OFILE_REALLOC_SIZE 256 typedef struct OFile { FILE *fp; char *s; int len; int limit; int alloc:1; int fail:1; } OFile; #if 0 static void appendsOFile(OFile *fp, const char *s) { int slen; if (fp->fail) return; slen = strlen(s); if (fp->fp) { fwrite(s,1,slen,fp->fp); } else { stuff: if (fp->len + slen < fp->limit) { memcpy(fp->s+fp->len,s,slen); fp->len += slen; return; } else if (fp->alloc) { fp->limit = fp->limit + OFILE_REALLOC_SIZE; if (OFILE_REALLOC_SIZE <= slen) fp->limit += slen; fp->s = (char *) realloc(fp->s,fp->limit); if (fp->s) goto stuff; } if (fp->alloc) free(fp->s); fp->s = 0; fp->fail = 1; } } static void appendcOFile(OFile *fp, char c) { if (fp->fail) return; if (fp->fp) { fputc(c,fp->fp); } else { stuff: if (fp->len+1 < fp->limit) { fp->s[fp->len] = c; fp->len++; return; } else if (fp->alloc) { fp->limit = fp->limit + OFILE_REALLOC_SIZE; fp->s = (char *) realloc(fp->s,fp->limit); if (fp->s) goto stuff; } if (fp->alloc) free(fp->s); fp->s = 0; fp->fail = 1; } } #else static void appendcOFile_(OFile *fp, char c) { if (fp->fail) return; if (fp->fp) { fputc(c,fp->fp); } else { stuff: if (fp->len+1 < fp->limit) { fp->s[fp->len] = c; fp->len++; return; } else if (fp->alloc) { fp->limit = fp->limit + OFILE_REALLOC_SIZE; fp->s = (char *)realloc(fp->s,fp->limit); if (fp->s) goto stuff; } if (fp->alloc) free(fp->s); fp->s = 0; fp->fail = 1; } } 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 appendsOFile(fp,NAME_OF(o)); if (pi) fields_ = pi->fields; initPropIterator(&t,o); while (moreIteration(&t)) { const char *s; VObject *eachProp = nextVObject(&t); s = NAME_OF(eachProp); if (qstricmp(VCGroupingProp,s) && !inList(fields_,s)) writeAttrValue(fp,eachProp); } if (fields_) { int i = 0, n = 0; const char** fields = fields_; /* output prop as fields */ bool printable = TRUE; while (*fields && printable) { VObject *t = isAPropertyOf(o,*fields); if (includesUnprintable(t)) printable = FALSE; fields++; } fields = fields_; if (!printable) { appendsOFile(fp, ";" VCEncodingProp "=" VCQuotedPrintableProp); appendsOFile(fp, ";" VCCharSetProp "=" "UTF-8"); } appendcOFile(fp,':'); while (*fields) { VObject *t = isAPropertyOf(o,*fields); i++; if (t) n = i; fields++; } fields = fields_; for (i=0;i<n;i++) { writeValue(fp,isAPropertyOf(o,*fields),0); fields++; if (i<(n-1)) appendcOFile(fp,';'); } } } if (VALUE_TYPE(o)) { if ( includesUnprintable(o) ) { appendsOFile(fp, ";" VCEncodingProp "=" VCQuotedPrintableProp); appendsOFile(fp, ";" VCCharSetProp "=" "UTF-8"); } unsigned long size = 0; VObject *p = isAPropertyOf(o,VCDataSizeProp); if (p) size = LONG_VALUE_OF(p); appendcOFile(fp,':'); writeValue(fp,o,size); } appendcOFile(fp,'\n'); } static void writeVObject_(OFile *fp, VObject *o) { if (NAME_OF(o)) { struct PreDefProp *pi; pi = lookupPropInfo(NAME_OF(o)); if (pi && ((pi->flags & PD_BEGIN) != 0)) { VObjectIterator t; const char *begin = NAME_OF(o); appendsOFile(fp,"BEGIN:"); appendsOFile(fp,begin); appendcOFile(fp,'\n'); initPropIterator(&t,o); while (moreIteration(&t)) { VObject *eachProp = nextVObject(&t); writeProp(fp, eachProp); } appendsOFile(fp,"END:"); appendsOFile(fp,begin); appendsOFile(fp,"\n\n"); } } } void writeVObject(FILE *fp, VObject *o) { OFile ofp; // ##### //_setmode(_fileno(fp), _O_BINARY); initOFile(&ofp,fp); writeVObject_(&ofp,o); } DLLEXPORT(void) writeVObjectToFile(char *fname, VObject *o) { QFileDirect f( fname); if ( !f.open( IO_WriteOnly ) ) { qWarning("Unable to open vobject write %s", fname); |