View Javadoc
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 }