<div dir="ltr"><span style="font-size:12.8px">Acked-by: Sagara Wickramasekara <<a href="mailto:sagaraw@gmail.com">sagaraw@gmail.com</a>></span><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Aug 26, 2016 at 3:32 PM, Aaron Conole <span dir="ltr"><<a href="mailto:aconole@bytheb.org" target="_blank">aconole@bytheb.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Introduce a mechanism for monitoring and calling back stream buffer<br>
objects.  This is useful for building busy-wait loops, which can perform<br>
tasks as interleaved callbacks.<br>
<br>
Signed-off-by: Aaron Conole <<a href="mailto:aconole@bytheb.org">aconole@bytheb.org</a>><br>
---<br>
 cxx-lib/inc/asn-buf.h | 99 ++++++++++++++++++++++++++++++<wbr>+++++++++++++++++++++<br>
 1 file changed, 99 insertions(+)<br>
<br>
diff --git a/cxx-lib/inc/asn-buf.h b/cxx-lib/inc/asn-buf.h<br>
index d316ba9..872484b 100644<br>
--- a/cxx-lib/inc/asn-buf.h<br>
+++ b/cxx-lib/inc/asn-buf.h<br>
@@ -7,9 +7,11 @@<br>
 #pragma warning(push,3)<br>
 #endif<br>
<br>
+#include <algorithm><br>
 #include <deque><br>
 #include <fstream><br>
 #include <list><br>
+#include <map><br>
 #include <ostream><br>
 #include <sstream><br>
 #include <streambuf><br>
@@ -413,6 +415,103 @@ private:<br>
<br>
 };<br>
<br>
+<br>
+class StreambufCallback<br>
+{<br>
+public:<br>
+    enum Streambuf_CB_RESULT {<br>
+        CB_NONE,<br>
+        CB_DROP_STREAM<br>
+    };<br>
+<br>
+    enum Streambuf_CB_STATUS {<br>
+        CB_READ_OK,<br>
+        CB_WRITE_OK,<br>
+        CB_OPENED,<br>
+        CB_CLOSED<br>
+    };<br>
+<br>
+    StreambufCallback(){}<br>
+    virtual ~StreambufCallback(){}<br>
+    virtual Streambuf_CB_RESULT callback(Streambuf_CB_STATUS status,<br>
+                                         std::streambuf *stream) = 0;<br>
+};<br>
+<br>
+class StreambufMonitor<br>
+{<br>
+public:<br>
+    typedef std::map<std::streambuf*,<wbr>StreambufCallback&> callbackMap;<br>
+<br>
+private:<br>
+    callbackMap                 callbacks;<br>
+    std::list<std::streambuf*>  toDrop;<br>
+<br>
+    static void check_buffer(callbackMap::<wbr>value_type t,<br>
+                             std::list<std::streambuf*> &StreamDropList)<br>
+    {<br>
+        std::streambuf *Stream = t.first;<br>
+        std::streamsize Bytes = Stream->in_avail();<br>
+        StreambufCallback::Streambuf_<wbr>CB_RESULT result =<br>
+            StreambufCallback::CB_NONE;<br>
+<br>
+        if (Bytes == -1) {<br>
+            result = (t.second).callback(<wbr>StreambufCallback::CB_CLOSED, Stream);<br>
+        } else if (Bytes > 0) {<br>
+            result = (t.second).callback(<wbr>StreambufCallback::CB_READ_OK,<br>
+                                         Stream);<br>
+        }<br>
+<br>
+        if (result == StreambufCallback::CB_DROP_<wbr>STREAM) {<br>
+            StreamDropList.push_back(<wbr>Stream);<br>
+        }<br>
+    }<br>
+<br>
+    struct buffer_checker<br>
+    {<br>
+        StreambufMonitor *Mon;<br>
+        void operator()(callbackMap::value_<wbr>type t)<br>
+        {<br>
+            StreambufMonitor::check_<wbr>buffer(t, Mon->toDrop);<br>
+        }<br>
+    };<br>
+<br>
+public:<br>
+    StreambufMonitor() {}<br>
+    ~StreambufMonitor() {}<br>
+<br>
+    /**<br>
+     * Adds a streambuf to be monitored, with a specific callback instance. */<br>
+    bool push(std::streambuf *Stream, StreambufCallback &CB, bool callOpen)<br>
+    {<br>
+        if (callOpen) {<br>
+            StreambufCallback::Streambuf_<wbr>CB_RESULT result =<br>
+                CB.callback(StreambufCallback:<wbr>:CB_OPENED, Stream);<br>
+            if (result == StreambufCallback::CB_DROP_<wbr>STREAM)<br>
+                return false;<br>
+        }<br>
+        callbacks.insert(<br>
+            std::pair<std::streambuf*,<wbr>StreambufCallback&>(Stream,CB)<wbr>);<br>
+        return true;<br>
+    }<br>
+<br>
+    /**<br>
+     * Removes a streambuf from the monitor. */<br>
+    bool pop(std::streambuf *Stream)<br>
+    {<br>
+        if (callbacks.erase(Stream))<br>
+            return true;<br>
+        return false;<br>
+    }<br>
+<br>
+    void operator()()<br>
+    {<br>
+        buffer_checker bc;<br>
+        bc.Mon = this;<br>
+        std::for_each(callbacks.begin(<wbr>), callbacks.end(), bc);<br>
+        toDrop.clear();<br>
+    }<br>
+};<br>
+<br>
 } // end namespace SNACC<br>
<br>
 SNACCDLL_API void sortSet(std::list<SNACC::<wbr>AsnBuf> &bufList);<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.5.5<br>
<br>
______________________________<wbr>_________________<br>
dev mailing list<br>
<a href="mailto:dev@lists.esnacc.org">dev@lists.esnacc.org</a><br>
<a href="http://mail.esnacc.org/mailman/listinfo/dev" rel="noreferrer" target="_blank">http://mail.esnacc.org/<wbr>mailman/listinfo/dev</a><br>
</font></span></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature">-Sagara</div>
</div></div>