]> err.no Git - sope/blob - sope-mime/NGMime/NGMimeUtilities.h
synced with latest additions and bumped framework versions
[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  = [_data bytes];
129   unsigned int length  = [_data length];
130   NSData       *result = nil;  
131   char         *des    = NULL;
132   unsigned int desLen  = 0;
133   unsigned     cnt     = length;
134   const char   *test   = bytes;    
135   BOOL         doEnc   = NO;
136
137   while (cnt > 0) {
138     if ((unsigned char)*test > 127) {
139       doEnc = YES;
140       break;
141     }
142     test++;
143     cnt--;
144   }
145   if (!doEnc) return _data;
146   desLen = length *3;
147   des = NGMallocAtomic(sizeof(char) * desLen + 2);
148   
149   desLen = NGEncodeQuotedPrintable(bytes, length, des, desLen);
150   if ((int)desLen != -1) {
151     result = [NSData dataWithBytesNoCopy:des length:desLen];
152   }
153   else {
154     NSLog(@"WARNING(%s): An error occour during quoted-printable decoding",
155           __PRETTY_FUNCTION__);
156     if (des) NGFree(des);
157     result = _data;
158   }
159   return result;
160 }
161
162 static inline NSData *_rfc2047Decoding(char _enc, const char *_bytes,
163                                        unsigned int _length) 
164 {
165   NSData *data = nil;
166
167   if ((_enc == 'b') || (_enc == 'B')) { // use BASE64 decoding
168     NSData *tmp;
169     
170     tmp = [[NSData alloc] initWithBytes:_bytes length:_length];
171     data = [tmp dataByDecodingBase64];
172     RELEASE(tmp);
173   }
174   else if ((_enc == 'q') || (_enc == 'Q')) { // use quoted-printable decoding
175     char   *dest    = NULL;
176     size_t destSize = 0;
177     size_t resSize  = 0;
178
179     destSize = _length;
180     dest = NGMallocAtomic(destSize * sizeof(char));
181     resSize = NGDecodeQuotedPrintable(_bytes, _length, dest, destSize);
182     if ((int)resSize != -1) {
183       data = [NSData dataWithBytesNoCopy:dest length:resSize];
184     }
185     else {
186       NSLog(@"WARNING(%s): An error occour during quoted-printable decoding",
187             __PRETTY_FUNCTION__);
188       NGFree(dest); dest = NULL;
189       data = [NSData dataWithBytes:_bytes length:_length];
190     }
191   }
192   else {
193     NSLog(@"WARNING(%s): unknown encoding type %c", __PRETTY_FUNCTION__, _enc);
194     data = [NSData dataWithBytes:_bytes length:_length];
195   }
196   return data;
197 }
198
199 #endif /* __NGMime_NGMimeUtilities_H__ */