]> err.no Git - sope/blob - sope-mime/NGImap4/NGImap4Message+BodyStructure.h
minor code cleanups
[sope] / sope-mime / NGImap4 / NGImap4Message+BodyStructure.h
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
22 #ifndef __NGImap4Message_BodyStructure_H__
23 #define __NGImap4Message_BodyStructure_H__
24
25 @interface NSCalendarDate(RFC822Dates)
26 + (NSCalendarDate *)calendarDateWithRfc822DateString:(NSString *)_str;
27 @end /* NSString(RFC822Dates) */
28
29 @interface NGImap4Message(BodyStructure)
30
31 static id _buildMultipartMessage(id self, NSURL *_baseUrl, NSDictionary *_dict,
32                                  id<NGMimePart>_part);
33 static id _buildMessage(id self, NSURL *_baseUrl, NSDictionary *_dict);
34 static id _buildPart(id self, NSURL *_baseUrl, NSDictionary *_dict);
35 static id _buildMimeBodyPart(id self, NSDictionary *_dict);
36 static id _buildMimeMessageBody(id self, NSURL *_baseUrl, NSDictionary *_dict,
37                                 id<NGMimePart>_part);
38 @end  /* NGImap4Message(BodyStructure) */
39
40 @implementation NGImap4Message(BodyStructure)
41        
42 static id _buildMultipartMessage(id self, NSURL *_baseUrl, NSDictionary *_dict,
43                                  id<NGMimePart>_part) {
44   NGMimeMultipartBody *body;
45   NSEnumerator        *enumerator;
46   NSDictionary        *part;
47   int                 cnt;
48   
49   body = [[NGMimeMultipartBody alloc] initWithPart:_part];
50   enumerator = [[_dict objectForKey:@"parts"] objectEnumerator];
51
52   cnt = 1;
53   while ((part = [enumerator nextObject])) {
54     NSURL *url;
55
56     {
57       NSString *baseStr;
58
59       baseStr = [_baseUrl absoluteString];
60
61       if ([baseStr hasSuffix:@"="])
62         url = [NSURL URLWithString:[NSString stringWithFormat:@"%@%d",
63                                              baseStr, cnt]];
64       else
65         url = [NSURL URLWithString:[NSString stringWithFormat:@"%@.%d",
66                                              baseStr, cnt]];
67     }
68     [body addBodyPart:_buildPart(self, url, part)];
69     cnt++;
70   }
71   return [body autorelease];
72 }
73
74 static id _buildMessage(id self, NSURL *_baseUrl, NSDictionary *_dict) {
75   NGMutableHashMap *map;
76   NGMimeMessage    *message;
77   NSString         *value;
78
79   static NGMimeHeaderNames *Fields = NULL;
80
81   if (!Fields)
82     Fields = (NGMimeHeaderNames *)[NGMimePartParser headerFieldNames];
83   
84
85   map = [NGMutableHashMap hashMapWithCapacity:4];
86
87   if ((value = [_dict objectForKey:@"subject"])) {
88     [map setObject:value forKey:Fields->subject];
89   }
90   if ((value = [_dict objectForKey:@"messageId"])) {
91     [map setObject:value forKey:Fields->messageID];
92   }
93   if ((value = [_dict objectForKey:@"in-reply-to"])) {
94     [map setObject:value forKey:@"in-reply-to"];
95   }
96   if ((value = [_dict objectForKey:Fields->contentLength])) {
97     [map setObject:value forKey:Fields->contentLength];
98   }
99   if ((value = [_dict objectForKey:@"date"])) {
100     NSCalendarDate *d;
101
102     if ((d = [NSCalendarDate calendarDateWithRfc822DateString:value])) 
103       [map setObject:d forKey:Fields->date];
104   }
105   {
106     NSEnumerator   *enumerator;
107     id             obj;
108     static NSArray *Array = nil;
109
110     if (Array == nil) {
111       Array = [[NSArray alloc] initWithObjects:
112                                Fields->from,
113                                @"sender",
114                                Fields->replyTo,
115                                Fields->to,
116                                Fields->cc,
117                                @"bcc", nil];
118     }
119     enumerator = [Array objectEnumerator];
120     while ((obj = [enumerator nextObject])) {
121       NSArray *addrs;
122
123       if ((addrs = [_dict objectForKey:obj])) {
124         NSEnumerator *addrEnum;
125         NSDictionary *addr;
126         NSMutableString *str;
127
128         addrEnum = [addrs objectEnumerator];
129         str      = nil;
130         while ((addr = [addrEnum nextObject])) {
131           NSString *personalName, *mailboxName, *hostName;
132           if (!str) {
133             str = [NSMutableString stringWithCapacity:32];
134           }
135           else {
136             [str appendString:@", "];
137           }
138           personalName = [addr objectForKey:@"personalName"];
139           mailboxName  = [addr objectForKey:@"mailboxName"];
140           hostName     = [addr objectForKey:@"hostName"];
141
142           if ([personalName length]) {
143             [str appendFormat:@"\"%@\" <%@@%@>", personalName,
144                  mailboxName, hostName];
145           }
146           else {
147             [str appendFormat:@"%@@%@", mailboxName, hostName];
148           }
149         }
150         if (str)
151           [map setObject:str forKey:obj];
152       }
153     }
154   }
155   {
156     id part, tmp, body;
157
158     part = _buildPart(self, _baseUrl, [_dict objectForKey:@"body"]);
159
160     [map setObject:[part contentType] forKey:Fields->contentType];
161
162     if (![[map valueForKey:Fields->contentTransferEncoding] length]) {
163       if ((tmp = [[part valuesOfHeaderFieldWithName:
164                         Fields->contentTransferEncoding] nextObject])) {
165         [map setObject:tmp forKey:Fields->contentTransferEncoding];
166       }
167     }
168     if (![[map valueForKey:Fields->contentLength] intValue]) {
169       if ((tmp = [[part valuesOfHeaderFieldWithName:Fields->contentLength]
170                   nextObject])) {
171         [map setObject:tmp forKey:Fields->contentLength];
172       }
173     }
174     message = [NGMimeMessage messageWithHeader:map];
175
176     if ([(body = [part body]) isKindOfClass:[NSURL class]]) {
177       NSString *baseStr;
178
179       baseStr = [body absoluteString];
180
181       if ([baseStr hasPrefix:@"="]) {
182         body = [NSURL URLWithString:[NSString stringWithFormat:@"%@1",
183                                               baseStr]];
184       }
185       else
186         body = [NSURL URLWithString:[NSString stringWithFormat:@"%@.1",
187                                               baseStr]];
188     }
189     [message setBody:body];
190   }
191   return message;
192 }
193
194 static id _buildPart(id self, NSURL *_baseUrl, NSDictionary *_dict) {
195   NSString       *type, *subType;
196   NGMimeBodyPart *part;
197   NSURL          *url;
198
199   url     = _baseUrl;
200   type    = [[_dict objectForKey:@"type"] lowercaseString]; 
201   subType = [[_dict objectForKey:@"subtype"] lowercaseString];
202  
203   part = _buildMimeBodyPart(self, _dict);
204     
205   if ([type isEqualToString:@"multipart"]) {
206     [part setBody:_buildMultipartMessage(self, url, _dict, part)];
207   }
208   else if ([type isEqualToString:@"message"] &&
209            [subType isEqualToString:@"rfc822"]) {
210     [part setBody:_buildMessage(self, url, _dict)];
211   }
212   else {
213     [part setBody:url];
214   }
215   return part;
216 }
217
218 static id _buildMimeBodyPart(id self, NSDictionary *_dict)
219 {
220   NGMutableHashMap *dict;
221   NSString         *value;
222   NGMimeType       *type;
223   static NGMimeHeaderNames *Fields = NULL;
224
225   if (!Fields)
226     Fields = (NGMimeHeaderNames *)[NGMimePartParser headerFieldNames];
227   
228
229   dict = [NGMutableHashMap hashMapWithCapacity:8];
230
231   type = [NGMimeType mimeType:[[_dict objectForKey:@"type"] lowercaseString]
232                      subType:[[_dict objectForKey:@"subtype"] lowercaseString]
233                      parameters:[_dict objectForKey:@"parameterList"]];
234
235   [dict setObject:type forKey:Fields->contentType];
236
237   if (([value = [_dict objectForKey:@"bodyId"] length])) {
238     [dict setObject:value forKey:Fields->messageID];
239   }
240
241   if (([value = [_dict objectForKey:@"size"] length])) {
242     [dict setObject:value forKey:Fields->contentLength];
243   }
244   if (([value = [_dict objectForKey:@"encoding"] length])) {
245     [dict setObject:[value lowercaseString]
246           forKey:Fields->contentTransferEncoding];
247   }
248   return [NGMimeBodyPart bodyPartWithHeader:dict];
249 }
250
251
252 static id _buildMimeMessageBody(id self, NSURL *_baseUrl, NSDictionary *_dict,
253                                 id<NGMimePart>_part)
254 {
255   NSString *type, *subType;
256   NSURL    *url;
257   id       result;
258
259   type    = [[_dict objectForKey:@"type"] lowercaseString];
260   subType = [[_dict objectForKey:@"subtype"] lowercaseString];
261
262   url = [NSURL URLWithString:[[_baseUrl absoluteString]
263                                         stringByAppendingString:@"?part="]];
264   if ([type isEqualToString:@"multipart"]) {
265     result = _buildMultipartMessage(self, url, _dict, _part);
266   }
267   else {
268     if ([type isEqualToString:@"message"] &&
269         [subType isEqualToString:@"rfc822"]) {
270       result = _buildMessage(self, url, _dict);
271     }
272     else {
273       result = [NSURL URLWithString:[[_baseUrl absoluteString]
274                                         stringByAppendingString:@"?part=1"]];
275     }
276   }
277   return result;
278 }
279
280 @end /* NGImap4Message(BodyStructure) */
281
282 #endif /* __NGImap4Message_BodyStructure_H__ */