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 "NGMimeJoinedData.h" 23#include "common.h" 24#include "timeMacros.h" 25#include <string.h> 26#include <sys/types.h> 27#include <sys/stat.h> 28#include <fcntl.h> 29#include <unistd.h> 30#include "NGMimeFileData.h" 31 32@implementation NGMimeJoinedData 33 34- (id)init { 35 if ((self = [super init])) { 36 self->joinedDataObjects = [[NSMutableArray alloc] initWithCapacity:16]; 37 } 38 return self; 39} 40 41- (void)dealloc { 42 [self->joinedDataObjects release]; 43 [super dealloc]; 44} 45 46/* NSCopying */ 47 48- (id)copyWithZone:(NSZone *)_zone { 49 // TODO: we are mutable, is -retain a bug or feature? 50 return [self retain]; 51} 52 53/* data */ 54 55- (NSArray *)_joinedDataObjects { 56 return self->joinedDataObjects; 57} 58 59- (NSUInteger)length { 60 NSUInteger i, count, size; 61 62 for (i = 0, count = [self->joinedDataObjects count], size = 0; i < count;i++) 63 size += [[self->joinedDataObjects objectAtIndex:i] length]; 64 return size; 65} 66 67/* appending data */ 68 69- (void)appendData:(NSData *)_data { 70 if ([_data isKindOfClass:[NGMimeJoinedData class]]) { 71 [self->joinedDataObjects addObjectsFromArray: 72 [(NGMimeJoinedData *)_data _joinedDataObjects]]; 73 } 74 else 75 [self->joinedDataObjects addObject:_data]; 76} 77 78- (void)appendBytes:(const void *)_bytes length:(unsigned int)_length { 79 NSMutableData *data; 80 81 if (_length == 0) 82 return; 83 84 data = (NSMutableData *)[self->joinedDataObjects lastObject]; 85 86 if ([data isKindOfClass:[NSMutableData class]]) { 87 [data appendBytes:_bytes length:_length]; 88 } 89 else { 90 /* 91 Note: we create a mutable because it is not unlikely that additional 92 appends are coming. 93 */ 94 data = [[NSMutableData alloc] initWithBytes:_bytes length:_length]; 95 if (data != nil) [self->joinedDataObjects addObject:data]; 96 [data release]; 97 } 98} 99 100/* writing to file */ 101 102- (BOOL)writeToFile:(NSString*)_path atomically:(BOOL)_useAuxiliaryFile { 103 NSString *filename = nil; 104 NSEnumerator *enumerator; 105 NSData *data; 106 volatile BOOL result; 107 108 int fd; 109 110 filename = _path; 111 112 fd = open([filename fileSystemRepresentation], 113 O_WRONLY | O_CREAT | O_TRUNC, 0600); 114 if (fd == -1) { 115 fprintf(stderr, "Could not open file for writing %s: %s\n", 116 [filename fileSystemRepresentation], strerror(errno)); 117 return NO; 118 } 119 120 result = YES; 121 enumerator = [self->joinedDataObjects objectEnumerator]; 122 123 while ((data = [enumerator nextObject])) { 124 125 TIME_START("write bytes "); 126 127 if ([data isKindOfClass:[NGMimeFileData class]]) { 128 if (![(NGMimeFileData *)data appendDataToFileDesc:fd]) { 129 fprintf(stderr, 130#if GS_64BIT_OLD 131 "Failed to write %i bytes to %s: %s\n", 132#else 133 "Failed to write %li bytes to %s: %s\n", 134#endif 135 [data length], 136 [filename fileSystemRepresentation], strerror(errno)); 137 close(fd); 138 } 139 } 140 else { 141 const void *bytes; 142 unsigned len; 143 144 TIME_START("bytes ...") 145 bytes = [data bytes]; 146 len = [data length]; 147 TIME_END; 148 149 if (write(fd, bytes, len) != (int)len) { 150 fprintf(stderr, "Failed to write %i bytes to %s: %s\n", 151 len, [filename fileSystemRepresentation], strerror(errno)); 152 close(fd); 153 return NO; 154 } 155 } 156 TIME_END; 157 } 158 close(fd); 159 160 return result; 161} 162 163/* description */ 164 165- (NSString *)description { 166 NSMutableString *ms; 167 168 ms = [NSMutableString stringWithCapacity:128]; 169 [ms appendFormat:@"<0x%p[%@]:", self, NSStringFromClass([self class])]; 170 [ms appendFormat:@" joinedDataObjects=%d>", 171 (int)[self->joinedDataObjects count]]; 172 [ms appendString:@">"]; 173 return ms; 174} 175 176@end /* NGMimeJoinedData */ 177