1 // Copyright 2013 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef URL_URL_CANON_STDSTRING_H_
6 #define URL_URL_CANON_STDSTRING_H_
7
8 // This header file defines a canonicalizer output method class for STL
9 // strings. Because the canonicalizer tries not to be dependent on the STL,
10 // we have segregated it here.
11
12 #include <string>
13 #include <string_view>
14
15 #include "base/compiler_specific.h"
16 #include "base/component_export.h"
17 #include "base/memory/raw_ptr_exclusion.h"
18 #include "url/url_canon.h"
19
20 namespace url {
21
22 // Write into a std::string given in the constructor. This object does not own
23 // the string itself, and the user must ensure that the string stays alive
24 // throughout the lifetime of this object.
25 //
26 // The given string will be appended to; any existing data in the string will
27 // be preserved.
28 //
29 // Note that when canonicalization is complete, the string will likely have
30 // unused space at the end because we make the string very big to start out
31 // with (by |initial_size|). This ends up being important because resize
32 // operations are slow, and because the base class needs to write directly
33 // into the buffer.
34 //
35 // Therefore, the user should call Complete() before using the string that
36 // this class wrote into.
COMPONENT_EXPORT(URL)37 class COMPONENT_EXPORT(URL) StdStringCanonOutput : public CanonOutput {
38 public:
39 StdStringCanonOutput(std::string* str);
40
41 StdStringCanonOutput(const StdStringCanonOutput&) = delete;
42 StdStringCanonOutput& operator=(const StdStringCanonOutput&) = delete;
43
44 ~StdStringCanonOutput() override;
45
46 // Must be called after writing has completed but before the string is used.
47 void Complete();
48
49 void Resize(size_t sz) override;
50
51 protected:
52 // `str_` is not a raw_ptr<...> for performance reasons (based on analysis of
53 // sampling profiler data and tab_search:top100:2020).
54 RAW_PTR_EXCLUSION std::string* str_;
55 };
56
57 // An extension of the Replacements class that allows the setters to use
58 // string_views (implicitly allowing strings or char*s).
59 //
60 // The contents of the string_views are not copied and must remain valid until
61 // the StringViewReplacements object goes out of scope.
62 //
63 // In order to make it harder to misuse the API the setters do not accept rvalue
64 // references to std::strings.
65 // Note: Extra const char* overloads are necessary to break ambiguities that
66 // would otherwise exist for char literals.
67 template <typename CharT>
68 class StringViewReplacements : public Replacements<CharT> {
69 private:
70 using StringT = std::basic_string<CharT>;
71 using StringViewT = std::basic_string_view<CharT>;
72 using ParentT = Replacements<CharT>;
73 using SetterFun = void (ParentT::*)(const CharT*, const Component&);
74
SetImpl(SetterFun fun,StringViewT str)75 void SetImpl(SetterFun fun, StringViewT str) {
76 (this->*fun)(str.data(), Component(0, static_cast<int>(str.size())));
77 }
78
79 public:
SetSchemeStr(const CharT * str)80 void SetSchemeStr(const CharT* str) { SetImpl(&ParentT::SetScheme, str); }
SetSchemeStr(StringViewT str)81 void SetSchemeStr(StringViewT str) { SetImpl(&ParentT::SetScheme, str); }
82 void SetSchemeStr(const StringT&&) = delete;
83
SetUsernameStr(const CharT * str)84 void SetUsernameStr(const CharT* str) { SetImpl(&ParentT::SetUsername, str); }
SetUsernameStr(StringViewT str)85 void SetUsernameStr(StringViewT str) { SetImpl(&ParentT::SetUsername, str); }
86 void SetUsernameStr(const StringT&&) = delete;
87 using ParentT::ClearUsername;
88
SetPasswordStr(const CharT * str)89 void SetPasswordStr(const CharT* str) { SetImpl(&ParentT::SetPassword, str); }
SetPasswordStr(StringViewT str)90 void SetPasswordStr(StringViewT str) { SetImpl(&ParentT::SetPassword, str); }
91 void SetPasswordStr(const StringT&&) = delete;
92 using ParentT::ClearPassword;
93
SetHostStr(const CharT * str)94 void SetHostStr(const CharT* str) { SetImpl(&ParentT::SetHost, str); }
SetHostStr(StringViewT str)95 void SetHostStr(StringViewT str) { SetImpl(&ParentT::SetHost, str); }
96 void SetHostStr(const StringT&&) = delete;
97 using ParentT::ClearHost;
98
SetPortStr(const CharT * str)99 void SetPortStr(const CharT* str) { SetImpl(&ParentT::SetPort, str); }
SetPortStr(StringViewT str)100 void SetPortStr(StringViewT str) { SetImpl(&ParentT::SetPort, str); }
101 void SetPortStr(const StringT&&) = delete;
102 using ParentT::ClearPort;
103
SetPathStr(const CharT * str)104 void SetPathStr(const CharT* str) { SetImpl(&ParentT::SetPath, str); }
SetPathStr(StringViewT str)105 void SetPathStr(StringViewT str) { SetImpl(&ParentT::SetPath, str); }
106 void SetPathStr(const StringT&&) = delete;
107 using ParentT::ClearPath;
108
SetQueryStr(const CharT * str)109 void SetQueryStr(const CharT* str) { SetImpl(&ParentT::SetQuery, str); }
SetQueryStr(StringViewT str)110 void SetQueryStr(StringViewT str) { SetImpl(&ParentT::SetQuery, str); }
111 void SetQueryStr(const StringT&&) = delete;
112 using ParentT::ClearQuery;
113
SetRefStr(const CharT * str)114 void SetRefStr(const CharT* str) { SetImpl(&ParentT::SetRef, str); }
SetRefStr(StringViewT str)115 void SetRefStr(StringViewT str) { SetImpl(&ParentT::SetRef, str); }
116 void SetRefStr(const StringT&&) = delete;
117 using ParentT::ClearRef;
118
119 private:
120 using ParentT::SetHost;
121 using ParentT::SetPassword;
122 using ParentT::SetPath;
123 using ParentT::SetPort;
124 using ParentT::SetQuery;
125 using ParentT::SetRef;
126 using ParentT::SetScheme;
127 using ParentT::SetUsername;
128 };
129
130 } // namespace url
131
132 #endif // URL_URL_CANON_STDSTRING_H_
133