]> git.tdb.fi Git - libs/core.git/blobdiff - source/io/windows/eventreader.cpp
Use size_t to represent sizes
[libs/core.git] / source / io / windows / eventreader.cpp
index 62c9763d9fa92595385f658b36710d68087e09b8..8c4102067854eb0c9096ff92ab4277c1e3cf6441 100644 (file)
@@ -11,12 +11,14 @@ namespace IO {
 
 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 = 0;
+       size_t buf_avail = 0;
+       char *buf_next = 0;
+       bool pending = false;
+       bool eof = false;
 };
 
 
@@ -24,18 +26,17 @@ EventReader::EventReader(Handle &h, unsigned size):
        handle(h),
        priv(new Private)
 {
-       priv->overlapped = 0;
+       memset(&priv->overlapped, 0, sizeof(OVERLAPPED));
        *priv->event = CreateEvent(0, true, false, 0);
+       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;
 }
@@ -48,43 +49,46 @@ const Handle &EventReader::get_event()
 
 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;
        }
 }
 
@@ -92,6 +96,9 @@ unsigned EventReader::read(char *buf, unsigned len)
 {
        if(!priv->buf_avail)
        {
+               if(priv->eof)
+                       return 0;
+
                // No data in buffer, try to get some
                start();
                wait();