fastcgi++
A C++ FastCGI/Web API
webstreambuf.cpp
Go to the documentation of this file.
1 
10 /*******************************************************************************
11 * Copyright (C) 2016 Eddie Carle [eddie@isatec.ca] *
12 * *
13 * This file is part of fastcgi++. *
14 * *
15 * fastcgi++ is free software: you can redistribute it and/or modify it under *
16 * the terms of the GNU Lesser General Public License as published by the Free *
17 * Software Foundation, either version 3 of the License, or (at your option) *
18 * any later version. *
19 * *
20 * fastcgi++ is distributed in the hope that it will be useful, but WITHOUT ANY *
21 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for *
23 * more details. *
24 * *
25 * You should have received a copy of the GNU Lesser General Public License *
26 * along with fastcgi++. If not, see <http://www.gnu.org/licenses/>. *
27 *******************************************************************************/
28 
30 #include "fastcgi++/log.hpp"
31 
32 #include <algorithm>
33 
34 template
35 std::basic_ostream<wchar_t, std::char_traits<wchar_t>>& Fastcgipp::operator<<(
36  std::basic_ostream<wchar_t, std::char_traits<wchar_t>>& os,
37  const Encoding& encoding);
38 template
39 std::basic_ostream<char, std::char_traits<char>>& Fastcgipp::operator<<(
40  std::basic_ostream<char, std::char_traits<char>>& os,
41  const Encoding& encoding);
42 template<class charT, class traits>
43 std::basic_ostream<charT, traits>& Fastcgipp::operator<<(
44  std::basic_ostream<charT, traits>& os,
45  const Encoding& encoding)
46 {
47  try
48  {
49  WebStreambuf<charT, traits>* webStreambuf =
50  dynamic_cast<WebStreambuf<charT, traits>*>(os.rdbuf());
51  webStreambuf->m_encoding = encoding;
52  }
53  catch(std::bad_cast& e)
54  {
55  ERROR_LOG("Trying to set encoding on a stream buffer that isn't a "\
56  "WebStreambuf")
57  }
58  return os;
59 }
60 
61 namespace Fastcgipp
62 {
63  template <>
64  const std::map<char, const std::basic_string<char>>
66  {
67  std::make_pair('"', "&quot;"),
68  std::make_pair('>', "&gt;"),
69  std::make_pair('<', "&lt;"),
70  std::make_pair('&', "&amp;"),
71  std::make_pair(0x27, "&apos;")
72  };
73 
74  template <>
75  const std::map<wchar_t, const std::basic_string<wchar_t>>
77  {
78  std::make_pair('"', L"&quot;"),
79  std::make_pair('>', L"&gt;"),
80  std::make_pair('<', L"&lt;"),
81  std::make_pair('&', L"&amp;"),
82  std::make_pair(0x27, L"&apos;")
83  };
84 
85  template <>
86  const std::map<char, const std::basic_string<char>>
88  {
89  std::make_pair('!', "%21"),
90  std::make_pair(']', "%5D"),
91  std::make_pair('[', "%5B"),
92  std::make_pair('#', "%23"),
93  std::make_pair('?', "%3F"),
94  std::make_pair('/', "%2F"),
95  std::make_pair(',', "%2C"),
96  std::make_pair('$', "%24"),
97  std::make_pair('+', "%2B"),
98  std::make_pair('=', "%3D"),
99  std::make_pair('&', "%26"),
100  std::make_pair('@', "%40"),
101  std::make_pair(':', "%3A"),
102  std::make_pair(';', "%3B"),
103  std::make_pair(')', "%29"),
104  std::make_pair('(', "%28"),
105  std::make_pair(0x27, "%27"),
106  std::make_pair('*', "%2A"),
107  std::make_pair('<', "%3C"),
108  std::make_pair('>', "%3E"),
109  std::make_pair('"', "%22"),
110  std::make_pair(' ', "%20"),
111  std::make_pair('%', "%25")
112  };
113 
114  template <>
115  const std::map<wchar_t, const std::basic_string<wchar_t>>
117  {
118  std::make_pair('!', L"%21"),
119  std::make_pair(']', L"%5D"),
120  std::make_pair('[', L"%5B"),
121  std::make_pair('#', L"%23"),
122  std::make_pair('?', L"%3F"),
123  std::make_pair('/', L"%2F"),
124  std::make_pair(',', L"%2C"),
125  std::make_pair('$', L"%24"),
126  std::make_pair('+', L"%2B"),
127  std::make_pair('=', L"%3D"),
128  std::make_pair('&', L"%26"),
129  std::make_pair('@', L"%40"),
130  std::make_pair(':', L"%3A"),
131  std::make_pair(';', L"%3B"),
132  std::make_pair(')', L"%29"),
133  std::make_pair('(', L"%28"),
134  std::make_pair(0x27, L"%27"),
135  std::make_pair('*', L"%2A"),
136  std::make_pair('<', L"%3C"),
137  std::make_pair('>', L"%3E"),
138  std::make_pair('"', L"%22"),
139  std::make_pair(' ', L"%20"),
140  std::make_pair('%', L"%25")
141  };
142 }
143 
144 template <class charT, class traits>
146  const char_type *s,
147  std::streamsize n)
148 {
149  const char_type* const end = s+n;
150 
151  while(true)
152  {
153  if(m_encoding == Encoding::NONE)
154  {
155  const std::streamsize actual = std::min(
156  end-s,
157  this->epptr()-this->pptr());
158  std::copy(s, s+actual, this->pptr());
159  this->pbump(actual);
160  s += actual;
161  }
162  else
163  {
164  const std::map<charT, const std::basic_string<charT>>* map;
165  if(m_encoding == Encoding::HTML)
166  map = &htmlCharacters;
167  else
168  map = &urlCharacters;
169 
170  while(s<end)
171  {
172  const size_t writeSpace = this->epptr() - this->pptr();
173  const auto mapping = map->find(*s);
174  if(mapping == map->cend())
175  {
176  if(writeSpace < 1)
177  break;
178  *this->pptr() = *s++;
179  this->pbump(1);
180  }
181  else
182  {
183  if(writeSpace < mapping->second.size())
184  break;
185  std::copy(
186  mapping->second.cbegin(),
187  mapping->second.cend(),
188  this->pptr());
189  this->pbump(mapping->second.size());
190  ++s;
191  }
192  }
193  }
194 
195  if(s<end)
196  this->sync();
197  else
198  break;
199  }
200 
201  return n;
202 }
203 
Encoding
Stream manipulator for setting output encoding.
Encoding m_encoding
Output encoding for stream buffer.
std::basic_streambuf< charT, traits >::char_type char_type
Topmost namespace for the fastcgi++ library.
Stream buffer class for output of HTML/Web stream.
std::basic_ostream< charT, traits > & operator<<(std::basic_ostream< charT, traits > &os, const Encoding &encoding)
Declares the WebStreambuf stuff.
#define ERROR_LOG(data)
Log any "errors" that can be recovered from.
Definition: log.hpp:107
Declares the Fastcgipp debugging/logging facilities.
std::streamsize xsputn(const char_type *s, std::streamsize n)
Derived from std::basic_streambuf<charT, traits>