2 // InternetTextMessageHeader.h
\r
6 #include <Raym/Log.h>
\r
7 #include "net/InternetTextMessageHeader.h"
\r
9 using namespace Raym;
\r
14 InternetTextMessageHeader::InternetTextMessageHeader()
\r
16 _encoding = ASCIIStringEncoding;
\r
21 InternetTextMessageHeader::~InternetTextMessageHeader()
\r
27 InternetTextMessageHeader *InternetTextMessageHeader::alloc()
\r
29 return new InternetTextMessageHeader();
\r
32 InternetTextMessageHeader *InternetTextMessageHeader::init()
\r
36 _fields = Dictionary::alloc()->initWithCapacity(0);
\r
40 InternetTextMessageHeader *InternetTextMessageHeader::initWithData(Data *data)
\r
42 DebugLog2("%s()\n", __FUNCTION__);
\r
48 _data = data->retain();
\r
51 const char *buffer = (const char *)data->bytes();
\r
55 while (offset < data->length())
\r
57 field[index++] = buffer[offset++];
\r
58 if ((field[index - 2] == '\r') && (field[index - 1] == '\n'))
\r
60 field[index - 2] = '\0';
\r
61 char *value = strchr(field, ':');
\r
65 while (*value == ' ')
\r
70 DebugLog3("%s: %s", field, value);
\r
71 String *body = String::stringWithUTF8String(value);
\r
72 String *name = String::stringWithUTF8String(field);
\r
73 setFieldBodyWithName(body, name);
\r
82 char *tmp = (char *)malloc([data length] + 1);
\r
83 [data getBytes:tmp length:[data length]];
\r
84 tmp[[data length]] = '\0';
\r
85 String *headStr = [String stringWithCString:tmp encoding:_encoding];
\r
86 if ([headStr rangeOfString:@"content-type" options:CaseInsensitiveSearch].location != NotFound)
\r
88 if ([headStr rangeOfString:@"charset" options:CaseInsensitiveSearch].location != NotFound)
\r
90 if ([headStr rangeOfString:@"iso-2022-jp" options:CaseInsensitiveSearch].location != NotFound)
\r
92 _encoding = ISO2022JPStringEncoding;
\r
94 else if ([headStr rangeOfString:@"shift_jis" options:CaseInsensitiveSearch].location != NotFound)
\r
96 _encoding = ShiftJISStringEncoding;
\r
98 else if ([headStr rangeOfString:@"euc-jp" options:CaseInsensitiveSearch].location != NotFound)
\r
100 _encoding = JapaneseEUCStringEncoding;
\r
102 else if ([headStr rangeOfString:@"utf-8" options:CaseInsensitiveSearch].location != NotFound)
\r
104 _encoding = UTF8StringEncoding;
\r
111 InternetTextMessageHeader *InternetTextMessageHeader::initWithArray(Array *array)
\r
114 if ((self = [super init]) != nil)
\r
116 _dictionary = [[MutableDictionary alloc] initWithCapacity:0];
\r
117 _encoding = ASCIIStringEncoding;
\r
118 for (int i = 0; i < [array count]; ++i)
\r
120 String *line = [array objectAtIndex:i];
\r
121 Range r = [line rangeOfString:@":"];
\r
122 if (r.location != NotFound)
\r
124 String *fieldName = [line substringToIndex:r.location];
\r
125 String *fieldBody = [[line substringFromIndex:(r.location + 1)] stringByTrimmingCharactersInSet:[CharacterSet whitespaceAndNewlineCharacterSet]];
\r
126 [_dictionary setObject:fieldBody forKey:fieldName];
\r
135 InternetTextMessageHeader *InternetTextMessageHeader::initWithSocket(SOCKET sock)
\r
137 DebugLog2("%s()\n", __FUNCTION__);
\r
139 char *tmp = "\r\n\r\n";
\r
144 while (length < sizeof(buf))
\r
147 if (recv(sock, &c, 1, 0) == 1)
\r
152 if (strncmp(&buf[length - 4], tmp, 4) == 0)
\r
154 Data *data = Data::alloc()->initWithBytesAndLength(buf, length);
\r
155 initWithData(data);
\r
171 - (StringEncoding)encoding
\r
177 InternetTextMessageHeader *InternetTextMessageHeader::retain()
\r
183 InternetTextMessageHeader *InternetTextMessageHeader::autorelease()
\r
185 Object::autorelease();
\r
189 Array *InternetTextMessageHeader::fieldNames()
\r
191 return _fields->allKeys();
\r
194 String *InternetTextMessageHeader::fieldBodyForName(String *name)
\r
196 return (String *)_fields->objectForKey(name);
\r
199 String *InternetTextMessageHeader::fieldBodyForName(const char *name)
\r
201 return (String *)_fields->objectForKey(name);
\r
204 void InternetTextMessageHeader::setFieldBodyWithName(String *body, String *name)
\r
206 _fields->setObject(body, name);
\r
208 if ([[name lowercaseString] isEqualToString:@"content-type"])
\r
210 if ([body rangeOfString:@"charset" options:CaseInsensitiveSearch].location != NotFound)
\r
212 if ([body rangeOfString:@"iso-2022-jp" options:CaseInsensitiveSearch].location != NotFound)
\r
214 _encoding = ISO2022JPStringEncoding;
\r
216 else if ([body rangeOfString:@"shift_jis" options:CaseInsensitiveSearch].location != NotFound)
\r
218 _encoding = ShiftJISStringEncoding;
\r
220 else if ([body rangeOfString:@"euc-jp" options:CaseInsensitiveSearch].location != NotFound)
\r
222 _encoding = JapaneseEUCStringEncoding;
\r
224 else if ([body rangeOfString:@"utf-8" options:CaseInsensitiveSearch].location != NotFound)
\r
226 _encoding = UTF8StringEncoding;
\r
233 void InternetTextMessageHeader::setFieldBodyWithName(const char *body, String *name)
\r
235 setFieldBodyWithName(String::stringWithUTF8String(body), name);
\r
238 void InternetTextMessageHeader::setFieldBodyWithName(String *body, const char *name)
\r
240 setFieldBodyWithName(body, String::stringWithUTF8String(name));
\r
243 void InternetTextMessageHeader::setFieldBodyWithName(const char *body, const char *name)
\r
245 setFieldBodyWithName(String::stringWithUTF8String(body), String::stringWithUTF8String(name));
\r
248 Data *InternetTextMessageHeader::data()
\r
251 MutableString *headerString = [MutableString stringWithCapacity:0];
\r
252 Array *fieldNames = [_dictionary allKeys];
\r
255 for (int i = 0; i < [fieldNames count]; ++i)
\r
257 String *fieldName = [fieldNames objectAtIndex:i];
\r
258 if ([[fieldName lowercaseString] isEqualToString:@"content-type"])
\r
260 [headerString appendFormat:@"Content-type: %@\r\n", [_dictionary objectForKey:fieldName]];
\r
266 for (int i = 0; i < [fieldNames count]; ++i)
\r
268 String *fieldName = [fieldNames objectAtIndex:i];
\r
269 String *lowercase = [fieldName lowercaseString];
\r
270 if (![lowercase isEqualToString:@"content-type"])
\r
272 [headerString appendFormat:@"%@: %@\r\n", fieldName, [_dictionary objectForKey:fieldName]];
\r
276 [headerString appendString:@"\r\n\r\n"];
\r
278 return [Data dataWithBytes:[headerString cStringUsingEncoding:_encoding] length:[headerString lengthOfBytesUsingEncoding:_encoding]];
\r
283 const char *InternetTextMessageHeader::className()
\r
285 return "NET::InternetTextMessageHeader";
\r