14 #include <pion/algorithm.hpp> 15 #include <boost/assert.hpp> 18 #define SHIFT_BITMASK(ptr, mask) if (mask & 0x01) { mask = 0x80; ++ptr; } else mask >>= 1; 26 static const char nop = -1;
27 static const char decoding_data[] = {
28 nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop,
29 nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop,
30 nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop, 62, nop,nop,nop, 63,
31 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,nop,nop, nop,nop,nop,nop,
32 nop, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
33 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,nop, nop,nop,nop,nop,
34 nop,26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
35 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,nop, nop,nop,nop,nop,
36 nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop,
37 nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop,
38 nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop,
39 nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop,
40 nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop,
41 nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop,
42 nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop,
43 nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop
46 unsigned int input_length=input.size();
47 const char * input_ptr = input.data();
51 output.reserve(((input_length+2)/3)*4);
56 for (
unsigned int i=0; i<input_length;i++) {
62 base64code0 = decoding_data[
static_cast<int>(input_ptr[i])];
65 if(!(++i<input_length))
67 base64code1 = decoding_data[
static_cast<int>(input_ptr[i])];
71 output += ((base64code0 << 2) | ((base64code1 >> 4) & 0x3));
73 if(++i<input_length) {
74 char c = input_ptr[i];
76 BOOST_ASSERT( (base64code1 & 0x0f)==0);
79 base64code2 = decoding_data[
static_cast<int>(input_ptr[i])];
83 output += ((base64code1 << 4) & 0xf0) | ((base64code2 >> 2) & 0x0f);
86 if(++i<input_length) {
87 char c = input_ptr[i];
89 BOOST_ASSERT( (base64code2 & 0x03)==0);
92 base64code3 = decoding_data[
static_cast<int>(input_ptr[i])];
96 output += (((base64code2 << 6) & 0xc0) | base64code3 );
106 static const char encoding_data[] =
107 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
109 unsigned int input_length=input.size();
110 const char * input_ptr = input.data();
114 output.reserve(((input_length+2)/3)*4);
119 for (
unsigned int i=0; i<input_length;i++) {
125 base64code0 = (input_ptr[i] >> 2) & 0x3f;
126 output += encoding_data[base64code0];
127 base64code1 = (input_ptr[i] << 4 ) & 0x3f;
129 if (++i < input_length) {
130 base64code1 |= (input_ptr[i] >> 4) & 0x0f;
131 output += encoding_data[base64code1];
132 base64code2 = (input_ptr[i] << 2) & 0x3f;
134 if (++i < input_length) {
135 base64code2 |= (input_ptr[i] >> 6) & 0x03;
136 base64code3 = input_ptr[i] & 0x3f;
137 output += encoding_data[base64code2];
138 output += encoding_data[base64code3];
140 output += encoding_data[base64code2];
144 output += encoding_data[base64code1];
157 result.reserve(str.size());
159 for (std::string::size_type pos = 0; pos < str.size(); ++pos) {
167 if (pos + 2 < str.size()) {
168 decode_buf[0] = str[++pos];
169 decode_buf[1] = str[++pos];
170 decode_buf[2] =
'\0';
172 char decoded_char =
static_cast<char>( strtol(decode_buf, 0, 16) );
177 if (decoded_char ==
'\0') {
181 result += decoded_char;
201 result.reserve(str.size());
206 for (std::string::size_type pos = 0; pos < str.size(); ++pos) {
209 if (str[pos] > 32 && str[pos] < 127) {
216 case '$':
case '&':
case '+':
case ',':
case '/':
case ':':
217 case ';':
case '=':
case '?':
case '@':
case '"':
case '<':
218 case '>':
case '#':
case '%':
case '{':
case '}':
case '|':
219 case '\\':
case '^':
case '~':
case '[':
case ']':
case '`':
221 sprintf(encode_buf+1,
"%.2X", (
unsigned char)(str[pos]));
222 result += encode_buf;
238 result.reserve(str.size() + 20);
239 const unsigned char *ptr =
reinterpret_cast<const unsigned char*
>(str.c_str());
240 const unsigned char *end_ptr = ptr + str.size();
241 while (ptr < end_ptr) {
246 if ((*ptr >= 0x20 && *ptr <= 0x7F) || *ptr == 0x9 || *ptr == 0xa || *ptr == 0xd) {
268 }
else if (*ptr >= 0xC2 && *ptr <= 0xDF) {
270 if (*(ptr+1) >= 0x80 && *(ptr+1) <= 0xBF) {
279 }
else if (*ptr >= 0xE0 && *ptr <= 0xEF) {
281 if (*(ptr+1) >= 0x80 && *(ptr+1) <= 0xBF
282 && *(ptr+2) >= 0x80 && *(ptr+2) <= 0xBF) {
292 }
else if (*ptr >= 0xF0 && *ptr <= 0xF4) {
294 if (*(ptr+1) >= 0x80 && *(ptr+1) <= 0xBF
295 && *(ptr+2) >= 0x80 && *(ptr+2) <= 0xBF
296 && *(ptr+3) >= 0x80 && *(ptr+3) <= 0xBF) {
322 const int value_sign = (*ptr & 0x80) ? -1 : 1;
325 unsigned char mask = 0x80;
326 boost::int16_t exponent = 0;
327 for (
size_t n = 0; n < num_exp_bits; ++n) {
328 SHIFT_BITMASK(ptr, mask);
335 long double significand = exponent ? 1.0 : 0.0;
336 long double significand_value = 1.0;
337 while (num_fraction_bits) {
338 SHIFT_BITMASK(ptr, mask);
339 significand_value /= 2;
341 significand += significand_value;
346 exponent -= (::pow((
long double)2, (
int)(num_exp_bits - 1)) - 1);
347 value = value_sign * significand * ::pow((
long double)2, exponent);
353 unsigned char *ptr = buf;
354 memset(ptr, 0x00, ::ceil(static_cast<float>(num_exp_bits + num_fraction_bits + 1) / 8));
363 boost::int16_t exponent = 0;
370 unsigned char mask = 0x40;
371 for (
size_t n = num_exp_bits; n > 0; --n) {
376 SHIFT_BITMASK(ptr, mask);
381 bool got_exponent =
false;
382 boost::uint16_t num_bits = 0;
383 while (value && num_bits < num_fraction_bits) {
390 SHIFT_BITMASK(ptr, mask);
403 boost::int32_t high_bit = ::pow((
long double)2, (
int)(num_exp_bits - 1));
405 exponent += (high_bit - 1);
412 for (
size_t n = 0; n < num_exp_bits; ++n) {
413 SHIFT_BITMASK(ptr, mask);
414 if (exponent >= high_bit) {
416 exponent -= high_bit;
static void float_to_bytes(long double value, unsigned char *ptr, size_t num_exp_bits, size_t num_fraction_bits)
static std::string url_encode(const std::string &str)
encodes strings so that they are safe for URLs (with%20spaces)
static bool base64_decode(std::string const &input, std::string &output)
static std::string xml_encode(const std::string &str)
TODO: escapes XML/HTML-encoded strings (1 < 2)
static std::string url_decode(const std::string &str)
escapes URL-encoded strings (a%20value+with%20spaces)
static bool base64_encode(std::string const &input, std::string &output)
static void float_from_bytes(long double &value, const unsigned char *ptr, size_t num_exp_bits, size_t num_fraction_bits)