-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathtlv.cpp
122 lines (111 loc) · 3.27 KB
/
tlv.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include "tlv.h"
#define HEAD_LEN sizeof(messageHead)
void Tlv::ParseConcrete(const char* data, int data_len) {
int type = 0;
int length = 0;
if (data_len >= HEAD_LEN) {
type = *((int*)data);
length = *((int*)data + 1);
if (length < 0) {
printf("%s receive error packet! len %d\n", __func__, length);
return;
}
if (length == data_len - HEAD_LEN) {
auto msg = new_message(type, length, data + HEAD_LEN);
queue_.push(msg);
}
else if (length > data_len - (int)HEAD_LEN) { //body is not enough
next_data_.append(data, data_len);
next_need_ = NEED_BODY;
}
else { //body is enough
auto msg = new_message(type, length, data + HEAD_LEN);
queue_.push(msg);
remain_data_.append(data + length + HEAD_LEN,
data_len - length - HEAD_LEN );
}
}
else { //Not enough head information
next_data_.append(data, data_len);
next_need_ = NEED_HEAD;
}
}
void Tlv::ParseConcreteNext2(const char* data, int data_len) {
int type = *((int*)data);
int length = *((int*)data + 1);
if (length < 0) {
printf("%s receive error packet! len %d\n", __func__, length);
return;
}
if (length == data_len - HEAD_LEN) {
auto msg = new_message(type, length, data + HEAD_LEN);
queue_.push(msg);
next_data_.clear();
next_need_ = NEED_NONE;
} else if (length > data_len - (int)HEAD_LEN) {
next_need_ = NEED_BODY;
} else {
auto msg = new_message(type, length, data + HEAD_LEN);
queue_.push(msg);
remain_data_.append(data + length + HEAD_LEN,
data_len - length - HEAD_LEN );
next_data_.clear();
next_need_ = NEED_NONE;
}
}
void Tlv::ParseConcreteNext(const char* data, int data_len) {
if (next_need_ == NEED_HEAD && data_len < HEAD_LEN)
next_need_ = NEED_HEAD;
else
ParseConcreteNext2(data, data_len);
}
void Tlv::ParseConcreteRemain(const char* data, int data_len) {
int type = 0;
int length = 0;
if (data_len >= HEAD_LEN) {
type = *((int*)data);
length = *((int*)data + 1);
if (length < 0) {
printf("%s receive error packet! len %d\n", __func__, length);
return;
}
if (length == data_len - HEAD_LEN) {
auto msg = new_message(type, length, data + HEAD_LEN);
queue_.push(msg);
remain_data_.clear();
}
else if (length > data_len - (int)HEAD_LEN) { //body is not enough
next_data_.append(data, data_len);
next_need_ = NEED_BODY;
remain_data_.clear();
}
else { //body is enough
auto msg = new_message(type, length, data + HEAD_LEN);
queue_.push(msg);
remain_data_.erase(0, length + HEAD_LEN );
}
}
else { //Not enough head information
next_data_.append(data, data_len);
next_need_ = NEED_HEAD;
remain_data_.clear();
}
}
void Tlv::Parse(const char* data, int data_len) {
if (!data || data_len <= 0)
return;
int i = 1;
while(i || !remain_data_.empty()) {
i = 0;
if (!remain_data_.empty()) {
ParseConcreteRemain(remain_data_.c_str(), remain_data_.size());
} else {
if (next_need_ == NEED_NONE) {
ParseConcrete(data, data_len);
} else {
next_data_.append(data, data_len);
ParseConcreteNext(next_data_.c_str(), next_data_.size());
}
}
}
}