From 2e536e4c246a7959df8f56a508bcc91c64480155 Mon Sep 17 00:00:00 2001 From: helge Date: Thu, 2 Nov 2006 09:12:06 +0000 Subject: [PATCH] added method to do RFC 2045 QP decoding git-svn-id: http://svn.opengroupware.org/SOPE/trunk@1370 e4a50df8-12e2-0310-a44c-efbce7f8a7e3 --- sope-core/NGExtensions/ChangeLog | 6 ++ .../NGExtensions/NGQuotedPrintableCoding.h | 32 +++++++---- .../NGExtensions/NGQuotedPrintableCoding.m | 57 +++++++++++++++---- sope-core/NGExtensions/Version | 2 +- 4 files changed, 74 insertions(+), 23 deletions(-) diff --git a/sope-core/NGExtensions/ChangeLog b/sope-core/NGExtensions/ChangeLog index 9518daa8..a47b29c8 100644 --- a/sope-core/NGExtensions/ChangeLog +++ b/sope-core/NGExtensions/ChangeLog @@ -1,3 +1,9 @@ +2006-11-02 Helge Hess + + * NGQuotedPrintableCoding.m: added NSData method to decode QP as per + RFC 2045: -dataByDecodingQuotedPrintableTransferEncoding, related to + OGo bug #1753 (v4.5.189) + 2006-07-24 Helge Hess * NGBundleManager.m: fixed a minor 64bit printing issue (v4.5.188) diff --git a/sope-core/NGExtensions/NGExtensions/NGQuotedPrintableCoding.h b/sope-core/NGExtensions/NGExtensions/NGQuotedPrintableCoding.h index 69982128..d7d5aac9 100644 --- a/sope-core/NGExtensions/NGExtensions/NGQuotedPrintableCoding.h +++ b/sope-core/NGExtensions/NGExtensions/NGQuotedPrintableCoding.h @@ -1,5 +1,6 @@ /* - Copyright (C) 2000-2005 SKYRIX Software AG + Copyright (C) 2000-2006 SKYRIX Software AG + Copyright (C) 2006 Helge Hess This file is part of SOPE. @@ -29,30 +30,27 @@ /* Quoted Printable encoder/decoder - As specified in RFC 822. + As specified in RFC 822 / 2045 / 2047. Note that 2045 and 2047 specify + different variants (Q vs content-transfer-encoding) TODO: explain what it does. It doesn't seem to decode a full line like "=?iso-8859-1?q?Yannick=20DAmboise?=" but only turns "=20D" style encodings to their charcode. + Note: apparently sope-mime contains a category on NSData which provides a method to decode the full value: -decodeQuotedPrintableValueOfMIMEHeaderField: (NGMimeMessageParser) */ -@interface NSString(QuotedPrintableCoding) - -- (NSString *)stringByDecodingQuotedPrintable; -- (NSString *)stringByEncodingQuotedPrintable; - -@end - @interface NSData(QuotedPrintableCoding) /* - Decode a quoted printable encoded data. Returns nil if decoding failed. + Decode a quoted printable encoded data. Returns nil if decoding failed. The + first method does the RFC 2047 variant, the second RFC 2045 (w/o _ replacing) */ - (NSData *)dataByDecodingQuotedPrintable; +- (NSData *)dataByDecodingQuotedPrintableTransferEncoding; /* Decode data in quoted printable encoding. Returns nil if encoding failed. @@ -61,11 +59,25 @@ @end + +/* Note: you should avoid NSString methods for QP, its defined on byte level */ +@interface NSString(QuotedPrintableCoding) + +- (NSString *)stringByDecodingQuotedPrintable; +- (NSString *)stringByEncodingQuotedPrintable; + +@end + + NGExtensions_EXPORT int NGEncodeQuotedPrintable(const char *_src, unsigned _srcLen, char *_dest, unsigned _destLen); NGExtensions_EXPORT int NGDecodeQuotedPrintable(const char *_src, unsigned _srcLen, char *_dest, unsigned _destLen); +NGExtensions_EXPORT int +NGDecodeQuotedPrintableX(const char *_src, unsigned _srcLen, + char *_dest, unsigned _destLen, + BOOL _replaceUnderline); #endif /* __NGExtensions_NGQuotedPrintableCoding_H__ */ diff --git a/sope-core/NGExtensions/NGQuotedPrintableCoding.m b/sope-core/NGExtensions/NGQuotedPrintableCoding.m index 22780df0..d1c2efb7 100644 --- a/sope-core/NGExtensions/NGQuotedPrintableCoding.m +++ b/sope-core/NGExtensions/NGQuotedPrintableCoding.m @@ -1,5 +1,6 @@ /* - Copyright (C) 2000-2005 SKYRIX Software AG + Copyright (C) 2000-2006 SKYRIX Software AG + Copyright (C) 2006 Helge Hess This file is part of SOPE. @@ -23,6 +24,7 @@ #include "common.h" #include "NGMemoryAllocation.h" + @implementation NSString(QuotedPrintableCoding) - (NSString *)stringByDecodingQuotedPrintable { @@ -34,14 +36,18 @@ buf = malloc(len + 10); [self getCString:buf]; data = [NSData dataWithBytes:buf length:len]; - if (buf) free(buf); + if (buf != NULL) free(buf); } else data = [NSData data]; data = [data dataByDecodingQuotedPrintable]; + + // TODO: should we default to some specific charset instead? (either + // Latin1 or UTF-8 return [NSString stringWithCString:[data bytes] length:[data length]]; } + - (NSString *)stringByEncodingQuotedPrintable { NSData *data; unsigned len; @@ -57,22 +63,40 @@ data = [NSData data]; data = [data dataByEncodingQuotedPrintable]; + return [NSString stringWithCString:[data bytes] length:[data length]]; } -@end +@end /* NSString(QuotedPrintableCoding) */ + @implementation NSData(QuotedPrintableCoding) - (NSData *)dataByDecodingQuotedPrintable { - char *dest = NULL; - size_t destSize = 0; - size_t resSize = 0; + char *dest; + size_t destSize; + size_t resSize; + + destSize = [self length]; + dest = malloc(destSize * sizeof(char) + 2); + + resSize = + NGDecodeQuotedPrintableX([self bytes], [self length], dest, destSize, YES); + + return ((int)resSize != -1) + ? [NSData dataWithBytesNoCopy:dest length:resSize] + : nil; +} +- (NSData *)dataByDecodingQuotedPrintableTransferEncoding { + char *dest; + size_t destSize; + size_t resSize; destSize = [self length]; - dest = NGMallocAtomic(destSize * sizeof(char)); + dest = malloc(destSize * sizeof(char) + 2); - resSize = NGDecodeQuotedPrintable([self bytes],[self length],dest,destSize); + resSize = + NGDecodeQuotedPrintableX([self bytes], [self length], dest, destSize, NO); return ((int)resSize != -1) ? [NSData dataWithBytesNoCopy:dest length:resSize] @@ -95,7 +119,8 @@ : nil; } -@end +@end /* NSData(QuotedPrintableCoding) */ + // implementation @@ -109,8 +134,9 @@ static inline signed char __hexToChar(char c) { return -1; } -int NGDecodeQuotedPrintable(const char *_src, unsigned _srcLen, - char *_dest, unsigned _destLen) +int NGDecodeQuotedPrintableX(const char *_src, unsigned _srcLen, + char *_dest, unsigned _destLen, + BOOL _replaceUnderline) { /* Eg: "Hello=20World" => "Hello World" @@ -126,7 +152,8 @@ int NGDecodeQuotedPrintable(const char *_src, unsigned _srcLen, for (cnt = 0; ((cnt < _srcLen) && (destCnt < _destLen)); cnt++) { if (_src[cnt] != '=') { - _dest[destCnt] = _src[cnt] == '_' ? 0x20 : _src[cnt]; + _dest[destCnt] = + (_replaceUnderline && _src[cnt] == '_') ? 0x20 : _src[cnt]; destCnt++; } else { @@ -168,6 +195,12 @@ int NGDecodeQuotedPrintable(const char *_src, unsigned _srcLen, return -1; return destCnt; } +int NGDecodeQuotedPrintable(const char *_src, unsigned _srcLen, + char *_dest, unsigned _destLen) +{ + // should we deprecated that? + return NGDecodeQuotedPrintableX(_src, _srcLen, _dest, _destLen, YES); +} /* From RFC 2045 Multipurpose Internet Mail Extensions diff --git a/sope-core/NGExtensions/Version b/sope-core/NGExtensions/Version index d8e69c4d..c55de3fb 100644 --- a/sope-core/NGExtensions/Version +++ b/sope-core/NGExtensions/Version @@ -1,6 +1,6 @@ # version -SUBMINOR_VERSION:=188 +SUBMINOR_VERSION:=189 # v4.3.115 requires libFoundation v1.0.59 # v4.2.72 requires libEOControl v4.2.39 -- 2.39.5