nsSimpleURI.h (6946B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #ifndef nsSimpleURI_h__ 7 #define nsSimpleURI_h__ 8 9 #include "nsIURI.h" 10 #include "nsISerializable.h" 11 #include "nsString.h" 12 #include "nsIClassInfo.h" 13 #include "nsIURIMutator.h" 14 #include "nsISimpleURIMutator.h" 15 16 namespace mozilla { 17 namespace net { 18 19 #define NS_THIS_SIMPLEURI_IMPLEMENTATION_CID \ 20 {/* 0b9bb0c2-fee6-470b-b9b9-9fd9462b5e19 */ \ 21 0x0b9bb0c2, \ 22 0xfee6, \ 23 0x470b, \ 24 {0xb9, 0xb9, 0x9f, 0xd9, 0x46, 0x2b, 0x5e, 0x19}} 25 26 class nsSimpleURI : public nsIURI, public nsISerializable { 27 protected: 28 nsSimpleURI() = default; 29 virtual ~nsSimpleURI() = default; 30 31 public: 32 NS_DECL_THREADSAFE_ISUPPORTS 33 NS_DECL_NSIURI 34 NS_DECL_NSISERIALIZABLE 35 36 static already_AddRefed<nsSimpleURI> From(nsIURI* aURI); 37 38 // nsSimpleURI methods: 39 40 bool Equals(nsSimpleURI* aOther) { return EqualsInternal(aOther, eHonorRef); } 41 42 protected: 43 // enum used in a few places to specify how .ref attribute should be handled 44 enum RefHandlingEnum { eIgnoreRef, eHonorRef, eReplaceRef }; 45 46 virtual nsresult Clone(nsIURI** result); 47 virtual nsresult SetSpecInternal(const nsACString& aSpec, 48 bool aStripWhitespace = false); 49 virtual nsresult SetScheme(const nsACString& input); 50 virtual nsresult SetUserPass(const nsACString& input); 51 nsresult SetUsername(const nsACString& input); 52 virtual nsresult SetPassword(const nsACString& input); 53 virtual nsresult SetHostPort(const nsACString& aValue); 54 virtual nsresult SetHost(const nsACString& input); 55 virtual nsresult SetPort(int32_t port); 56 virtual nsresult SetPathQueryRef(const nsACString& aPath); 57 virtual nsresult SetRef(const nsACString& aRef); 58 virtual nsresult SetFilePath(const nsACString& aFilePath); 59 virtual nsresult SetQuery(const nsACString& aQuery); 60 virtual nsresult SetQueryWithEncoding(const nsACString& aQuery, 61 const Encoding* encoding); 62 nsresult ReadPrivate(nsIObjectInputStream* stream); 63 64 // Helper to share code between Equals methods. 65 virtual nsresult EqualsInternal(nsIURI* other, 66 RefHandlingEnum refHandlingMode, 67 bool* result); 68 69 // Helper to be used by inherited classes who want to test 70 // equality given an assumed nsSimpleURI. This must NOT check 71 // the passed-in other for QI to our CID. 72 bool EqualsInternal(nsSimpleURI* otherUri, RefHandlingEnum refHandlingMode); 73 74 virtual already_AddRefed<nsSimpleURI> StartClone(); 75 76 void TrimTrailingCharactersFromPath(); 77 78 // Initialize `mQueryPos` and `mRefPos` from `mSpec`, and perform 79 // component-specific escapes. `mPathPos` should already be initialized. 80 nsresult SetPathQueryRefInternal(); 81 82 bool Deserialize(const mozilla::ipc::URIParams&); 83 84 // computed index helpers 85 size_t SchemeStart() const { return 0; } 86 size_t SchemeEnd() const { return mPathSep; } 87 size_t SchemeLen() const { return SchemeEnd() - SchemeStart(); } 88 89 size_t PathStart() const { return mPathSep + 1; } 90 inline size_t PathEnd() const; 91 size_t PathLen() const { return PathEnd() - PathStart(); } 92 93 bool IsQueryValid() const { return mQuerySep != kNotFound; } 94 inline size_t QueryStart() const; 95 inline size_t QueryEnd() const; 96 size_t QueryLen() const { return QueryEnd() - QueryStart(); } 97 98 bool IsRefValid() const { return mRefSep != kNotFound; } 99 inline size_t RefStart() const; 100 inline size_t RefEnd() const; 101 size_t RefLen() const { return RefEnd() - RefStart(); } 102 103 // dependent substring getters 104 nsDependentCSubstring Scheme() { 105 return Substring(mSpec, SchemeStart(), SchemeLen()); 106 } 107 nsDependentCSubstring Path() { 108 return Substring(mSpec, PathStart(), PathLen()); 109 } 110 nsDependentCSubstring Query() { 111 return Substring(mSpec, QueryStart(), QueryLen()); 112 } 113 nsDependentCSubstring Ref() { return Substring(mSpec, RefStart(), RefLen()); } 114 nsDependentCSubstring SpecIgnoringRef() { 115 return Substring(mSpec, 0, IsRefValid() ? mRefSep : -1); 116 } 117 118 // mSpec contains the normalized version of the URL spec (UTF-8 encoded). 119 nsCString mSpec; 120 121 // Index of the `:` character which indicates the start of the path. 122 int32_t mPathSep = kNotFound; 123 // Index of the `?` character which indicates the start of the query. 124 // Will be `kNotFound` if there is no query. 125 int32_t mQuerySep = kNotFound; 126 // Index of the `#` character which indicates the start of the ref. 127 // Will be `kNotFound` if there is no ref. 128 int32_t mRefSep = kNotFound; 129 130 public: 131 class Mutator final : public nsIURIMutator, 132 public BaseURIMutator<nsSimpleURI>, 133 public nsISimpleURIMutator, 134 public nsISerializable { 135 NS_DECL_ISUPPORTS 136 NS_FORWARD_SAFE_NSIURISETTERS_RET(mURI) 137 NS_DEFINE_NSIMUTATOR_COMMON 138 139 NS_IMETHOD 140 Write(nsIObjectOutputStream* aOutputStream) override { 141 return NS_ERROR_NOT_IMPLEMENTED; 142 } 143 144 [[nodiscard]] NS_IMETHOD Read(nsIObjectInputStream* aStream) override { 145 return InitFromInputStream(aStream); 146 } 147 148 [[nodiscard]] NS_IMETHOD SetSpecAndFilterWhitespace( 149 const nsACString& aSpec, nsIURIMutator** aMutator) override { 150 if (aMutator) { 151 *aMutator = do_AddRef(this).take(); 152 } 153 154 nsresult rv = NS_OK; 155 RefPtr<nsSimpleURI> uri = new nsSimpleURI(); 156 rv = uri->SetSpecInternal(aSpec, /* filterWhitespace */ true); 157 if (NS_FAILED(rv)) { 158 return rv; 159 } 160 mURI = std::move(uri); 161 return NS_OK; 162 } 163 164 explicit Mutator() = default; 165 166 private: 167 virtual ~Mutator() = default; 168 169 friend class nsSimpleURI; 170 }; 171 172 friend BaseURIMutator<nsSimpleURI>; 173 }; 174 175 //----------------------------------------------------------------------------- 176 // Computed index helpers 177 //----------------------------------------------------------------------------- 178 179 inline size_t nsSimpleURI::PathEnd() const { 180 if (IsQueryValid()) { 181 return mQuerySep; 182 } 183 if (IsRefValid()) { 184 return mRefSep; 185 } 186 return mSpec.Length(); 187 } 188 189 inline size_t nsSimpleURI::QueryStart() const { 190 MOZ_DIAGNOSTIC_ASSERT(IsQueryValid()); 191 return mQuerySep + 1; 192 } 193 194 inline size_t nsSimpleURI::QueryEnd() const { 195 MOZ_DIAGNOSTIC_ASSERT(IsQueryValid()); 196 if (IsRefValid()) { 197 return mRefSep; 198 } 199 return mSpec.Length(); 200 } 201 202 inline size_t nsSimpleURI::RefStart() const { 203 MOZ_DIAGNOSTIC_ASSERT(IsRefValid()); 204 return mRefSep + 1; 205 } 206 207 inline size_t nsSimpleURI::RefEnd() const { 208 MOZ_DIAGNOSTIC_ASSERT(IsRefValid()); 209 return mSpec.Length(); 210 } 211 212 } // namespace net 213 } // namespace mozilla 214 215 #endif // nsSimpleURI_h__