nsCommandParams.cpp (8703B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "nsCommandParams.h" 8 9 #include <new> 10 11 #include "mozilla/HashFunctions.h" 12 #include "nsCRT.h" 13 #include "nscore.h" 14 15 using namespace mozilla; 16 17 const PLDHashTableOps nsCommandParams::sHashOps = { 18 HashKey, HashMatchEntry, HashMoveEntry, HashClearEntry}; 19 20 NS_IMPL_ISUPPORTS(nsCommandParams, nsICommandParams) 21 22 nsCommandParams::nsCommandParams() 23 : mValuesHash(&sHashOps, sizeof(HashEntry), 2) {} 24 25 nsCommandParams::~nsCommandParams() = default; 26 27 NS_IMETHODIMP 28 nsCommandParams::GetValueType(const char* aName, int16_t* aRetVal) { 29 NS_ENSURE_ARG_POINTER(aRetVal); 30 31 HashEntry* foundEntry = GetNamedEntry(aName); 32 if (foundEntry) { 33 *aRetVal = foundEntry->mEntryType; 34 return NS_OK; 35 } 36 *aRetVal = eNoType; 37 return NS_ERROR_FAILURE; 38 } 39 40 NS_IMETHODIMP 41 nsCommandParams::GetBooleanValue(const char* aName, bool* aRetVal) { 42 NS_ENSURE_ARG_POINTER(aRetVal); 43 44 ErrorResult error; 45 *aRetVal = GetBool(aName, error); 46 return error.StealNSResult(); 47 } 48 49 bool nsCommandParams::GetBool(const char* aName, ErrorResult& aRv) const { 50 MOZ_ASSERT(!aRv.Failed()); 51 52 HashEntry* foundEntry = GetNamedEntry(aName); 53 if (foundEntry && foundEntry->mEntryType == eBooleanType) { 54 return foundEntry->mData.mBoolean; 55 } 56 aRv.Throw(NS_ERROR_FAILURE); 57 return false; 58 } 59 60 NS_IMETHODIMP 61 nsCommandParams::GetLongValue(const char* aName, int32_t* aRetVal) { 62 NS_ENSURE_ARG_POINTER(aRetVal); 63 64 ErrorResult error; 65 *aRetVal = GetInt(aName, error); 66 return error.StealNSResult(); 67 } 68 69 int32_t nsCommandParams::GetInt(const char* aName, ErrorResult& aRv) const { 70 MOZ_ASSERT(!aRv.Failed()); 71 72 HashEntry* foundEntry = GetNamedEntry(aName); 73 if (foundEntry && foundEntry->mEntryType == eLongType) { 74 return foundEntry->mData.mLong; 75 } 76 aRv.Throw(NS_ERROR_FAILURE); 77 return 0; 78 } 79 80 NS_IMETHODIMP 81 nsCommandParams::GetDoubleValue(const char* aName, double* aRetVal) { 82 NS_ENSURE_ARG_POINTER(aRetVal); 83 84 ErrorResult error; 85 *aRetVal = GetDouble(aName, error); 86 return error.StealNSResult(); 87 } 88 89 double nsCommandParams::GetDouble(const char* aName, ErrorResult& aRv) const { 90 MOZ_ASSERT(!aRv.Failed()); 91 92 HashEntry* foundEntry = GetNamedEntry(aName); 93 if (foundEntry && foundEntry->mEntryType == eDoubleType) { 94 return foundEntry->mData.mDouble; 95 } 96 aRv.Throw(NS_ERROR_FAILURE); 97 return 0.0; 98 } 99 100 NS_IMETHODIMP 101 nsCommandParams::GetStringValue(const char* aName, nsAString& aRetVal) { 102 return GetString(aName, aRetVal); 103 } 104 105 nsresult nsCommandParams::GetString(const char* aName, 106 nsAString& aRetVal) const { 107 HashEntry* foundEntry = GetNamedEntry(aName); 108 if (foundEntry && foundEntry->mEntryType == eWStringType) { 109 NS_ASSERTION(foundEntry->mData.mString, "Null string"); 110 aRetVal.Assign(*foundEntry->mData.mString); 111 return NS_OK; 112 } 113 aRetVal.Truncate(); 114 return NS_ERROR_FAILURE; 115 } 116 117 NS_IMETHODIMP 118 nsCommandParams::GetCStringValue(const char* aName, nsACString& aRetVal) { 119 return GetCString(aName, aRetVal); 120 } 121 122 nsresult nsCommandParams::GetCString(const char* aName, 123 nsACString& aRetVal) const { 124 HashEntry* foundEntry = GetNamedEntry(aName); 125 if (foundEntry && foundEntry->mEntryType == eStringType) { 126 NS_ASSERTION(foundEntry->mData.mCString, "Null string"); 127 aRetVal.Assign(*foundEntry->mData.mCString); 128 return NS_OK; 129 } 130 aRetVal.Truncate(); 131 return NS_ERROR_FAILURE; 132 } 133 134 NS_IMETHODIMP 135 nsCommandParams::GetISupportsValue(const char* aName, nsISupports** aRetVal) { 136 NS_ENSURE_ARG_POINTER(aRetVal); 137 138 ErrorResult error; 139 nsCOMPtr<nsISupports> result = GetISupports(aName, error); 140 if (result) { 141 result.forget(aRetVal); 142 } else { 143 *aRetVal = nullptr; 144 } 145 return error.StealNSResult(); 146 } 147 148 already_AddRefed<nsISupports> nsCommandParams::GetISupports( 149 const char* aName, ErrorResult& aRv) const { 150 MOZ_ASSERT(!aRv.Failed()); 151 152 HashEntry* foundEntry = GetNamedEntry(aName); 153 if (foundEntry && foundEntry->mEntryType == eISupportsType) { 154 nsCOMPtr<nsISupports> result = foundEntry->mISupports; 155 return result.forget(); 156 } 157 aRv.Throw(NS_ERROR_FAILURE); 158 return nullptr; 159 } 160 161 NS_IMETHODIMP 162 nsCommandParams::SetBooleanValue(const char* aName, bool aValue) { 163 return SetBool(aName, aValue); 164 } 165 166 nsresult nsCommandParams::SetBool(const char* aName, bool aValue) { 167 HashEntry* foundEntry = GetOrMakeEntry(aName, eBooleanType); 168 if (!foundEntry) { 169 return NS_ERROR_OUT_OF_MEMORY; 170 } 171 foundEntry->mData.mBoolean = aValue; 172 return NS_OK; 173 } 174 175 NS_IMETHODIMP 176 nsCommandParams::SetLongValue(const char* aName, int32_t aValue) { 177 return SetInt(aName, aValue); 178 } 179 180 nsresult nsCommandParams::SetInt(const char* aName, int32_t aValue) { 181 HashEntry* foundEntry = GetOrMakeEntry(aName, eLongType); 182 if (!foundEntry) { 183 return NS_ERROR_OUT_OF_MEMORY; 184 } 185 foundEntry->mData.mLong = aValue; 186 return NS_OK; 187 } 188 189 NS_IMETHODIMP 190 nsCommandParams::SetDoubleValue(const char* aName, double aValue) { 191 return SetDouble(aName, aValue); 192 } 193 194 nsresult nsCommandParams::SetDouble(const char* aName, double aValue) { 195 HashEntry* foundEntry = GetOrMakeEntry(aName, eDoubleType); 196 if (!foundEntry) { 197 return NS_ERROR_OUT_OF_MEMORY; 198 } 199 foundEntry->mData.mDouble = aValue; 200 return NS_OK; 201 } 202 203 NS_IMETHODIMP 204 nsCommandParams::SetStringValue(const char* aName, const nsAString& aValue) { 205 return SetString(aName, aValue); 206 } 207 208 nsresult nsCommandParams::SetString(const char* aName, 209 const nsAString& aValue) { 210 HashEntry* foundEntry = GetOrMakeEntry(aName, eWStringType); 211 if (!foundEntry) { 212 return NS_ERROR_OUT_OF_MEMORY; 213 } 214 foundEntry->mData.mString = new nsString(aValue); 215 return NS_OK; 216 } 217 218 NS_IMETHODIMP 219 nsCommandParams::SetCStringValue(const char* aName, const nsACString& aValue) { 220 return SetCString(aName, aValue); 221 } 222 223 nsresult nsCommandParams::SetCString(const char* aName, 224 const nsACString& aValue) { 225 HashEntry* foundEntry = GetOrMakeEntry(aName, eStringType); 226 if (!foundEntry) { 227 return NS_ERROR_OUT_OF_MEMORY; 228 } 229 foundEntry->mData.mCString = new nsCString(aValue); 230 return NS_OK; 231 } 232 233 NS_IMETHODIMP 234 nsCommandParams::SetISupportsValue(const char* aName, nsISupports* aValue) { 235 return SetISupports(aName, aValue); 236 } 237 238 nsresult nsCommandParams::SetISupports(const char* aName, nsISupports* aValue) { 239 HashEntry* foundEntry = GetOrMakeEntry(aName, eISupportsType); 240 if (!foundEntry) { 241 return NS_ERROR_OUT_OF_MEMORY; 242 } 243 foundEntry->mISupports = aValue; // addrefs 244 return NS_OK; 245 } 246 247 NS_IMETHODIMP 248 nsCommandParams::RemoveValue(const char* aName) { 249 mValuesHash.Remove((void*)aName); 250 return NS_OK; 251 } 252 253 nsCommandParams::HashEntry* nsCommandParams::GetNamedEntry( 254 const char* aName) const { 255 return static_cast<HashEntry*>(mValuesHash.Search((void*)aName)); 256 } 257 258 nsCommandParams::HashEntry* nsCommandParams::GetOrMakeEntry( 259 const char* aName, uint8_t aEntryType) { 260 auto foundEntry = static_cast<HashEntry*>(mValuesHash.Search((void*)aName)); 261 if (foundEntry) { // reuse existing entry 262 foundEntry->Reset(aEntryType); 263 return foundEntry; 264 } 265 266 foundEntry = static_cast<HashEntry*>(mValuesHash.Add((void*)aName, fallible)); 267 if (!foundEntry) { 268 return nullptr; 269 } 270 271 // Use placement new. Our ctor does not clobber keyHash, which is important. 272 new (foundEntry) HashEntry(aEntryType, aName); 273 return foundEntry; 274 } 275 276 PLDHashNumber nsCommandParams::HashKey(const void* aKey) { 277 return HashString((const char*)aKey); 278 } 279 280 bool nsCommandParams::HashMatchEntry(const PLDHashEntryHdr* aEntry, 281 const void* aKey) { 282 const char* keyString = (const char*)aKey; 283 const HashEntry* thisEntry = static_cast<const HashEntry*>(aEntry); 284 return thisEntry->mEntryName.Equals(keyString); 285 } 286 287 void nsCommandParams::HashMoveEntry(PLDHashTable* aTable, 288 const PLDHashEntryHdr* aFrom, 289 PLDHashEntryHdr* aTo) { 290 auto* fromEntry = 291 const_cast<HashEntry*>(static_cast<const HashEntry*>(aFrom)); 292 HashEntry* toEntry = static_cast<HashEntry*>(aTo); 293 294 new (KnownNotNull, toEntry) HashEntry(std::move(*fromEntry)); 295 296 fromEntry->~HashEntry(); 297 } 298 299 void nsCommandParams::HashClearEntry(PLDHashTable* aTable, 300 PLDHashEntryHdr* aEntry) { 301 HashEntry* thisEntry = static_cast<HashEntry*>(aEntry); 302 thisEntry->~HashEntry(); 303 }