1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
/*=============================================================================
Copyright (c) 2002 2004 2006 Joel de Guzman
Copyright (c) 2004 Eric Niebler
http://spirit.sourceforge.net/
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#include "utils.hpp"
#include <cctype>
#include <cstring>
#include <map>
namespace quickbook { namespace detail
{
std::string encode_string(boost::string_ref str)
{
std::string result;
result.reserve(str.size());
for (boost::string_ref::const_iterator it = str.begin();
it != str.end(); ++it)
{
switch (*it)
{
case '<': result += "<"; break;
case '>': result += ">"; break;
case '&': result += "&"; break;
case '"': result += """; break;
default: result += *it; break;
}
}
return result;
}
void print_char(char ch, std::ostream& out)
{
switch (ch)
{
case '<': out << "<"; break;
case '>': out << ">"; break;
case '&': out << "&"; break;
case '"': out << """; break;
default: out << ch; break;
// note ' is not included. see the curse of apos:
// http://fishbowl.pastiche.org/2003/07/01/the_curse_of_apos
}
}
void print_string(boost::string_ref str, std::ostream& out)
{
for (boost::string_ref::const_iterator cur = str.begin();
cur != str.end(); ++cur)
{
print_char(*cur, out);
}
}
char filter_identifier_char(char ch)
{
if (!std::isalnum(static_cast<unsigned char>(ch)))
ch = '_';
return static_cast<char>(std::tolower(static_cast<unsigned char>(ch)));
}
static std::string escape_uri_impl(std::string& uri_param, char const* mark)
{
// Extra capital characters for validating percent escapes.
static char const hex[] = "0123456789abcdefABCDEF";
std::string uri;
uri.swap(uri_param);
for (std::string::size_type n = 0; n < uri.size(); ++n)
{
if (static_cast<unsigned char>(uri[n]) > 127 ||
(!std::isalnum(static_cast<unsigned char>(uri[n])) &&
!std::strchr(mark, uri[n])) ||
(uri[n] == '%' && !(n + 2 < uri.size() &&
std::strchr(hex, uri[n+1]) &&
std::strchr(hex, uri[n+2]))))
{
char escape[] = { hex[uri[n] / 16], hex[uri[n] % 16] };
uri.insert(n + 1, escape, 2);
uri[n] = '%';
n += 2;
}
else if (uri[n] == '%')
{
n += 2;
}
}
return uri;
}
std::string escape_uri(std::string uri_param)
{
// TODO: I don't understand this choice of characters.....
return escape_uri_impl(uri_param, "-_.!~*'()?\\/");
}
std::string partially_escape_uri(std::string uri_param)
{
return escape_uri_impl(uri_param, "-_.!~*'()?\\/:&=#%+");
}
}}
|