Commit 07320c94 authored by louiz’'s avatar louiz’

Revert "Make Command and CommandHandler classes use a command name as char. #60"

This reverts commit 471930197b9e7cde7482595a237d006c916a9b36.
parent 7a7279b2
...@@ -29,7 +29,7 @@ void Command::set_body(const char* body, int size) ...@@ -29,7 +29,7 @@ void Command::set_body(const char* body, int size)
this->set_body_size(size); this->set_body_size(size);
} }
void Command::set_name(char name) void Command::set_name(const std::string name)
{ {
this->name = name; this->name = name;
} }
...@@ -43,5 +43,5 @@ void Command::pack() ...@@ -43,5 +43,5 @@ void Command::pack()
{ {
std::ostringstream slength; std::ostringstream slength;
slength << this->body_size; slength << this->body_size;
this->header = std::string(1, this->name) + slength.str() + ":"; this->header = std::string(this->name) + "." + slength.str() + ":";
} }
...@@ -58,8 +58,8 @@ public: ...@@ -58,8 +58,8 @@ public:
* it will set the header correctly, using the body size etc. * it will set the header correctly, using the body size etc.
*/ */
void pack(); void pack();
void set_name(char name); void set_name(const std::string);
char get_name() { return this->name; } std::string get_name() { return this->name; }
/** /**
* Use this member to manually set the body. For example you can pass it to * Use this member to manually set the body. For example you can pass it to
* a ostream::get() method after having manually new[]ed it. This avoid * a ostream::get() method after having manually new[]ed it. This avoid
...@@ -67,7 +67,7 @@ public: ...@@ -67,7 +67,7 @@ public:
*/ */
char* body; char* body;
std::string header; std::string header;
char name; std::string name;
size_t body_size; size_t body_size;
/** /**
* If not 0, will be called from the send_handler. * If not 0, will be called from the send_handler.
......
...@@ -10,43 +10,43 @@ CommandHandler::~CommandHandler() ...@@ -10,43 +10,43 @@ CommandHandler::~CommandHandler()
{ {
} }
void CommandHandler::install_callback(const char name, void CommandHandler::install_callback(const std::string& command,
t_read_callback callback) t_read_callback callback)
{ {
log_debug("installing callback for command " << name); log_debug("installing callback for command " << command);
this->callbacks[name] = callback; this->callbacks[command] = callback;
} }
void CommandHandler::install_callback_once(const char name, void CommandHandler::install_callback_once(const std::string& command,
t_read_callback callback) t_read_callback callback)
{ {
log_debug("installing ONCE callback for command " << name); log_debug("installing ONCE callback for command " << command);
this->callbacks_once[name] = callback; this->callbacks_once[command] = callback;
} }
void CommandHandler::remove_callback(const char name) void CommandHandler::remove_callback(const std::string& command)
{ {
std::map<const char, t_read_callback >::iterator it; std::map<const std::string, t_read_callback >::iterator it;
it = this->callbacks.find(name); it = this->callbacks.find(command);
if (it != this->callbacks.end()) if (it != this->callbacks.end())
this->callbacks.erase(it); this->callbacks.erase(it);
else else
log_warning("Could not remove callback: " << name); log_warning("Could not remove callback: " << command);
} }
t_read_callback CommandHandler::get_callback(const char name) t_read_callback CommandHandler::get_callback(const std::string& command)
{ {
std::map<const std::string, t_read_callback >::iterator it; std::map<const std::string, t_read_callback >::iterator it;
it = this->callbacks.find(name); it = this->callbacks.find(command);
if (it != this->callbacks.end()) if (it != this->callbacks.end())
return it->second; return it->second;
it = this->callbacks_once.find(name); it = this->callbacks_once.find(command);
if (it != this->callbacks_once.end()) if (it != this->callbacks_once.end())
{ {
log_debug("Removing callback for command " << name); log_debug("Removing callback for command " << command);
t_read_callback callback = it->second; t_read_callback callback = it->second;
this->callbacks_once.erase(it); this->callbacks_once.erase(it);
return callback; return callback;
...@@ -57,31 +57,37 @@ t_read_callback CommandHandler::get_callback(const char name) ...@@ -57,31 +57,37 @@ t_read_callback CommandHandler::get_callback(const char name)
void CommandHandler::read_handler(const boost::system::error_code& error, const std::size_t bytes_transferred) void CommandHandler::read_handler(const boost::system::error_code& error, const std::size_t bytes_transferred)
{ {
log_debug("read_handler, size: " << bytes_transferred << " bytes."); log_debug("read_handler, size: " << bytes_transferred << " bytes.");
if (error)
log_debug("Read error: " << error);
if (error) if (error)
{ {
log_info("Read error: " << error);
// TODO check more precisely for errors // TODO check more precisely for errors
this->on_connection_closed(); this->on_connection_closed();
return; return;
} }
if (bytes_transferred <= 1)
{
log_warning("read_handler: data received is too short to contain a command name and a size. Ignoring");
return ;
}
// Extract the needed data from the buffer // Extract the needed data from the buffer
char *c = new char[bytes_transferred+1]; char *c = new char[bytes_transferred+1];
this->data.sgetn(c, bytes_transferred); this->data.sgetn(c, bytes_transferred);
c[bytes_transferred] = 0; c[bytes_transferred] = 0;
// find the . separator
char command_name = c[0]; size_t pos = 0;
// remove the ending : and the first char, to get the size argument. while (c[pos] && c[pos] != '.')
// If the data for the size is empty or invalid (not a number), atoi pos++;
// returns 0, and that's how much we want to read in that case.
std::size_t size = atoi(std::string(c+1, bytes_transferred-2).data()); std::string command_name;
std::size_t size;
log_debug("Received command: " << command_name << size); if (pos == bytes_transferred)
{ // no . was found
command_name = std::string(c, pos-1);
size = 0;
}
else
{
command_name = std::string(c, pos);
size = atoi(std::string(c+pos+1, bytes_transferred-pos-2).data()); // remove the ending :
}
log_debug("Received : " << command_name << " . " << size);
Command* command = new Command; Command* command = new Command;
command->set_name(command_name); command->set_name(command_name);
...@@ -134,9 +140,9 @@ void CommandHandler::install_read_handler(void) ...@@ -134,9 +140,9 @@ void CommandHandler::install_read_handler(void)
boost::asio::placeholders::bytes_transferred)); boost::asio::placeholders::bytes_transferred));
} }
void CommandHandler::request_answer(Command* command, t_read_callback on_answer, char name) void CommandHandler::request_answer(Command* command, t_read_callback on_answer, std::string name)
{ {
if (name == '\0') if (name.size() == 0)
name = command->get_name(); name = command->get_name();
this->install_callback_once(name, on_answer); this->install_callback_once(name, on_answer);
this->send(command); this->send(command);
...@@ -181,13 +187,15 @@ void CommandHandler::send_handler(const boost::system::error_code& error, ...@@ -181,13 +187,15 @@ void CommandHandler::send_handler(const boost::system::error_code& error,
Command* command) Command* command)
{ {
this->writing = false; this->writing = false;
// TODO, actually just disconnect in these cases.
assert(bytes_transferred == command->header.length() + command->body_size); assert(bytes_transferred == command->header.length() + command->body_size);
assert(!error);
if (command->callback) if (command->callback)
command->callback(); command->callback();
delete command; delete command;
// TODO check for error
if (error)
exit(1);
this->check_commands_to_send(); this->check_commands_to_send();
} }
...@@ -36,8 +36,8 @@ public: ...@@ -36,8 +36,8 @@ public:
void install_read_handler(); void install_read_handler();
/** /**
* called when there's something to read on the socket. Reads the command * called when there's something to read on the socket. Reads the command
* name, the size of the arguments, and then calls binary_read_handler to * the size of the arguments, and then calls binary_read_handler to read
* read the arguments of the commad, if any. * the arguments of the commad, if any.
*/ */
void read_handler(const boost::system::error_code& error, const std::size_t bytes_transferred); void read_handler(const boost::system::error_code& error, const std::size_t bytes_transferred);
/** /**
...@@ -49,23 +49,23 @@ public: ...@@ -49,23 +49,23 @@ public:
* Sends a command, and use install_callback_once to wait for the answer * Sends a command, and use install_callback_once to wait for the answer
* and call that callback to handle it. * and call that callback to handle it.
*/ */
void request_answer(Command*, t_read_callback on_answer, char name = '\0'); void request_answer(Command*, t_read_callback on_answer, std::string name = "");
/** /**
* Install a new callback associated with a command. This callback will * Install a new callback associated with a command. This callback will
* be called upon receiving that command. * be called upon receiving that command.
*/ */
void install_callback(const char, t_read_callback); void install_callback(const std::string&, t_read_callback);
/** /**
* Install a new callback associated with a command. This callback will * Install a new callback associated with a command. This callback will
* be called upon receiving that command, but only once. This is used * be called upon receiving that command, but only once. This is used
* for example if you send a command waiting for and answer, you install * for example if you send a command waiting for and answer, you install
* a callback that will handle that answer, and only this one. * a callback that will handle that answer, and only this one.
*/ */
void install_callback_once(const char, t_read_callback); void install_callback_once(const std::string&, t_read_callback);
/** /**
* Remove a callback that has been installed. * Remove a callback that has been installed.
*/ */
void remove_callback(const char); void remove_callback(const std::string&);
/** /**
* Add the given command to the commands_to_send queue, then * Add the given command to the commands_to_send queue, then
* calls check_commands_to_send. Which may send the next available * calls check_commands_to_send. Which may send the next available
...@@ -80,7 +80,7 @@ protected: ...@@ -80,7 +80,7 @@ protected:
* Returns 0 if nothing was found, in that case the execution of the * Returns 0 if nothing was found, in that case the execution of the
* return value cause a failure. * return value cause a failure.
*/ */
t_read_callback get_callback(const char); t_read_callback get_callback(const std::string&);
/** /**
* @todo Check if the data was correctly sent on the socket * @todo Check if the data was correctly sent on the socket
*/ */
...@@ -111,8 +111,8 @@ private: ...@@ -111,8 +111,8 @@ private:
CommandHandler(const CommandHandler&); CommandHandler(const CommandHandler&);
CommandHandler& operator=(const CommandHandler&); CommandHandler& operator=(const CommandHandler&);
std::map<const char, t_read_callback > callbacks; std::map<const std::string, t_read_callback > callbacks;
std::map<const char, t_read_callback > callbacks_once; std::map<const std::string, t_read_callback > callbacks_once;
/** /**
* A queue of messages. If there's not async_write running, we pop one * A queue of messages. If there's not async_write running, we pop one
* from it and we send it. * from it and we send it.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment