1 /*
2  * Copyright 2006-2008 The FLWOR Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 #ifndef ZORBA_ZORBATYPES_URI_H
18 #define ZORBA_ZORBATYPES_URI_H
19 
20 #include <iostream>
21 
22 #include <zorba/config.h>
23 #include "schema_types.h"
24 
25 namespace zorba
26 {
27 
28 class ZORBA_DLL_PUBLIC URI
29 {
30 public:
31 
32   static bool is_unreserved_char(uint32_t c);
33 
34   static bool is_path_character(uint32_t c);
35 
36   static bool is_reservered_or_unreserved_char(uint32_t c);
37 
38   static void decode_file_URI(const zstring& uri, zstring& filepath);
39 
40   static void encode_file_URI(const zstring& filepath, zstring& uri);
41 
42   static std::string encode_file_URI(const std::string& filepath);
43 
44   static bool is_well_formed_address(const char* addr, ulong length);
45 
46   static bool is_well_formed_ipv6_reference(const char* addr, ulong length);
47 
48   static bool is_well_formed_ipv4_address(const char* addr, ulong length);
49 
50   static long scanHexSequence(const char* addr, long idx, long end, long& counter);
51 
52 protected:
53   enum States
54   {
55     Scheme            = 1,
56     UserInfo          = 2,
57     Host              = 4,
58     Port              = 8,
59     RegBasedAuthority = 16,
60     Path              = 32,
61     QueryString       = 64,
62     Fragment          = 128
63   };
64 
65   // keep track whether particular components of a uri are defined or undefined
66   mutable uint32_t theState;
67 
68   // the uri text is composed out of the components below it's mutable because
69   // get_uri_text is const
70   mutable zstring  theURIText;      // encoded
71   mutable zstring  theASCIIURIText; // decoded
72   mutable zstring  thePathNotation;
73 
74   // The uri components (UserInfo, RegBasedAuthority, Path, QueryString, and
75   // Fragment are always encoded)
76   zstring          theScheme;
77   zstring          theHost;
78   uint32_t         thePort;
79   zstring          theUserInfo;
80   zstring          theRegBasedAuthority;
81   zstring          thePath;
82   zstring          theQueryString;
83   zstring          theFragment;
84 
85   // true if the constructed URI is valid
86   bool             valid;
87 
88 public:
89   URI(const zstring& uri, bool validate = true);
90 
91   URI(const URI& base_uri, const zstring& uri, bool validate = true);
92 
93   URI (const URI& full_uri, const URI& base_uri);
94 
95   URI (const URI& to_copy);
96 
97   URI();
98 
99   ~URI();
100 
101   bool is_absolute() const;
102 
103   // get the full uri as text
104   const zstring& toString() const;
105 
106   const zstring& toASCIIString() const;
107 
108   const zstring& toPathNotation() const;
109 
110   // getters and setters for each component
111   bool is_valid() const;
112 
113   const zstring& get_scheme() const;
114 
115   void set_scheme(const zstring& new_scheme);
116 
117   const zstring& get_host() const;
118 
119   void set_host(const zstring& new_host);
120 
121   int get_port() const;
122 
123   void set_port(int new_port);
124 
125   void get_user_info(zstring& result) const;
126 
127   const zstring& get_encoded_user_info() const;
128 
129   void set_user_info(const zstring& new_user_info);
130 
131   void get_reg_based_authority(zstring& result) const;
132 
133   const zstring& get_encoded_reg_based_authority() const;
134 
135   void set_reg_based_authority(const zstring& new_authority);
136 
137   void get_path(zstring& result) const;
138 
139   const zstring& get_encoded_path() const;
140 
141   void set_path(const zstring& new_path);
142 
143   void get_query(zstring& result) const;
144 
145   const zstring& get_encoded_query() const;
146 
147   void set_query(const zstring& new_query_string);
148 
149   void get_fragment(zstring& result) const;
150 
151   const zstring& get_encoded_fragment() const;
152 
153   void set_fragment(const zstring& new_fragment);
154 
155   void clear_fragment();
156 
157 protected:
158   void build_full_text() const;
159 
160   void build_ascii_full_text() const;
161 
162   void build_path_notation() const;
163 
164   void initialize(const URI& toCopy);
165 
166   void initialize(const zstring& uri, bool have_base = false);
167 
168   void initializeScheme(const zstring& uri);
169 
170   void initializeAuthority(const zstring& uri);
171 
172   void initializePath(const zstring& uri);
173 
174   bool is_conformant_scheme_name(const zstring& scheme);
175 
176   bool is_valid_server_based_authority(
177     const zstring& host,
178     const int port,
179     const zstring& user_info,
180     bool user_info_found);
181 
182   void resolve(const URI* base_uri);
183 
184   void relativize(const URI* base_uri);
185 
set_state(uint32_t s)186   void set_state(uint32_t s) const { theState |= s; }
187 
is_set(uint32_t s)188   bool is_set(uint32_t s) const { return ((theState & s) > 0); }
189 
unset_state(uint32_t s)190   void unset_state(uint32_t s) const { theState &= ~s; }
191 
192   void invalidate_text() const;
193 };
194 
195 
is_valid()196 inline bool URI::is_valid() const
197 {
198   return valid;
199 }
200 
201 
get_scheme()202 inline const zstring& URI::get_scheme() const
203 {
204   return theScheme;
205 }
206 
207 
get_host()208 inline const zstring& URI::get_host() const
209 {
210   return theHost;
211 }
212 
213 
get_port()214 inline int URI::get_port() const
215 {
216   return thePort;
217 }
218 
219 
get_encoded_user_info()220 inline const zstring& URI::get_encoded_user_info() const
221 {
222   return theUserInfo;
223 }
224 
225 
get_encoded_reg_based_authority()226 inline const zstring& URI::get_encoded_reg_based_authority() const
227 {
228   return theRegBasedAuthority;
229 }
230 
231 
get_encoded_path()232 inline const zstring& URI::get_encoded_path() const
233 {
234   return thePath;
235 }
236 
237 
get_encoded_query()238 inline const zstring& URI::get_encoded_query() const
239 {
240   return theQueryString;
241 }
242 
243 
get_encoded_fragment()244 inline const zstring& URI::get_encoded_fragment() const
245 {
246   return theFragment;
247 }
248 
set_fragment(const zstring & new_fragment)249 inline void URI::set_fragment(const zstring &new_fragment)
250 {
251   theFragment = new_fragment;
252   invalidate_text();
253 }
254 
clear_fragment()255 inline void URI::clear_fragment()
256 {
257   theFragment.clear();
258   unset_state(Fragment);
259   invalidate_text();
260 }
261 
invalidate_text()262 inline void URI::invalidate_text() const
263 {
264   theASCIIURIText.clear();
265   theURIText.clear();
266 }
267 
268 inline std::ostream& operator<<( std::ostream &o, URI const &uri ) {
269   return o << uri.toString();
270 }
271 
272 } // namespace zorba
273 #endif /* ZORBA_ZORBATYPES_URI_H */
274 /*
275  * Local variables:
276  * mode: c++
277  * End:
278  */
279 /* vim:set et sw=2 ts=2: */
280