]> err.no Git - sope/blob - sope-mime/NGMime/NGMimeFileData.m
updated framework version
[sope] / sope-mime / NGMime / NGMimeFileData.m
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 #include "NGMimeFileData.h"
23 #include "common.h"
24 #include <unistd.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <fcntl.h>
28
29 @implementation NGMimeFileData
30
31 static NSString      *TmpPath = nil;
32 static NSProcessInfo *Pi      = nil;
33 static unsigned      tmpmask  = 0600;
34
35 + (void)initialize {
36   NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
37   
38   if (TmpPath == nil) {
39     TmpPath = [ud stringForKey:@"NGMimeBuildMimeTempDirectory"];
40     if (TmpPath == nil) TmpPath = @"/tmp/";
41     TmpPath = [[TmpPath stringByAppendingPathComponent:@"OGo"] copy];
42   }
43   if (Pi == nil) Pi = [[NSProcessInfo processInfo] retain];
44 }
45
46 - (id)initWithPath:(NSString *)_path removeFile:(BOOL)_remove {
47   if ((self = [super init])) {
48     if (![[NSFileManager defaultManager] fileExistsAtPath:_path]) {
49       NSLog(@"ERROR[%s]: missing file at path %@", __PRETTY_FUNCTION__, _path);
50       [self release];
51       return nil;
52     }
53     self->path       = [_path copy];
54     self->removeFile = _remove;
55     self->length     = -1;
56   }
57   return self;
58 }
59
60 - (id)initWithBytes:(const void*)_bytes
61   length:(unsigned int)_length
62 {
63   NSString *filename = nil;
64   int      fd;
65   
66   filename = [Pi temporaryFileName:TmpPath];
67
68   fd = open([filename fileSystemRepresentation],
69             O_WRONLY | O_CREAT | O_TRUNC, tmpmask);
70   if (fd == -1) {
71     fprintf(stderr, "Could not open file for writing %s: %s\n",
72             [filename fileSystemRepresentation], strerror(errno));
73     [self release];
74     return nil;
75   }
76   if (write(fd, _bytes, _length) != (int)_length) {
77     fprintf(stderr, "Failed to write %i bytes to %s: %s\n",
78             _length, [filename fileSystemRepresentation], strerror(errno));
79     close(fd);
80     [self release];
81     return nil;
82   }
83   return [self initWithPath:filename removeFile:YES];
84 }
85
86 - (void)dealloc {
87   if (self->removeFile) {
88     [[NSFileManager defaultManager]
89                     removeFileAtPath:self->path handler:nil];
90   }
91   [self->path release];
92   [super dealloc];
93 }
94
95 - (NSData *)_data {
96   return [NSData dataWithContentsOfMappedFile:self->path];
97 }
98
99 - (id)copyWithZone:(NSZone *)zone {
100   return [self retain];
101 }
102
103 - (const void*)bytes {
104   return [[self _data] bytes];
105 }
106
107 - (unsigned int)length {
108   if (self->length == -1) {
109     self->length = [[[[NSFileManager defaultManager]
110                                      fileAttributesAtPath:self->path
111                                      traverseLink:NO]
112                                      objectForKey:NSFileSize] intValue];
113   }
114   return self->length;
115 }
116
117 - (BOOL)appendDataToFileDesc:(int)_fd {
118   NGFileStream *fs;
119   int  bufCnt = 8192;
120   char buffer[bufCnt];
121   BOOL result;
122   int  fileLen;
123
124   if (![[NSFileManager defaultManager] isReadableFileAtPath:self->path]) {
125     NSLog(@"ERROR[%s] missing file at path %@", __PRETTY_FUNCTION__, 
126           self->path);
127     return NO;
128   }
129   
130   fileLen = [self length];
131   result  = YES;
132   fs      = [NGFileStream alloc]; /* to keep gcc 3.4 happy */
133   fs      = [fs initWithPath:self->path];
134
135   if (![fs openInMode:@"r"]) {
136     NSLog(@"%s: could not open file stream ... %@",
137           __PRETTY_FUNCTION__, self->path);
138     [fs release]; fs = nil;
139     return NO;
140   }
141
142   NS_DURING {
143     int read;
144     int alreadyRead;
145
146     alreadyRead = 0;
147     
148     read = (bufCnt > (fileLen - alreadyRead)) ? fileLen - alreadyRead : bufCnt;
149     
150     while ((read = [fs readBytes:buffer count:read])) {
151       alreadyRead += read;
152       if (write(_fd, buffer, read) != read) {
153         fprintf(stderr, "%s: Failed to write %i bytes to file\n",
154                 __PRETTY_FUNCTION__, read);
155         result = NO;
156         break;
157       }
158       if (alreadyRead == fileLen)
159         break;
160     }
161   }
162   NS_HANDLER {
163     printf("got exceptions %s\n", [[localException description] cString]);
164     if (![localException isKindOfClass:[NGEndOfStreamException class]]) {
165       [fs release]; fs = nil;
166       result = NO;
167     }
168   }
169   NS_ENDHANDLER;
170   [fs release]; fs = nil;
171   return result;
172 }
173
174 /* description */
175
176 - (NSString *)description {
177   return [NSString stringWithFormat:@"<0x%08X[%@]: path=%@>",
178                      self, NSStringFromClass([self class]), self->path];
179 }
180
181 @end /* NGMimeFileData */