ClickHouse

Форк
0
/
reverseUTF8.cpp 
84 строки · 2.3 Кб
1
#include <DataTypes/DataTypeString.h>
2
#include <Columns/ColumnString.h>
3
#include <Functions/FunctionFactory.h>
4
#include <Functions/FunctionStringToString.h>
5

6

7
namespace DB
8
{
9
namespace ErrorCodes
10
{
11
    extern const int ILLEGAL_COLUMN;
12
}
13

14
namespace
15
{
16

17
/** Reverse the sequence of code points in a UTF-8 encoded string.
18
  * The result may not match the expected result, because modifying code points (for example, diacritics) may be applied to another symbols.
19
  * If the string is not encoded in UTF-8, then the behavior is undefined.
20
  */
21
struct ReverseUTF8Impl
22
{
23
    static void vector(const ColumnString::Chars & data,
24
        const ColumnString::Offsets & offsets,
25
        ColumnString::Chars & res_data,
26
        ColumnString::Offsets & res_offsets)
27
    {
28
        res_data.resize(data.size());
29
        res_offsets.assign(offsets);
30
        size_t size = offsets.size();
31

32
        ColumnString::Offset prev_offset = 0;
33
        for (size_t i = 0; i < size; ++i)
34
        {
35
            ColumnString::Offset j = prev_offset;
36
            while (j < offsets[i] - 1)
37
            {
38
                if (data[j] < 0xBF)
39
                {
40
                    res_data[offsets[i] + prev_offset - 2 - j] = data[j];
41
                    j += 1;
42
                }
43
                else if (data[j] < 0xE0)
44
                {
45
                    memcpy(&res_data[offsets[i] + prev_offset - 2 - j - 1], &data[j], 2);
46
                    j += 2;
47
                }
48
                else if (data[j] < 0xF0)
49
                {
50
                    memcpy(&res_data[offsets[i] + prev_offset - 2 - j - 2], &data[j], 3);
51
                    j += 3;
52
                }
53
                else
54
                {
55
                    res_data[offsets[i] + prev_offset - 2 - j] = data[j];
56
                    j += 1;
57
                }
58
            }
59

60
            res_data[offsets[i] - 1] = 0;
61
            prev_offset = offsets[i];
62
        }
63
    }
64

65
    [[noreturn]] static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &)
66
    {
67
        throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Cannot apply function reverseUTF8 to fixed string.");
68
    }
69
};
70

71
struct NameReverseUTF8
72
{
73
    static constexpr auto name = "reverseUTF8";
74
};
75
using FunctionReverseUTF8 = FunctionStringToString<ReverseUTF8Impl, NameReverseUTF8, true>;
76

77
}
78

79
REGISTER_FUNCTION(ReverseUTF8)
80
{
81
    factory.registerFunction<FunctionReverseUTF8>();
82
}
83

84
}
85

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.