1
/*---------------------------------------------------------------------\
3
| |__ / \ / / . \ . \ |
8
\---------------------------------------------------------------------*/
10
* \file zypp/url/UrlUtils.cc
12
#include "zypp/base/Gettext.h"
13
#include "zypp/base/String.h"
14
#include "zypp/url/UrlUtils.h"
16
#include <stdlib.h> // strtol
17
#include <cctype> // isxdigit
21
//////////////////////////////////////////////////////////////////////
23
{ ////////////////////////////////////////////////////////////////////
25
////////////////////////////////////////////////////////////////////
27
{ //////////////////////////////////////////////////////////////////
30
// ---------------------------------------------------------------
32
encode(const std::string &str, const std::string &safe,
35
std::string skip("ABCDEFGHIJKLMNOPQRSTUVWXYZ"
36
"abcdefghijklmnopqrstuvwxyz"
38
std::string more(":/?#[]@!$&'()*+,;=");
42
for(size_t i=0; i<safe.size(); i++)
44
if( more.find(safe.at(i)) != std::string::npos)
45
skip.append(1, safe.at(i));
52
pos = str.find_first_not_of(skip, beg);
53
if(pos != std::string::npos)
57
out.append(str, beg, pos - beg);
60
if( eflag == E_ENCODED &&
63
std::isxdigit(str.at(pos + 1)) &&
64
std::isxdigit(str.at(pos + 2)))
66
out.append(str, pos, 3);
71
out.append( encode_octet( str.at(pos)));
77
out.append(str, beg, len - beg);
85
// ---------------------------------------------------------------
87
decode(const std::string &str, bool allowNUL)
97
if( pos + 2 < len && out.at(pos) == '%')
99
int c = decode_octet(out.c_str() + pos + 1);
103
// not a hex noted octet...
107
// is a %00 octet allowed ?
110
ZYPP_THROW(UrlDecodingException(
111
_("Encoded string contains a NUL byte")
115
// other octets are fine...
130
// ---------------------------------------------------------------
132
encode_octet(const unsigned char c)
134
static const unsigned char tab[] = "0123456789ABCDEF";
135
unsigned char out[4];
138
out[1] = tab[0x0f & (c >> 4)];
139
out[2] = tab[0x0f & c];
142
//snprintf(out, sizeof(out), "%%%02X", c);
143
return std::string((char *)out);
147
// ---------------------------------------------------------------
149
decode_octet(const char *hex)
151
if(hex && std::isxdigit(hex[0]) && std::isxdigit(hex[1]))
153
char x[3] = { hex[0], hex[1], '\0'};
154
return 0xff & ::strtol(x, NULL, 16);
163
// ---------------------------------------------------------------
165
split(ParamVec &pvec,
166
const std::string &pstr,
167
const std::string &psep)
169
size_t beg, pos, len;
172
ZYPP_THROW(UrlNotSupportedException(
173
_("Invalid parameter array split separator character")
182
pos = pstr.find(psep, beg);
183
if(pos != std::string::npos)
185
pvec.push_back( pstr.substr(beg, pos - beg));
190
pvec.push_back( pstr.substr(beg, len - beg));
197
// ---------------------------------------------------------------
199
split(ParamMap &pmap,
200
const std::string &str,
201
const std::string &psep,
202
const std::string &vsep,
206
ParamVec::const_iterator pitr;
210
if( psep.empty() || vsep.empty())
212
ZYPP_THROW(UrlNotSupportedException(
213
_("Invalid parameter map split separator character")
217
split(pvec, str, psep);
219
for( pitr = pvec.begin(); pitr != pvec.end(); ++pitr)
221
pos = pitr->find(vsep);
222
if(pos != std::string::npos)
224
if( eflag == E_DECODED)
226
k = url::decode(pitr->substr(0, pos));
227
v = url::decode(pitr->substr(pos + 1));
232
k = pitr->substr(0, pos);
233
v = pitr->substr(pos + 1);
239
if( eflag == E_DECODED)
241
pmap[ url::decode(*pitr) ] = "";
252
// ---------------------------------------------------------------
254
join(const ParamVec &pvec,
255
const std::string &psep)
258
ParamVec::const_iterator i( pvec.begin());
263
while( ++i != pvec.end())
273
// ---------------------------------------------------------------
275
join(const ParamMap &pmap,
276
const std::string &psep,
277
const std::string &vsep,
278
const std::string &safe)
280
if( psep.empty() || vsep.empty())
282
ZYPP_THROW(UrlNotSupportedException(
283
_("Invalid parameter array join separator character")
287
std::string join_safe;
288
for(std::string::size_type i=0; i<safe.size(); i++)
290
if( psep.find(safe[i]) == std::string::npos &&
291
vsep.find(safe[i]) == std::string::npos)
293
join_safe.append(1, safe[i]);
297
ParamMap::const_iterator i( pmap.begin());
301
str = encode(i->first, join_safe);
302
if( !i->second.empty())
303
str += vsep + encode(i->second, join_safe);
305
while( ++i != pmap.end())
307
str += psep + encode(i->first, join_safe);
308
if( !i->second.empty())
309
str += vsep + encode(i->second, join_safe);
317
//////////////////////////////////////////////////////////////////
319
////////////////////////////////////////////////////////////////////
321
////////////////////////////////////////////////////////////////////
323
//////////////////////////////////////////////////////////////////////
325
** vim: set ts=2 sts=2 sw=2 ai et: