acl/lib_acl_cpp/include/acl_cpp/mqtt/mqtt_message.hpp
2021-06-22 16:07:34 +08:00

115 lines
3.4 KiB
C++

#pragma once
#include "../stdlib/string.hpp"
#include "mqtt_header.hpp"
namespace acl {
/**
* the pure virtual class for creating one mqtt message object from or to mqtt
* message data, all subclass of it should implement the pure virtual method.
* Any subclass of it can be used to parse mqtt data to create mqtt message,
* or serialize to string data from mqtt message.
*/
class ACL_CPP_API mqtt_message {
public:
/**
* create message object to be used for sending message to peer.
* @param type {mqtt_type_t}
*/
mqtt_message(mqtt_type_t type);
/**
* create message object after receiving message data from peer,
* because the mqtt message includes header and body, so we parse
* the protocol data in two steps: frist parsing the mqtt header,
* and then parsing the mqtt body.
* @param header {const mqtt_header&} created from the mqtt data and
* passed to the message object to be created.
*/
mqtt_message(const mqtt_header& header);
/**
* virtual destructor.
*/
virtual ~mqtt_message(void);
public:
/**
* the subclass should implement this method to build mqtt message data,
* this is used as the mqtt message serialize.
* @param out {string&} used to store the mqtt data.
* @return {bool} return true if serialize sucessfully.
*/
virtual bool to_string(string& out) = 0;
/**
* the subclass should implement this method to parse mqtt data,
* this is used as the mqtt message deserialize.
* @param data {char*} mqtt message data received from socket.
* @param dlen {int} the length of data.
* @return {int} return the length of left data not consumed:
* > 0: the current mqtt message object has been finished, the left
* data is for the next message object;
* -1: some error happened when parsing the mqtt message data;
* 0: all the data passed in has been consumed by the current mqtt
* message object, the object maybe complete or not, you should
* call finished() to check if the object has been completed.
*/
virtual int update(const char* data, int dlen) = 0;
/**
* check if the current mqtt object been parsing from mqtt data has
* been completed.
* @return {bool}
*/
virtual bool finished(void) const {
return false;
}
/**
* get the current mqtt message header in variable mode in order to
* change some information of the header.
* @return {mqtt_header&}
*/
mqtt_header& get_header(void) {
return header_;
}
/**
* get the current mqtt message header in invariable mode, just for
* getting some information from it.
* @return {const mqtt_header&}
*/
const mqtt_header& get_header(void) const {
return header_;
}
public:
/**
* create mqtt message object with the specified mqtt header after
* parsing the mqtt data.
* @param header {const mqtt_header&}
* @return {mqtt_message*} return no-NULL if successful, or NULL if
* the mqtt object type of header is invalid.
*/
static mqtt_message* create_message(const mqtt_header& header);
protected:
mqtt_header header_;
// add one byte to string buffer when building mqtt message.
void pack_add(unsigned char ch, string& out);
// add two bytes to string buffer when building mqtt message.
void pack_add(unsigned short n, string& out);
// add string data to string buffer when building mqtt message.
void pack_add(const string& s, string& out);
// parse one short from mqtt data.
bool unpack_short(const char* data, size_t len, unsigned short& out);
};
} // namespace acl