[esnacc-dev] [PATCH] asn-buf: Add available helper to the fdbuf

Aaron Conole aconole at bytheb.org
Thu Nov 17 16:04:00 UTC 2016


Currently, the streambuf monitor won't read socket data from the buffer if
it isn't advised that some socket data is available.  This change provides
an implementation for 'showmanyc' to query the underlying descriptor for the
number of availble bytes.

Signed-off-by: Aaron Conole <aconole at bytheb.org>
---
 cxx-lib/inc/asn-buf.h   |  2 ++
 cxx-lib/src/asn-buf.cpp | 53 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+)

diff --git a/cxx-lib/inc/asn-buf.h b/cxx-lib/inc/asn-buf.h
index 639dc70..4d06590 100644
--- a/cxx-lib/inc/asn-buf.h
+++ b/cxx-lib/inc/asn-buf.h
@@ -72,6 +72,8 @@ protected:
     std::streambuf::int_type overflow(std::streambuf::int_type c);
     std::streamsize xsputn (const char* s, std::streamsize num);
 
+    std::streamsize showmanyc();
+
 public:
     explicit AsnFDBuf(int descriptor, bool socket = false, bool failure = true,
                       size_t buffersz = 256, size_t putsize = 8)
diff --git a/cxx-lib/src/asn-buf.cpp b/cxx-lib/src/asn-buf.cpp
index 76eb714..a24c1b4 100644
--- a/cxx-lib/src/asn-buf.cpp
+++ b/cxx-lib/src/asn-buf.cpp
@@ -892,3 +892,56 @@ AsnFDBuf::extra_reset()
         fd = -1;
     }
 }
+
+#ifndef WIN32
+#include <sys/ioctl.h>
+#else
+#include <winsock2.h>
+#include <windows.h>
+#include <ws2tcpip.h>
+#endif
+
+#ifndef WIN32
+static int ioctlsocket(int fd, long request, void *data )
+{
+	return ioctl(fd, request, data);
+}
+#endif
+
+std::streamsize
+AsnFDBuf::showmanyc()
+{
+    if (sock) {
+        fd_set fds;
+        struct timeval tv;
+
+        tv.tv_sec = 0;
+        tv.tv_usec = 0;
+
+        FD_ZERO(&fds);
+        FD_SET(
+#ifdef WIN32 
+            (unsigned int)
+#endif
+            fd, &fds);
+
+        if (select(fd+1, &fds, NULL, NULL, &tv) > 0) {
+            return 1; // at least 1 available...
+        }
+
+        // black arts... try an ioctl
+        size_t numBytes = 0;
+        int i = ioctlsocket(fd, FIONREAD, &numBytes);
+        if (i > 0) {
+            return i;
+        }
+    } else {
+        // we can check for file length
+        size_t numBytes = 0;
+        int i = ioctl(fd, FIONREAD, &numBytes);
+        if (i > 0) {
+            return i;
+        }
+    }
+    return 0;
+}
-- 
2.7.4



More information about the dev mailing list