/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsString.h" #include "nsIControllerCommand.h" #include "nsControllerCommandTable.h" // prototype; nsresult NS_NewControllerCommandTable(nsIControllerCommandTable** aResult); // this value is used to size the hash table. Just a sensible upper bound #define NUM_COMMANDS_LENGTH 32 nsControllerCommandTable::nsControllerCommandTable() : mCommandsTable(NUM_COMMANDS_LENGTH) , mMutable(true) { } nsControllerCommandTable::~nsControllerCommandTable() { } NS_IMPL_ISUPPORTS(nsControllerCommandTable, nsIControllerCommandTable, nsISupportsWeakReference) NS_IMETHODIMP nsControllerCommandTable::MakeImmutable(void) { mMutable = false; return NS_OK; } NS_IMETHODIMP nsControllerCommandTable::RegisterCommand(const char * aCommandName, nsIControllerCommand *aCommand) { NS_ENSURE_TRUE(mMutable, NS_ERROR_FAILURE); mCommandsTable.Put(nsDependentCString(aCommandName), aCommand); return NS_OK; } NS_IMETHODIMP nsControllerCommandTable::UnregisterCommand(const char * aCommandName, nsIControllerCommand *aCommand) { NS_ENSURE_TRUE(mMutable, NS_ERROR_FAILURE); nsDependentCString commandKey(aCommandName); if (!mCommandsTable.Get(commandKey, nullptr)) { return NS_ERROR_FAILURE; } mCommandsTable.Remove(commandKey); return NS_OK; } NS_IMETHODIMP nsControllerCommandTable::FindCommandHandler(const char * aCommandName, nsIControllerCommand **outCommand) { NS_ENSURE_ARG_POINTER(outCommand); *outCommand = nullptr; nsCOMPtr foundCommand; mCommandsTable.Get(nsDependentCString(aCommandName), getter_AddRefs(foundCommand)); if (!foundCommand) return NS_ERROR_FAILURE; foundCommand.forget(outCommand); return NS_OK; } /* boolean isCommandEnabled (in wstring command); */ NS_IMETHODIMP nsControllerCommandTable::IsCommandEnabled(const char * aCommandName, nsISupports *aCommandRefCon, bool *aResult) { NS_ENSURE_ARG_POINTER(aResult); *aResult = false; // find the command nsCOMPtr commandHandler; FindCommandHandler(aCommandName, getter_AddRefs(commandHandler)); if (!commandHandler) { #if DEBUG NS_WARNING("Controller command table asked about a command that it does not handle -- "); #endif return NS_OK; // we don't handle this command } return commandHandler->IsCommandEnabled(aCommandName, aCommandRefCon, aResult); } NS_IMETHODIMP nsControllerCommandTable::UpdateCommandState(const char * aCommandName, nsISupports *aCommandRefCon) { // find the command nsCOMPtr commandHandler; FindCommandHandler(aCommandName, getter_AddRefs(commandHandler)); if (!commandHandler) { #if DEBUG NS_WARNING("Controller command table asked to update the state of a command that it does not handle -- "); #endif return NS_OK; // we don't handle this command } return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP nsControllerCommandTable::SupportsCommand(const char * aCommandName, nsISupports *aCommandRefCon, bool *aResult) { NS_ENSURE_ARG_POINTER(aResult); // XXX: need to check the readonly and disabled states *aResult = false; // find the command nsCOMPtr commandHandler; FindCommandHandler(aCommandName, getter_AddRefs(commandHandler)); *aResult = (commandHandler.get() != nullptr); return NS_OK; } /* void doCommand (in wstring command); */ NS_IMETHODIMP nsControllerCommandTable::DoCommand(const char * aCommandName, nsISupports *aCommandRefCon) { // find the command nsCOMPtr commandHandler; FindCommandHandler(aCommandName, getter_AddRefs(commandHandler)); if (!commandHandler) { #if DEBUG NS_WARNING("Controller command table asked to do a command that it does not handle -- "); #endif return NS_OK; // we don't handle this command } return commandHandler->DoCommand(aCommandName, aCommandRefCon); } NS_IMETHODIMP nsControllerCommandTable::DoCommandParams(const char *aCommandName, nsICommandParams *aParams, nsISupports *aCommandRefCon) { // find the command nsCOMPtr commandHandler; FindCommandHandler(aCommandName, getter_AddRefs(commandHandler)); if (!commandHandler) { #if DEBUG NS_WARNING("Controller command table asked to do a command that it does not handle -- "); #endif return NS_OK; // we don't handle this command } return commandHandler->DoCommandParams(aCommandName, aParams, aCommandRefCon); } NS_IMETHODIMP nsControllerCommandTable::GetCommandState(const char *aCommandName, nsICommandParams *aParams, nsISupports *aCommandRefCon) { // find the command nsCOMPtr commandHandler; FindCommandHandler(aCommandName, getter_AddRefs(commandHandler)); if (!commandHandler) { #if DEBUG NS_WARNING("Controller command table asked to do a command that it does not handle -- "); #endif return NS_OK; // we don't handle this command } return commandHandler->GetCommandStateParams(aCommandName, aParams, aCommandRefCon); } static PLDHashOperator AddCommand(const nsACString& aKey, nsIControllerCommand* aData, void* aArg) { // aArg is a pointer to a array of strings. It gets incremented after // allocating each one so that it points to the next location for AddCommand // to assign a string to. char*** commands = static_cast(aArg); (**commands) = ToNewCString(aKey); (*commands)++; return PL_DHASH_NEXT; } NS_IMETHODIMP nsControllerCommandTable::GetSupportedCommands(uint32_t* aCount, char*** aCommands) { char** commands = static_cast(NS_Alloc(sizeof(char *) * mCommandsTable.Count())); *aCount = mCommandsTable.Count(); *aCommands = commands; mCommandsTable.EnumerateRead(AddCommand, &commands); return NS_OK; } nsresult NS_NewControllerCommandTable(nsIControllerCommandTable** aResult) { NS_PRECONDITION(aResult != nullptr, "null ptr"); if (! aResult) return NS_ERROR_NULL_POINTER; nsControllerCommandTable* newCommandTable = new nsControllerCommandTable(); if (! newCommandTable) return NS_ERROR_OUT_OF_MEMORY; NS_ADDREF(newCommandTable); *aResult = newCommandTable; return NS_OK; }