aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/clickhouse/src/Core/MySQL/IMySQLReadPacket.cpp
blob: bb00444c6b3b42ee27532e10f6c44f8bd6744c1a (plain) (blame)
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
#include <Core/MySQL/IMySQLReadPacket.h>
#include <IO/MySQLPacketPayloadReadBuffer.h>
#include <IO/LimitReadBuffer.h>

namespace DB
{

namespace ErrorCodes
{
    extern const int UNKNOWN_PACKET_FROM_CLIENT;
}

namespace MySQLProtocol
{

void IMySQLReadPacket::readPayload(ReadBuffer & in, uint8_t & sequence_id)
{
    MySQLPacketPayloadReadBuffer payload(in, sequence_id);
    payload.next();
    readPayloadImpl(payload);
    if (!payload.eof())
    {
        throw Exception(ErrorCodes::UNKNOWN_PACKET_FROM_CLIENT,
                        "Packet payload is not fully read. Stopped after {} bytes, while {} bytes are in buffer.",
                        payload.count(), payload.available());
    }
}

void IMySQLReadPacket::readPayloadWithUnpacked(ReadBuffer & in)
{
    readPayloadImpl(in);
}

void LimitedReadPacket::readPayload(ReadBuffer &in, uint8_t &sequence_id)
{
    LimitReadBuffer limited(in, 10000, /* trow_exception */ true, /* exact_limit */ {}, "too long MySQL packet.");
    IMySQLReadPacket::readPayload(limited, sequence_id);
}

void LimitedReadPacket::readPayloadWithUnpacked(ReadBuffer & in)
{
    LimitReadBuffer limited(in, 10000, /* trow_exception */ true, /* exact_limit */ {}, "too long MySQL packet.");
    IMySQLReadPacket::readPayloadWithUnpacked(limited);
}

uint64_t readLengthEncodedNumber(ReadBuffer & buffer, UInt16 & bytes_read)
{
    char c{};
    uint64_t buf = 0;
    buffer.readStrict(c);
    bytes_read = 1;
    auto cc = static_cast<uint8_t>(c);
    switch (cc)
    {
        /// NULL
        case 0xfb:
            break;
        case 0xfc:
            buffer.readStrict(reinterpret_cast<char *>(&buf), 2);
            bytes_read += 2;
            break;
        case 0xfd:
            buffer.readStrict(reinterpret_cast<char *>(&buf), 3);
            bytes_read += 3;
            break;
        case 0xfe:
            buffer.readStrict(reinterpret_cast<char *>(&buf), 8);
            bytes_read += 8;
            break;
        default:
            return cc;
    }
    return buf;
}

uint64_t readLengthEncodedNumber(ReadBuffer & buffer)
{
    UInt16 bytes_read = 0;
    return readLengthEncodedNumber(buffer, bytes_read);
}

void readLengthEncodedString(String & s, ReadBuffer & buffer)
{
    uint64_t len = readLengthEncodedNumber(buffer);
    s.resize(len);
    buffer.readStrict(reinterpret_cast<char *>(s.data()), len);
}

}

}