mirror of
https://gitee.com/acl-dev/acl.git
synced 2024-12-14 00:40:55 +08:00
115 lines
3.4 KiB
C++
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
|