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)
this->set_body_size(size);
}
void Command::set_name(char name)
void Command::set_name(const std::string name)
{
this->name = name;
}
......@@ -43,5 +43,5 @@ void Command::pack()
{
std::ostringstream slength;
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:
* it will set the header correctly, using the body size etc.
*/
void pack();
void set_name(char name);
char get_name() { return this->name; }
void set_name(const std::string);
std::string get_name() { return this->name; }
/**
* 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
......@@ -67,7 +67,7 @@ public:
*/
char* body;
std::string header;
char name;
std::string name;
size_t body_size;
/**
* If not 0, will be called from the send_handler.
......
......@@ -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)
{
log_debug("installing callback for command " << name);
this->callbacks[name] = callback;
log_debug("installing callback for command " << command);
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)
{
log_debug("installing ONCE callback for command " << name);
this->callbacks_once[name] = callback;
log_debug("installing ONCE callback for command " << command);
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())
this->callbacks.erase(it);
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;
it = this->callbacks.find(name);
it = this->callbacks.find(command);
if (it != this->callbacks.end())
return it->second;
it = this->callbacks_once.find(name);
it = this->callbacks_once.find(command);
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;
this->callbacks_once.erase(it);
return callback;
......@@ -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)
{
log_debug("read_handler, size: " << bytes_transferred << " bytes.");
if (error)
log_debug("Read error: " << error);
if (error)
{
log_info("Read error: " << error);
// TODO check more precisely for errors
this->on_connection_closed();
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
char *c = new char[bytes_transferred+1];
this->data.sgetn(c, bytes_transferred);
c[bytes_transferred] = 0;
char command_name = c[0];
// remove the ending : and the first char, to get the size argument.
// If the data for the size is empty or invalid (not a number), atoi
// 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());
log_debug("Received command: " << command_name << size);
// find the . separator
size_t pos = 0;
while (c[pos] && c[pos] != '.')
pos++;
std::string command_name;
std::size_t 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->set_name(command_name);
......@@ -134,9 +140,9 @@ void CommandHandler::install_read_handler(void)
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();
this->install_callback_once(name, on_answer);
this->send(command);
......@@ -181,13 +187,15 @@ void CommandHandler::send_handler(const boost::system::error_code& error,
Command* command)
{
this->writing = false;
// TODO, actually just disconnect in these cases.
assert(bytes_transferred == command->header.length() + command->body_size);
assert(!error);
if (command->callback)
command->callback();
delete command;
// TODO check for error
if (error)
exit(1);
this->check_commands_to_send();
}
......@@ -36,8 +36,8 @@ public:
void install_read_handler();
/**
* 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
* read the arguments of the commad, if any.
* the size of the arguments, and then calls binary_read_handler to read
* the arguments of the commad, if any.
*/
void read_handler(const boost::system::error_code& error, const std::size_t bytes_transferred);
/**
......@@ -49,23 +49,23 @@ public:
* Sends a command, and use install_callback_once to wait for the answer
* 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
* 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
* 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
* 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.
*/
void remove_callback(const char);
void remove_callback(const std::string&);
/**
* Add the given command to the commands_to_send queue, then
* calls check_commands_to_send. Which may send the next available
......@@ -80,7 +80,7 @@ protected:
* Returns 0 if nothing was found, in that case the execution of the
* 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
*/
......@@ -111,8 +111,8 @@ private:
CommandHandler(const CommandHandler&);
CommandHandler& operator=(const CommandHandler&);
std::map<const char, t_read_callback > callbacks;
std::map<const char, t_read_callback > callbacks_once;
std::map<const std::string, t_read_callback > callbacks;
std::map<const std::string, t_read_callback > callbacks_once;
/**
* A queue of messages. If there's not async_write running, we pop one
* 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