struct EventReader::Private
{
- OVERLAPPED *overlapped;
+ OVERLAPPED overlapped;
Handle event;
- unsigned buf_size;
- char *buffer;
- unsigned buf_avail;
- char *buf_next;
+ size_t buf_size = 0;
+ char *buffer = nullptr;
+ size_t buf_avail = 0;
+ char *buf_next = nullptr;
+ bool pending = false;
+ bool eof = false;
};
-EventReader::EventReader(Handle &h, unsigned size):
+EventReader::EventReader(Handle &h, size_t size):
handle(h),
priv(new Private)
{
- priv->overlapped = 0;
- *priv->event = CreateEvent(0, true, false, 0);
+ memset(&priv->overlapped, 0, sizeof(OVERLAPPED));
+ *priv->event = CreateEvent(nullptr, true, false, nullptr);
+ priv->overlapped.hEvent = *priv->event;
priv->buf_size = size;
priv->buffer = new char[priv->buf_size];
- priv->buf_avail = 0;
priv->buf_next = priv->buffer;
}
EventReader::~EventReader()
{
CloseHandle(*priv->event);
- delete priv->overlapped;
delete[] priv->buffer;
delete priv;
}
void EventReader::start()
{
- if(priv->buf_avail || priv->overlapped)
+ if(priv->buf_avail || priv->pending)
return;
- priv->overlapped = new OVERLAPPED;
- memset(priv->overlapped, 0, sizeof(OVERLAPPED));
- priv->overlapped->hEvent = *priv->event;
-
DWORD ret;
priv->buf_next = priv->buffer;
- if(!ReadFile(*handle, priv->buffer, priv->buf_size, &ret, priv->overlapped))
+ if(!ReadFile(*handle, priv->buffer, priv->buf_size, &ret, &priv->overlapped))
{
unsigned err = GetLastError();
- if(err!=ERROR_IO_PENDING)
+ if(err==ERROR_BROKEN_PIPE)
+ priv->eof = true;
+ else if(err==ERROR_IO_PENDING)
+ priv->pending = true;
+ else
throw system_error("ReadFile");
}
else
{
priv->buf_avail = ret;
- delete priv->overlapped;
- priv->overlapped = 0;
SetEvent(*priv->event);
}
}
void EventReader::wait()
{
- if(!priv->overlapped)
+ if(!priv->pending)
return;
DWORD ret;
- if(!GetOverlappedResult(*handle, priv->overlapped, &ret, true))
- throw system_error("GetOverlappedResult");
+ if(!GetOverlappedResult(*handle, &priv->overlapped, &ret, true))
+ {
+ DWORD err = GetLastError();
+ if(err==ERROR_BROKEN_PIPE)
+ priv->eof = true;
+ else
+ throw system_error("GetOverlappedResult");
+ }
else
{
priv->buf_avail = ret;
- delete priv->overlapped;
- priv->overlapped = 0;
+ priv->pending = false;
}
}
-unsigned EventReader::read(char *buf, unsigned len)
+unsigned EventReader::read(char *buf, size_t len)
{
if(!priv->buf_avail)
{
+ if(priv->eof)
+ return 0;
+
// No data in buffer, try to get some
start();
wait();