1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.shardingsphere.db.protocol.mysql.payload;
19
20 import com.google.common.base.Strings;
21 import io.netty.buffer.ByteBuf;
22 import lombok.Getter;
23 import lombok.RequiredArgsConstructor;
24 import org.apache.shardingsphere.db.protocol.payload.PacketPayload;
25
26 import java.nio.charset.Charset;
27
28 /**
29 * MySQL payload operation for MySQL packet data types.
30 *
31 * @see <a href="https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_basic_data_types.html">Basic Data Types</a>
32 */
33 @RequiredArgsConstructor
34 @Getter
35 public final class MySQLPacketPayload implements PacketPayload {
36
37 private final ByteBuf byteBuf;
38
39 private final Charset charset;
40
41 /**
42 * Read 1 byte fixed length integer from byte buffers.
43 *
44 * @return 1 byte fixed length integer
45 */
46 public int readInt1() {
47 return byteBuf.readUnsignedByte();
48 }
49
50 /**
51 * Write 1 byte fixed length integer to byte buffers.
52 *
53 * @param value 1 byte fixed length integer
54 */
55 public void writeInt1(final int value) {
56 byteBuf.writeByte(value);
57 }
58
59 /**
60 * Read 2 byte fixed length integer from byte buffers.
61 *
62 * @return 2 byte fixed length integer
63 */
64 public int readInt2() {
65 return byteBuf.readUnsignedShortLE();
66 }
67
68 /**
69 * Write 2 byte fixed length integer to byte buffers.
70 *
71 * @param value 2 byte fixed length integer
72 */
73 public void writeInt2(final int value) {
74 byteBuf.writeShortLE(value);
75 }
76
77 /**
78 * Read 3 byte fixed length integer from byte buffers.
79 *
80 * @return 3 byte fixed length integer
81 */
82 public int readInt3() {
83 return byteBuf.readUnsignedMediumLE();
84 }
85
86 /**
87 * Write 3 byte fixed length integer to byte buffers.
88 *
89 * @param value 3 byte fixed length integer
90 */
91 public void writeInt3(final int value) {
92 byteBuf.writeMediumLE(value);
93 }
94
95 /**
96 * Read 4 byte fixed length integer from byte buffers.
97 *
98 * @return 4 byte fixed length integer
99 */
100 public int readInt4() {
101 return byteBuf.readIntLE();
102 }
103
104 /**
105 * Write 4 byte fixed length integer to byte buffers.
106 *
107 * @param value 4 byte fixed length integer
108 */
109 public void writeInt4(final int value) {
110 byteBuf.writeIntLE(value);
111 }
112
113 /**
114 * Read 6 byte fixed length integer from byte buffers.
115 *
116 * @return 6 byte fixed length integer
117 */
118 public long readInt6() {
119 long result = 0;
120 for (int i = 0; i < 6; i++) {
121 result |= ((long) (0xff & byteBuf.readByte())) << (8 * i);
122 }
123 return result;
124 }
125
126 /**
127 * Write 6 byte fixed length integer to byte buffers.
128 *
129 * @param value 6 byte fixed length integer
130 */
131 public void writeInt6(final long value) {
132 // TODO
133 }
134
135 /**
136 * Read 8 byte fixed length integer from byte buffers.
137 *
138 * @return 8 byte fixed length integer
139 */
140 public long readInt8() {
141 return byteBuf.readLongLE();
142 }
143
144 /**
145 * Write 8 byte fixed length integer to byte buffers.
146 *
147 * @param value 8 byte fixed length integer
148 */
149 public void writeInt8(final long value) {
150 byteBuf.writeLongLE(value);
151 }
152
153 /**
154 * Read lenenc integer from byte buffers.
155 *
156 * @return lenenc integer
157 */
158 public long readIntLenenc() {
159 int firstByte = readInt1();
160 if (firstByte < 0xfb) {
161 return firstByte;
162 }
163 if (0xfb == firstByte) {
164 return 0;
165 }
166 if (0xfc == firstByte) {
167 return readInt2();
168 }
169 if (0xfd == firstByte) {
170 return readInt3();
171 }
172 return byteBuf.readLongLE();
173 }
174
175 /**
176 * Write lenenc integer to byte buffers.
177 *
178 * @param value lenenc integer
179 */
180 public void writeIntLenenc(final long value) {
181 if (value < 0xfb) {
182 byteBuf.writeByte((int) value);
183 return;
184 }
185 if (value < Math.pow(2, 16)) {
186 byteBuf.writeByte(0xfc);
187 byteBuf.writeShortLE((int) value);
188 return;
189 }
190 if (value < Math.pow(2, 24)) {
191 byteBuf.writeByte(0xfd);
192 byteBuf.writeMediumLE((int) value);
193 return;
194 }
195 byteBuf.writeByte(0xfe);
196 byteBuf.writeLongLE(value);
197 }
198
199 /**
200 * Read fixed length long from byte buffers.
201 *
202 * @param length length read from byte buffers
203 * @return fixed length long
204 */
205 public long readLong(final int length) {
206 long result = 0;
207 for (int i = 0; i < length; i++) {
208 result = result << 8 | readInt1();
209 }
210 return result;
211 }
212
213 /**
214 * Read lenenc string from byte buffers.
215 *
216 * @return lenenc string
217 */
218 public String readStringLenenc() {
219 return new String(readStringLenencByBytes(), charset);
220 }
221
222 /**
223 * Read lenenc string from byte buffers for bytes.
224 *
225 * @return lenenc bytes
226 */
227 public byte[] readStringLenencByBytes() {
228 int length = (int) readIntLenenc();
229 byte[] result = new byte[length];
230 byteBuf.readBytes(result);
231 return result;
232 }
233
234 /**
235 * Write lenenc string to byte buffers.
236 *
237 * @param value fixed length string
238 */
239 public void writeStringLenenc(final String value) {
240 if (Strings.isNullOrEmpty(value)) {
241 byteBuf.writeByte(0);
242 return;
243 }
244 byte[] valueBytes = value.getBytes(charset);
245 writeIntLenenc(valueBytes.length);
246 byteBuf.writeBytes(valueBytes);
247 }
248
249 /**
250 * Write lenenc bytes to byte buffers.
251 *
252 * @param value fixed length bytes
253 */
254 public void writeBytesLenenc(final byte[] value) {
255 if (0 == value.length) {
256 byteBuf.writeByte(0);
257 return;
258 }
259 writeIntLenenc(value.length);
260 byteBuf.writeBytes(value);
261 }
262
263 /**
264 * Read fixed length string from byte buffers.
265 *
266 * @param length length of fixed string
267 * @return fixed length string
268 */
269 public String readStringFix(final int length) {
270 byte[] result = new byte[length];
271 byteBuf.readBytes(result);
272 return new String(result, charset);
273 }
274
275 /**
276 * Read fixed length string from byte buffers and return bytes.
277 *
278 * @param length length of fixed string
279 * @return fixed length bytes
280 */
281 public byte[] readStringFixByBytes(final int length) {
282 byte[] result = new byte[length];
283 byteBuf.readBytes(result);
284 return result;
285 }
286
287 /**
288 * Write variable length string to byte buffers.
289 *
290 * @param value fixed length string
291 */
292 public void writeStringFix(final String value) {
293 byteBuf.writeBytes(value.getBytes(charset));
294 }
295
296 /**
297 * Write variable length bytes to byte buffers.
298 *
299 * @param value fixed length bytes
300 */
301 public void writeBytes(final byte[] value) {
302 byteBuf.writeBytes(value);
303 }
304
305 /**
306 * Read variable length string from byte buffers.
307 *
308 * @return variable length string
309 */
310 public String readStringVar() {
311 // TODO
312 return "";
313 }
314
315 /**
316 * Write fixed length string to byte buffers.
317 *
318 * @param value variable length string
319 */
320 public void writeStringVar(final String value) {
321 // TODO
322 }
323
324 /**
325 * Read null terminated string from byte buffers.
326 *
327 * @return null terminated string
328 */
329 public String readStringNul() {
330 return new String(readStringNulByBytes(), charset);
331 }
332
333 /**
334 * Read null terminated string from byte buffers and return bytes.
335 *
336 * @return null terminated bytes
337 */
338 public byte[] readStringNulByBytes() {
339 byte[] result = new byte[byteBuf.bytesBefore((byte) 0)];
340 byteBuf.readBytes(result);
341 byteBuf.skipBytes(1);
342 return result;
343 }
344
345 /**
346 * Write null terminated string to byte buffers.
347 *
348 * @param value null terminated string
349 */
350 public void writeStringNul(final String value) {
351 byteBuf.writeBytes(value.getBytes(charset));
352 byteBuf.writeByte(0);
353 }
354
355 /**
356 * Read rest of packet string from byte buffers and return bytes.
357 *
358 * @return rest of packet string bytes
359 */
360 public byte[] readStringEOFByBytes() {
361 byte[] result = new byte[byteBuf.readableBytes()];
362 byteBuf.readBytes(result);
363 return result;
364 }
365
366 /**
367 * Read rest of packet string from byte buffers.
368 *
369 * @return rest of packet string
370 */
371 public String readStringEOF() {
372 byte[] result = new byte[byteBuf.readableBytes()];
373 byteBuf.readBytes(result);
374 return new String(result, charset);
375 }
376
377 /**
378 * Write rest of packet string to byte buffers.
379 *
380 * @param value rest of packet string
381 */
382 public void writeStringEOF(final String value) {
383 byteBuf.writeBytes(value.getBytes(charset));
384 }
385
386 /**
387 * Skip reserved from byte buffers.
388 *
389 * @param length length of reserved
390 */
391 public void skipReserved(final int length) {
392 byteBuf.skipBytes(length);
393 }
394
395 /**
396 * Write null for reserved to byte buffers.
397 *
398 * @param length length of reserved
399 */
400 public void writeReserved(final int length) {
401 byteBuf.writeZero(length);
402 }
403 }