Coverage Report

Created: 2024-11-18 10:37

/root/doris/be/src/vec/common/hex.h
Line
Count
Source (jump to first uncovered line)
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with 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,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
// This file is copied from
18
// https://github.com/ClickHouse/ClickHouse/blob/master/src/Common/hex.h
19
// and modified by Doris
20
21
#pragma once
22
#include <cstring>
23
#include <string>
24
25
#include "vec/core/types.h"
26
27
namespace doris::vectorized {
28
29
/// Maps 0..15 to 0..9A..F or 0..9a..f correspondingly.
30
31
extern const char* const hex_digit_to_char_uppercase_table;
32
extern const char* const hex_digit_to_char_lowercase_table;
33
34
0
inline char hex_digit_uppercase(unsigned char c) {
35
0
    return hex_digit_to_char_uppercase_table[c];
36
0
}
37
38
0
inline char hex_digit_lowercase(unsigned char c) {
39
0
    return hex_digit_to_char_lowercase_table[c];
40
0
}
41
42
/// Maps 0..255 to 00..FF or 00..ff correspondingly
43
44
extern const char* const hex_byte_to_char_uppercase_table;
45
extern const char* const hex_byte_to_char_lowercase_table;
46
47
0
inline void write_hex_byte_uppercase(UInt8 byte, void* out) {
48
0
    memcpy(out, &hex_byte_to_char_uppercase_table[static_cast<size_t>(byte) * 2], 2);
49
0
}
50
51
0
inline void write_hex_byte_lowercase(UInt8 byte, void* out) {
52
0
    memcpy(out, &hex_byte_to_char_lowercase_table[static_cast<size_t>(byte) * 2], 2);
53
0
}
54
55
extern const char* const bin_byte_to_char_table;
56
57
0
inline void write_bin_byte(UInt8 byte, void* out) {
58
0
    memcpy(out, &bin_byte_to_char_table[static_cast<size_t>(byte) * 8], 8);
59
0
}
60
61
/// Produces hex representation of an unsigned int with leading zeros (for checksums)
62
template <typename TUInt>
63
349
void write_hex_uint_impl(TUInt uint_, char* out, const char* const table) {
64
349
    union {
65
349
        TUInt value;
66
349
        UInt8 uint8[sizeof(TUInt)];
67
349
    };
68
69
349
    value = uint_;
70
71
    /// Use little endian
72
5.93k
    for (size_t i = 0; i < sizeof(TUInt); ++i) {
73
5.58k
        memcpy(out + i * 2, &table[static_cast<size_t>(uint8[sizeof(TUInt) - 1 - i]) * 2], 2);
74
5.58k
    }
75
349
}
76
77
template <typename TUInt>
78
void write_hex_uint_uppercase(TUInt uint_, char* out) {
79
    write_hex_uint_impl(uint_, out, hex_byte_to_char_uppercase_table);
80
}
81
82
template <typename TUInt>
83
349
void write_hex_uint_lowercase(TUInt uint_, char* out) {
84
349
    write_hex_uint_impl(uint_, out, hex_byte_to_char_lowercase_table);
85
349
}
86
87
template <typename TUInt>
88
std::string get_hex_uint_uppercase(TUInt uint_) {
89
    std::string res(sizeof(TUInt) * 2, '\0');
90
    write_hex_uint_uppercase(uint_, res.data());
91
    return res;
92
}
93
94
template <typename TUInt>
95
349
std::string get_hex_uint_lowercase(TUInt uint_) {
96
349
    std::string res(sizeof(TUInt) * 2, '\0');
97
349
    write_hex_uint_lowercase(uint_, res.data());
98
349
    return res;
99
349
}
100
101
/// Maps 0..9, A..F, a..f to 0..15. Other chars are mapped to implementation specific value.
102
103
extern const char* const hex_char_to_digit_table;
104
105
160
inline UInt8 unhex(char c) {
106
160
    return hex_char_to_digit_table[static_cast<UInt8>(c)];
107
160
}
108
109
0
inline UInt8 unhex2(const char* data) {
110
0
    return static_cast<UInt8>(unhex(data[0])) * 0x10 + static_cast<UInt8>(unhex(data[1]));
111
0
}
112
113
0
inline UInt16 unhex4(const char* data) {
114
0
    return static_cast<UInt16>(unhex(data[0])) * 0x1000 +
115
0
           static_cast<UInt16>(unhex(data[1])) * 0x100 +
116
0
           static_cast<UInt16>(unhex(data[2])) * 0x10 + static_cast<UInt16>(unhex(data[3]));
117
0
}
118
119
template <typename TUInt>
120
15
TUInt unhex_uint(const char* data) {
121
15
    TUInt res = TUInt(0);
122
15
    if constexpr ((sizeof(TUInt) <= 8) || ((sizeof(TUInt) % 8) != 0)) {
123
170
        for (size_t i = 0; i < sizeof(TUInt) * 2; ++i, ++data) {
124
160
            res <<= 4;
125
160
            res += unhex(*data);
126
160
        }
127
10
    } else {
128
15
        for (size_t i = 0; i < sizeof(TUInt) / 8; ++i, data += 16) {
129
10
            res <<= TUInt(64);
130
10
            res += TUInt(unhex_uint<UInt64>(data));
131
10
        }
132
5
    }
133
15
    return res;
134
15
}
_ZN5doris10vectorized10unhex_uintINS0_7UInt128EEET_PKc
Line
Count
Source
120
5
TUInt unhex_uint(const char* data) {
121
5
    TUInt res = TUInt(0);
122
5
    if constexpr ((sizeof(TUInt) <= 8) || ((sizeof(TUInt) % 8) != 0)) {
123
5
        for (size_t i = 0; i < sizeof(TUInt) * 2; ++i, ++data) {
124
5
            res <<= 4;
125
5
            res += unhex(*data);
126
5
        }
127
5
    } else {
128
15
        for (size_t i = 0; i < sizeof(TUInt) / 8; ++i, data += 16) {
129
10
            res <<= TUInt(64);
130
10
            res += TUInt(unhex_uint<UInt64>(data));
131
10
        }
132
5
    }
133
5
    return res;
134
5
}
_ZN5doris10vectorized10unhex_uintImEET_PKc
Line
Count
Source
120
10
TUInt unhex_uint(const char* data) {
121
10
    TUInt res = TUInt(0);
122
10
    if constexpr ((sizeof(TUInt) <= 8) || ((sizeof(TUInt) % 8) != 0)) {
123
170
        for (size_t i = 0; i < sizeof(TUInt) * 2; ++i, ++data) {
124
160
            res <<= 4;
125
160
            res += unhex(*data);
126
160
        }
127
10
    } else {
128
10
        for (size_t i = 0; i < sizeof(TUInt) / 8; ++i, data += 16) {
129
10
            res <<= TUInt(64);
130
10
            res += TUInt(unhex_uint<UInt64>(data));
131
10
        }
132
10
    }
133
10
    return res;
134
10
}
135
} // namespace doris::vectorized