1 /* Copyright (c) 2014, 2021, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software Foundation,
21 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
22
23 #include "gcs_plugin_messages.h"
24
25 const int Plugin_gcs_message::PLUGIN_GCS_MESSAGE_VERSION= 1;
26
27 const unsigned int Plugin_gcs_message::WIRE_VERSION_SIZE= 4;
28 const unsigned int Plugin_gcs_message::WIRE_HD_LEN_SIZE= 2;
29 const unsigned int Plugin_gcs_message::WIRE_MSG_LEN_SIZE= 8;
30 const unsigned int Plugin_gcs_message::WIRE_CARGO_TYPE_SIZE= 2;
31
32 const unsigned int Plugin_gcs_message::WIRE_FIXED_HEADER_SIZE=
33 Plugin_gcs_message::WIRE_VERSION_SIZE +
34 Plugin_gcs_message::WIRE_HD_LEN_SIZE +
35 Plugin_gcs_message::WIRE_MSG_LEN_SIZE +
36 Plugin_gcs_message::WIRE_CARGO_TYPE_SIZE;
37
38 const unsigned int Plugin_gcs_message::WIRE_PAYLOAD_ITEM_TYPE_SIZE= 2;
39
40 const unsigned int Plugin_gcs_message::WIRE_PAYLOAD_ITEM_LEN_SIZE= 8;
41
42 const unsigned int Plugin_gcs_message::WIRE_PAYLOAD_ITEM_HEADER_SIZE=
43 Plugin_gcs_message::WIRE_PAYLOAD_ITEM_TYPE_SIZE +
44 Plugin_gcs_message::WIRE_PAYLOAD_ITEM_LEN_SIZE;
45
Plugin_gcs_message(enum_cargo_type cargo_type)46 Plugin_gcs_message::Plugin_gcs_message(enum_cargo_type cargo_type)
47 : m_version(PLUGIN_GCS_MESSAGE_VERSION),
48 m_fixed_header_len(WIRE_FIXED_HEADER_SIZE),
49 m_msg_len(WIRE_FIXED_HEADER_SIZE),
50 m_cargo_type(cargo_type)
51 {
52 }
53
encode(std::vector<unsigned char> * buffer) const54 void Plugin_gcs_message::encode(std::vector<unsigned char>* buffer) const
55 {
56 DBUG_ENTER("Plugin_gcs_message::encode");
57 unsigned char buf[WIRE_FIXED_HEADER_SIZE];
58 unsigned char* slider= buf;
59
60 int4store(slider, m_version);
61 slider += WIRE_VERSION_SIZE;
62
63 int2store(slider, m_fixed_header_len);
64 slider += WIRE_HD_LEN_SIZE;
65
66 int8store(slider, m_msg_len);
67 slider += WIRE_MSG_LEN_SIZE;
68
69 unsigned short s_cargo_type= (unsigned short) m_cargo_type;
70 int2store(slider, s_cargo_type);
71 slider += WIRE_CARGO_TYPE_SIZE;
72
73 buffer->insert(buffer->end(), buf, buf + WIRE_FIXED_HEADER_SIZE);
74
75 encode_payload(buffer);
76
77 DBUG_VOID_RETURN;
78 }
79
decode(const unsigned char * buffer,uint64 length)80 void Plugin_gcs_message::decode(const unsigned char* buffer,
81 uint64 length)
82 {
83 DBUG_ENTER("Plugin_gcs_message::decode");
84 const unsigned char *slider= buffer;
85 const unsigned char *end= buffer + length;
86
87 m_version= uint4korr(slider);
88 slider += WIRE_VERSION_SIZE;
89
90 m_fixed_header_len= uint2korr(slider);
91 slider += WIRE_HD_LEN_SIZE;
92
93 m_msg_len= uint8korr(slider);
94 slider += WIRE_MSG_LEN_SIZE;
95
96 unsigned short s_cargo_type= 0;
97 s_cargo_type= uint2korr(slider);
98 // enum may have 32bit storage
99 m_cargo_type= (Plugin_gcs_message::enum_cargo_type)
100 s_cargo_type;
101 slider += WIRE_CARGO_TYPE_SIZE;
102
103 decode_payload(slider, end);
104
105 DBUG_VOID_RETURN;
106 }
107
108 Plugin_gcs_message::enum_cargo_type
get_cargo_type(const unsigned char * buffer)109 Plugin_gcs_message::get_cargo_type(const unsigned char* buffer)
110 {
111 DBUG_ENTER("Plugin_gcs_message::decode");
112 const unsigned char *slider= buffer +
113 WIRE_VERSION_SIZE +
114 WIRE_HD_LEN_SIZE +
115 WIRE_MSG_LEN_SIZE;
116
117 unsigned short s_cargo_type= 0;
118 s_cargo_type= uint2korr(slider);
119 // enum may have 32bit storage
120 Plugin_gcs_message::enum_cargo_type cargo_type=
121 (Plugin_gcs_message::enum_cargo_type) s_cargo_type;
122
123 DBUG_RETURN(cargo_type);
124 }
125
126 void
get_first_payload_item_raw_data(const unsigned char * buffer,const unsigned char ** payload_item_data,uint64 * payload_item_length)127 Plugin_gcs_message::get_first_payload_item_raw_data(const unsigned char* buffer,
128 const unsigned char** payload_item_data,
129 uint64* payload_item_length)
130 {
131 DBUG_ENTER("Plugin_gcs_message::get_first_payload_item_raw_data");
132 const unsigned char *slider= buffer +
133 WIRE_FIXED_HEADER_SIZE +
134 WIRE_PAYLOAD_ITEM_TYPE_SIZE;
135
136 *payload_item_length= uint8korr(slider);
137 slider += WIRE_PAYLOAD_ITEM_LEN_SIZE;
138 *payload_item_data= slider;
139
140 DBUG_VOID_RETURN;
141 }
142
143 void
encode_payload_item_type_and_length(std::vector<unsigned char> * buffer,uint16 payload_item_type,unsigned long long payload_item_length) const144 Plugin_gcs_message::encode_payload_item_type_and_length(std::vector<unsigned char>* buffer,
145 uint16 payload_item_type,
146 unsigned long long payload_item_length)
147 const
148 {
149 DBUG_ENTER("Plugin_gcs_message::encode_payload_item_type_and_length");
150 unsigned char buf[WIRE_PAYLOAD_ITEM_HEADER_SIZE];
151 unsigned char* slider= buf;
152
153 int2store(slider, payload_item_type);
154 slider += WIRE_PAYLOAD_ITEM_TYPE_SIZE;
155
156 int8store(slider, payload_item_length);
157 slider += WIRE_PAYLOAD_ITEM_LEN_SIZE;
158
159 buffer->insert(buffer->end(), buf, buf + WIRE_PAYLOAD_ITEM_HEADER_SIZE);
160
161 DBUG_VOID_RETURN;
162 }
163
164 void
decode_payload_item_type_and_length(const unsigned char ** buffer,uint16 * payload_item_type,unsigned long long * payload_item_length)165 Plugin_gcs_message::decode_payload_item_type_and_length(const unsigned char** buffer,
166 uint16* payload_item_type,
167 unsigned long long* payload_item_length)
168 {
169 DBUG_ENTER("Plugin_gcs_message::decode_payload_item_type_and_length");
170
171 *payload_item_type= uint2korr(*buffer);
172 *buffer += WIRE_PAYLOAD_ITEM_TYPE_SIZE;
173
174 *payload_item_length= uint8korr(*buffer);
175 *buffer += WIRE_PAYLOAD_ITEM_LEN_SIZE;
176
177 DBUG_VOID_RETURN;
178 }
179
180 void
encode_payload_item_char(std::vector<unsigned char> * buffer,uint16 type,unsigned char value) const181 Plugin_gcs_message::encode_payload_item_char(std::vector<unsigned char>* buffer,
182 uint16 type,
183 unsigned char value)
184 const
185 {
186 DBUG_ENTER("Plugin_gcs_message::encode_payload_item_char");
187 unsigned char buf[1];
188
189 encode_payload_item_type_and_length(buffer, type, 1);
190 buf[0]= value;
191 buffer->insert(buffer->end(), buf, buf + 1);
192
193 DBUG_VOID_RETURN;
194 }
195
196 void
decode_payload_item_char(const unsigned char ** buffer,uint16 * type,unsigned char * value)197 Plugin_gcs_message::decode_payload_item_char(const unsigned char** buffer,
198 uint16* type,
199 unsigned char* value)
200 {
201 DBUG_ENTER("Plugin_gcs_message::decode_payload_item_char");
202
203 unsigned long long length= 0;
204 decode_payload_item_type_and_length(buffer, type, &length);
205 *value= **buffer;
206 *buffer += 1;
207
208 DBUG_VOID_RETURN;
209 }
210
211 void
encode_payload_item_int2(std::vector<unsigned char> * buffer,uint16 type,uint16 value) const212 Plugin_gcs_message::encode_payload_item_int2(std::vector<unsigned char>* buffer,
213 uint16 type,
214 uint16 value)
215 const
216 {
217 DBUG_ENTER("Plugin_gcs_message::encode_payload_item_int2");
218 unsigned char buf[2];
219
220 encode_payload_item_type_and_length(buffer, type, 2);
221 int2store(buf, value);
222 buffer->insert(buffer->end(), buf, buf + 2);
223
224 DBUG_VOID_RETURN;
225 }
226
227 void
decode_payload_item_int2(const unsigned char ** buffer,uint16 * type,uint16 * value)228 Plugin_gcs_message::decode_payload_item_int2(const unsigned char** buffer,
229 uint16* type,
230 uint16* value)
231 {
232 DBUG_ENTER("Plugin_gcs_message::decode_payload_item_int2");
233
234 unsigned long long length= 0;
235 decode_payload_item_type_and_length(buffer, type, &length);
236 *value= uint2korr(*buffer);
237 *buffer += 2;
238
239 DBUG_VOID_RETURN;
240 }
241
242 void
encode_payload_item_int4(std::vector<unsigned char> * buffer,uint16 type,uint32 value) const243 Plugin_gcs_message::encode_payload_item_int4(std::vector<unsigned char>* buffer,
244 uint16 type,
245 uint32 value)
246 const
247 {
248 DBUG_ENTER("Plugin_gcs_message::encode_payload_item_int4");
249 unsigned char buf[4];
250
251 encode_payload_item_type_and_length(buffer, type, 4);
252 int4store(buf, value);
253 buffer->insert(buffer->end(), buf, buf + 4);
254
255 DBUG_VOID_RETURN;
256 }
257
258 void
decode_payload_item_int4(const unsigned char ** buffer,uint16 * type,uint32 * value)259 Plugin_gcs_message::decode_payload_item_int4(const unsigned char** buffer,
260 uint16* type,
261 uint32* value)
262 {
263 DBUG_ENTER("Plugin_gcs_message::decode_payload_item_int4");
264
265 unsigned long long length= 0;
266 decode_payload_item_type_and_length(buffer, type, &length);
267 *value= uint4korr(*buffer);
268 *buffer += 4;
269
270 DBUG_VOID_RETURN;
271 }
272
273 void
encode_payload_item_int8(std::vector<unsigned char> * buffer,uint16 type,ulonglong value) const274 Plugin_gcs_message::encode_payload_item_int8(std::vector<unsigned char>* buffer,
275 uint16 type,
276 ulonglong value)
277 const
278 {
279 DBUG_ENTER("Plugin_gcs_message::encode_payload_item_int8");
280 unsigned char buf[8];
281
282 encode_payload_item_type_and_length(buffer, type, 8);
283 int8store(buf, value);
284 buffer->insert(buffer->end(), buf, buf + 8);
285
286 DBUG_VOID_RETURN;
287 }
288
289 void
decode_payload_item_int8(const unsigned char ** buffer,uint16 * type,ulonglong * value)290 Plugin_gcs_message::decode_payload_item_int8(const unsigned char** buffer,
291 uint16* type,
292 ulonglong* value)
293 {
294 DBUG_ENTER("Plugin_gcs_message::decode_payload_item_int8");
295
296 unsigned long long length= 0;
297 decode_payload_item_type_and_length(buffer, type, &length);
298 *value= uint8korr(*buffer);
299 *buffer += 8;
300
301 DBUG_VOID_RETURN;
302 }
303
304 void
encode_payload_item_string(std::vector<unsigned char> * buffer,uint16 type,const char * value,unsigned long long length) const305 Plugin_gcs_message::encode_payload_item_string(std::vector<unsigned char>* buffer,
306 uint16 type,
307 const char* value,
308 unsigned long long length)
309 const
310 {
311 DBUG_ENTER("Plugin_gcs_message::encode_payload_item_string");
312
313 encode_payload_item_type_and_length(buffer, type, length);
314 buffer->insert(buffer->end(), value, value + length);
315
316 DBUG_VOID_RETURN;
317 }
318
319 void
decode_payload_item_string(const unsigned char ** buffer,uint16 * type,std::string * value,unsigned long long * length)320 Plugin_gcs_message::decode_payload_item_string(const unsigned char** buffer,
321 uint16* type,
322 std::string* value,
323 unsigned long long* length)
324 {
325 DBUG_ENTER("Plugin_gcs_message::decode_payload_item_string");
326
327 decode_payload_item_type_and_length(buffer, type, length);
328 value->assign(reinterpret_cast<const char*>(*buffer), (size_t)*length);
329 *buffer += *length;
330
331 DBUG_VOID_RETURN;
332 }
333