FreeCAD

Форк
0
/
Base64.cpp 
168 строк · 6.8 Кб
1
/*
2
base64.cpp and base64.h
3

4
Copyright (C) 2004-2008 René Nyffenegger
5

6
This source code is provided 'as-is', without any express or implied
7
warranty. In no event will the author be held liable for any damages
8
arising from the use of this software.
9

10
Permission is granted to anyone to use this software for any purpose,
11
including commercial applications, and to alter it and redistribute it
12
freely, subject to the following restrictions:
13

14
1. The origin of this source code must not be misrepresented; you must not
15
   claim that you wrote the original source code. If you use this source code
16
   in a product, an acknowledgment in the product documentation would be
17
   appreciated but is not required.
18

19
2. Altered source versions must be plainly marked as such, and must not be
20
   misrepresented as being the original source code.
21

22
3. This notice may not be removed or altered from any source distribution.
23

24
René Nyffenegger rene.nyffenegger@adp-gmbh.ch
25

26
NOTICE: The source code here has been altered from the original to use a provided character buffer
27
rather than returning a new string for each call.
28
These modifications are Copyright (c) 2019 Zheng Lei (realthunder.dev@gmail.com)
29

30
*/
31
#include "PreCompiled.h"
32

33
#ifndef _PreComp_
34
#include <string>
35
#endif
36

37
#include "Base64.h"
38

39
// NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic,
40
// cppcoreguidelines-pro-bounds-constant-array-index, cppcoreguidelines-avoid-magic-numbers,
41
// readability-magic-numbers)
42

43
static const std::array<char, 65> base64_chars {"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
44
                                                "abcdefghijklmnopqrstuvwxyz"
45
                                                "0123456789+/"};
46

47

48
std::array<const signed char, Base::base64DecodeTableSize> Base::base64_decode_table()
49
{
50
    static std::array<const signed char, Base::base64DecodeTableSize> _table = {
51
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -2, -2, -1, -2, -1, -1,  //   0-15
52
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  //  16-31
53
        -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,  //  32-47
54
        52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1,  //  48-63
55
        -1, 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14,  //  64-79
56
        15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,  //  80-95
57
        -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,  //  96-111
58
        41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,  // 112-127
59
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  // 128-143
60
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  // 144-159
61
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  // 160-175
62
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  // 176-191
63
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  // 192-207
64
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  // 208-223
65
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  // 224-239
66
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1   // 240-255
67
    };
68
    return _table;
69
}
70

71
std::size_t Base::base64_encode(char* out, void const* in, std::size_t in_len)
72
{
73
    char* ret = out;
74
    auto const* bytes_to_encode = reinterpret_cast<unsigned char const*>(in);  // NOLINT
75
    int char3 {0};
76
    int char4 {};
77
    std::array<unsigned char, 3> char_array_3 {};
78
    std::array<unsigned char, 4> char_array_4 {};
79

80
    while ((in_len--) != 0U) {
81
        char_array_3[char3++] = *(bytes_to_encode++);
82
        if (char3 == 3) {
83
            char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
84
            char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
85
            char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
86
            char_array_4[3] = char_array_3[2] & 0x3f;
87

88
            for (char3 = 0; (char3 < 4); char3++) {
89
                *ret++ = base64_chars[char_array_4[char3]];
90
            }
91
            char3 = 0;
92
        }
93
    }
94

95
    if (char3 != 0) {
96
        for (char4 = char3; char4 < 3; char4++) {
97
            char_array_3[char4] = '\0';
98
        }
99

100
        char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
101
        char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
102
        char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
103
        char_array_4[3] = char_array_3[2] & 0x3f;
104

105
        for (char4 = 0; (char4 < char3 + 1); char4++) {
106
            *ret++ = base64_chars[char_array_4[char4]];
107
        }
108

109
        while ((char3++ < 3)) {
110
            *ret++ = '=';
111
        }
112
    }
113

114
    return ret - out;
115
}
116

117
std::pair<std::size_t, std::size_t>
118
Base::base64_decode(void* _out, char const* in, std::size_t in_len)
119
{
120
    auto* out = reinterpret_cast<unsigned char*>(_out);  // NOLINT
121
    unsigned char* ret = out;
122
    char const* input = in;
123
    int byteCounter1 {0};
124
    int byteCounter2 {};
125
    std::array<unsigned char, 4> char_array_4 {};
126
    std::array<unsigned char, 3> char_array_3 {};
127

128
    static auto table = base64_decode_table();
129

130
    while (((in_len--) != 0U) && *in != '=') {
131
        const signed char lookup = table[static_cast<unsigned char>(*in++)];
132
        if (lookup < 0) {
133
            break;
134
        }
135

136
        char_array_4[byteCounter1++] = (unsigned char)lookup;
137
        if (byteCounter1 == 4) {
138
            char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
139
            char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
140
            char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
141

142
            for (byteCounter1 = 0; (byteCounter1 < 3); byteCounter1++) {
143
                *ret++ = char_array_3[byteCounter1];
144
            }
145
            byteCounter1 = 0;
146
        }
147
    }
148

149
    if (byteCounter1 != 0) {
150
        for (byteCounter2 = byteCounter1; byteCounter2 < 4; byteCounter2++) {
151
            char_array_4[byteCounter2] = 0;
152
        }
153

154
        char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
155
        char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
156
        char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
157

158
        for (byteCounter2 = 0; (byteCounter2 < byteCounter1 - 1); byteCounter2++) {
159
            *ret++ = char_array_3[byteCounter2];
160
        }
161
    }
162

163
    return std::make_pair((std::size_t)(ret - out), (std::size_t)(in - input));
164
}
165

166
// NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic,
167
// cppcoreguidelines-pro-bounds-constant-array-index, cppcoreguidelines-avoid-magic-numbers,
168
// readability-magic-numbers)
169

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

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

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

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