]> err.no Git - sope/blob - sope-mime/NGMime/NGMimeUtilities.h
some code cleanups
[sope] / sope-mime / NGMime / NGMimeUtilities.h
1 /*
2   Copyright (C) 2000-2005 SKYRIX Software AG
3
4   This file is part of SOPE.
5
6   SOPE 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   SOPE 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 SOPE; 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 __NGMime_NGMimeUtilities_H__
23 #define __NGMime_NGMimeUtilities_H__
24
25 #import <Foundation/Foundation.h>
26 #import <NGExtensions/NGExtensions.h>
27 #include <NGMime/NGMimeDecls.h>
28
29 // ******************** RFC 822 ********************
30
31 static inline BOOL isRfc822_SpecialByte(unsigned char _byte) {
32   switch (_byte) {
33   case '(': case ')': case '<': case '>': case '@':
34   case ',': case ';': case ':': case '"': case '\\':
35   case '.': case '[': case ']':
36     return YES;
37   default:
38     return NO;
39   }
40 }
41
42 // single chars
43 NSDictionary *parseParameters(id self, NSString *_str, unichar *cstr);
44
45 static inline BOOL isRfc822_CR(unsigned char _byte) {
46   return (_byte == 13);
47 }
48 static inline BOOL isRfc822_LF(unsigned char _byte) {
49   return (_byte == 10);
50 }
51 static inline BOOL isRfc822_HTAB(unsigned char _byte) {
52   return (_byte == 9);
53 }
54 static inline BOOL isRfc822_SPACE(unsigned char _byte) {
55   return (_byte == 32);
56 }
57 static inline BOOL isRfc822_QUOTE(unsigned char _byte) {
58   return (_byte == 34);
59 }
60
61 // ranges
62
63 static inline BOOL isRfc822_CHAR(unsigned char _byte) {
64   return (_byte < 128);
65 }
66
67 static inline BOOL isRfc822_CTL(unsigned char _byte) {
68   return (_byte < 32) || (_byte == 127);
69 }
70
71 static inline BOOL isRfc822_ALPHA(unsigned char _byte) {
72   return (((_byte >= 65) && (_byte <= 90)) ||
73           ((_byte >= 97) && (_byte <= 122)));
74 }
75
76 static inline BOOL isRfc822_DIGIT(unsigned char _byte) {
77   return (_byte >= 48) && (_byte <= 57);
78 }
79
80 static inline BOOL isRfc822_LWSP(unsigned char _byte) {
81   return (isRfc822_SPACE(_byte) || isRfc822_HTAB(_byte));
82 }
83
84
85 static inline BOOL isRfc822_FieldNameChar(unsigned char _byte) {
86   return (isRfc822_CHAR(_byte) &&
87           !(isRfc822_CTL(_byte) || isRfc822_SPACE(_byte) || (_byte == ':')));
88 }
89
90 static inline BOOL isRfc822_AtomChar(unsigned char _byte) {
91   return (isRfc822_CHAR(_byte) &&
92           !(isRfc822_SpecialByte(_byte) || isRfc822_SPACE(_byte) ||
93             isRfc822_CTL(_byte)));
94 }
95
96 // ******************** MIME ***********************
97
98 static inline BOOL isMime_SpecialByte(unsigned char _byte) {
99   switch (_byte) {
100   case '(': case ')': case '<': case '>': case '@':
101   case ',': case ';': case ':': case '"': case '\\':
102   case '/': case '=': case '[': case ']': case '?':
103     return YES;
104   default:
105     return NO;
106   }
107 }
108
109 static inline BOOL isMime_TokenChar(unsigned char _byte) {
110   return (isRfc822_CHAR(_byte) &&
111           !(isRfc822_CTL(_byte) || isRfc822_SPACE(_byte) ||
112             isMime_SpecialByte(_byte)));
113 }
114
115 static inline BOOL isMime_SafeChar(unsigned char _byte) {
116   return ((_byte >= 33 && _byte <= 60) || (_byte >= 62 && _byte <= 126));
117 }
118
119 static inline BOOL isMime_ValidTypeXTokenChar(unsigned char _byte) {
120   return !isRfc822_SPACE(_byte);
121 }
122
123 static inline BOOL isMime_ValidTypeAttributeChar(unsigned char _byte) {
124   return isMime_TokenChar(_byte);
125 }
126
127 static inline NSData *_quotedPrintableEncoding(NSData *_data) {
128   const char   *bytes;
129   unsigned int length;
130   NSData       *result = nil;  
131   char         *des    = NULL;
132   unsigned int desLen  = 0;
133   unsigned     cnt;
134   const char   *test;    
135   BOOL         doEnc   = NO;
136
137   bytes  = [_data bytes];
138   length = [_data length];
139   cnt    = length;
140   test   = bytes;    
141   
142   for (cnt = length, test = bytes; cnt > 0; test++, cnt--) {
143     if ((unsigned char)*test > 127) {
144       doEnc = YES;
145       break;
146     }
147   }
148   if (!doEnc) 
149     return _data;
150   
151   desLen = length *3;
152   des = NGMallocAtomic(sizeof(char) * desLen + 2);
153   
154   desLen = NGEncodeQuotedPrintable(bytes, length, des, desLen);
155   if ((int)desLen != -1) {
156     result = [NSData dataWithBytesNoCopy:des length:desLen];
157   }
158   else {
159     NSLog(@"WARNING(%s): An error occour during quoted-printable decoding",
160           __PRETTY_FUNCTION__);
161     if (des) NGFree(des);
162     result = _data;
163   }
164   return result;
165 }
166
167 static inline NSData *_rfc2047Decoding(char _enc, const char *_bytes,
168                                        unsigned int _length) 
169 {
170   NSData *data = nil;
171
172   if ((_enc == 'b') || (_enc == 'B')) { // use BASE64 decoding
173     // TODO: improve efficiency (directly decode buffers w/o NSData)
174     NSData *tmp;
175     
176     tmp = [[NSData alloc] initWithBytes:_bytes length:_length];
177     data = [tmp dataByDecodingBase64];
178     [tmp release]; tmp = nil;
179   }
180   else if ((_enc == 'q') || (_enc == 'Q')) { // use quoted-printable decoding
181     char   *dest    = NULL;
182     size_t destSize = 0;
183     size_t resSize  = 0;
184
185     destSize = _length;
186     dest    = calloc(destSize + 2, sizeof(char));
187     resSize = NGDecodeQuotedPrintable(_bytes, _length, dest, destSize);
188     if ((int)resSize != -1) {
189       data = [NSData dataWithBytesNoCopy:dest length:resSize];
190     }
191     else {
192       NSLog(@"WARNING(%s): An error occour during quoted-printable decoding",
193             __PRETTY_FUNCTION__);
194       if (dest != NULL) free(dest); dest = NULL;
195       data = [NSData dataWithBytes:_bytes length:_length];
196     }
197   }
198   else {
199     NSLog(@"WARNING(%s): unknown encoding type %c", __PRETTY_FUNCTION__, _enc);
200     data = [NSData dataWithBytes:_bytes length:_length];
201   }
202   return data;
203 }
204
205 #endif /* __NGMime_NGMimeUtilities_H__ */