Modified
This commit is contained in:
parent
abeb88b481
commit
e9b667da26
@ -15,6 +15,7 @@ using std::queue;
|
||||
|
||||
namespace Net {
|
||||
|
||||
// the structure to store the option part of a message
|
||||
class Option {
|
||||
public:
|
||||
Option(const string &key, const string &value);
|
||||
@ -34,6 +35,7 @@ public:
|
||||
void updateValue(const string &value);
|
||||
|
||||
private:
|
||||
// the key is unique within a message
|
||||
shared_ptr<string> key;
|
||||
shared_ptr<string> value;
|
||||
};
|
||||
@ -105,30 +107,45 @@ private:
|
||||
|
||||
ssize_t decode_tail(const vector<char> &raw_Data, size_t offset, Message &msg);
|
||||
|
||||
void calculate_options_hash(const vector<char> &raw_data, int32_t end_index, int16_t &sum_hash);
|
||||
|
||||
SHA256Generator sign_gen;
|
||||
};
|
||||
|
||||
class MessageParser {
|
||||
public:
|
||||
|
||||
|
||||
// send a received buffer to parse
|
||||
void parse(const void *buf, size_t size);
|
||||
|
||||
// Get a parsed message from the queue
|
||||
shared_ptr<Message> getMessage();
|
||||
|
||||
// Get the count of the parsed meaasge
|
||||
size_t getMessageCount();
|
||||
|
||||
private:
|
||||
|
||||
// state recorder of a special part of a message
|
||||
int head_state = -5;
|
||||
int option_state = -4;
|
||||
ssize_t body_state = -1;
|
||||
int tail_state = -4;
|
||||
|
||||
// factory used to read data and form the message step by step
|
||||
MessageFactory factory;
|
||||
|
||||
// store the message parsed
|
||||
queue<shared_ptr<Message>> msgs;
|
||||
// buffer to store the data give by
|
||||
queue<char> buffer;
|
||||
// buffer to temporarily store the data of the certain part related to the state of the parser
|
||||
vector<char> temp_buffer;
|
||||
|
||||
// temporarily record the message concentrated
|
||||
shared_ptr<Message> temp_msg;
|
||||
|
||||
|
||||
// reset all state and refresh the parser
|
||||
void reset_state();
|
||||
|
||||
void locate_head();
|
||||
|
BIN
src/communicate/.message_parser.cpp.swo
Normal file
BIN
src/communicate/.message_parser.cpp.swo
Normal file
Binary file not shown.
@ -2,6 +2,7 @@
|
||||
#include "communicate/message.h"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace Net {
|
||||
|
||||
@ -24,18 +25,21 @@ void MessageFactory::encode_head(const Message &msg, vector<char> &raw_data) {
|
||||
|
||||
raw_data.push_back(' ');
|
||||
|
||||
// 协议版本
|
||||
const string s_version = std::to_string(msg.version);
|
||||
|
||||
raw_data.insert(raw_data.end(), s_version.cbegin(), s_version.cend());
|
||||
|
||||
raw_data.push_back(' ');
|
||||
|
||||
// 消息类型
|
||||
const string s_type = std::to_string(msg.type);
|
||||
|
||||
raw_data.insert(raw_data.end(), s_type.cbegin(), s_type.cend());
|
||||
|
||||
raw_data.push_back(' ');
|
||||
|
||||
// 会话ID
|
||||
const string s_tid = std::to_string(msg.tid);
|
||||
|
||||
raw_data.insert(raw_data.end(), s_tid.cbegin(), s_tid.cend());
|
||||
@ -67,6 +71,16 @@ void MessageFactory::encode_options(const Message &msg,
|
||||
raw_data.push_back('\n');
|
||||
}
|
||||
|
||||
// 计算头部和配置部分的哈希值
|
||||
int16_t sum_hash;
|
||||
|
||||
calculate_options_hash(raw_data, raw_data.size() - 1, sum_hash);
|
||||
const string sum_hash_str = std::to_string(sum_hash);
|
||||
raw_data.insert(raw_data.end(), sum_hash_str.cbegin(), sum_hash_str.cend());
|
||||
|
||||
raw_data.push_back('\r');
|
||||
raw_data.push_back('\n');
|
||||
|
||||
raw_data.push_back('\r');
|
||||
raw_data.push_back('\n');
|
||||
}
|
||||
@ -158,8 +172,26 @@ ssize_t MessageFactory::decode_options(const vector<char> &raw_data,
|
||||
msg.addOption(key.c_str(), value.c_str());
|
||||
}
|
||||
|
||||
int sum_hash_range = index - 2;
|
||||
|
||||
--index;
|
||||
|
||||
string sum_hash_str;
|
||||
while((c = raw_data[index++]) != '\r') {
|
||||
sum_hash_str.push_back(c);
|
||||
}
|
||||
|
||||
if(raw_data[index++] != '\n') {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int16_t sum_hash = std::stoi(sum_hash_str);
|
||||
int16_t sum_hash_check;
|
||||
|
||||
calculate_options_hash(raw_data, sum_hash_range, sum_hash_check);
|
||||
|
||||
if(sum_hash_check != sum_hash) return -1;
|
||||
|
||||
if (raw_data[index++] != '\r' || raw_data[index++] != '\n')
|
||||
return -1;
|
||||
|
||||
@ -200,6 +232,24 @@ ssize_t MessageFactory::decode_tail(const vector<char> &raw_data, size_t offset,
|
||||
return index;
|
||||
}
|
||||
|
||||
void MessageFactory::calculate_options_hash(const vector<char> &raw_data, int32_t end_index, int16_t &sum_hash) {
|
||||
|
||||
if(end_index > raw_data.size()) {
|
||||
throw std::runtime_error("end index out of range");
|
||||
}
|
||||
|
||||
sum_hash = 0;
|
||||
|
||||
int32_t index = 0;
|
||||
|
||||
for(auto &c : raw_data) {
|
||||
sum_hash += static_cast<int16_t>(c);
|
||||
sum_hash %= 65535;
|
||||
if (index++ >= end_index) break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool MessageFactory::decodeMessage(const vector<char> &raw_data, Message &msg) {
|
||||
msg.clear();
|
||||
|
||||
@ -251,4 +301,5 @@ bool MessageFactory::decodeMessageTail(const vector<char> &raw_data, Message &ms
|
||||
if(!~decode_tail(raw_data, 0, msg)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Net
|
||||
|
@ -6,12 +6,16 @@ namespace Net {
|
||||
|
||||
void MessageParser::parse(const void *buf, size_t size) {
|
||||
|
||||
// push all data in buff into queue named buffer
|
||||
const char *c_buf = (const char *)buf;
|
||||
for (int i = 0; i < size; i++) {
|
||||
buffer.push(c_buf[i]);
|
||||
}
|
||||
|
||||
// process the data byte by byte until the queue is empty
|
||||
while(!buffer.empty()) {
|
||||
|
||||
// if there is no message concentrated then create new message
|
||||
if (temp_msg == nullptr) {
|
||||
temp_msg = std::make_shared<Message>();
|
||||
}
|
||||
@ -26,9 +30,12 @@ void MessageParser::parse(const void *buf, size_t size) {
|
||||
locate_tail();
|
||||
}
|
||||
|
||||
// tail processing done
|
||||
if(!tail_state){
|
||||
// release the message concentrated
|
||||
msgs.push(temp_msg);
|
||||
temp_msg = nullptr;
|
||||
// reset the state of the parser
|
||||
reset_state();
|
||||
}
|
||||
}
|
||||
@ -91,6 +98,8 @@ void MessageParser::locate_option() {
|
||||
option_state++;
|
||||
else if(c == '\r')
|
||||
option_state = -1;
|
||||
else if (c > 47 && c < 58)
|
||||
option_state++;
|
||||
continue;
|
||||
}
|
||||
if(option_state == -3) {
|
||||
@ -219,8 +228,10 @@ void MessageParser::locate_tail() {
|
||||
|
||||
void MessageParser::reset_state() {
|
||||
temp_buffer.clear();
|
||||
// reset the message concentrated
|
||||
if(temp_msg != nullptr)
|
||||
temp_msg->clear();
|
||||
// reset the state recorder
|
||||
head_state = -5;
|
||||
option_state = -4;
|
||||
body_state = -1;
|
||||
|
@ -26,6 +26,11 @@ TEST(Message_Test, base_test_1) {
|
||||
mf.encodeMessage(msg, rd);
|
||||
PrintTools::printInfoBuffer(rd, "Message Raw Data");
|
||||
|
||||
for(auto &c : rd) {
|
||||
printf("%c", c);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
ASSERT_TRUE(mf.decodeMessage(rd, msg));
|
||||
|
||||
ASSERT_EQ(msg.getTID(), 1);
|
||||
@ -55,8 +60,6 @@ TEST(MessageParser_Test, base_test_1) {
|
||||
MessageParser mp;
|
||||
mp.parse(rd.data(), rd.size());
|
||||
|
||||
printf("SIZE: %lu\n", rd.size());
|
||||
|
||||
ASSERT_EQ(mp.getMessageCount(), 1);
|
||||
|
||||
shared_ptr<Message> p_msg = mp.getMessage();
|
||||
|
Loading…
Reference in New Issue
Block a user