+#include "scd_command_reader.h"
+
+#include <arpa/inet.h>
+
+#include "scd_logging.h"
+
+
+scd_command_reader::scd_command_reader():
+ _command(NULL), _is_reading(false), _success(false) {}
+
+
+scd_command_reader::~scd_command_reader()
+{
+ if (_is_reading || _success)
+ {
+ delete _command;
+ }
+}
+
+
+void scd_command_reader::set_socket(scd_socket& sock) { _socket = &sock; }
+
+
+void scd_command_reader::read()
+{
+ if (!_is_reading)
+ {
+ if (_success)
+ return;
+
+ _is_reading = true;
+ _header_read = false;
+ _remaining = SCD_CM_HEADER;
+ _off = 0;
+ _command = new scd_command;
+ }
+
+ // receive header
+ if (!_header_read)
+ {
+ // read header
+ size_t read = _socket->recv(_header_buf + _off, _remaining);
+ _remaining -= read;
+ _off += read;
+
+ if (_remaining == 0)
+ {
+ // read values from buffer
+ uint16_t* intbuf = reinterpret_cast<uint16_t*>(_header_buf);
+ _command->_type = ntohs( intbuf[0] );
+ _command->_subtype = ntohs( intbuf[1] );
+ _command->_msglen = ntohs( intbuf[2] );
+
+ _header_read = true;
+
+ // allocate buffer for further receiption
+ if (_command->_msglen > 0)
+ {
+ if (_command->_msglen > SCD_CM_MAXLEN)
+ {
+ // illegal command
+ _command->_msglen = 0;
+ delete _command;
+ _is_reading = false;
+ }
+ else
+ {
+ _command->_msg = new char[_command->_msglen];
+ _remaining = _command->_msglen;
+ _off = 0;
+ }
+ }
+ else
+ {
+ // command without payload
+ _command->_msglen = 0; // to prevent negative values
+ _remaining = 0;
+ _is_reading = false;
+ _success = true;
+ }
+ }
+ }
+
+ // receive msg
+ if (_header_read && _is_reading)
+ {
+ size_t read = _socket->recv(_command->_msg + _off, _remaining);
+ _remaining -= read;
+ _off += read;
+
+ if (_remaining == 0)
+ {
+ _is_reading = false;
+ _success = true;
+ }
+ }
+
+} // read()
+
+
+bool scd_command_reader::is_reading() { return _is_reading; }
+
+
+bool scd_command_reader::has_command() { return _success; }
+
+
+scd_command* scd_command_reader::get_command()
+{
+ if (!_success)
+ {
+ return NULL;
+ }
+ else
+ {
+ _success = false;
+ return _command;
+ }
+
+} // get_command()