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