3 #include <msp/core/systemerror.h>
4 #include "eventreader.h"
5 #include "handle_private.h"
12 struct EventReader::Private
14 OVERLAPPED overlapped;
25 EventReader::EventReader(Handle &h, unsigned size):
29 memset(&priv->overlapped, 0, sizeof(OVERLAPPED));
30 *priv->event = CreateEvent(0, true, false, 0);
31 priv->overlapped.hEvent = *priv->event;
32 priv->buf_size = size;
33 priv->buffer = new char[priv->buf_size];
35 priv->buf_next = priv->buffer;
36 priv->pending = false;
40 EventReader::~EventReader()
42 CloseHandle(*priv->event);
43 delete[] priv->buffer;
47 const Handle &EventReader::get_event()
53 void EventReader::start()
55 if(priv->buf_avail || priv->pending)
59 priv->buf_next = priv->buffer;
60 if(!ReadFile(*handle, priv->buffer, priv->buf_size, &ret, &priv->overlapped))
62 unsigned err = GetLastError();
63 if(err==ERROR_BROKEN_PIPE)
65 else if(err==ERROR_IO_PENDING)
68 throw system_error("ReadFile");
72 priv->buf_avail = ret;
73 SetEvent(*priv->event);
77 void EventReader::wait()
83 if(!GetOverlappedResult(*handle, &priv->overlapped, &ret, true))
85 DWORD err = GetLastError();
86 if(err==ERROR_BROKEN_PIPE)
89 throw system_error("GetOverlappedResult");
93 priv->buf_avail = ret;
94 priv->pending = false;
98 unsigned EventReader::read(char *buf, unsigned len)
105 // No data in buffer, try to get some
110 len = min(len, priv->buf_avail);
111 memcpy(buf, priv->buf_next, len);
112 priv->buf_next += len;
113 priv->buf_avail -= len;
117 ResetEvent(*priv->event);