Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 259 lines (201 sloc) 5.113 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
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
21 ILStream::ILStream(int fd) : ILObject() {
22 _fd = fd;
23 _mutex = ILRetain(new ILMutex());
24 }
3d58e5f @millenomi Shortcut to get the current message hub.
authored
25
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
26 ILStream::~ILStream() {
27 close();
28 ILRelease(_mutex);
29 }
30
31 ILData* ILStream::read(ILSize maximumBytes, ILStreamError* e) {
32 int fd = fileDescriptor();
33 if (fd < 0) {
34 if (e) *e = kILStreamErrorIsClosed;
35 return NULL;
36 }
3d58e5f @millenomi Shortcut to get the current message hub.
authored
37
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
38 uint8_t* bytes = (uint8_t*) malloc(maximumBytes);
39 int result = ::read(fd, bytes, maximumBytes);
40
41 if (result > 0) {
42 realloc(bytes, result);
43 return new ILData(bytes, (ILSize) result, kILDataTakeOwnershipOfMallocBuffer);
44 } else if (result == 0) {
45 if (e) *e = kILStreamErrorEndOfFile;
46 } else {
47 if ((errno == EAGAIN || errno == EWOULDBLOCK) && e)
48 *e = kILStreamErrorWouldHaveBlocked;
49 else if (e)
50 *e = kILStreamErrorPOSIX;
3d58e5f @millenomi Shortcut to get the current message hub.
authored
51 }
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
52
53 return NULL;
54 }
55
56 bool ILStream::write(ILData* data, ILSize* writtenBytes, ILStreamError* e) {
57 int fd = fileDescriptor();
58 if (fd < 0) {
59 if (e) *e = kILStreamErrorIsClosed;
60 return false;
61 }
62
63 int result = ::write(_fd, data->bytes(), data->length());
3d58e5f @millenomi Shortcut to get the current message hub.
authored
64
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
65 if (result >= 0) {
66 if (writtenBytes) *writtenBytes = result;
67 return true;
68 } else {
69 if ((errno == EAGAIN || errno == EWOULDBLOCK) && e)
70 *e = kILStreamErrorWouldHaveBlocked;
71 else if (e)
72 *e = kILStreamErrorPOSIX;
3d58e5f @millenomi Shortcut to get the current message hub.
authored
73 }
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
74
75 return false;
76 }
3d58e5f @millenomi Shortcut to get the current message hub.
authored
77
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
78 bool ILStream::writeAllOf(ILData* data, ILStreamError* e) {
79 ILSize written = 0;
80 ILStreamError innerError;
3d58e5f @millenomi Shortcut to get the current message hub.
authored
81
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
82 do {
83 ILReleasePool p;
84
85 ILSize newlyWritten;
86 bool result = write(new ILData(data->bytes() + written, data->length() - written), &newlyWritten, &innerError);
3d58e5f @millenomi Shortcut to get the current message hub.
authored
87
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
88 if (!result && innerError != kILStreamErrorWouldHaveBlocked) {
89 if (e) *e = innerError;
90 return false;
91 }
3d58e5f @millenomi Shortcut to get the current message hub.
authored
92
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
93 if (result)
94 written += newlyWritten;
95 } while (written < data->length());
96
97 return true;
98 }
3d58e5f @millenomi Shortcut to get the current message hub.
authored
99
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
100 ILData* ILStream::readBytesUpTo(ILSize toRead, bool endOfFileIsError, ILStreamError* e) {
101 ILData* d = new ILData();
102
103 do {
104 ILReleasePool p;
3d58e5f @millenomi Shortcut to get the current message hub.
authored
105
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
106 ILStreamError innerError;
107 ILData* part = read(toRead, &innerError);
3d58e5f @millenomi Shortcut to get the current message hub.
authored
108
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
109 if (part) {
110 d->appendData(part);
111 toRead -= part->length();
112 } else {
113 if (innerError == kILStreamErrorEndOfFile && !endOfFileIsError)
3d58e5f @millenomi Shortcut to get the current message hub.
authored
114 break;
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
115
116 if (e) *e = innerError;
117 return NULL;
118 }
119 } while (toRead > 0);
120
121 return d;
3d58e5f @millenomi Shortcut to get the current message hub.
authored
122 }
123
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
124 ILData* ILStream::readUntilEnd(ILStreamError* e) {
125 ILData* d = new ILData();
3d58e5f @millenomi Shortcut to get the current message hub.
authored
126
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
127 ILStreamError innerError;
128 do {
129 ILReleasePool p;
130
131 ILData* part = read(1024 * 512, &innerError);
132
133 if (part) {
134 innerError = kILStreamErrorNone;
135 d->appendData(part);
136 } else if (innerError != kILStreamErrorEndOfFile) {
137 if (e) *e = innerError;
138 return NULL;
139 }
140 } while (innerError == kILStreamErrorNone);
3d58e5f @millenomi Shortcut to get the current message hub.
authored
141
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
142 return d;
3d58e5f @millenomi Shortcut to get the current message hub.
authored
143 }
144
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
145 void ILStream::close() {
146 ILAcquiredMutex m(_mutex);
147 ::close(_fd);
148 _fd = -1;
3d58e5f @millenomi Shortcut to get the current message hub.
authored
149 }
150
151
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
152 // Non-blocking I/O
153 // 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
154
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
155 bool ILStream::allowsBlocking() {
156 int fd = fileDescriptor();
3d58e5f @millenomi Shortcut to get the current message hub.
authored
157 if (fd < 0)
158 return false;
159
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
160 int flags = fcntl(fd, F_GETFD);
161 if (flags < 0)
162 return false;
3d58e5f @millenomi Shortcut to get the current message hub.
authored
163
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
164 return (flags & O_NONBLOCK) != 0;
3d58e5f @millenomi Shortcut to get the current message hub.
authored
165 }
166
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
167 bool ILStream::setAllowsBlocking(bool x) {
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 if (x)
177 flags |= O_NONBLOCK;
178 else
179 flags &= ~O_NONBLOCK;
180
181 return fcntl(fd, F_SETFD, flags) >= 0;
3d58e5f @millenomi Shortcut to get the current message hub.
authored
182 }
183
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
184 bool ILStream::canDisableBlocking() {
185 return true;
3d58e5f @millenomi Shortcut to get the current message hub.
authored
186 }
187
188
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
189 bool ILStream::canDetermineReadyState() {
190 return true;
3d58e5f @millenomi Shortcut to get the current message hub.
authored
191 }
192
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
193 bool ILStream::isReadyForWriting() {
194 bool canWrite;
195 _determineReadyState(NULL, &canWrite);
196 return canWrite;
3d58e5f @millenomi Shortcut to get the current message hub.
authored
197 }
198
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
199 bool ILStream::isReadyForReading() {
200 bool canRead;
201 _determineReadyState(&canRead, NULL);
202 return canRead;
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 void ILStream::_determineReadyState(bool* reading, bool* writing) {
206 int fd = fileDescriptor();
207 if (fd < 0) {
208 if (reading) *reading = false;
209 if (writing) *writing = false;
210 return;
211 }
212
213 fd_set* readingSetPointer = NULL;
214 fd_set readingSet;
215 if (reading) {
216 FD_ZERO(&readingSet);
217 FD_SET(fd, &readingSet);
218 readingSetPointer = &readingSet;
219 }
3d58e5f @millenomi Shortcut to get the current message hub.
authored
220
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
221 fd_set* writingSetPointer = NULL;
222 fd_set writingSet;
223 if (writing) {
224 FD_ZERO(&writingSet);
225 FD_SET(fd, &writingSet);
226 writingSetPointer = &writingSet;
227 }
228
229 // TODO error conds?
230 struct timeval tv;
231 tv.tv_sec = 0;
232 tv.tv_usec = 0;
233 int result = select(fd + 1, readingSetPointer, writingSetPointer, NULL, &tv);
234
235 if (result < 0) {
236 if (reading) *reading = false;
237 if (writing) *writing = false;
3d58e5f @millenomi Shortcut to get the current message hub.
authored
238 return;
239 }
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
240
241 if (reading)
242 *reading = FD_ISSET(fd, readingSetPointer);
243
244 if (writing)
245 *writing = FD_ISSET(fd, writingSetPointer);
3d58e5f @millenomi Shortcut to get the current message hub.
authored
246 }
da3bf9d @millenomi Shortcut to add and remove a stream from the current run loop.
authored
247
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
248 int ILStream::fileDescriptor() {
249 ILAcquiredMutex m(_mutex);
250 return _fd;
da3bf9d @millenomi Shortcut to add and remove a stream from the current run loop.
authored
251 }
252
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
253 // ~ ILStreamSource ~
254
255 ILStreamSource::ILStreamSource() : ILObject() {}
256 ILStreamSource::~ILStreamSource() {}
da3bf9d @millenomi Shortcut to add and remove a stream from the current run loop.
authored
257
32a1d74 @millenomi Reverted to another, simpler implementation of ILStream; disabled stuff ...
authored
258 bool ILStreamSource::canOpen() { return true; }
Something went wrong with that request. Please try again.