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