message.hpp 3.02 KB
Newer Older
1 2 3 4 5
/** @addtogroup Network
 *  @{
 */

/**
6 7
 * Represents one single network message, for the base network protocol.
 * A message has a header and a body (also called binary part, which can have
8
 * size of 0).
9
 * The header is MESSAGE_NAME.BODY_SIZE:
10 11 12 13
 * The body can be anything, but it is BODY_SIZE bytes long.
 * The \n char is not used anywhere in the protocol, and there's no delimiter
 * between a body and the header of the next message.
 *
14 15
 * To send a message, a Message object must be created anywhere and filled with
 * the correct data and then passed to the MessageHandler::send() method.
16
 * The object will be deleted by the send_handler, after it has been
17
 * successfully sent.
18
 *
19 20
 * A Message object is passed by a MessageHandler to the callback associated
 * with a message name. This callback is responsible for deleting the message
21
 * object. (MAYBE)
22
 * @class Message
23 24
 */

25 26 27 28
#ifndef MESSAGE_HPP
# define MESSAGE_HPP

#include <google/protobuf/message.h>
29
#include <serialization/exception.hpp>
30 31 32 33

#include "logging/logging.hpp"

#include <functional>
34 35 36 37
#include <string>
#include <cstring>
#include <fstream>
#include <sstream>
38
#include <functional>
39

40
class Message
41 42
{
public:
43 44 45
  Message();
  Message(const Message&);
  ~Message();
46 47 48 49 50 51 52
  /**
   * Sets the body of the message. A char* will be new[]ed using the size, and
   * the data will be copied in it. To avoid that copy, see the body attribute
   * and the set_data() method. You should use one of the two methods on an
   * object, not both.
   */
  void set_body(const char*, int size = -1);
53 54 55 56 57
  /**
   * Sets the body of the message with the content of given the
   * protobuf::Message, serialized.
   */
  void set_body(const google::protobuf::Message& msg);
58 59 60 61 62 63
  /**
   * If you manually set the content of the body member, use this method to
   * set the proper body size. Do not use it after set_body() though.
   */
  void set_body_size(int size);
  /**
64
   * This must be called before the object is passed to MessageHandler::send(),
65 66 67
   * it will set the header correctly, using the body size etc.
   */
  void pack();
68
  void set_name(const std::string& name);
69
  std::string get_name() { return this->name; }
70 71 72 73 74 75 76
  /**
   * 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
   * copying data twice.
   */
  char* body;
  size_t body_size;
77
  /**
78 79 80
   * If not empty, will be called from the send_handler.
   */
  std::function<void(void)> callback;
louiz’'s avatar
louiz’ committed
81 82
  std::string header;
  std::string name;
83 84 85
  /**
   * Converts the body to a protobuf object. Does not check if it's valid
   * nor complete.
86
   */
87 88 89 90 91 92
  template<typename ProtobufClass>
  ProtobufClass parse_body_to_protobuf_object() const
  {
    ProtobufClass res;
    res.ParseFromArray(this->body, this->body_size);
    log_debug("parse_body_to_protobuf_object: " << res.ShortDebugString());
93 94
    if (!res.IsInitialized())
      throw SerializationException{res.InitializationErrorString()};
95 96
    return res;
  }
97 98

private:
99
  Message& operator=(const Message&);
100 101
};

102
#endif // __MESSAGE_HPP__