1 module hunt.database.driver.mysql.impl.util.BufferUtils;
2 
3 import hunt.net.buffer.ByteBuf;
4 import hunt.text.Charset;
5 
6 class BufferUtils {
7     private enum byte TERMINAL = 0x00;
8 
9     static string readNullTerminatedString(ByteBuf buffer, Charset charset) {
10         int len = buffer.bytesBefore(TERMINAL);
11         string s = buffer.readCharSequence(len, charset);
12         buffer.readByte();
13         return s;
14     }
15 
16     static string readFixedLengthString(ByteBuf buffer, int length, Charset charset) {
17         return buffer.readCharSequence(length, charset);
18     }
19 
20     static void writeNullTerminatedString(ByteBuf buffer, CharSequence charSequence, Charset charset) {
21         buffer.writeCharSequence(charSequence, charset);
22         buffer.writeByte(0);
23     }
24 
25     static void writeLengthEncodedInteger(ByteBuf buffer, long value) {
26         if (value < 251) {
27             // 1-byte integer
28             buffer.writeByte(cast(byte) value);
29         } else if (value <= 0xFFFF) {
30             // 0xFC + 2-byte integer
31             buffer.writeByte(0xFC);
32             buffer.writeShortLE(cast(int) value);
33         } else if (value < 0xFFFFFF) {
34             // 0xFD + 3-byte integer
35             buffer.writeByte(0xFD);
36             buffer.writeMediumLE(cast(int) value);
37         } else {
38             // 0xFE + 8-byte integer
39             buffer.writeByte(0xFE);
40             buffer.writeLongLE(value);
41         }
42     }
43 
44     static long readLengthEncodedInteger(ByteBuf buffer) {
45         short firstByte = buffer.readUnsignedByte();
46         switch (firstByte) {
47             case 0xFB:
48                 return -1;
49             case 0xFC:
50                 return buffer.readUnsignedShortLE();
51             case 0xFD:
52                 return buffer.readUnsignedMediumLE();
53             case 0xFE:
54                 return buffer.readLongLE();
55             default:
56                 return firstByte;
57         }
58     }
59 
60     static void writeLengthEncodedString(ByteBuf buffer, string value, Charset charset) {
61         byte[] bytes = cast(byte[])value; // .getBytes(charset);
62         writeLengthEncodedInteger(buffer, cast(int)bytes.length);
63         buffer.writeBytes(bytes);
64     }
65 
66     static string readLengthEncodedString(ByteBuf buffer, Charset charset) {
67         long length = readLengthEncodedInteger(buffer);
68         return readFixedLengthString(buffer, cast(int) length, charset);
69     }
70 }