yaml-cpp

FORK: A YAML parser and emitter in C++
git clone https://git.neptards.moe/neptards/yaml-cpp.git
Log | Files | Refs | README | LICENSE

binary.cpp (3316B)


      1 #include "yaml-cpp/binary.h"
      2 
      3 #include <cctype>
      4 
      5 namespace YAML {
      6 static const char encoding[] =
      7     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
      8 
      9 std::string EncodeBase64(const unsigned char *data, std::size_t size) {
     10   const char PAD = '=';
     11 
     12   std::string ret;
     13   ret.resize(4 * size / 3 + 3);
     14   char *out = &ret[0];
     15 
     16   std::size_t chunks = size / 3;
     17   std::size_t remainder = size % 3;
     18 
     19   for (std::size_t i = 0; i < chunks; i++, data += 3) {
     20     *out++ = encoding[data[0] >> 2];
     21     *out++ = encoding[((data[0] & 0x3) << 4) | (data[1] >> 4)];
     22     *out++ = encoding[((data[1] & 0xf) << 2) | (data[2] >> 6)];
     23     *out++ = encoding[data[2] & 0x3f];
     24   }
     25 
     26   switch (remainder) {
     27     case 0:
     28       break;
     29     case 1:
     30       *out++ = encoding[data[0] >> 2];
     31       *out++ = encoding[((data[0] & 0x3) << 4)];
     32       *out++ = PAD;
     33       *out++ = PAD;
     34       break;
     35     case 2:
     36       *out++ = encoding[data[0] >> 2];
     37       *out++ = encoding[((data[0] & 0x3) << 4) | (data[1] >> 4)];
     38       *out++ = encoding[((data[1] & 0xf) << 2)];
     39       *out++ = PAD;
     40       break;
     41   }
     42 
     43   ret.resize(out - &ret[0]);
     44   return ret;
     45 }
     46 
     47 static const unsigned char decoding[] = {
     48     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     49     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     50     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62,  255,
     51     255, 255, 63,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  255, 255,
     52     255, 0,   255, 255, 255, 0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
     53     10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,
     54     25,  255, 255, 255, 255, 255, 255, 26,  27,  28,  29,  30,  31,  32,  33,
     55     34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  48,
     56     49,  50,  51,  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     57     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     58     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     59     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     60     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     61     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     62     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     63     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     64     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     65     255,
     66 };
     67 
     68 std::vector<unsigned char> DecodeBase64(const std::string &input) {
     69   using ret_type = std::vector<unsigned char>;
     70   if (input.empty())
     71     return ret_type();
     72 
     73   ret_type ret(3 * input.size() / 4 + 1);
     74   unsigned char *out = &ret[0];
     75 
     76   unsigned value = 0;
     77   for (std::size_t i = 0, cnt = 0; i < input.size(); i++) {
     78     if (std::isspace(input[i])) {
     79       // skip newlines
     80       continue;
     81     }
     82     unsigned char d = decoding[static_cast<unsigned>(input[i])];
     83     if (d == 255)
     84       return ret_type();
     85 
     86     value = (value << 6) | d;
     87     if (cnt % 4 == 3) {
     88       *out++ = value >> 16;
     89       if (i > 0 && input[i - 1] != '=')
     90         *out++ = value >> 8;
     91       if (input[i] != '=')
     92         *out++ = value;
     93     }
     94     ++cnt;
     95   }
     96 
     97   ret.resize(out - &ret[0]);
     98   return ret;
     99 }
    100 }  // namespace YAML