91 lines
2.6 KiB
C++
91 lines
2.6 KiB
C++
// IACore-OSS; The Core Library for All IA Open Source Projects
|
|
// Copyright (C) 2026 IAS (ias@iasoft.dev)
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#include <IACore/StringOps.hpp>
|
|
|
|
namespace IACore {
|
|
const String BASE64_CHAR_TABLE =
|
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
|
|
auto StringOps::encode_base64(Span<const u8> data) -> String {
|
|
String result;
|
|
result.reserve(((data.size() + 2) / 3) * 4);
|
|
for (size_t i = 0; i < data.size(); i += 3) {
|
|
uint32_t value = 0;
|
|
i32 num_bytes = 0;
|
|
for (i32 j = 0; j < 3 && (i + j) < data.size(); ++j) {
|
|
value = (value << 8) | data[i + j];
|
|
num_bytes++;
|
|
}
|
|
for (i32 j = 0; j < num_bytes + 1; ++j) {
|
|
if (j < 4) {
|
|
result += BASE64_CHAR_TABLE[(value >> (6 * (3 - j))) & 0x3F];
|
|
}
|
|
}
|
|
if (num_bytes < 3) {
|
|
for (i32 j = 0; j < (3 - num_bytes); ++j) {
|
|
result += '=';
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
auto StringOps::decode_base64(const String &data) -> Vec<u8> {
|
|
Vec<u8> result;
|
|
|
|
const auto is_base64 = [](u8 c) {
|
|
return (isalnum(c) || (c == '+') || (c == '/'));
|
|
};
|
|
|
|
i32 in_len = data.size();
|
|
i32 i = 0, j = 0, in = 0;
|
|
u8 tmp_buf0[4], tmp_buf1[3];
|
|
|
|
while (in_len-- && (data[in] != '=') && is_base64(data[in])) {
|
|
tmp_buf0[i++] = data[in];
|
|
in++;
|
|
if (i == 4) {
|
|
for (i = 0; i < 4; i++)
|
|
tmp_buf0[i] = BASE64_CHAR_TABLE.find(tmp_buf0[i]);
|
|
|
|
tmp_buf1[0] = (tmp_buf0[0] << 2) + ((tmp_buf0[1] & 0x30) >> 4);
|
|
tmp_buf1[1] = ((tmp_buf0[1] & 0xf) << 4) + ((tmp_buf0[2] & 0x3c) >> 2);
|
|
tmp_buf1[2] = ((tmp_buf0[2] & 0x3) << 6) + tmp_buf0[3];
|
|
|
|
for (i = 0; (i < 3); i++)
|
|
result.push_back(tmp_buf1[i]);
|
|
i = 0;
|
|
}
|
|
}
|
|
|
|
if (i) {
|
|
for (j = i; j < 4; j++)
|
|
tmp_buf0[j] = 0;
|
|
|
|
for (j = 0; j < 4; j++)
|
|
tmp_buf0[j] = BASE64_CHAR_TABLE.find(tmp_buf0[j]);
|
|
|
|
tmp_buf1[0] = (tmp_buf0[0] << 2) + ((tmp_buf0[1] & 0x30) >> 4);
|
|
tmp_buf1[1] = ((tmp_buf0[1] & 0xf) << 4) + ((tmp_buf0[2] & 0x3c) >> 2);
|
|
tmp_buf1[2] = ((tmp_buf0[2] & 0x3) << 6) + tmp_buf0[3];
|
|
|
|
for (j = 0; (j < i - 1); j++)
|
|
result.push_back(tmp_buf1[j]);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
} // namespace IACore
|