00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifdef HAVE_CONFIG_H
00033 #include <config.h>
00034 #endif
00035
00036 #include "bodypartformatter.h"
00037
00038 #include "objecttreeparser.h"
00039 #include "partNode.h"
00040
00041 #include <mimelib/enum.h>
00042 #include <mimelib/string.h>
00043 #include <mimelib/utility.h>
00044
00045 namespace {
00046 class AnyTypeBodyPartFormatter : public KMail::BodyPartFormatter {
00047 static const AnyTypeBodyPartFormatter * self;
00048 public:
00049 bool process( KMail::ObjectTreeParser *, partNode *, KMail::ProcessResult & result ) const {
00050 result.setNeverDisplayInline( true );
00051 return false;
00052 }
00053 static const KMail::BodyPartFormatter * create() {
00054 if ( !self )
00055 self = new AnyTypeBodyPartFormatter();
00056 return self;
00057 }
00058 };
00059
00060 const AnyTypeBodyPartFormatter * AnyTypeBodyPartFormatter::self = 0;
00061
00062
00063 class ImageTypeBodyPartFormatter : public KMail::BodyPartFormatter {
00064 static const ImageTypeBodyPartFormatter * self;
00065 public:
00066 bool process( KMail::ObjectTreeParser *, partNode *, KMail::ProcessResult & result ) const {
00067 result.setIsImage( true );
00068 return false;
00069 }
00070 static const KMail::BodyPartFormatter * create() {
00071 if ( !self )
00072 self = new ImageTypeBodyPartFormatter();
00073 return self;
00074 }
00075 };
00076
00077 const ImageTypeBodyPartFormatter * ImageTypeBodyPartFormatter::self = 0;
00078
00079 #define CREATE_BODY_PART_FORMATTER(subtype) \
00080 class subtype##BodyPartFormatter : public KMail::BodyPartFormatter { \
00081 static const subtype##BodyPartFormatter * self; \
00082 public: \
00083 bool process( KMail::ObjectTreeParser *, partNode *, KMail::ProcessResult & ) const; \
00084 static const KMail::BodyPartFormatter * create() { \
00085 if ( !self ) \
00086 self = new subtype##BodyPartFormatter(); \
00087 return self; \
00088 } \
00089 }; \
00090 \
00091 const subtype##BodyPartFormatter * subtype##BodyPartFormatter::self; \
00092 \
00093 bool subtype##BodyPartFormatter::process( KMail::ObjectTreeParser * otp, partNode * node, KMail::ProcessResult & result ) const { \
00094 return otp->process##subtype##Subtype( node, result ); \
00095 }
00096
00097 CREATE_BODY_PART_FORMATTER(TextPlain)
00098 CREATE_BODY_PART_FORMATTER(TextHtml)
00099 CREATE_BODY_PART_FORMATTER(TextVCal)
00100
00101
00102 CREATE_BODY_PART_FORMATTER(ApplicationOctetStream)
00103 CREATE_BODY_PART_FORMATTER(ApplicationPkcs7Mime)
00104 CREATE_BODY_PART_FORMATTER(ApplicationMsTnef)
00105
00106
00107 CREATE_BODY_PART_FORMATTER(MessageRfc822)
00108
00109 CREATE_BODY_PART_FORMATTER(MultiPartMixed)
00110 CREATE_BODY_PART_FORMATTER(MultiPartAlternative)
00111 CREATE_BODY_PART_FORMATTER(MultiPartSigned)
00112 CREATE_BODY_PART_FORMATTER(MultiPartEncrypted)
00113
00114 typedef TextPlainBodyPartFormatter ApplicationPgpBodyPartFormatter;
00115
00116
00117 #undef CREATE_BODY_PART_FORMATTER
00118 }
00119
00120 typedef const KMail::BodyPartFormatter * (*BodyPartFormatterCreator)();
00121
00122 struct SubtypeBuiltin {
00123 const char * subtype;
00124 BodyPartFormatterCreator create;
00125 };
00126
00127 static const SubtypeBuiltin applicationSubtypeBuiltins[] = {
00128 { "octet-stream", &ApplicationOctetStreamBodyPartFormatter::create },
00129 { "pkcs7-mime", &ApplicationPkcs7MimeBodyPartFormatter::create },
00130 { "x-pkcs7-mime", &ApplicationPkcs7MimeBodyPartFormatter::create },
00131 { "ms-tnef", &ApplicationMsTnefBodyPartFormatter::create },
00132 { "pgp", &ApplicationPgpBodyPartFormatter::create },
00133 };
00134
00135 static const SubtypeBuiltin textSubtypeBuiltins[] = {
00136 { "html", &TextHtmlBodyPartFormatter::create },
00137
00138 { "calendar", &TextVCalBodyPartFormatter::create },
00139 { "x-vcard", &AnyTypeBodyPartFormatter::create },
00140 { "vcard", &AnyTypeBodyPartFormatter::create },
00141 { "rtf", &AnyTypeBodyPartFormatter::create },
00142 { "*", &TextPlainBodyPartFormatter::create },
00143 };
00144
00145 static const SubtypeBuiltin multipartSubtypeBuiltins[] = {
00146 { "mixed", &MultiPartMixedBodyPartFormatter::create },
00147 { "alternative", &MultiPartAlternativeBodyPartFormatter::create },
00148
00149
00150
00151 { "signed", &MultiPartSignedBodyPartFormatter::create },
00152 { "encrypted", &MultiPartEncryptedBodyPartFormatter::create },
00153
00154 };
00155
00156 static const SubtypeBuiltin messageSubtypeBuiltins[] = {
00157 { "rfc822", &MessageRfc822BodyPartFormatter::create },
00158 };
00159
00160 static const SubtypeBuiltin imageSubtypeBuiltins[] = {
00161 { "*", &ImageTypeBodyPartFormatter::create },
00162 };
00163
00164 static const SubtypeBuiltin anySubtypeBuiltins[] = {
00165 { "*", &AnyTypeBodyPartFormatter::create },
00166 };
00167
00168 #ifdef DIM
00169 #undef DIM
00170 #endif
00171 #define DIM(x) sizeof(x) / sizeof(*x)
00172
00173 static const struct {
00174 const char * type;
00175 const SubtypeBuiltin * subtypes;
00176 unsigned int num_subtypes;
00177 } builtins[] = {
00178 { "application", applicationSubtypeBuiltins, DIM(applicationSubtypeBuiltins) },
00179 { "text", textSubtypeBuiltins, DIM(textSubtypeBuiltins) },
00180 { "multipart", multipartSubtypeBuiltins, DIM(multipartSubtypeBuiltins) },
00181 { "message", messageSubtypeBuiltins, DIM(messageSubtypeBuiltins) },
00182 { "image", imageSubtypeBuiltins, DIM(imageSubtypeBuiltins) },
00183
00184
00185
00186 { "*", anySubtypeBuiltins, DIM(anySubtypeBuiltins) },
00187 };
00188
00189 #undef DIM
00190
00191 const KMail::BodyPartFormatter * KMail::BodyPartFormatter::createFor( int type, int subtype ) {
00192 DwString t, st;
00193 DwTypeEnumToStr( type, t );
00194 DwSubtypeEnumToStr( subtype, st );
00195 return createFor( t.c_str(), st.c_str() );
00196 }
00197
00198 static const KMail::BodyPartFormatter * createForText( const char * subtype ) {
00199 if ( subtype && *subtype )
00200 switch ( subtype[0] ) {
00201 case 'h':
00202 case 'H':
00203 if ( qstricmp( subtype, "html" ) == 0 )
00204 return TextHtmlBodyPartFormatter::create();
00205 break;
00206 case 'c':
00207 case 'C':
00208 if ( qstricmp( subtype, "calendar" ) == 0 )
00209 return TextVCalBodyPartFormatter::create();
00210 break;
00211 case 'r':
00212 case 'R':
00213 if ( qstricmp( subtype, "rtf" ) == 0 )
00214 return AnyTypeBodyPartFormatter::create();
00215 break;
00216 case 'x':
00217 case 'X':
00218 case 'v':
00219 case 'V':
00220 if ( qstricmp( subtype, "x-vcard" ) == 0 ||
00221 qstricmp( subtype, "vcard" ) == 0 )
00222 return AnyTypeBodyPartFormatter::create();
00223 break;
00224 }
00225
00226 return TextPlainBodyPartFormatter::create();
00227 }
00228
00229 static const KMail::BodyPartFormatter * createForImage( const char * ) {
00230 return ImageTypeBodyPartFormatter::create();
00231 }
00232
00233 static const KMail::BodyPartFormatter * createForMessage( const char * subtype ) {
00234 if ( qstricmp( subtype, "rfc822" ) == 0 )
00235 return MessageRfc822BodyPartFormatter::create();
00236 return AnyTypeBodyPartFormatter::create();
00237 }
00238
00239 static const KMail::BodyPartFormatter * createForMultiPart( const char * subtype ) {
00240 if ( subtype && *subtype )
00241 switch ( subtype[0] ) {
00242 case 'a':
00243 case 'A':
00244 if ( qstricmp( subtype, "alternative" ) == 0 )
00245 return MultiPartAlternativeBodyPartFormatter::create();
00246 break;
00247 case 'e':
00248 case 'E':
00249 if ( qstricmp( subtype, "encrypted" ) == 0 )
00250 return MultiPartEncryptedBodyPartFormatter::create();
00251 break;
00252 case 's':
00253 case 'S':
00254 if ( qstricmp( subtype, "signed" ) == 0 )
00255 return MultiPartSignedBodyPartFormatter::create();
00256 break;
00257 }
00258
00259 return MultiPartMixedBodyPartFormatter::create();
00260 }
00261
00262 static const KMail::BodyPartFormatter * createForApplication( const char * subtype ) {
00263 if ( subtype && *subtype )
00264 switch ( subtype[0] ) {
00265 case 'p':
00266 case 'P':
00267 if ( qstricmp( subtype, "pgp" ) == 0 )
00268 return ApplicationPgpBodyPartFormatter::create();
00269
00270 case 'x':
00271 case 'X':
00272 if ( qstricmp( subtype, "pkcs7-mime" ) == 0 ||
00273 qstricmp( subtype, "x-pkcs7-mime" ) == 0 )
00274 return ApplicationPkcs7MimeBodyPartFormatter::create();
00275 break;
00276 case 'm':
00277 case 'M':
00278 if ( qstricmp( subtype, "ms-tnef" ) == 0 )
00279 return ApplicationMsTnefBodyPartFormatter::create();
00280 break;
00281 }
00282
00283 return AnyTypeBodyPartFormatter::create();
00284 }
00285
00286
00287 const KMail::BodyPartFormatter * KMail::BodyPartFormatter::createFor( const char * type, const char * subtype ) {
00288 if ( type && *type )
00289 switch ( type[0] ) {
00290 case 'a':
00291 case 'A':
00292 if ( qstricmp( type, "application" ) == 0 )
00293 return createForApplication( subtype );
00294 break;
00295 case 'i':
00296 case 'I':
00297 if ( qstricmp( type, "image" ) == 0 )
00298 return createForImage( subtype );
00299 break;
00300 case 'm':
00301 case 'M':
00302 if ( qstricmp( type, "multipart" ) == 0 )
00303 return createForMultiPart( subtype );
00304 else if ( qstricmp( type, "message" ) == 0 )
00305 return createForMessage( subtype );
00306 break;
00307 case 't':
00308 case 'T':
00309 if ( qstricmp( type, "text" ) == 0 )
00310 return createForText( subtype );
00311 break;
00312 }
00313
00314 return AnyTypeBodyPartFormatter::create();
00315 }
00316