-
Notifications
You must be signed in to change notification settings - Fork 0
/
Dispatcher.cpp
131 lines (116 loc) · 3.16 KB
/
Dispatcher.cpp
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
#include "Dispatcher.h"
/**
* @author Lauri Orgla
*/
Dispatcher::Dispatcher() {
}
/**
* @author Lauri Orgla
* @param orig
*/
Dispatcher::Dispatcher(const Dispatcher& orig) {
}
/**
* @author Lauri Orgla
*/
Dispatcher::~Dispatcher() {
/**
* Deletes all
*/
for (std::map<std::string, HandlerBase * >::iterator it = this->handlers.begin(); it != this->handlers.end(); ++it) {
delete it->second;
}
}
/**
*
* @author Lauri Orgla
*
* @param name
* @param handler
*/
void Dispatcher::registerHandler(std::string name, HandlerBase* handler) {
/**Convert name to uppercase*/
std::locale locale;
for (std::string::size_type i = 0; i < name.length(); ++i)
name[i] = std::toupper(name[i], locale);
/**conversion end*/
if (handlers.find(name) == handlers.end()) {
std::cout << "[System] Registrering handler: " << name << " ... done!" << std::endl;
handlers.insert(std::pair<std::string, HandlerBase*>(name, handler));
} else {
//deletes handler in case if handler is not added to map
//Garbage collection.
delete handler;
std::cout << "[System] Handler with name " << name << " Is already registered." << std::endl;
}
}
/**
* @author Lauri Orgla
*
* @param message
* @param result
* @param self
* @param session_pool
*/
void Dispatcher::handle(Message *msg) {
//Remove newline characters
for (int i = 0; i < msg->message.length(); i++) {
if (msg->message[i] == '\n') {
msg->message[i] = ' ';
}
}
std::string body;
std::string action;
parseMessage(msg->message, action, body);
msg->message = body;
if (handlers.find(action) != handlers.end()) {
handlers.find(action)->second->run(msg);
} else {
*msg->result = "ERROR\n";
}
}
/**
* Parses message that has to be handled.
*
* First part will be action and everything after that body.
*
* @author Lauri Orgla
*
* @param input
* @param action
* @param body
*/
void Dispatcher::parseMessage(std::string input, std::string& action, std::string& body) {
if (input.length() == 0)
return;
char *token;
//bodyVec holds all body pieces after tokenizing, so body could be built later.
std::vector<std::string> bodyVec;
//Locale for converting action to uppercase
std::locale locale;
/** Convert input for strtok */
char buffer[input.length()];
strncpy(buffer, input.c_str(), input.length() + 1);
token = strtok(buffer, " ");
/* Conversion ends*/
int number = 0;
while (token != NULL) {
//First part is action
if (number == 0) {
action = token;
} else {
//All other parts are pushed to vector
bodyVec.push_back(token);
}
token = strtok(NULL, " ");
number++;
}
if (action.length() == 0)
action = input;
for (std::vector<std::string>::iterator it = bodyVec.begin(); it != bodyVec.end(); ++it) {
if (body.length() > 0) body.append(" ");
body.append(it->data());
}
for (std::string::size_type i = 0; i < action.length(); ++i)
action[i] = std::toupper(action[i], locale);
}