dol: initial dol commit
[jump.git] / dol / src / dol / visitor / hdsd / scd / scd_command_writer.cpp
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_command_writer.cpp b/dol/src/dol/visitor/hdsd/scd/scd_command_writer.cpp
new file mode 100644 (file)
index 0000000..64193ff
--- /dev/null
@@ -0,0 +1,93 @@
+#include "scd_command_writer.h"
+
+#include <string.h>
+
+#include "scd_logging.h"
+
+
+scd_command_writer::scd_command_writer():
+    _is_writing(false), _remaining(0) {}
+
+
+scd_command_writer::~scd_command_writer()
+{
+    std::list<scd_command*>::iterator iter;
+    for ( iter = _commands.begin(); iter != _commands.end(); iter++)
+        delete *iter;
+}
+
+
+void scd_command_writer::set_socket(scd_socket& sock) { _socket = &sock; }
+
+
+bool scd_command_writer::is_writing() const { return _is_writing; }
+
+
+bool scd_command_writer::queue_command(scd_command* cmd)
+{
+    if (cmd->_msglen <= SCD_CM_MAXLEN)
+    {
+        _commands.push_back(cmd);
+        _is_writing = true;
+        return true;
+    }
+    else
+    {
+        scd_warn("command too long");
+        delete cmd;
+        return false;
+    }
+}
+
+void scd_command_writer::write()
+{
+    bool finishedmsg;
+    do
+    {
+        finishedmsg = _send_cmd();
+    }
+    while (finishedmsg);
+
+} // write()
+
+
+inline bool scd_command_writer::_send_cmd()
+{
+    if (!_is_writing)
+        return false;
+
+    if (_remaining == 0)
+    {
+        /* fetch next command */
+        scd_command* cmd = _commands.front();
+        _commands.pop_front();
+
+        // store header to buffer
+        uint16_t* intbuf = reinterpret_cast<uint16_t*>(_buf);
+        intbuf[0] = htons(cmd->_type);
+        intbuf[1] = htons(cmd->_subtype);
+        intbuf[2] = htons(cmd->_msglen);
+
+        // store message to buffer
+        memcpy(_buf + SCD_CM_HEADER, cmd->_msg, cmd->_msglen);
+
+        _remaining = SCD_CM_HEADER + cmd->_msglen;
+        _off = 0;
+        delete cmd;
+    }
+
+    size_t sent = _socket->send(_buf + _off, _remaining);
+
+    _off += sent;
+    _remaining -= sent;
+
+    if (_remaining == 0)
+    {
+        if (_commands.empty())
+            _is_writing = false;
+        return true;
+    }
+    else
+        return false;
+    
+} // _send_cmd()