19 #include <boost/algorithm/string.hpp>
20 #include <boost/archive/iterators/base64_from_binary.hpp>
21 #include <boost/archive/iterators/binary_from_base64.hpp>
22 #include <boost/archive/iterators/transform_width.hpp>
23 #include <boost/foreach.hpp>
29 using boost::algorithm::is_any_of;
30 using boost::archive::iterators::base64_from_binary;
31 using boost::archive::iterators::binary_from_base64;
32 using boost::archive::iterators::transform_width;
33 using namespace impala;
48 static inline void UrlEncode(
const char* in,
int in_len,
string* out,
bool hive_compat) {
49 (*out).reserve(in_len);
51 for (
int i = 0; i < in_len; ++i) {
52 const char ch = in[i];
59 ss << '%' << uppercase << hex << static_cast<uint32_t>(ch);
68 void UrlEncode(
const vector<uint8_t>& in,
string* out,
bool hive_compat) {
72 UrlEncode(reinterpret_cast<const char*>(&in[0]), in.size(), out, hive_compat);
76 void UrlEncode(
const string& in,
string* out,
bool hive_compat) {
77 UrlEncode(in.c_str(), in.size(), out, hive_compat);
84 bool UrlDecode(
const string& in,
string* out,
bool hive_compat) {
86 out->reserve(in.size());
87 for (
size_t i = 0; i < in.size(); ++i) {
89 if (i + 3 <= in.size()) {
91 istringstream is(in.substr(i + 1, 2));
92 if (is >> hex >> value) {
93 (*out) +=
static_cast<char>(value);
101 }
else if (!hive_compat && in[i] ==
'+') {
110 static inline void Base64Encode(
const char* in,
int in_len, stringstream* out) {
111 typedef base64_from_binary<transform_width<const char*, 6, 8> > base64_encode;
113 stringstream::pos_type len_before = out->tellp();
114 copy(base64_encode(in), base64_encode(in + in_len), std::ostream_iterator<char>(*out));
115 int bytes_written = out->tellp() - len_before;
117 int num_pad = bytes_written % 4;
119 num_pad = 4 - num_pad;
120 for (
int i = 0; i < num_pad; ++i) {
124 DCHECK_EQ((out->tellp() - len_before) % 4, 0);
140 string tmp(reinterpret_cast<const char*>(&in[0]), in.size());
156 typedef transform_width<
157 binary_from_base64<string::const_iterator> , 8, 6> base64_decode;
160 replace(tmp.begin(), tmp.end(),
'=',
'A');
162 *out = string(base64_decode(tmp.begin()), base64_decode(tmp.end()));
163 }
catch(std::exception& e) {
169 int num_padded_chars = 0;
170 for (
int i = out->size() - 1; i >= 0; --i) {
171 if ((*out)[i] !=
'\0')
break;
174 out->resize(out->size() - num_padded_chars);
180 BOOST_FOREACH(
const char& c, in) {
182 case '<': (*out) <<
"<";
184 case '>': (*out) <<
">";
186 case '&': (*out) <<
"&";
188 default: (*out) << c;
static function< bool(char)> HiveShouldEscape
bool UrlDecode(const string &in, string *out, bool hive_compat)
static void Base64Encode(const char *in, int in_len, stringstream *out)
static void UrlEncode(const char *in, int in_len, string *out, bool hive_compat)
bool Base64Decode(const string &in, string *out)
void EscapeForHtml(const string &in, stringstream *out)
static function< bool(char)> ShouldNotEscape