-
Notifications
You must be signed in to change notification settings - Fork 0
/
minecontrol-protocol.h
140 lines (118 loc) · 4.38 KB
/
minecontrol-protocol.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// minecontrol-protocol.h
#ifndef MINECONTROL_PROTOCOL_H
#define MINECONTROL_PROTOCOL_H
#include <rlibrary/rqueue.h>
#include <rlibrary/rstringstream.h> // gets rstream
#include "socket.h"
namespace minecraft_controller
{
class minecontrol_message_error { };
class minecontrol_encrypt_error { }; // these should be handled
/* crypt_session
* represents an RSA public-key encryptor/decryptor
*/
class crypt_session
{
public:
crypt_session();
crypt_session(const rtypes::generic_string& publicKey);
~crypt_session();
bool encrypt(const char* source,rtypes::generic_string& result) const;
bool decrypt(const char* source,rtypes::generic_string& result) const;
rtypes::str get_public_key() const;
private:
static const int _bits;
static const int _bytes;
void* _internal;
};
/* minecontrol_message:
* represents a message used in implementing the simple
* minecontrol communications protocol; every command name
* and field, value pair are normalized to lower case
*/
class minecontrol_message
{
friend rtypes::rstream& operator >>(rtypes::rstream&,minecontrol_message&);
friend rtypes::rstream& operator <<(rtypes::rstream&,const minecontrol_message&);
public:
minecontrol_message();
minecontrol_message(const char* command);
void assign_command(const char* command);
void add_field(const char* field,const char* value,const crypt_session* pencrypt = NULL);
void reset_fields();
bool good() const
{ return _state; }
bool is_blank() const
{ return _command.length() == 0; }
bool is_command(const char* command) const
{ return _command == command; }
const char* get_header() const
{ return _header.c_str(); }
const char* get_command() const
{ return _command.c_str(); }
const char* get_fields() const
{ return _fields.c_str(); }
const char* get_values() const
{ return _values.c_str(); }
rtypes::rstream& get_field_key_stream() const
{ return _fieldKeys; }
rtypes::rstream& get_field_value_stream() const
{ return _fieldValues; }
rtypes::str get_protocol_message() const;
void read_protocol_message(socket& input);
void write_protocol_message(socket& output);
private:
static const char* const MINECONTROL_PROTO_HEADER;
static void _readProtocolLine(rtypes::rstream& stream,rtypes::str& line);
bool _state;
rtypes::str _header;
rtypes::str _command;
rtypes::str _fields, _values;
mutable rtypes::const_stringstream _fieldKeys;
mutable rtypes::const_stringstream _fieldValues;
};
rtypes::rstream& operator >>(rtypes::rstream&,minecontrol_message&);
rtypes::rstream& operator <<(rtypes::rstream&,const minecontrol_message&);
/* minecontrol_message_buffer
* simplifies the creation of minecontrol messages by providing
* a local buffer for field values; maintains a queue of desired
* fields and expects their values on the stream; each field is
* delimited by a newline
*/
class minecontrol_message_buffer : public rtypes::rstream
{
public:
minecontrol_message_buffer();
void begin(const char* command);
// add a field name to be expected; these are queued
void enqueue_field_name(const char* fieldName,const crypt_session* encrypt = NULL);
void repeat_field(const char* fieldName);
// retrieve the internal message that is being compiled
const minecontrol_message& get_message() const
{ return _message; }
rtypes::uint32 count_fields() const;
private:
struct field_item
{
field_item() {}
field_item(const char* fieldName,const crypt_session* pencrypt)
: field(fieldName), encrypt(pencrypt) {}
rtypes::str field;
const crypt_session* encrypt;
};
minecontrol_message _message;
rtypes::queue<field_item> _fields;
const char* _repeatField;
virtual bool _inDevice() const
{ return false; } // no input expected from this stream buffer
virtual void _outDevice();
};
}
#endif
/*
* Local Variables:
* mode:c++
* indent-tabs-mode:nil
* tab-width:4
* End:
*/