1 /* 2 * Copyright (c) 2011-2021, The DART development contributors 3 * All rights reserved. 4 * 5 * The list of contributors can be found at: 6 * https://github.com/dartsim/dart/blob/master/LICENSE 7 * 8 * This file is provided under the following "BSD-style" License: 9 * Redistribution and use in source and binary forms, with or 10 * without modification, are permitted provided that the following 11 * conditions are met: 12 * * Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * * Redistributions in binary form must reproduce the above 15 * copyright notice, this list of conditions and the following 16 * disclaimer in the documentation and/or other materials provided 17 * with the distribution. 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 19 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 20 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 27 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 29 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #ifndef DART_COMMON_URI_HPP_ 34 #define DART_COMMON_URI_HPP_ 35 36 #include <string> 37 38 namespace dart { 39 namespace common { 40 41 class UriComponent final 42 { 43 public: 44 using value_type = std::string; 45 using reference_type = value_type&; 46 using reference_const_type = const value_type&; 47 using pointer_type = value_type*; 48 using pointer_const_type = const value_type*; 49 50 UriComponent(); 51 UriComponent(reference_const_type _value); 52 53 operator bool() const; 54 55 bool operator!() const; 56 57 UriComponent& operator=(reference_const_type _value); 58 59 reference_type operator*(); 60 reference_const_type operator*() const; 61 62 pointer_type operator->(); 63 pointer_const_type operator->() const; 64 65 void assign(reference_const_type _value); 66 void reset(); 67 68 reference_type get(); 69 reference_const_type get() const; 70 71 reference_type get_value_or(reference_type _default); 72 reference_const_type get_value_or(reference_const_type _default) const; 73 74 private: 75 bool mExists; 76 std::string mValue; 77 }; 78 79 /// The Uri struct provides URI parsing and merging functionality based on RFC 80 /// 3986. 81 /// 82 /// We have Uri as a struct rather than class to expose member variables. Many 83 /// ResourceRetreiver classes rewrite URIs to other types of URIs (e.g, resolve 84 /// 'package://' URIs to 'file://' URIs), which is easier to implement if you 85 /// have direct access to the URI components. 86 struct Uri final 87 { 88 /// Scheme, e.g. 'http', 'file', 'package' 89 UriComponent mScheme; 90 91 /// Authority, e.g. 'google.com', 'en.wikipedia.org' 92 UriComponent mAuthority; 93 94 /// Path, e.g. '/index.html', '/foo/bar.txt' 95 UriComponent mPath; 96 97 /// Query string, i.e. the part of the URI after the ? 98 UriComponent mQuery; 99 100 /// Fragment, e.g. the part of the URI after the # 101 UriComponent mFragment; 102 103 /// Constructor 104 Uri() = default; 105 106 /// Constructor that takes a URI or local path. Internally, this is equivalent 107 /// to calling fromStringOrPath(_input) after default constructor. 108 /// 109 /// We don't declare this constructor as explicit in order to allow implicit 110 /// conversion from string so that you can pass in string parameter to a 111 /// function that takes Uri. 112 Uri(const std::string& _input); 113 114 /// Constructor that takes a URI or local path as const char*. The behavior is 115 /// identical to Uri(const std::string&). 116 Uri(const char* _input); 117 118 /// Clear the URI by reset()ing all components. 119 void clear(); 120 121 /// Parse a URI from a string; return success. All the components will be 122 /// cleared on failure. 123 bool fromString(const std::string& _input); 124 125 /// Parse a local path (i.e. URI with no schema) from a string; return 126 /// success. Note that the input path should be absolute path. All the 127 /// components will be cleared on failure. 128 bool fromPath(const std::string& _path); 129 130 /// Parse a URI or local path (i.e. URI with no schema) from a string; return 131 /// success. We assume that any string without a scheme is a path. All the 132 /// components will be cleared on failure. 133 bool fromStringOrPath(const std::string& _input); 134 135 /// Resolve a relative path reference; return success. All the components will 136 /// be cleared on failure. 137 bool fromRelativeUri( 138 const std::string& _base, 139 const std::string& _relative, 140 bool _strict = false); 141 142 /// Resolve a relative path reference; return success. All the components will 143 /// be cleared on failure. 144 bool fromRelativeUri( 145 const char* _base, const char* _relative, bool _strict = false); 146 147 /// Resolve a relative path reference; return success. All the components will 148 /// be cleared on failure. 149 bool fromRelativeUri( 150 const Uri& _base, const std::string& _relative, bool _strict = false); 151 152 /// Resolve a relative path reference; return success. All the components will 153 /// be cleared on failure. 154 bool fromRelativeUri( 155 const Uri& _base, const char* _relative, bool _strict = false); 156 157 /// Resolve a relative path reference; return success. All the components will 158 /// be cleared on failure. 159 bool fromRelativeUri( 160 const Uri& _base, const Uri& _relative, bool _strict = false); 161 162 /// Combine the parts of the URI into a string. 163 std::string toString() const; 164 165 /// Create URI from a string; return an empty URI on failure. 166 static Uri createFromString(const std::string& _input); 167 168 /// Create file URI from a string; return an empty URI on failure. 169 static Uri createFromPath(const std::string& _path); 170 171 /// Create general URI or file URI from a string; return an empty URI on 172 /// failure. 173 static Uri createFromStringOrPath(const std::string& _input); 174 175 /// Create URI resolving a relative path reference; return an empty URI on 176 /// failure. 177 static Uri createFromRelativeUri( 178 const std::string& _base, 179 const std::string& _relative, 180 bool _strict = false); 181 182 /// Create URI resolving a relative path reference; return an empty URI on 183 /// failure. 184 static Uri createFromRelativeUri( 185 const Uri& _base, const std::string& _relative, bool _strict = false); 186 187 /// Create URI resolving a relative path reference; return an empty URI on 188 /// failure. 189 static Uri createFromRelativeUri( 190 const Uri& _base, const Uri& _relative, bool _strict = false); 191 192 /// Parse a URI from a string; return an empty string on failure. 193 static std::string getUri(const std::string& _input); 194 195 /// Resolve a relative path reference; return an empty string on failure. 196 static std::string getRelativeUri( 197 const std::string& _base, 198 const std::string& _relative, 199 bool _strict = false); 200 201 /// Resolve a relative path reference; return an empty string on failure. 202 static std::string getRelativeUri( 203 const Uri& _base, const std::string& _relative, bool _strict = false); 204 205 /// Resolve a relative path reference; return an empty string on failure. 206 static std::string getRelativeUri( 207 const Uri& _base, const Uri& _relative, bool _strict = false); 208 209 /// Get the path component of the URI as a string. 210 std::string getPath() const; 211 212 /// Get the path in the local filesystem as a string. You should use this 213 /// function rather than getPath() if you are trying to access a local file. 214 /// Note that this function is identical to getPath() for Unix systems, but 215 /// differ by the leading '/' on Windows. 216 std::string getFilesystemPath() const; 217 218 private: 219 /// Implement section 5.2.3 of RFC 3986. 220 static std::string mergePaths(const Uri& _base, const Uri& _relative); 221 222 /// Implement section 5.2.4 of RFC 3986. 223 static std::string removeDotSegments(const std::string& _path); 224 }; 225 226 } // namespace common 227 } // namespace dart 228 229 #endif // ifndef DART_COMMON_URI_HPP_ 230