]> err.no Git - sope/blob - sope-mime/NGMime/NGMimeContentTypeHeaderFieldGenerator.m
added reply-to parameter support for text mime types
[sope] / sope-mime / NGMime / NGMimeContentTypeHeaderFieldGenerator.m
1 /*
2   Copyright (C) 2000-2004 SKYRIX Software AG
3
4   This file is part of OpenGroupware.org.
5
6   OGo is free software; you can redistribute it and/or modify it under
7   the terms of the GNU Lesser General Public License as published by the
8   Free Software Foundation; either version 2, or (at your option) any
9   later version.
10
11   OGo is distributed in the hope that it will be useful, but WITHOUT ANY
12   WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14   License for more details.
15
16   You should have received a copy of the GNU Lesser General Public
17   License along with OGo; see the file COPYING.  If not, write to the
18   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19   02111-1307, USA.
20 */
21 // $Id: NGMimeContentTypeHeaderFieldGenerator.m 1 2004-08-20 10:08:27Z znek $
22
23 #include "NGMimeHeaderFieldGenerator.h"
24 #include "NGMimeHeaderFields.h"
25 #include "common.h"
26
27 @implementation NGMimeContentTypeHeaderFieldGenerator
28
29 + (int)version {
30   return 2;
31 }
32
33 - (NSData *)generateDataForHeaderFieldNamed:(NSString *)_headerField
34   value:(id)_value
35 {
36   NGMimeType    *type = nil; // only one content-type field
37   NSString      *tmp  = nil;
38   NSMutableData *data = nil;
39   unsigned char *ctmp = NULL;
40   unsigned      len   = 0;
41   
42   type = _value;
43
44   if (type == nil) {
45     NSLog(@"WARNING(%s): empty content type field", __PRETTY_FUNCTION__);
46     return [NSData dataWithBytes:"application/octet" length:17];
47   }
48   if ([_value isKindOfClass:[NSString class]]) {
49     return [_value dataUsingEncoding:NSUTF8StringEncoding];
50   }
51   
52   if (![type isKindOfClass:[NGMimeType class]]) {
53     NSLog(@"WARNING(%s): invalid MIME type value (%@) !", __PRETTY_FUNCTION__,
54           type);
55     return [NSData dataWithBytes:"application/octet" length:17];
56   }
57   
58   data = [NSMutableData dataWithCapacity:64];
59   
60   tmp = [type type];
61   NSAssert(tmp, @"type should not be nil");
62   len  = [tmp length];
63   ctmp = malloc(len + 1);
64   [tmp getCString:ctmp]; ctmp[len] = '\0';
65   [data appendBytes:ctmp length:len];
66   free(ctmp);
67   
68   [data appendBytes:"//" length:1];
69   
70   tmp = [type subType];
71   if (tmp != nil) {
72     len  = [tmp length];
73     ctmp = malloc(len + 1);
74     [tmp getCString:ctmp]; ctmp[len] = '\0';
75     [data appendBytes:ctmp length:len];
76     free(ctmp);
77   }
78   else
79     [data appendBytes:"*" length:1];
80
81   {  // parameters
82     NSEnumerator *enumerator = [type parameterNames];
83     NSString     *name       = nil;
84     NSString     *value      = nil;
85     
86     while ((name = [enumerator nextObject])) {
87       value = [type valueOfParameter:name];
88       if (![value isKindOfClass:[NSString class]]) {
89         NSLog(@"ERROR[%s]: parameter should be a NSString headerField: %@ "
90               @"value %@", __PRETTY_FUNCTION__, _headerField, _value);
91         continue;
92       }
93       [data appendBytes:"; " length:2];
94       
95       len  = [name cStringLength];
96       ctmp = malloc(len + 1);
97       [name getCString:ctmp]; ctmp[len] = '\0';
98       [data appendBytes:ctmp length:len];
99       free(ctmp);
100
101       /*
102         this confuses GroupWise: "= \"" (a space)
103       */
104       [data appendBytes:"=\"" length:2];
105
106       /* check for encoding */
107       {
108         unsigned cnt;
109         BOOL doEnc;
110         
111         len  = [value cStringLength];
112         ctmp = malloc(len + 1);
113         [value getCString:ctmp]; ctmp[len] = '\0';
114         cnt  = 0;
115         doEnc = NO;
116         while (cnt < len) {
117           if ((unsigned char)ctmp[cnt] > 127) {
118             doEnc = YES;
119             break;
120           }
121           cnt++;
122         }
123         if (doEnc) {
124           unsigned char iso[]     = "=?iso-8859-15?q?";
125           unsigned      isoLen    = 16;
126           unsigned char isoEnd[]  = "?=";
127           unsigned      isoEndLen = 2;
128           unsigned      desLen;
129           unsigned char *des;
130           
131           if (ctmp) free(ctmp);
132           {
133             NSData *data;
134
135 #if APPLE_Foundation_LIBRARY || NeXT_Foundation_LIBRARY
136             data = [value dataUsingEncoding:NSISOLatin1StringEncoding];
137 #else
138             data = [value dataUsingEncoding:NSISOLatin9StringEncoding];
139 #endif
140
141             len  = [data length];
142             ctmp =  malloc(len + 10);
143             [data getBytes:ctmp];  ctmp[len] = '\0';
144           }
145           
146           desLen = len * 3 + 20;
147           des    = calloc(desLen + 10, sizeof(char));
148       
149           memcpy(des, ctmp, cnt);
150           memcpy(des + cnt, iso, isoLen);
151           desLen =
152                NGEncodeQuotedPrintableMime(ctmp + cnt, len - cnt,
153                                            des + cnt + isoLen,
154                                            desLen - cnt - isoLen);
155           if ((int)desLen != -1) {
156             memcpy(des + cnt + isoLen + desLen, isoEnd, isoEndLen);
157             [data appendBytes:des length:(cnt + isoLen + desLen + isoEndLen)];
158           }
159           else {
160             NSLog(@"WARNING: An error occour during quoted-printable decoding");
161           }
162           if (des) free(des);
163         }
164         else {
165           [data appendBytes:ctmp length:len];
166         }
167           free(ctmp);
168       }
169       [data appendBytes:"\"" length:1];      
170     }
171   }
172   return data;
173 }
174
175 @end /* NGMimeContentTypeHeaderFieldGenerator */