root/lang/c/mpio/trunk/mp/ios/rw.h @ 7791

Revision 7791, 9.4 kB (checked in by frsyuki, 6 years ago)

lang/c/mpio: fiexed ios_{read,write}_just bug

Line 
1#ifndef MP_IOS_RW_H__
2#define MP_IOS_RW_H__
3
4#include <unistd.h>
5#include <errno.h>
6
7namespace mp {
8namespace ios {
9
10
11template <typename IO, typename Callback>
12struct iosf_read : ios {
13        iosf_read(IO& _io, void* _buf, size_t _buflen, Callback _callback) :
14                io(_io), buf((char*)_buf), buflen(_buflen), callback(_callback) {}
15        ~iosf_read() {}
16        next_t operator() (int fd, short event)
17        {
18                ssize_t rl;
19                if( (rl = read(fd, buf, buflen)) < 0 ) {
20                        if( errno == EAGAIN || errno == EINTR ) { return MP_IOS_CONTINUE; }
21                        int err = callback(io, errno, fd, buf, buflen, static_cast<size_t>(rl));
22                        return MP_IOS_END(err);
23                }
24                int err = callback(io, 0, fd, buf, buflen, static_cast<size_t>(rl));
25                return MP_IOS_END(err);
26        }
27private:
28        IO& io;
29        char* buf;
30        size_t buflen;
31        ios_callback<int (IO&, int, int, char*, size_t, size_t), Callback> callback;
32};
33
34template <typename IO, typename Callback>
35int ios_read(IO& io, int fd, void* buf, size_t buflen, Callback callback)
36{
37        typedef iosf_read<IO, Callback> IOS;
38        return MP_IOS_ADD(io, IOS, &IOS::operator(),
39                        fd, EV_READ, IOS(io, buf, buflen, callback));
40}
41
42
43template <typename IO, typename Callback>
44struct iosf_read_at_least : ios {
45        iosf_read_at_least(IO& _io, void* _buf, size_t _buflen,
46                           size_t _minlen, Callback _callback) :
47                io(_io), buf((char*)_buf), current(_buf), buflen(_buflen),
48                rest(_buflen), minlen(_minlen), callback(_callback) {}
49        next_t operator() (int fd, short event)
50        {
51                ssize_t rl;
52                if( (rl = read(fd, current, rest)) < 0 ) {
53                        if( errno == EAGAIN || errno == EINTR ) { return MP_IOS_CONTINUE; }
54                        int err = callback(io, errno, fd, buf, buflen,
55                                           minlen, current - buf);
56                        return MP_IOS_END(err);
57                }
58                if( rl == 0 ) {
59                        int err = callback(io, 0, fd, buf, buflen,
60                                           minlen, current - buf);
61                        return MP_IOS_END(err);
62                }
63                current += rl;
64                if( rest <= rl ) {
65                        int err = callback(io, 0, fd, buf, buflen,
66                                           minlen, current - buf);
67                        return MP_IOS_END(err);
68                }
69                rest -= rl;
70                return MP_IOS_CONTINUE;
71        }
72private:
73        IO& io;
74        char* buf;
75        char* current;
76        size_t buflen;
77        size_t rest;
78        size_t minlen;
79        ios_callback<int (IO&, int, int, char*, size_t), Callback> callback;
80};
81
82template <typename IO, typename Callback>
83int ios_read_at_least(IO& io, int fd, void* buf, size_t buflen,
84                      size_t minlen, Callback callback)
85{
86        typedef iosf_read_at_least<IO, Callback> IOS;
87        return MP_IOS_ADD(io, IOS, &IOS::operator(),
88                        fd, EV_READ, IOS(io, buf, buflen, minlen, callback));
89}
90
91
92template <typename IO, typename Callback>
93struct iosf_read_at_most : ios {
94        iosf_read_at_most(IO& _io, void* _buf, size_t _buflen,
95                          size_t _maxlen, Callback _callback) :
96                io(_io), buf((char*)_buf), buflen(_buflen),
97                maxlen(_maxlen), callback(_callback) {}
98        next_t operator() (int fd, short event)
99        {
100                ssize_t rl;
101                if( (rl = read(fd, buf, maxlen)) < 0 ) {
102                        if( errno == EAGAIN || errno == EINTR ) { return MP_IOS_CONTINUE; }
103                        int err = callback(io, errno, fd, buf, buflen,
104                                           maxlen, static_cast<size_t>(rl));
105                        return MP_IOS_END(err);
106                }
107                int err = callback(io, 0, fd, buf, buflen,
108                                   maxlen, static_cast<size_t>(rl));
109                return MP_IOS_END(err);
110        }
111private:
112        IO& io;
113        char* buf;
114        size_t buflen;
115        size_t maxlen;
116        ios_callback<int (IO&, int, int, char*, size_t, size_t), Callback> callback;
117};
118
119template <typename IO, typename Callback>
120int ios_read_at_most(IO& io, int fd, void* buf, size_t buflen,
121                     size_t maxlen, Callback callback)
122{
123        return io.add(  fd,
124                        EV_READ,
125                        iosf_read_at_most<IO, Callback>(io, buf, buflen,
126                                                        maxlen, callback) );
127}
128
129
130
131template <typename IO, typename Callback>
132struct iosf_read_just : ios {
133        iosf_read_just(IO& _io, void* _buf, size_t _len, Callback _callback) :
134                io(_io), buf((char*)_buf), current((char*)_buf), rest(_len),
135                callback(_callback) {}
136        next_t operator() (int fd, short event)
137        {
138                ssize_t rl;
139                if( (rl = read(fd, current, rest)) < 0 ) {
140                        if( errno == EAGAIN ) {
141                                return MP_IOS_CONTINUE;
142                        }
143                        size_t reached = current - buf;
144                        int err = callback(io, fd, buf, reached + rest, reached);
145                        return MP_IOS_END(err);
146                }
147                if( rl == 0 ) {
148                        size_t reached = current - buf;
149                        int err = callback(io, fd, buf, reached + rest, reached);
150                        return MP_IOS_END(err);
151                }
152                if( rest <= (size_t)rl ) {
153                        size_t reached = current - buf + rl;
154                        int err = callback(io, fd, buf, reached, reached);
155                        return MP_IOS_END(err);
156                }
157                rest -= rl;
158                current += rl;
159                return MP_IOS_CONTINUE;
160        }
161private:
162        IO& io;
163        char* buf;
164        char* current;
165        size_t rest;
166        ios_callback<int (IO&, int, char*, size_t, size_t), Callback> callback;
167};
168
169template <typename IO, typename Callback>
170int ios_read_just(IO& io, int fd, void* buf, size_t len, Callback callback)
171{
172        typedef iosf_read_just<IO, Callback> IOS;
173        return MP_IOS_ADD(io, IOS, &IOS::operator(),
174                        fd, EV_READ, IOS(io, buf, len, callback));
175}
176
177/* =================================== */
178
179
180template <typename IO, typename Callback>
181struct iosf_write : ios {
182        iosf_write(IO& _io, void* _buf, size_t _buflen, Callback _callback) :
183                io(_io), buf((char*)_buf), buflen(_buflen), callback(_callback) {}
184        next_t operator() (int fd, short event)
185        {
186                ssize_t rl;
187                if( (rl = write(fd, buf, buflen)) < 0 ) {
188                        if( errno == EAGAIN || errno == EINTR ) { return MP_IOS_CONTINUE; }
189                        int err = callback(io, errno, fd, buf, buflen, static_cast<size_t>(rl));
190                        return MP_IOS_END(err);
191                }
192                int err = callback(io, 0, fd, buf, buflen, static_cast<size_t>(rl));
193                return MP_IOS_END(err);
194        }
195private:
196        IO& io;
197        char* buf;
198        size_t buflen;
199        ios_callback<int (IO&, int, int, char*, size_t, size_t), Callback> callback;
200};
201
202template <typename IO, typename Callback>
203int ios_write(IO& io, int fd, void* buf, size_t buflen, Callback callback)
204{
205        return io.add(  fd,
206                        EV_WRITE,
207                        iosf_write<IO, Callback>(io, buf, buflen, callback) );
208}
209
210
211
212template <typename IO, typename Callback>
213struct iosf_write_at_least : ios {
214        iosf_write_at_least(IO& _io, void* _buf, size_t _buflen,
215                           size_t _minlen, Callback _callback) :
216                io(_io), buf((char*)_buf), current(_buf), buflen(_buflen),
217                rest(_buflen), minlen(_minlen), callback(_callback) {}
218        next_t operator() (int fd, short event)
219        {
220                ssize_t rl;
221                if( (rl = write(fd, current, rest)) < 0 ) {
222                        if( errno == EAGAIN || errno == EINTR ) { return MP_IOS_CONTINUE; }
223                        int err = callback(io, errno, fd, buf, buflen,
224                                           minlen, current - buf);
225                        return MP_IOS_END(err);
226                }
227                if( rl == 0 ) {
228                        int err = callback(io, 0, fd, buf, buflen,
229                                           minlen, current - buf);
230                        return MP_IOS_END(err);
231                }
232                current += rl;
233                if( rest <= rl ) {
234                        int err = callback(io, 0, fd, buf, buflen,
235                                           minlen, current - buf);
236                        return MP_IOS_END(err);
237                }
238                rest -= rl;
239                return MP_IOS_CONTINUE;
240        }
241private:
242        IO& io;
243        char* buf;
244        char* current;
245        size_t buflen;
246        size_t rest;
247        size_t minlen;
248        ios_callback<int (IO&, int, int, char*, size_t), Callback> callback;
249};
250
251
252template <typename IO, typename Callback>
253int ios_write_at_least(IO& io, int fd, void* buf, size_t buflen,
254                      size_t minlen, Callback callback)
255{
256        return io.add( fd,
257                       EV_WRITE,
258                       iosf_write_at_least<IO, Callback>(io, buf, buflen,
259                                                        minlen, callback)
260                       );
261}
262
263
264template <typename IO, typename Callback>
265struct iosf_write_at_most : ios {
266        iosf_write_at_most(IO& _io, void* _buf, size_t _buflen,
267                          size_t _maxlen, Callback _callback) :
268                io(_io), buf((char*)_buf), buflen(_buflen),
269                maxlen(_maxlen), callback(_callback) {}
270        next_t operator() (int fd, short event)
271        {
272                ssize_t rl;
273                if( (rl = write(fd, buf, maxlen)) < 0 ) {
274                        if( errno == EAGAIN || errno == EINTR ) { return MP_IOS_CONTINUE; }
275                        int err = callback(io, errno, fd, buf, buflen,
276                                           maxlen, static_cast<size_t>(rl));
277                        return MP_IOS_END(err);
278                }
279                int err = callback(io, 0, fd, buf, buflen,
280                                   maxlen, static_cast<size_t>(rl));
281                return MP_IOS_END(err);
282        }
283private:
284        IO& io;
285        char* buf;
286        size_t buflen;
287        size_t maxlen;
288        ios_callback<int (IO&, int, int, char*, size_t, size_t), Callback> callback;
289};
290
291template <typename IO, typename Callback>
292int ios_write_at_most(IO& io, int fd, void* buf, size_t buflen,
293                     size_t maxlen, Callback callback)
294{
295        return io.add(  fd,
296                        EV_WRITE,
297                        iosf_write_at_most<IO, Callback>(io, buf, buflen,
298                                                        maxlen, callback) );
299}
300
301
302
303template <typename IO, typename Callback>
304struct iosf_write_just : ios {
305        iosf_write_just(IO& _io, void* _buf, size_t _len, Callback _callback) :
306                io(_io), buf((char*)_buf), current((char*)_buf), rest(_len),
307                callback(_callback) {}
308        next_t operator() (int fd, short event)
309        {
310                ssize_t rl;
311                if( (rl = write(fd, current, rest)) < 0 ) {
312                        if( errno == EAGAIN ) {
313                                return MP_IOS_CONTINUE;
314                        }
315                        size_t reached = current - buf;
316                        int err = callback(io, fd, buf, reached + rest, reached);
317                        return MP_IOS_END(err);
318                }
319                if( rl == 0 ) {
320                        size_t reached = current - buf;
321                        int err = callback(io, fd, buf, reached + rest, reached);
322                        return MP_IOS_END(err);
323                }
324                if( rest <= (size_t)rl ) {
325                        size_t reached = current - buf + rl;
326                        int err = callback(io, fd, buf, reached, reached);
327                        return MP_IOS_END(err);
328                }
329                rest -= rl;
330                current += rl;
331                return MP_IOS_CONTINUE;
332        }
333private:
334        IO& io;
335        char* buf;
336        char* current;
337        size_t rest;
338        ios_callback<int (IO&, int, char*, size_t, size_t), Callback> callback;
339};
340
341template <typename IO, typename Callback>
342int ios_write_just(IO& io, int fd, void* buf, size_t len, Callback callback)
343{
344        typedef iosf_write_just<IO, Callback> IOS;
345        return MP_IOS_ADD(io, IOS, &IOS::operator(),
346                        fd, EV_WRITE, IOS(io, buf, len, callback));
347}
348
349
350
351}  // namespace ios
352}  // namespace mp
353
354#endif /* mp/ios/rw.h */
355
Note: See TracBrowser for help on using the browser.