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 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> 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> 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. 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. 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. 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. 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. 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. 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. 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. 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