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 <NGStreams/NGConcreteStreamFileHandle.h> 23#include <NGStreams/NGStreamProtocols.h> 24#include <NGStreams/NGStreamExceptions.h> 25#include <NGStreams/NGBufferedStream.h> 26#include "common.h" 27 28@interface NGStream(FileHandleReset) 29 30- (void)resetFileHandle; 31 32@end 33 34@implementation NGConcreteStreamFileHandle 35 36- (id)initWithStream:(id<NGStream>)_stream { 37 if ((self = [super init])) { 38 self->stream = [_stream retain]; 39 } 40 return self; 41} 42 43- (void)dealloc { 44 if ([stream respondsToSelector:@selector(resetFileHandle)]) 45 [(NGStream *)self->stream resetFileHandle]; 46 [self->stream release]; 47 [super dealloc]; 48} 49 50// accessors 51 52- (id<NGStream>)stream { 53 return self->stream; 54} 55 56/* NSFileHandle operations */ 57 58- (void)closeFile { 59 [self->stream close]; 60} 61 62- (int)fileDescriptor { 63 if ([self->stream respondsToSelector:@selector(fileDescriptor)]) 64 return [(id)self->stream fileDescriptor]; 65 else { 66 [self subclassResponsibility:_cmd]; 67 return -1; 68 } 69} 70 71/* buffering */ 72 73- (void)synchronizeFile { 74 [self->stream flush]; 75} 76 77/* reading */ 78 79- (NSData *)readDataOfLength:(unsigned int)_length { 80 char *buffer; 81 NSData *data; 82 83 *(&buffer) = NGMallocAtomic(_length); 84 *(&data) = nil; 85 86 NS_DURING { 87 [stream safeReadBytes:buffer count:_length]; 88 data = [[NSData alloc] initWithBytes:buffer length:_length]; 89 } 90 NS_HANDLER { 91 if ([localException isKindOfClass:[NGEndOfStreamException class]]) { 92 data = [(NGEndOfStreamException *)localException readBytes]; 93 94 data = data ? [data retain] : [[NSData alloc] init]; 95 } 96 else { 97 if (buffer) { 98 NGFree(buffer); 99 buffer = NULL; 100 } 101 [localException raise]; 102 } 103 } 104 NS_ENDHANDLER; 105 106 if (buffer) { 107 NGFree(buffer); 108 buffer = NULL; 109 } 110 111 return [data autorelease]; 112} 113 114- (NSData *)readDataToEndOfFile { 115 NGBufferedStream *bs; 116 NSMutableData *data; 117 char buf[2048]; 118 119 *(&data) = [NSMutableData dataWithCapacity:2048]; 120 *(&bs) = [self->stream isKindOfClass:[NGBufferedStream class]] 121 ? (id)[self->stream retain] 122 : [(NGBufferedStream *)[NGBufferedStream alloc] 123 initWithSource:self->stream]; 124 125 NS_DURING { 126 while (1 == 1) { 127 unsigned got = [bs readBytes:buf count:2048]; 128 [data appendBytes:buf length:got]; 129 } 130 } 131 NS_HANDLER { 132 if (![localException isKindOfClass:[NGEndOfStreamException class]]) { 133 [bs release]; 134 bs = nil; 135 [localException raise]; 136 } 137 } 138 NS_ENDHANDLER; 139 [bs release]; bs = nil; 140 141 return data; 142} 143 144- (NSData *)availableData { 145 NSLog(@"NGConcreteStreamFileHandle(availableData) not implemented"); 146 [self notImplemented:_cmd]; 147 return nil; 148} 149 150/* writing */ 151 152- (void)writeData:(NSData *)_data { 153 [self->stream safeWriteBytes:[_data bytes] count:[_data length]]; 154} 155 156/* seeking */ 157 158- (unsigned long long)seekToEndOfFile { 159 NSLog(@"NGConcreteStreamFileHandle(seekToEndOfFile) not implemented"); 160 [self notImplemented:_cmd]; 161 return 0; 162} 163- (void)seekToFileOffset:(unsigned long long)_offset { 164 [(id<NGPositionableStream>)stream moveToLocation:_offset]; 165} 166 167- (unsigned long long)offsetInFile { 168 NSLog(@"_NGConcreteFileStreamFileHandle(offsetInFile:) not implemented, abort"); 169 [self notImplemented:_cmd]; 170 return 0; 171} 172 173/* asynchronous operations */ 174 175- (void)acceptConnectionInBackgroundAndNotify { 176 NSLog(@"NGConcreteStreamFileHandle(acceptConnectionInBackgroundAndNotify) " 177 @"not implemented"); 178 [self notImplemented:_cmd]; 179} 180- (void)acceptConnectionInBackgroundAndNotifyForModes:(NSArray *)_modes { 181 NSLog(@"NGConcreteStreamFileHandle(acceptConnectionInBackgroundAndNotifyForModes:) " 182 @"not implemented"); 183 [self notImplemented:_cmd]; 184} 185 186- (void)readInBackgroundAndNotify { 187 NSLog(@"NGConcreteStreamFileHandle(readInBackgroundAndNotify) not implemented"); 188 [self notImplemented:_cmd]; 189} 190- (void)readInBackgroundAndNotifyForModes:(NSArray *)_modes { 191 NSLog(@"NGConcreteStreamFileHandle(readInBackgroundAndNotifyForModes:) " 192 @"not implemented"); 193 [self notImplemented:_cmd]; 194} 195- (void)readToEndOfFileInBackgroundAndNotify { 196 NSLog(@"NGConcreteStreamFileHandle(readToEndOfFileInBackgroundAndNotify)" 197 @"not implemented"); 198 [self notImplemented:_cmd]; 199} 200- (void)readToEndOfFileInBackgroundAndNotifyForModes:(NSArray *)_modes { 201 NSLog(@"NGConcreteStreamFileHandle(" 202 @"readToEndOfFileInBackgroundAndNotifyForModes:)" 203 @"not implemented"); 204 [self notImplemented:_cmd]; 205} 206 207- (void)waitForDataInBackgroundAndNotify { 208 NSLog(@"NGConcreteStreamFileHandle(" 209 @"waitForDataInBackgroundAndNotify)" 210 @"not implemented"); 211 [self notImplemented:_cmd]; 212} 213- (void)waitForDataInBackgroundAndNotifyForModes:(NSArray *)_modes { 214 NSLog(@"NGConcreteStreamFileHandle(" 215 @"waitForDataInBackgroundAndNotifyForModes:)" 216 @"not implemented"); 217 [self notImplemented:_cmd]; 218} 219 220@end /* NGConcreteStreamFileHandle */ 221