1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/embedding/components/commandhandler/src/nsCommandGroup.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,341 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "nsString.h" 1.10 +#include "nsReadableUtils.h" 1.11 +#include "nsTArray.h" 1.12 +#include "nsISimpleEnumerator.h" 1.13 +#include "nsXPCOM.h" 1.14 +#include "nsSupportsPrimitives.h" 1.15 +#include "nsIComponentManager.h" 1.16 + 1.17 +#include "nsCommandGroup.h" 1.18 +#include "nsIControllerCommand.h" 1.19 +#include "nsCRT.h" 1.20 + 1.21 + 1.22 +class nsGroupsEnumerator : public nsISimpleEnumerator 1.23 +{ 1.24 +public: 1.25 + nsGroupsEnumerator(nsHashtable& inHashTable); 1.26 + virtual ~nsGroupsEnumerator(); 1.27 + 1.28 + NS_DECL_ISUPPORTS 1.29 + NS_DECL_NSISIMPLEENUMERATOR 1.30 + 1.31 +protected: 1.32 + 1.33 + static bool HashEnum(nsHashKey *aKey, void *aData, void* aClosure); 1.34 + 1.35 + nsresult Initialize(); 1.36 + 1.37 +protected: 1.38 + 1.39 + nsHashtable& mHashTable; 1.40 + int32_t mIndex; 1.41 + char ** mGroupNames; // array of pointers to char16_t* in the hash table 1.42 + bool mInitted; 1.43 + 1.44 +}; 1.45 + 1.46 +/* Implementation file */ 1.47 +NS_IMPL_ISUPPORTS(nsGroupsEnumerator, nsISimpleEnumerator) 1.48 + 1.49 +nsGroupsEnumerator::nsGroupsEnumerator(nsHashtable& inHashTable) 1.50 +: mHashTable(inHashTable) 1.51 +, mIndex(-1) 1.52 +, mGroupNames(nullptr) 1.53 +, mInitted(false) 1.54 +{ 1.55 + /* member initializers and constructor code */ 1.56 +} 1.57 + 1.58 +nsGroupsEnumerator::~nsGroupsEnumerator() 1.59 +{ 1.60 + delete [] mGroupNames; // ok on null pointer 1.61 +} 1.62 + 1.63 +/* boolean hasMoreElements (); */ 1.64 +NS_IMETHODIMP 1.65 +nsGroupsEnumerator::HasMoreElements(bool *_retval) 1.66 +{ 1.67 + nsresult rv = NS_OK; 1.68 + 1.69 + NS_ENSURE_ARG_POINTER(_retval); 1.70 + 1.71 + if (!mInitted) { 1.72 + rv = Initialize(); 1.73 + if (NS_FAILED(rv)) return rv; 1.74 + } 1.75 + 1.76 + *_retval = (mIndex < mHashTable.Count() - 1); 1.77 + return NS_OK; 1.78 +} 1.79 + 1.80 +/* nsISupports getNext (); */ 1.81 +NS_IMETHODIMP 1.82 +nsGroupsEnumerator::GetNext(nsISupports **_retval) 1.83 +{ 1.84 + nsresult rv = NS_OK; 1.85 + 1.86 + NS_ENSURE_ARG_POINTER(_retval); 1.87 + 1.88 + if (!mInitted) { 1.89 + rv = Initialize(); 1.90 + if (NS_FAILED(rv)) return rv; 1.91 + } 1.92 + 1.93 + mIndex ++; 1.94 + if (mIndex >= mHashTable.Count()) 1.95 + return NS_ERROR_FAILURE; 1.96 + 1.97 + char *thisGroupName = mGroupNames[mIndex]; 1.98 + 1.99 + nsCOMPtr<nsISupportsCString> supportsString = do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID, &rv); 1.100 + if (NS_FAILED(rv)) return rv; 1.101 + 1.102 + supportsString->SetData(nsDependentCString(thisGroupName)); 1.103 + return CallQueryInterface(supportsString, _retval); 1.104 +} 1.105 + 1.106 +/* static */ 1.107 +/* return false to stop */ 1.108 +bool 1.109 +nsGroupsEnumerator::HashEnum(nsHashKey *aKey, void *aData, void* aClosure) 1.110 +{ 1.111 + nsGroupsEnumerator* groupsEnum = reinterpret_cast<nsGroupsEnumerator *>(aClosure); 1.112 + nsCStringKey* stringKey = static_cast<nsCStringKey*>(aKey); 1.113 + 1.114 + groupsEnum->mGroupNames[groupsEnum->mIndex] = (char*)stringKey->GetString(); 1.115 + groupsEnum->mIndex ++; 1.116 + return true; 1.117 +} 1.118 + 1.119 +nsresult 1.120 +nsGroupsEnumerator::Initialize() 1.121 +{ 1.122 + if (mInitted) return NS_OK; 1.123 + 1.124 + mGroupNames = new char*[mHashTable.Count()]; 1.125 + if (!mGroupNames) return NS_ERROR_OUT_OF_MEMORY; 1.126 + 1.127 + mIndex = 0; 1.128 + mHashTable.Enumerate(HashEnum, (void*)this); 1.129 + 1.130 + mIndex = -1; 1.131 + mInitted = true; 1.132 + return NS_OK; 1.133 +} 1.134 + 1.135 +#if 0 1.136 +#pragma mark - 1.137 +#endif 1.138 + 1.139 +class nsNamedGroupEnumerator : public nsISimpleEnumerator 1.140 +{ 1.141 +public: 1.142 + nsNamedGroupEnumerator(nsTArray<char*>* inArray); 1.143 + virtual ~nsNamedGroupEnumerator(); 1.144 + 1.145 + NS_DECL_ISUPPORTS 1.146 + NS_DECL_NSISIMPLEENUMERATOR 1.147 + 1.148 +protected: 1.149 + 1.150 + nsTArray<char*>* mGroupArray; 1.151 + int32_t mIndex; 1.152 + 1.153 +}; 1.154 + 1.155 +nsNamedGroupEnumerator::nsNamedGroupEnumerator(nsTArray<char*>* inArray) 1.156 +: mGroupArray(inArray) 1.157 +, mIndex(-1) 1.158 +{ 1.159 +} 1.160 + 1.161 +nsNamedGroupEnumerator::~nsNamedGroupEnumerator() 1.162 +{ 1.163 +} 1.164 + 1.165 +NS_IMPL_ISUPPORTS(nsNamedGroupEnumerator, nsISimpleEnumerator) 1.166 + 1.167 +/* boolean hasMoreElements (); */ 1.168 +NS_IMETHODIMP 1.169 +nsNamedGroupEnumerator::HasMoreElements(bool *_retval) 1.170 +{ 1.171 + NS_ENSURE_ARG_POINTER(_retval); 1.172 + 1.173 + int32_t arrayLen = mGroupArray ? mGroupArray->Length() : 0; 1.174 + *_retval = (mIndex < arrayLen - 1); 1.175 + return NS_OK; 1.176 +} 1.177 + 1.178 +/* nsISupports getNext (); */ 1.179 +NS_IMETHODIMP 1.180 +nsNamedGroupEnumerator::GetNext(nsISupports **_retval) 1.181 +{ 1.182 + NS_ENSURE_ARG_POINTER(_retval); 1.183 + 1.184 + if (!mGroupArray) 1.185 + return NS_ERROR_FAILURE; 1.186 + 1.187 + mIndex ++; 1.188 + if (mIndex >= int32_t(mGroupArray->Length())) 1.189 + return NS_ERROR_FAILURE; 1.190 + 1.191 + char16_t *thisGroupName = (char16_t*)mGroupArray->ElementAt(mIndex); 1.192 + NS_ASSERTION(thisGroupName, "Bad Element in mGroupArray"); 1.193 + 1.194 + nsresult rv; 1.195 + nsCOMPtr<nsISupportsString> supportsString = do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv); 1.196 + if (NS_FAILED(rv)) return rv; 1.197 + 1.198 + supportsString->SetData(nsDependentString(thisGroupName)); 1.199 + return CallQueryInterface(supportsString, _retval); 1.200 +} 1.201 + 1.202 +#if 0 1.203 +#pragma mark - 1.204 +#endif 1.205 + 1.206 + 1.207 +/* Implementation file */ 1.208 +NS_IMPL_ISUPPORTS(nsControllerCommandGroup, nsIControllerCommandGroup) 1.209 + 1.210 +nsControllerCommandGroup::nsControllerCommandGroup() 1.211 +{ 1.212 +} 1.213 + 1.214 +nsControllerCommandGroup::~nsControllerCommandGroup() 1.215 +{ 1.216 + ClearGroupsHash(); 1.217 +} 1.218 + 1.219 +void 1.220 +nsControllerCommandGroup::ClearGroupsHash() 1.221 +{ 1.222 + mGroupsHash.Reset(ClearEnumerator, (void *)this); 1.223 +} 1.224 + 1.225 +#if 0 1.226 +#pragma mark - 1.227 +#endif 1.228 + 1.229 +/* void addCommandToGroup (in DOMString aCommand, in DOMString aGroup); */ 1.230 +NS_IMETHODIMP 1.231 +nsControllerCommandGroup::AddCommandToGroup(const char * aCommand, const char *aGroup) 1.232 +{ 1.233 + nsCStringKey groupKey(aGroup); 1.234 + nsTArray<char*>* commandList; 1.235 + if ((commandList = (nsTArray<char*> *)mGroupsHash.Get(&groupKey)) == nullptr) 1.236 + { 1.237 + // make this list 1.238 + commandList = new nsAutoTArray<char*, 8>; 1.239 + mGroupsHash.Put(&groupKey, (void *)commandList); 1.240 + } 1.241 + // add the command to the list. Note that we're not checking for duplicates here 1.242 + char* commandString = NS_strdup(aCommand); // we store allocated char16_t* in the array 1.243 + if (!commandString) return NS_ERROR_OUT_OF_MEMORY; 1.244 + 1.245 +#ifdef DEBUG 1.246 + char** appended = 1.247 +#endif 1.248 + commandList->AppendElement(commandString); 1.249 + NS_ASSERTION(appended, "Append failed"); 1.250 + 1.251 + return NS_OK; 1.252 +} 1.253 + 1.254 +/* void removeCommandFromGroup (in DOMString aCommand, in DOMString aGroup); */ 1.255 +NS_IMETHODIMP 1.256 +nsControllerCommandGroup::RemoveCommandFromGroup(const char * aCommand, const char * aGroup) 1.257 +{ 1.258 + nsCStringKey groupKey(aGroup); 1.259 + nsTArray<char*>* commandList = (nsTArray<char*> *)mGroupsHash.Get(&groupKey); 1.260 + if (!commandList) return NS_OK; // no group 1.261 + 1.262 + uint32_t numEntries = commandList->Length(); 1.263 + for (uint32_t i = 0; i < numEntries; i ++) 1.264 + { 1.265 + char* commandString = commandList->ElementAt(i); 1.266 + if (!nsCRT::strcmp(aCommand,commandString)) 1.267 + { 1.268 + commandList->RemoveElementAt(i); 1.269 + nsMemory::Free(commandString); 1.270 + break; 1.271 + } 1.272 + } 1.273 + 1.274 + return NS_OK; 1.275 +} 1.276 + 1.277 +/* boolean isCommandInGroup (in DOMString aCommand, in DOMString aGroup); */ 1.278 +NS_IMETHODIMP 1.279 +nsControllerCommandGroup::IsCommandInGroup(const char * aCommand, const char * aGroup, bool *_retval) 1.280 +{ 1.281 + NS_ENSURE_ARG_POINTER(_retval); 1.282 + *_retval = false; 1.283 + 1.284 + nsCStringKey groupKey(aGroup); 1.285 + nsTArray<char*>* commandList = (nsTArray<char*> *)mGroupsHash.Get(&groupKey); 1.286 + if (!commandList) return NS_OK; // no group 1.287 + 1.288 + uint32_t numEntries = commandList->Length(); 1.289 + for (uint32_t i = 0; i < numEntries; i ++) 1.290 + { 1.291 + char* commandString = commandList->ElementAt(i); 1.292 + if (!nsCRT::strcmp(aCommand,commandString)) 1.293 + { 1.294 + *_retval = true; 1.295 + break; 1.296 + } 1.297 + } 1.298 + return NS_OK; 1.299 +} 1.300 + 1.301 +/* nsISimpleEnumerator getGroupsEnumerator (); */ 1.302 +NS_IMETHODIMP 1.303 +nsControllerCommandGroup::GetGroupsEnumerator(nsISimpleEnumerator **_retval) 1.304 +{ 1.305 + nsGroupsEnumerator* groupsEnum = new nsGroupsEnumerator(mGroupsHash); 1.306 + if (!groupsEnum) return NS_ERROR_OUT_OF_MEMORY; 1.307 + 1.308 + return groupsEnum->QueryInterface(NS_GET_IID(nsISimpleEnumerator), (void **)_retval); 1.309 +} 1.310 + 1.311 +/* nsISimpleEnumerator getEnumeratorForGroup (in DOMString aGroup); */ 1.312 +NS_IMETHODIMP 1.313 +nsControllerCommandGroup::GetEnumeratorForGroup(const char * aGroup, nsISimpleEnumerator **_retval) 1.314 +{ 1.315 + nsCStringKey groupKey(aGroup); 1.316 + nsTArray<char*>* commandList = (nsTArray<char*> *)mGroupsHash.Get(&groupKey); // may be null 1.317 + 1.318 + nsNamedGroupEnumerator* theGroupEnum = new nsNamedGroupEnumerator(commandList); 1.319 + if (!theGroupEnum) return NS_ERROR_OUT_OF_MEMORY; 1.320 + 1.321 + return theGroupEnum->QueryInterface(NS_GET_IID(nsISimpleEnumerator), (void **)_retval); 1.322 +} 1.323 + 1.324 +#if 0 1.325 +#pragma mark - 1.326 +#endif 1.327 + 1.328 +bool nsControllerCommandGroup::ClearEnumerator(nsHashKey *aKey, void *aData, void* closure) 1.329 +{ 1.330 + nsTArray<char*>* commandList = (nsTArray<char*> *)aData; 1.331 + if (commandList) 1.332 + { 1.333 + uint32_t numEntries = commandList->Length(); 1.334 + for (uint32_t i = 0; i < numEntries; i ++) 1.335 + { 1.336 + char* commandString = commandList->ElementAt(i); 1.337 + nsMemory::Free(commandString); 1.338 + } 1.339 + 1.340 + delete commandList; 1.341 + } 1.342 + 1.343 + return true; 1.344 +}