URI.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/URI.cpp
23 
24  \brief A class for representing an Uniform Resource Identifier (URI).
25 
26  \author Vinicius Campanha
27  \author Gilberto Ribeiro de Queiroz
28  */
29 
30 // TerraLib
31 #include "URI.h"
32 
33 // Boost
34 #include <boost/regex.hpp>
35 
36 static const std::string regex_scheme = "(?<SCHEME_TYPE>[^\\]\\[:/?#@!$&'()*+,;=]+?):";
37 
38 static const std::string regex_userInfo = "((?<USER_TYPE>.+):(?<PASSWORD_TYPE>.*)@)?";
39 
40 static const std::string regex_host = "(?<HOST_TYPE>[^\\]\\[:/?#@!$&'()*+,;=]+)";
41 
42 static const std::string regex_port = "(:(?<PORT_TYPE>[0-9]{1,5}))?";
43 
44 static const std::string regex_path = "(?<PATH_TYPE>[^\\]\\[?#!$&'()*+,;=]+)?";
45 
46 static const std::string regex_query = "(\\?(?<QUERY_TYPE>[^\\]\\[?#@!$'()*+,]+)?)?";
47 
48 static const std::string regex_fragment = "(#(?<FRAGMENT_TYPE>.+))?";
49 
51 {
52  std::string m_uri;
53  boost::match_results< std::string::const_iterator > m_match;
54  bool m_isValid;
55 };
56 
58  : m_pimpl(new Impl)
59 {
60  m_pimpl->m_isValid = false;
61 }
62 
63 te::core::URI::URI(const std::string& uri)
64  : m_pimpl(new Impl)
65 {
66  m_pimpl->m_uri = uri;
67  m_pimpl->m_isValid = false;
68  parse();
69 }
70 
71 te::core::URI::URI(const URI& other)
72  : m_pimpl(new Impl)
73 {
74  m_pimpl->m_uri = other.m_pimpl->m_uri;
75  parse();
76 }
77 
78 te::core::URI::~URI() = default;
79 
82 {
83  URI(other).swap(*this);
84  return *this;
85 }
86 
87 const std::string&
89 {
90  return m_pimpl->m_uri;
91 }
92 
93 std::string te::core::URI::scheme() const
94 {
95  return m_pimpl->m_match["SCHEME_TYPE"].str();
96 }
97 
98 std::string te::core::URI::user() const
99 {
100  return m_pimpl->m_match["USER_TYPE"].str();
101 }
102 
103 std::string te::core::URI::password() const
104 {
105  return m_pimpl->m_match["PASSWORD_TYPE"].str();
106 }
107 
108 std::string te::core::URI::host() const
109 {
110  return m_pimpl->m_match["HOST_TYPE"].str();
111 }
112 
113 std::string te::core::URI::port() const
114 {
115  return m_pimpl->m_match["PORT_TYPE"].str();
116 }
117 
118 std::string te::core::URI::path() const
119 {
120  return m_pimpl->m_match["PATH_TYPE"].str();
121 }
122 
123 std::string te::core::URI::query() const
124 {
125  return m_pimpl->m_match["QUERY_TYPE"].str();
126 }
127 
128 std::string te::core::URI::fragment() const
129 {
130  return m_pimpl->m_match["FRAGMENT_TYPE"].str();
131 }
132 
134 {
135  return m_pimpl->m_isValid;
136 }
137 
138 void
140 {
141  std::swap(m_pimpl->m_uri, other.m_pimpl->m_uri);
142  std::swap(m_pimpl->m_match, other.m_pimpl->m_match);
143  std::swap(m_pimpl->m_isValid, other.m_pimpl->m_isValid);
144 }
145 
146 void
148 {
149  m_pimpl->m_isValid = false;
150 
151  encode();
152 
153 // first, let's try to match an URI with host
154  boost::regex expression(regex_scheme + "//" + regex_userInfo + regex_host + regex_port + regex_path + regex_query + regex_fragment);
155 
156  boost::match_results< std::string::const_iterator > match;
157 
158 // clear match results
159  m_pimpl->m_match = match;
160 
161 // is it a valid URI with host?
162  if(boost::regex_match(m_pimpl->m_uri, match, expression, boost::match_default))
163  {
164  m_pimpl->m_isValid = true;
165  }
166  else
167  {
168 // let's try to macth an URI without host!
169 
170  // Has empty groups to compensate the non used user, password and host groups
171  boost::regex expression(regex_scheme + "/{0,2}((?<USER_TYPE>)(?<PASSWORD_TYPE>))(?<HOST_TYPE>)(?<PORT_TYPE>())" + regex_path + regex_query + regex_fragment);
172 
173  if(boost::regex_match(m_pimpl->m_uri, match, expression, boost::match_default))
174  m_pimpl->m_isValid = true;
175  }
176 
177  m_pimpl->m_match = match;
178 }
179 
180 void
182 {
183  std::string temp;
184 
185  std::string::const_iterator it = std::begin(m_pimpl->m_uri);
186 
187  while(it != std::end(m_pimpl->m_uri))
188  {
189  int ASCIIvalue = *it;
190 
191  if(ASCIIvalue < 33 || ASCIIvalue > 126)
192  {
193  temp += '%';
194  temp += hexToLetter((*it >> 4) & 0x0f);
195  temp += hexToLetter(*it & 0x0f);
196  }
197  else
198  temp += *it;
199 
200  it++;
201  }
202 
203  m_pimpl->m_uri = temp;
204 }
205 
206 
207 std::string
209 {
210  int ASCIIvalue = i;
211  std::string value;
212 
213  switch (ASCIIvalue) {
214  case 0:
215  case 1:
216  case 2:
217  case 3:
218  case 4:
219  case 5:
220  case 6:
221  case 7:
222  case 8:
223  case 9:
224  {
225  value = ASCIIvalue + '0';
226  return value;
227  }
228  case 10:
229  case 11:
230  case 12:
231  case 13:
232  case 14:
233  default:
234  {
235  value = ASCIIvalue - 10 + 'A';
236  return value;
237  }
238  }
239  return std::string();
240 }
static const std::string regex_host
Definition: URI.cpp:40
std::string path() const
Retrieving the path.
Definition: URI.cpp:118
std::string scheme() const
Retrieving the scheme.
Definition: URI.cpp:93
std::string fragment() const
Retrieving the fragment.
Definition: URI.cpp:128
std::string password() const
Retrieving the password information.
Definition: URI.cpp:103
bool isValid() const
Return if the given URI is valid or not.
Definition: URI.cpp:133
static const std::string regex_port
Definition: URI.cpp:42
URI()
Default constructor.
Definition: URI.cpp:57
static const std::string regex_scheme
Definition: URI.cpp:36
std::string query() const
Retrieving the query.
Definition: URI.cpp:123
static const std::string regex_path
Definition: URI.cpp:44
void parse()
Parse the URI stored in uri_ member.
Definition: URI.cpp:147
void swap(URI &other)
Swap operation.
Definition: URI.cpp:139
static const std::string regex_userInfo
Definition: URI.cpp:38
std::string port() const
Retrieving the port.
Definition: URI.cpp:113
std::string host() const
Retrieving the host.
Definition: URI.cpp:108
std::string hexToLetter(int i)
Definition: URI.cpp:208
const std::string & uri() const
Retrieving the full URI.
Definition: URI.cpp:88
A class for representing an Uniform Resource Identifier (URI).
Definition: URI.h:49
std::unique_ptr< Impl > m_pimpl
Definition: URI.h:178
void encode()
Check if the uri_ contains any invalid character and parse it to his hexadecimal value.
Definition: URI.cpp:181
static const std::string regex_query
Definition: URI.cpp:46
static const std::string regex_fragment
Definition: URI.cpp:48
A class for representing an Uniform Resource Identifier (URI).
boost::match_results< std::string::const_iterator > m_match
Definition: URI.cpp:53
URI & operator=(const URI &other)
Assingment operator.
Definition: URI.cpp:81
std::string user() const
Retrieving the user information.
Definition: URI.cpp:98
std::string m_uri
Definition: URI.cpp:52