]> err.no Git - sope/blob - sope-core/NGExtensions/FileObjectHolder.m
Drop apache 1 build-dependency
[sope] / sope-core / NGExtensions / FileObjectHolder.m
1 /*
2   Copyright (C) 2002-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 "FileObjectHolder.h"
23 #include "NSRunLoop+FileObjects.h"
24 #import <Foundation/NSException.h>
25 #import <Foundation/NSNotification.h>
26 #import <Foundation/NSFileHandle.h>
27 #include "common.h"
28
29 @implementation FileObjectHolder
30
31 - (id)initWithFileObject:(id)_object
32   activities:(int)_activities
33   mode:(NSString *)_mode 
34 {
35   if (_object == nil) {
36     [self release];
37     return nil;
38   }
39   self->fileObject = [_object retain];
40   self->fd         = [_object fileDescriptor];
41   self->activities = _activities;
42   self->mode       = [_mode copy];
43   self->fileHandle =
44     [[NSFileHandle alloc] initWithFileDescriptor:self->fd closeOnDealloc:NO];
45   NSAssert(self->fileHandle, @"couldn't create filehandle ...");
46
47   [[self notificationCenter]
48          addObserver:self selector:@selector(_dataAvailable:)
49          name:NSFileHandleDataAvailableNotification 
50          object:self->fileHandle];
51   [[self notificationCenter]
52          addObserver:self selector:@selector(_acceptAvailable:)
53          name:NSFileHandleConnectionAcceptedNotification
54          object:self->fileHandle];
55   
56   return self;
57 }
58
59 - (void)dealloc {
60   if (self->waitActive)
61     [[self notificationCenter] removeObserver:self];
62   [self->mode       release];
63   [self->fileHandle release];
64   [self->fileObject release];
65   [super dealloc];
66 }
67
68 /* accessors */
69
70 - (int)fileDescriptor {
71   return self->fd;
72 }
73 - (NSFileHandle *)fileHandle {
74   return self->fileHandle;
75 }
76 - (id)fileObject {
77   return self->fileObject;
78 }
79 - (int)activities {
80   return self->activities;
81 }
82 - (NSString *)mode {
83   return self->mode;
84 }
85
86 - (NSArray *)modes {
87   return [NSArray arrayWithObject:[self mode]];
88 }
89
90 /* notifications */
91
92 - (NSNotificationCenter *)notificationCenter {
93   return [NSNotificationCenter defaultCenter];
94 }
95
96 - (void)handleException:(NSException *)_exception {
97   NSLog(@"%s: catched: %@", __PRETTY_FUNCTION__, _exception);
98 }
99
100 - (void)_dataAvailable:(NSNotification *)_notification {
101   if ([_notification object] != self->fileHandle) {
102     NSLog(@"%s: notification object %@ does not match file handle %@",
103           __PRETTY_FUNCTION__, [_notification object], self->fileHandle);
104     return;
105   }
106   
107   if (![self->fileObject isOpen]) {
108     //NSLog(@"file object is closed ...");
109     return;
110   }
111   
112   NS_DURING {
113     self->waitActive = NO;
114     [self wait];
115     [[self notificationCenter]
116            postNotificationName:NSFileObjectBecameActiveNotificationName
117            object:self->fileObject];
118   }
119   NS_HANDLER
120     [self handleException:localException];
121   NS_ENDHANDLER;
122 }
123
124 - (void)_acceptAvailable:(NSNotification *)_notification {
125   NSLog(@"accept available ...");
126   if ([_notification object] != self->fileHandle) {
127     NSLog(@"%s: notification object %@ does not match file handle %@",
128           __PRETTY_FUNCTION__, [_notification object], self->fileHandle);
129     return;
130   }
131   [[self notificationCenter]
132          postNotificationName:NSFileObjectBecameActiveNotificationName
133          object:self->fileObject];
134 }
135
136 /* operations */
137
138 - (void)wait {
139   if (self->waitActive) return;
140   
141   if (![self->fileObject isOpen]) return;
142   
143   self->waitActive = YES;
144   
145 #if 0
146   /* use accept for passive fileobjects ?, wait seems to work too ... :-) */
147   if ([self->fileObject isPassive]) {
148     NSLog(@"add passive %@ ..", self->fileObject);
149 // => this also accepts the connection :-(
150     [self->fileHandle acceptConnectionInBackgroundAndNotifyForModes:
151                         [self modes]];
152   }
153   else
154 #endif
155     [self->fileHandle waitForDataInBackgroundAndNotifyForModes:[self modes]];
156 }
157 - (void)stopWaiting {
158 }
159
160 /* equality */
161
162 - (BOOL)isEqualToFileObjectHolder:(FileObjectHolder *)_other {
163   if (self->fd != _other->fd) return NO;
164   if (![self->mode isEqualToString:_other->mode]) return NO;
165   if (![self->fileObject isEqual:_other->fileObject]) return NO;
166   return YES;
167 }
168 - (BOOL)isEqual:(id)_other {
169   if (_other == self) return YES;
170   if (_other == nil)  return NO;
171   if ([_other class] != [self class]) return NO;
172   return [self isEqualToFileObjectHolder:_other];
173 }
174
175 /* description */
176
177 @end /* FileObject */