]> err.no Git - sope/blob - sope-core/NGStreams/NGStreamPipe.m
fixed a Tiger warning
[sope] / sope-core / NGStreams / NGStreamPipe.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 "config.h"
23 #include "common.h"
24 #include "NGStreamPipe.h"
25 #include "NGFileStream.h"
26 #include "NGBufferedStream.h"
27
28 #if defined(WIN32)
29
30 @implementation NGStreamPipe
31 @end
32
33 #else
34
35 static const int NGInvalidUnixDescriptor = -1;
36
37 @interface _NGConcretePipeFileHandle : NSFileHandle
38 {
39 @public
40   int *fd;
41 }
42
43 - (id)initWithDescriptor:(int *)_fd;
44
45 @end
46
47 @interface NGFileStream(PrivateMethods)
48 - (id)__initWithDescriptor:(int)_fd mode:(NGStreamMode)_mode;
49 @end
50
51 @implementation NGStreamPipe
52
53 + (id)pipe {
54   return [[[self alloc] init] autorelease];
55 }
56
57 - (id)init {
58   if (pipe(self->fildes) == -1) {
59     NSLog (@"pipe() system call failed: %s", strerror (errno));
60     self = [self autorelease];
61     return nil;
62   }
63   return self;
64 }
65
66 - (void)gcFinalize {
67   [self close];
68 }
69
70 - (void)dealloc {
71   [self gcFinalize];
72   [self->fhIn  release];
73   [self->fhOut release];
74   [super dealloc];
75 }
76
77 - (NSFileHandle *)fileHandleForReading {
78   if (self->fhIn == nil) {
79     self->fhIn = [[_NGConcretePipeFileHandle alloc]
80                       initWithDescriptor:&(self->fildes[0])];
81   }
82   return self->fhIn;
83 }
84 - (NSFileHandle *)fileHandleForWriting {
85   if (self->fhOut == nil) {
86     self->fhOut = [[_NGConcretePipeFileHandle alloc]
87                        initWithDescriptor:&(self->fildes[1])];
88   }
89   return self->fhOut;
90 }
91
92 - (id<NGByteSequenceStream>)streamForReading {
93   return self;
94 }
95 - (id<NGOutputStream>)streamForWriting {
96   return self;
97 }
98
99 - (NSException *)lastException {
100   return nil;
101 }
102
103 /* NGInputStream */
104
105 - (unsigned)readBytes:(void *)_buf count:(unsigned)_len {
106   int readResult;
107
108   if (self->fildes[0] == NGInvalidUnixDescriptor) {
109     [NGStreamReadErrorException raiseWithStream:self
110                                 reason:@"read end of pipe is closed"];
111   }
112   
113   readResult = read(self->fildes[0], _buf, _len);
114
115   if (readResult == 0)
116     [NGEndOfStreamException raiseWithStream:self];
117   else if (readResult == -1)
118     [NGStreamReadErrorException raiseWithStream:self errorCode:errno];
119
120   return readResult;
121 }
122 - (BOOL)safeReadBytes:(void *)_buf count:(unsigned)_len {
123   return NGSafeReadBytesFromStream(self, _buf, _len);
124 }
125
126 /* marks */
127
128 - (BOOL)mark {
129   NSLog(@"WARNING: called mark on a stream which doesn't support marking !");
130   return NO;
131 }
132 - (BOOL)rewind {
133   [NGStreamException raiseWithStream:self reason:@"marking not supported"];
134   return NO;
135 }
136 - (BOOL)markSupported {
137   return NO;
138 }
139
140 /* NGOutputStream */
141
142 - (unsigned)writeBytes:(const void *)_buf count:(unsigned)_len {
143   int writeResult;
144
145   if (self->fildes[1] == NGInvalidUnixDescriptor) {
146     [NGStreamWriteErrorException raiseWithStream:self
147                                  reason:@"write end of pipe is closed"];
148   }
149   
150   writeResult = write(self->fildes[1], _buf, _len);
151
152   if (writeResult == -1)
153     [NGStreamWriteErrorException raiseWithStream:self errorCode:errno];
154   return writeResult;
155 }
156 - (BOOL)safeWriteBytes:(const void *)_buf count:(unsigned)_len {
157   return NGSafeWriteBytesToStream(self, _buf, _len);
158 }
159
160 - (BOOL)flush {
161   return YES;
162 }
163
164 /* NGStream */
165
166 - (BOOL)close {
167   if (self->fildes[0] != NGInvalidUnixDescriptor) close(self->fildes[0]);
168   if (self->fildes[1] != NGInvalidUnixDescriptor) close(self->fildes[1]);
169   return YES;
170 }
171
172 - (NGStreamMode)mode {
173   NGStreamMode mode = NGStreamMode_undefined;
174
175   if (self->fildes[0] != NGInvalidUnixDescriptor)
176     mode |= NGStreamMode_readOnly;
177   if (self->fildes[1] != NGInvalidUnixDescriptor)
178     mode |= NGStreamMode_writeOnly;
179
180   return mode;
181 }
182
183 // NGByteSequenceStream
184
185 - (int)readByte {
186   return NGReadByteFromStream(self);
187 }
188
189 // Extensions
190
191 - (BOOL)isOpen {
192   return (self->fildes[0] == NGInvalidUnixDescriptor) &&
193          (self->fildes[1] == NGInvalidUnixDescriptor) ? NO : YES;
194 }
195
196 /* description */
197
198 - (NSString *)description {
199   return [NSString stringWithFormat:@"<0x%08X[%@]: in=%i out=%i>",
200                      self, NSStringFromClass([self class]),
201                      self->fildes[0], self->fildes[1]];
202 }
203
204 @end /* NGStreamPipe */
205
206 @implementation _NGConcretePipeFileHandle
207
208 - (id)initWithDescriptor:(int *)_fd {
209   self->fd = _fd;
210   return self;
211 }
212
213 - (int)fileDescriptor {
214   return *(self->fd);
215 }
216
217 - (void)closeFile {
218   close(*(self->fd));
219   *(self->fd) = NGInvalidUnixDescriptor;
220 }
221
222 @end
223
224 #endif /* WIN32 */