Home | History | Annotate | Download | only in xmpmeta
      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