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: