00001 #include "yaml-cpp-pm/binary.h" 00002 #include "yaml-cpp-pm/node.h" 00003 00004 namespace YAML_PM 00005 { 00006 static const char encoding[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 00007 00008 std::string EncodeBase64(const unsigned char *data, std::size_t size) 00009 { 00010 const char PAD = '='; 00011 00012 std::string ret; 00013 ret.resize(4 * size / 3 + 3); 00014 char *out = &ret[0]; 00015 00016 std::size_t chunks = size / 3; 00017 std::size_t remainder = size % 3; 00018 00019 for(std::size_t i=0;i<chunks;i++, data += 3) { 00020 *out++ = encoding[data[0] >> 2]; 00021 *out++ = encoding[((data[0] & 0x3) << 4) | (data[1] >> 4)]; 00022 *out++ = encoding[((data[1] & 0xf) << 2) | (data[2] >> 6)]; 00023 *out++ = encoding[data[2] & 0x3f]; 00024 } 00025 00026 switch(remainder) { 00027 case 0: 00028 break; 00029 case 1: 00030 *out++ = encoding[data[0] >> 2]; 00031 *out++ = encoding[((data[0] & 0x3) << 4)]; 00032 *out++ = PAD; 00033 *out++ = PAD; 00034 break; 00035 case 2: 00036 *out++ = encoding[data[0] >> 2]; 00037 *out++ = encoding[((data[0] & 0x3) << 4) | (data[1] >> 4)]; 00038 *out++ = encoding[((data[1] & 0xf) << 2)]; 00039 *out++ = PAD; 00040 break; 00041 } 00042 00043 ret.resize(out - &ret[0]); 00044 return ret; 00045 } 00046 00047 static const unsigned char decoding[] = { 00048 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 00049 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 00050 255,255,255,255,255,255,255,255,255,255,255, 62,255,255,255, 63, 00051 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255, 0,255,255, 00052 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 00053 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255, 00054 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 00055 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255, 00056 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 00057 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 00058 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 00059 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 00060 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 00061 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 00062 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 00063 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 00064 }; 00065 00066 std::vector<unsigned char> DecodeBase64(const std::string& input) 00067 { 00068 typedef std::vector<unsigned char> ret_type; 00069 if(input.empty()) 00070 return ret_type(); 00071 00072 ret_type ret(3 * input.size() / 4 + 1); 00073 unsigned char *out = &ret[0]; 00074 00075 unsigned value = 0; 00076 for(std::size_t i=0;i<input.size();i++) { 00077 unsigned char d = decoding[static_cast<unsigned>(input[i])]; 00078 if(d == 255) 00079 return ret_type(); 00080 00081 value = (value << 6) | d; 00082 if(i % 4 == 3) { 00083 *out++ = value >> 16; 00084 if(i > 0 && input[i - 1] != '=') 00085 *out++ = value >> 8; 00086 if(input[i] != '=') 00087 *out++ = value; 00088 } 00089 } 00090 00091 ret.resize(out - &ret[0]); 00092 return ret; 00093 } 00094 00095 void operator >> (const Node& node, Binary& binary) 00096 { 00097 std::string scalar; 00098 node.GetScalar(scalar); 00099 std::vector<unsigned char> data = DecodeBase64(scalar); 00100 binary.swap(data); 00101 } 00102 }