dol: initial dol commit
[jump.git] / dol / src / dol / visitor / hdsd / scd / scd_command_reader.cpp
1 #include "scd_command_reader.h"
2
3 #include <arpa/inet.h>
4
5 #include "scd_logging.h"
6
7
8 scd_command_reader::scd_command_reader():
9     _command(NULL), _is_reading(false), _success(false) {}
10
11
12 scd_command_reader::~scd_command_reader()
13 {
14     if (_is_reading || _success)
15     {
16         delete _command;
17     }
18 }
19
20
21 void scd_command_reader::set_socket(scd_socket& sock) { _socket = &sock; }
22
23
24 void scd_command_reader::read()
25 {
26     if (!_is_reading)
27     {
28         if (_success)
29             return;
30
31         _is_reading = true;
32         _header_read = false;
33         _remaining = SCD_CM_HEADER;
34         _off = 0;
35         _command = new scd_command;
36     }
37
38     // receive header
39     if (!_header_read)
40     {
41         // read header
42         size_t read = _socket->recv(_header_buf + _off, _remaining);
43         _remaining -= read;
44         _off += read;
45
46         if (_remaining == 0)
47         {
48             // read values from buffer
49             uint16_t* intbuf = reinterpret_cast<uint16_t*>(_header_buf);
50             _command->_type = ntohs( intbuf[0] );
51             _command->_subtype = ntohs( intbuf[1] );
52             _command->_msglen = ntohs( intbuf[2] );
53
54             _header_read = true;
55
56             // allocate buffer for further receiption
57             if (_command->_msglen > 0)
58             {
59                 if (_command->_msglen > SCD_CM_MAXLEN)
60                 {
61                     // illegal command
62                     _command->_msglen = 0;
63                     delete _command;
64                     _is_reading = false;
65                 }
66                 else
67                 {
68                     _command->_msg = new char[_command->_msglen];
69                     _remaining = _command->_msglen;
70                     _off = 0;
71                 }
72             }
73             else
74             {
75                 // command without payload
76                 _command->_msglen = 0; // to prevent negative values
77                 _remaining = 0;
78                 _is_reading = false;
79                 _success = true;
80             }
81         }
82     }
83
84     // receive msg
85     if (_header_read && _is_reading)
86     {
87         size_t read = _socket->recv(_command->_msg + _off, _remaining);
88         _remaining -= read;
89         _off += read;
90
91         if (_remaining == 0)
92         {
93             _is_reading = false;
94             _success = true;
95         }
96     }
97
98 } // read()
99
100
101 bool scd_command_reader::is_reading() { return _is_reading; }
102
103
104 bool scd_command_reader::has_command() { return _success; }
105
106
107 scd_command* scd_command_reader::get_command()
108 {
109     if (!_success)
110     {
111         return NULL;
112     }
113     else
114     {
115         _success = false;
116         return _command;
117     }
118
119 } // get_command()