Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / common / url_escape.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #include "url_escape.h"
5
6 #include <stdexcept>
7 #include <sstream>
8
9 std::string url_escape(const std::string& s)
10 {
11   std::string out;
12   for (auto c : s) {
13     if (std::isalnum(c) || c == '-' || c == '.' || c == '_' || c == '~' ||
14         c == '/') {
15       out.push_back(c);
16     } else {
17       char t[4];
18       snprintf(t, sizeof(t), "%%%02x", (int)(unsigned char)c);
19       out.append(t);
20     }
21   }
22   return out;
23 }
24
25 std::string url_unescape(const std::string& s)
26 {
27   std::string out;
28   const char *end = s.c_str() + s.size();
29   for (const char *c = s.c_str(); c < end; ++c) {
30     switch (*c) {
31     case '%':
32       {
33         unsigned char v = 0;
34         for (unsigned i=0; i<2; ++i) {
35           ++c;
36           if (c >= end) {
37             std::ostringstream ss;
38             ss << "invalid escaped string at pos " << (c - s.c_str()) << " of '"
39                << s << "'";
40             throw std::runtime_error(ss.str());
41           }
42           v <<= 4;
43           if (*c >= '0' && *c <= '9') {
44             v += *c - '0';
45           } else if (*c >= 'a' && *c <= 'f') {
46             v += *c - 'a' + 10;
47           } else if (*c >= 'A' && *c <= 'F') {
48             v += *c - 'A' + 10;
49           } else {
50             std::ostringstream ss;
51             ss << "invalid escaped string at pos " << (c - s.c_str()) << " of '"
52                << s << "'";
53             throw std::runtime_error(ss.str());
54           }
55         }
56         out.push_back(v);
57       }
58       break;
59     default:
60       out.push_back(*c);
61     }
62   }
63   return out;
64 }