1 #include "xmpmeta/base64.h"
2
3 #include "android-base/logging.h"
4 #include "strings/escaping.h"
5
6 namespace dynamic_depth {
7 namespace xmpmeta {
8 namespace {
9
EncodeBase64RawData(const uint8 * data,size_t data_size,string * output)10 bool EncodeBase64RawData(const uint8* data, size_t data_size, string* output) {
11 // Disable linting because string_view doesn't appear to support uint8_t.
12 dynamic_depth::Base64Escape(data, data_size, output, false); // NOLINT
13 return output->length() > 0;
14 }
15
16 template <typename T>
InternalEncodeArrayBase64(const std::vector<T> & data,string * output)17 bool InternalEncodeArrayBase64(const std::vector<T>& data, string* output) {
18 size_t buffer_size = data.size() * sizeof(T);
19 return EncodeBase64RawData(reinterpret_cast<const uint8_t*>(data.data()),
20 buffer_size, output);
21 }
22
23 template <typename T>
InternalDecodeArrayBase64(const string & data,std::vector<T> * output)24 bool InternalDecodeArrayBase64(const string& data, std::vector<T>* output) {
25 string bytes;
26 if (!DecodeBase64(data, &bytes)) {
27 return false;
28 }
29
30 const int count = bytes.size() / sizeof(T);
31 output->clear();
32 output->resize(count);
33 memcpy(output->data(), bytes.data(), output->size() * sizeof(T));
34 return !output->empty();
35 }
36
37 } // namespace
38
39 // Decodes the base64-encoded input range.
DecodeBase64(const string & data,string * output)40 bool DecodeBase64(const string& data, string* output) {
41 // Support decoding of both web-safe and regular base64.
42 // "Web-safe" base-64 replaces + with - and / with _, and omits
43 // trailing = padding characters.
44 if (dynamic_depth::Base64Unescape(data, output)) {
45 return true;
46 }
47 return dynamic_depth::WebSafeBase64Unescape(data, output);
48 }
49
50 // Base64-encodes the given data.
EncodeBase64(const string & data,string * output)51 bool EncodeBase64(const string& data, string* output) {
52 return EncodeBase64RawData(reinterpret_cast<const uint8*>(data.c_str()),
53 data.length(), output);
54 }
55
56 // Base64-encodes the given int array.
EncodeIntArrayBase64(const std::vector<int32_t> & data,string * output)57 bool EncodeIntArrayBase64(const std::vector<int32_t>& data, string* output) {
58 return InternalEncodeArrayBase64<int32_t>(data, output);
59 }
60
61 // Base64-decodes the given base64-encoded string.
DecodeIntArrayBase64(const string & data,std::vector<int32_t> * output)62 bool DecodeIntArrayBase64(const string& data, std::vector<int32_t>* output) {
63 return InternalDecodeArrayBase64<int32_t>(data, output);
64 }
65
66 // Base64-encodes the given float array.
EncodeFloatArrayBase64(const std::vector<float> & data,string * output)67 bool EncodeFloatArrayBase64(const std::vector<float>& data, string* output) {
68 return InternalEncodeArrayBase64<float>(data, output);
69 }
70
71 // Base64-decodes the given base64-encoded string.
DecodeFloatArrayBase64(const string & data,std::vector<float> * output)72 bool DecodeFloatArrayBase64(const string& data, std::vector<float>* output) {
73 return InternalDecodeArrayBase64<float>(data, output);
74 }
75
76 // Base64-encodes the given double array.
EncodeDoubleArrayBase64(const std::vector<double> & data,string * output)77 bool EncodeDoubleArrayBase64(const std::vector<double>& data, string* output) {
78 return InternalEncodeArrayBase64<double>(data, output);
79 }
80
81 // Base64-decodes the given base64-encoded string.
DecodeDoubleArrayBase64(const string & data,std::vector<double> * output)82 bool DecodeDoubleArrayBase64(const string& data, std::vector<double>* output) {
83 return InternalDecodeArrayBase64<double>(data, output);
84 }
85 } // namespace xmpmeta
86 } // namespace dynamic_depth
87