base64-decode.cc
1.6 KB
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
// sherpa-onnx/csrc/base64-decode.cc
//
// Copyright (c) 2022-2023 Xiaomi Corporation
#include "sherpa-onnx/csrc/base64-decode.h"
#include "sherpa-onnx/csrc/macros.h"
namespace sherpa_onnx {
static int32_t Ord(char c) {
if (c >= 'A' && c <= 'Z') {
return c - 'A';
} else if (c >= 'a' && c <= 'z') {
return c - 'a' + ('Z' - 'A') + 1;
} else if (c >= '0' && c <= '9') {
return c - '0' + ('Z' - 'A') + ('z' - 'a') + 2;
} else if (c == '+') {
return 62;
} else if (c == '/') {
return 63;
}
SHERPA_ONNX_LOGE("Unknown character %d, %c\n", c, c);
exit(-1);
}
// see
// https://github.com/ReneNyffenegger/cpp-base64/blob/master/base64.cpp#L243
std::string Base64Decode(const std::string &s) {
if (s.empty()) {
SHERPA_ONNX_LOGE("Empty string!");
exit(-1);
}
int32_t n = static_cast<int32_t>(s.size()) / 4 * 3;
std::string ans;
ans.reserve(n);
int32_t i = 0;
while (i < static_cast<int32_t>(s.size())) {
if (s[i] == '=') {
return " ";
}
int32_t first = (Ord(s[i]) << 2) + ((Ord(s[i + 1]) & 0x30) >> 4);
ans.push_back(static_cast<char>(first));
if (i + 2 < static_cast<int32_t>(s.size()) && s[i + 2] != '=') {
int32_t second =
((Ord(s[i + 1]) & 0x0f) << 4) + ((Ord(s[i + 2]) & 0x3c) >> 2);
ans.push_back(static_cast<char>(second));
if (i + 3 < static_cast<int32_t>(s.size()) && s[i + 3] != '=') {
int32_t third = ((Ord(s[i + 2]) & 0x03) << 6) + Ord(s[i + 3]);
ans.push_back(static_cast<char>(third));
}
}
i += 4;
}
return ans;
}
} // namespace sherpa_onnx