Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 282 lines (217 sloc) 5.865 kb
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
1 //
2 // ILStream.cpp
3 // MoverCore
4 //
5 // Created by ∞ on 23/07/10.
6 // Copyright (c) 2010 __MyCompanyName__. All rights reserved.
7 //
3d58e5f @millenomi Shortcut to get the current message hub.
authored
8
9 #include "ILStream.h"
10
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
11 #include <stdio.h>
12 #include <sys/types.h>
13 #include <sys/uio.h>
14 #include <unistd.h>
15 #include <errno.h>
16
17 #include <fcntl.h>
18
3d58e5f @millenomi Shortcut to get the current message hub.
authored
19 #include <sys/select.h>
20
341418a @millenomi Fixed stream monitor not delivering monitoring messages if there is no i...
authored
21 #include "ILRunLoop.h"
22
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
23 ILStream::ILStream(int fd) : ILObject() {
24 _fd = fd;
25 _mutex = ILRetain(new ILMutex());
341418a @millenomi Fixed stream monitor not delivering monitoring messages if there is no i...
authored
26 _countOfObservingClients = 0;
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
27 }
3d58e5f @millenomi Shortcut to get the current message hub.
authored
28
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
29 ILStream::~ILStream() {
30 close();
31 ILRelease(_mutex);
32 }
33
17294f4 @millenomi Renamed ILStream observation messages for consistency.
authored
34 ILUniqueConstant(kILStreamDidReadMessage);
35 ILUniqueConstant(kILStreamDidWriteMessage);
341418a @millenomi Fixed stream monitor not delivering monitoring messages if there is no i...
authored
36
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
37 ILData* ILStream::read(ILSize maximumBytes, ILStreamError* e) {
38 int fd = fileDescriptor();
39 if (fd < 0) {
40 if (e) *e = kILStreamErrorIsClosed;
41 return NULL;
42 }
3d58e5f @millenomi Shortcut to get the current message hub.
authored
43
341418a @millenomi Fixed stream monitor not delivering monitoring messages if there is no i...
authored
44 if (_countOfObservingClients > 0)
17294f4 @millenomi Renamed ILStream observation messages for consistency.
authored
45 ILRunLoop::current()->currentThreadTarget()->deliverMessage(new ILMessage(kILStreamDidReadMessage, this, NULL));
341418a @millenomi Fixed stream monitor not delivering monitoring messages if there is no i...
authored
46
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
47 uint8_t* bytes = (uint8_t*) malloc(maximumBytes);
48 int result = ::read(fd, bytes, maximumBytes);
49
50 if (result > 0) {
51 realloc(bytes, result);
52 return new ILData(bytes, (ILSize) result, kILDataTakeOwnershipOfMallocBuffer);
53 } else if (result == 0) {
54 if (e) *e = kILStreamErrorEndOfFile;
55 } else {
56 if ((errno == EAGAIN || errno == EWOULDBLOCK) && e)
57 *e = kILStreamErrorWouldHaveBlocked;
58 else if (e)
59 *e = kILStreamErrorPOSIX;
3d58e5f @millenomi Shortcut to get the current message hub.
authored
60 }
341418a @millenomi Fixed stream monitor not delivering monitoring messages if there is no i...
authored
61
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
62 return NULL;
63 }
64
65 bool ILStream::write(ILData* data, ILSize* writtenBytes, ILStreamError* e) {
66 int fd = fileDescriptor();
67 if (fd < 0) {
68 if (e) *e = kILStreamErrorIsClosed;
69 return false;
70 }
71
341418a @millenomi Fixed stream monitor not delivering monitoring messages if there is no i...
authored
72 if (_countOfObservingClients > 0)
17294f4 @millenomi Renamed ILStream observation messages for consistency.
authored
73 ILRunLoop::current()->currentThreadTarget()->deliverMessage(new ILMessage(kILStreamDidWriteMessage, this, NULL));
341418a @millenomi Fixed stream monitor not delivering monitoring messages if there is no i...
authored
74
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
75 int result = ::write(_fd, data->bytes(), data->length());
3d58e5f @millenomi Shortcut to get the current message hub.
authored
76
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
77 if (result >= 0) {
78 if (writtenBytes) *writtenBytes = result;
79 return true;
80 } else {
81 if ((errno == EAGAIN || errno == EWOULDBLOCK) && e)
82 *e = kILStreamErrorWouldHaveBlocked;
83 else if (e)
84 *e = kILStreamErrorPOSIX;
3d58e5f @millenomi Shortcut to get the current message hub.
authored
85 }
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
86
87 return false;
88 }
3d58e5f @millenomi Shortcut to get the current message hub.
authored
89
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
90 bool ILStream::writeAllOf(ILData* data, ILStreamError* e) {
91 ILSize written = 0;
92 ILStreamError innerError;
3d58e5f @millenomi Shortcut to get the current message hub.
authored
93
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
94 do {
95 ILReleasePool p;
96
97 ILSize newlyWritten;
98 bool result = write(new ILData(data->bytes() + written, data->length() - written), &newlyWritten, &innerError);
3d58e5f @millenomi Shortcut to get the current message hub.
authored
99
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
100 if (!result && innerError != kILStreamErrorWouldHaveBlocked) {
101 if (e) *e = innerError;
102 return false;
103 }
3d58e5f @millenomi Shortcut to get the current message hub.
authored
104
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
105 if (result)
106 written += newlyWritten;
107 } while (written < data->length());
108
109 return true;
110 }
3d58e5f @millenomi Shortcut to get the current message hub.
authored
111
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
112 ILData* ILStream::readBytesUpTo(ILSize toRead, bool endOfFileIsError, ILStreamError* e) {
113 ILData* d = new ILData();
114
115 do {
116 ILReleasePool p;
3d58e5f @millenomi Shortcut to get the current message hub.
authored
117
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
118 ILStreamError innerError;
119 ILData* part = read(toRead, &innerError);
3d58e5f @millenomi Shortcut to get the current message hub.
authored
120
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
121 if (part) {
122 d->appendData(part);
123 toRead -= part->length();
124 } else {
125 if (innerError == kILStreamErrorEndOfFile && !endOfFileIsError)
3d58e5f @millenomi Shortcut to get the current message hub.
authored
126 break;
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
127
128 if (e) *e = innerError;
129 return NULL;
130 }
131 } while (toRead > 0);
132
133 return d;
3d58e5f @millenomi Shortcut to get the current message hub.
authored
134 }
135
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
136 ILData* ILStream::readUntilEnd(ILStreamError* e) {
137 ILData* d = new ILData();
3d58e5f @millenomi Shortcut to get the current message hub.
authored
138
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
139 ILStreamError innerError;
140 do {
141 ILReleasePool p;
142
143 ILData* part = read(1024 * 512, &innerError);
144
145 if (part) {
146 innerError = kILStreamErrorNone;
147 d->appendData(part);
148 } else if (innerError != kILStreamErrorEndOfFile) {
149 if (e) *e = innerError;
150 return NULL;
151 }
152 } while (innerError == kILStreamErrorNone);
3d58e5f @millenomi Shortcut to get the current message hub.
authored
153
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
154 return d;
3d58e5f @millenomi Shortcut to get the current message hub.
authored
155 }
156
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
157 void ILStream::close() {
158 ILAcquiredMutex m(_mutex);
159 ::close(_fd);
160 _fd = -1;
3d58e5f @millenomi Shortcut to get the current message hub.
authored
161 }
162
163
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
164 // Non-blocking I/O
165 // NOTE: For now, we REQUIRE the platform to support it. This may be relaxed in a future version of this code.
3d58e5f @millenomi Shortcut to get the current message hub.
authored
166
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
167 bool ILStream::allowsBlocking() {
168 int fd = fileDescriptor();
3d58e5f @millenomi Shortcut to get the current message hub.
authored
169 if (fd < 0)
170 return false;
171
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
172 int flags = fcntl(fd, F_GETFD);
173 if (flags < 0)
174 return false;
3d58e5f @millenomi Shortcut to get the current message hub.
authored
175
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
176 return (flags & O_NONBLOCK) != 0;
3d58e5f @millenomi Shortcut to get the current message hub.
authored
177 }
178
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
179 bool ILStream::setAllowsBlocking(bool x) {
180 int fd = fileDescriptor();
3d58e5f @millenomi Shortcut to get the current message hub.
authored
181 if (fd < 0)
182 return false;
183
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
184 int flags = fcntl(fd, F_GETFD);
185 if (flags < 0)
186 return false;
3d58e5f @millenomi Shortcut to get the current message hub.
authored
187
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
188 if (x)
189 flags |= O_NONBLOCK;
190 else
191 flags &= ~O_NONBLOCK;
192
193 return fcntl(fd, F_SETFD, flags) >= 0;
3d58e5f @millenomi Shortcut to get the current message hub.
authored
194 }
195
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
196 bool ILStream::canDisableBlocking() {
197 return true;
3d58e5f @millenomi Shortcut to get the current message hub.
authored
198 }
199
200
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
201 bool ILStream::canDetermineReadyState() {
202 return true;
3d58e5f @millenomi Shortcut to get the current message hub.
authored
203 }
204
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
205 bool ILStream::isReadyForWriting() {
206 bool canWrite;
207 _determineReadyState(NULL, &canWrite);
208 return canWrite;
3d58e5f @millenomi Shortcut to get the current message hub.
authored
209 }
210
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
211 bool ILStream::isReadyForReading() {
212 bool canRead;
213 _determineReadyState(&canRead, NULL);
214 return canRead;
3d58e5f @millenomi Shortcut to get the current message hub.
authored
215 }
216
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
217 void ILStream::_determineReadyState(bool* reading, bool* writing) {
218 int fd = fileDescriptor();
219 if (fd < 0) {
220 if (reading) *reading = false;
221 if (writing) *writing = false;
222 return;
223 }
224
225 fd_set* readingSetPointer = NULL;
226 fd_set readingSet;
227 if (reading) {
228 FD_ZERO(&readingSet);
229 FD_SET(fd, &readingSet);
230 readingSetPointer = &readingSet;
231 }
3d58e5f @millenomi Shortcut to get the current message hub.
authored
232
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
233 fd_set* writingSetPointer = NULL;
234 fd_set writingSet;
235 if (writing) {
236 FD_ZERO(&writingSet);
237 FD_SET(fd, &writingSet);
238 writingSetPointer = &writingSet;
239 }
240
241 // TODO error conds?
242 struct timeval tv;
243 tv.tv_sec = 0;
244 tv.tv_usec = 0;
245 int result = select(fd + 1, readingSetPointer, writingSetPointer, NULL, &tv);
246
247 if (result < 0) {
248 if (reading) *reading = false;
249 if (writing) *writing = false;
3d58e5f @millenomi Shortcut to get the current message hub.
authored
250 return;
251 }
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
252
253 if (reading)
254 *reading = FD_ISSET(fd, readingSetPointer);
255
256 if (writing)
257 *writing = FD_ISSET(fd, writingSetPointer);
3d58e5f @millenomi Shortcut to get the current message hub.
authored
258 }
da3bf9d @millenomi Shortcut to add and remove a stream from the current run loop.
authored
259
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
260 int ILStream::fileDescriptor() {
261 ILAcquiredMutex m(_mutex);
262 return _fd;
da3bf9d @millenomi Shortcut to add and remove a stream from the current run loop.
authored
263 }
264
341418a @millenomi Fixed stream monitor not delivering monitoring messages if there is no i...
authored
265 void ILStream::beginObservingStream() {
266 _countOfObservingClients++;
267 }
268
269 void ILStream::endObservingStream() {
270 if (_countOfObservingClients == 0)
271 ILAbort("Mismatched call (end... called without a matching begin...).");
272
273 _countOfObservingClients--;
274 }
275
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
276 // ~ ILStreamSource ~
277
278 ILStreamSource::ILStreamSource() : ILObject() {}
279 ILStreamSource::~ILStreamSource() {}
da3bf9d @millenomi Shortcut to add and remove a stream from the current run loop.
authored
280
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
281 bool ILStreamSource::canOpen() { return true; }
Something went wrong with that request. Please try again.