20
20
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23
#import <Pantomime/LocalMessage.h>
25
#import <Pantomime/Constants.h>
26
#import <Pantomime/LocalFolder.h>
27
#import <Pantomime/NSDataExtensions.h>
23
#include <Pantomime/LocalMessage.h>
25
#include <Pantomime/Constants.h>
26
#include <Pantomime/LocalFolder.h>
27
#include <Pantomime/LocalStore.h>
28
#include <Pantomime/NSData+Extensions.h>
30
#include <Foundation/NSDebug.h>
31
#include <Foundation/NSException.h>
32
#include <Foundation/NSValue.h>
36
static int currentLocalMessageVersion = 1;
31
41
@implementation LocalMessage
47
[LocalMessage setVersion: currentLocalMessageVersion];
34
54
// NSCoding protocol
36
56
- (void) encodeWithCoder: (NSCoder *) theCoder
38
//NSLog(@"Encoding LocalMessage...");
39
58
[super encodeWithCoder: theCoder];
60
[LocalMessage setVersion: currentLocalMessageVersion];
41
62
[theCoder encodeObject: [NSNumber numberWithLong: [self filePosition]]];
42
63
[theCoder encodeObject: [NSNumber numberWithLong: [self bodyFilePosition]]];
65
// Store the name of the file; we need it for local.
66
[theCoder encodeObject: mailFilename];
68
// Store the message type; useful to have.
69
[theCoder encodeObject: [NSNumber numberWithInt: [self messageType]]];
45
76
- (id) initWithCoder: (NSCoder *) theCoder
47
80
self = [super initWithCoder: theCoder];
49
//NSLog(@"Decoding LocalMessage...");
51
82
[self setFilePosition: [[theCoder decodeObject] longValue]];
52
83
[self setBodyFilePosition: [[theCoder decodeObject] longValue]];
85
version = [theCoder versionForClassName: @"LocalMessage"];
89
// Retrieve the mail file name which we need for local storage.
90
[self setMailFilename: [theCoder decodeObject]];
92
// Retrieve the message type
93
[self setMessageType: [[theCoder decodeObject] intValue]];
97
[NSException raise: NSInternalInconsistencyException
98
format: @"LocalMessage cache error."];
58
106
// access / mutation methods
67
115
filePosition = theFilePosition;
70
122
- (long) bodyFilePosition
72
124
return bodyFilePosition;
75
128
- (void) setBodyFilePosition: (long) theBodyFilePosition
77
130
bodyFilePosition = theBodyFilePosition;
143
- (void) setMessageType: (int) theType
145
messageType = theType;
152
- (NSString *) mailFilename
154
return (mailFilename);
158
- (void) setMailFilename: (NSString *) theFilename
163
RELEASE(mailFilename);
164
mailFilename = theFilename;
168
DESTROY(mailFilename);
178
TEST_RELEASE(mailFilename);
80
187
- (NSData *) rawSource
82
189
NSMutableData *aMutableData;
89
196
aLocalFolder = (LocalFolder *)[self folder];
90
aStream = [aLocalFolder stream];
199
// If we are reading from a mbox file, the file is already open
200
if ([self messageType] == MAILBOX_FORMAT_MBOX)
202
aStream = [aLocalFolder stream];
204
// we need to open the specific file
205
else if ([self messageType] == MAILBOX_FORMAT_MAILDIR)
207
aStream = fopen([[self mailFilename] cString], "r");
212
NSDebugLog(@"Stream is null!");
92
216
mark = ftell(aStream);
94
218
if (fseek(aStream, [self filePosition], SEEK_SET) < 0)
96
NSLog( @"Seek operation failed!" );
220
NSDebugLog( @"Seek operation to position %d failed!", [self filePosition]);
100
224
// We initialize our mutable data and our buffer
101
225
aMutableData = [[NSMutableData alloc] init];
226
memset(aLine, 0, 1024);
104
while( fgets(aLine, 1024, aStream) != NULL &&
105
ftell(aStream) < ([self filePosition] + [self size]) )
228
while ( fgets(aLine, 1024, aStream) != NULL &&
229
ftell(aStream) < ([self filePosition] + [self size]) )
107
231
[aMutableData appendBytes: aLine length: strlen(aLine) ];
232
memset(aLine, 0, 1024);
111
235
fseek(aStream, mark, SEEK_SET);
237
// If we are operating on a local file, close it.
238
if ([self messageType] == MAILBOX_FORMAT_MAILDIR)
113
243
return AUTORELEASE(aMutableData);
117
248
// This method is called to initialize the message if it wasn't.
118
249
// If we set it to NO and we HAD a content, we release the content;
126
NSMutableData *aMutableData;
127
LocalFolder *aLocalFolder;
135
aLocalFolder = (LocalFolder *)[self folder];
136
aStream = [aLocalFolder stream];
138
mark = ftell(aStream);
140
if (fseek(aStream, [self bodyFilePosition], SEEK_SET) < 0)
142
NSLog( @"Seek operation failed!" );
259
aData = [self rawSource];
265
aRange = [aData rangeOfCString: "\n\n"];
267
if (aRange.length == 0)
269
NSDebugLog(@"LocalMessage: Failed to initialize the message from data.");
270
[super setInitialized: NO];
274
[self setHeadersFromData: [aData subdataWithRange: NSMakeRange(0,aRange.location)]];
275
[self setContentFromRawSource:
276
[aData subdataWithRange:
277
NSMakeRange(aRange.location + 2, [aData length]-(aRange.location+2))]];
281
NSDebugLog(@"LocalMessage: Failed to get the raw source of the local message.");
143
282
[super setInitialized: NO];
147
// We calculate the length of our body to make parsing faster
148
lengthOfBody = ([self filePosition] + [self size] - [self bodyFilePosition]);
149
aMutableData = [[NSMutableData alloc] initWithCapacity: lengthOfBody];
152
while( fgets(aLine, 1024, aStream) != NULL &&
153
ftell(aStream) < ([self filePosition] + [self size]) )
155
[aMutableData appendBytes: aLine length: strlen(aLine) ];
160
fseek(aStream, mark, SEEK_SET);
162
[self setContentFromRawSource: aMutableData];
163
RELEASE(aMutableData);
167
TEST_RELEASE(content);