1 | /* |
2 | * Copyright 2013-present Facebook, Inc. |
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 | |
17 | #ifndef FOLLY_URI_H_ |
18 | #error This file may only be included from folly/Uri.h |
19 | #endif |
20 | |
21 | #include <functional> |
22 | #include <tuple> |
23 | |
24 | #include <folly/Conv.h> |
25 | #include <folly/hash/Hash.h> |
26 | |
27 | namespace folly { |
28 | |
29 | namespace uri_detail { |
30 | |
31 | using UriTuple = std::tuple< |
32 | const std::string&, |
33 | const std::string&, |
34 | const std::string&, |
35 | const std::string&, |
36 | uint16_t, |
37 | const std::string&, |
38 | const std::string&, |
39 | const std::string&>; |
40 | |
41 | inline UriTuple as_tuple(const folly::Uri& k) { |
42 | return UriTuple( |
43 | k.scheme(), |
44 | k.username(), |
45 | k.password(), |
46 | k.host(), |
47 | k.port(), |
48 | k.path(), |
49 | k.query(), |
50 | k.fragment()); |
51 | } |
52 | |
53 | } // namespace uri_detail |
54 | |
55 | template <class String> |
56 | String Uri::toString() const { |
57 | String str; |
58 | if (hasAuthority_) { |
59 | toAppend(scheme_, "://" , &str); |
60 | if (!password_.empty()) { |
61 | toAppend(username_, ":" , password_, "@" , &str); |
62 | } else if (!username_.empty()) { |
63 | toAppend(username_, "@" , &str); |
64 | } |
65 | toAppend(host_, &str); |
66 | if (port_ != 0) { |
67 | toAppend(":" , port_, &str); |
68 | } |
69 | } else { |
70 | toAppend(scheme_, ":" , &str); |
71 | } |
72 | toAppend(path_, &str); |
73 | if (!query_.empty()) { |
74 | toAppend("?" , query_, &str); |
75 | } |
76 | if (!fragment_.empty()) { |
77 | toAppend("#" , fragment_, &str); |
78 | } |
79 | return str; |
80 | } |
81 | |
82 | } // namespace folly |
83 | |
84 | namespace std { |
85 | |
86 | template <> |
87 | struct hash<folly::Uri> { |
88 | std::size_t operator()(const folly::Uri& k) const { |
89 | return std::hash<folly::uri_detail::UriTuple>{}( |
90 | folly::uri_detail::as_tuple(k)); |
91 | } |
92 | }; |
93 | |
94 | template <> |
95 | struct equal_to<folly::Uri> { |
96 | bool operator()(const folly::Uri& a, const folly::Uri& b) const { |
97 | return folly::uri_detail::as_tuple(a) == folly::uri_detail::as_tuple(b); |
98 | } |
99 | }; |
100 | |
101 | } // namespace std |
102 | |