src/terralib/core/uri/Utils.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 National Institute For Space Research (INPE) - Brazil.
3 
4  This file is part of the TerraLib - a Framework for building GIS enabled applications.
5 
6  TerraLib is free software: you can redistribute it and/or modify
7  it under the terms of the GNU Lesser General Public License as published by
8  the Free Software Foundation, either version 3 of the License,
9  or (at your option) any later version.
10 
11  TerraLib is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public License
17  along with TerraLib. See COPYING. If not, write to
18  TerraLib Team at <terralib-team@terralib.org>.
19  */
20 
21  /*!
22  \file terralib/core/uri/Utils.cpp
23 
24  \brief This file contains utility functions used to manipulate data from a URI.
25 
26  \author Andre Gomes de Oliveira
27  \author Gilberto Ribeiro de Queiroz
28 */
29 
30 //Terralib
31 #include "../Exception.h"
32 #include "../translator/Translator.h"
33 #include "../utils/HexUtils.h"
34 #include "Utils.h"
35 
36 // STL
37 #include <iterator>
38 
39 // Boost
40 #include <boost/format.hpp>
41 #include <boost/tokenizer.hpp>
42 
43 std::map<std::string, std::string>
44 te::core::Expand(const std::string& query_str)
45 {
46  std::map<std::string, std::string> result;
47 
48  boost::char_separator<char> kvp_sep("&");
49 
50  boost::tokenizer<boost::char_separator<char> > key_value_pairs(query_str, kvp_sep);
51 
52  boost::tokenizer<boost::char_separator<char> >::iterator ikv_pair = key_value_pairs.begin();
53 
54  while(ikv_pair != key_value_pairs.end())
55  {
56  std::string kv = *ikv_pair;
57 
58  boost::char_separator<char> kv_sep("=");
59 
60  boost::tokenizer<boost::char_separator<char> > key_value_pair(kv, kv_sep);
61 
62  boost::tokenizer<boost::char_separator<char> >::iterator ikv = key_value_pair.begin();
63 
64  if(ikv == key_value_pair.end())
65  {
66  boost::format err_msg(TE_TR("Invalid key-value pair format in query string!"));
67  throw Exception() << te::ErrorDescription((err_msg).str());
68  }
69 
70  std::string k = *ikv;
71 
72  ++ikv;
73 
74  if (ikv == key_value_pair.end())
75  {
76  boost::format err_msg(TE_TR("Invalid key-value pair format in query string!"));
77  throw Exception() << te::ErrorDescription((err_msg).str());
78  }
79 
80  std::string v = *ikv;
81 
82  std::string decodedValue = te::core::URIDecode(v);
83 
84  result[k] = decodedValue;
85 
86  ++ikv_pair;
87  }
88 
89  return result;
90 }
91 
92 std::string te::core::URIDecode(const std::string &srcUri)
93 {
94 
95  const unsigned char * pSrc = (const unsigned char *)srcUri.c_str();
96  const size_t SRC_LEN = srcUri.length();
97  const unsigned char * const SRC_END = pSrc + SRC_LEN;
98  const unsigned char * const SRC_LAST_DEC = SRC_END - 2; // last decodable '%'
99 
100  char * const pStart = new char[SRC_LEN];
101  char * pEnd = pStart;
102 
103  while (pSrc < SRC_LAST_DEC)
104  {
105  if (*pSrc == '%')
106  {
107  char * hex = new char[2];
108  hex[0] = *(pSrc + 1);
109  hex[1] = *(pSrc + 2);
110 
111  char c = te::core::Hex2Char(hex);
112 
113  *pEnd++ = c;
114  pSrc += 3;
115 
116  delete [] hex;
117  continue;
118  }
119 
120  *pEnd++ = *pSrc++;
121  }
122 
123  // the last 2- chars
124  while (pSrc < SRC_END)
125  *pEnd++ = *pSrc++;
126 
127  std::string sResult(pStart, pEnd);
128  delete [] pStart;
129  return sResult;
130 }
131 
132 
133 std::string te::core::URIEncode(const std::string &srcUri)
134 {
135  const unsigned char * pSrc = (const unsigned char *)srcUri.c_str();
136  const size_t SRC_LEN = srcUri.length();
137  unsigned char * const pStart = new unsigned char[SRC_LEN * 3];
138  unsigned char * pEnd = pStart;
139  const unsigned char * const SRC_END = pSrc + SRC_LEN;
140 
141  for (; pSrc < SRC_END; ++pSrc)
142  {
143  const char& c = *pSrc;
144  if ((48 <= c && c <= 57) ||//0-9
145  (65 <= c && c <= 90) ||//abc...xyz
146  (97 <= c && c <= 122) || //ABC...XYZ
147  (c=='-' || c=='_' || c=='.' || c=='~'))
148  {
149  *pEnd++ = c;
150  }
151  else
152  {
153  // escape this char
154  *pEnd++ = '%';
155  char* res = new char[2];
156 
157  te::core::Char2Hex(c, res);
158 
159  *pEnd++ = res[0];
160  *pEnd++ = res[1];
161 
162  delete [] res;
163  }
164  }
165 
166  std::string sResult((char *)pStart, (char *)pEnd);
167  delete [] pStart;
168  return sResult;
169 }
TECOREEXPORT std::string URIEncode(const std::string &srcUri)
Encodes an decoded URI. The algorithm implementation is based on http://www.codeguru.com/cpp/cpp/algorithms/strings/article.php/c12759/URI-Encoding-and-Decoding.htm.
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:242
boost::error_info< struct tag_error_description, std::string > ErrorDescription
The base type for error report messages.
char Hex2Char(const char *hex)
It converts the character from a hex representation to a byte.
Definition: HexUtils.h:270
This file contains utility functions used to manipulate data from a URI.
TECOREEXPORT std::map< std::string, std::string > Expand(const std::string &query_str)
Split a query string into its components.
void Char2Hex(unsigned char c, char *r)
It converts the character to a hex representation.
Definition: HexUtils.h:248
TECOREEXPORT std::string URIDecode(const std::string &srcUri)
Decodes an encoded URI. The algorithm implementation is based on http://www.codeguru.com/cpp/cpp/algorithms/strings/article.php/c12759/URI-Encoding-and-Decoding.htm.
Base exception class for TerraLib Core Runtime Library.