mirror of
https://github.com/WinampDesktop/winamp.git
synced 2024-12-18 17:15:51 +01:00
343 lines
6.1 KiB
C++
343 lines
6.1 KiB
C++
|
#include "main.h"
|
||
|
#include "./deviceSupportedCommandStore.h"
|
||
|
|
||
|
DeviceSupportedCommandStore::DeviceSupportedCommandStore()
|
||
|
: ref(1)
|
||
|
{
|
||
|
InitializeCriticalSection(&lock);
|
||
|
}
|
||
|
|
||
|
DeviceSupportedCommandStore::~DeviceSupportedCommandStore()
|
||
|
{
|
||
|
RemoveAll();
|
||
|
DeleteCriticalSection(&lock);
|
||
|
}
|
||
|
|
||
|
HRESULT DeviceSupportedCommandStore::CreateInstance(DeviceSupportedCommandStore **instance)
|
||
|
{
|
||
|
if (NULL == instance)
|
||
|
return E_POINTER;
|
||
|
|
||
|
*instance = new DeviceSupportedCommandStore();
|
||
|
|
||
|
if (NULL == *instance)
|
||
|
return E_OUTOFMEMORY;
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
size_t DeviceSupportedCommandStore::AddRef()
|
||
|
{
|
||
|
return InterlockedIncrement((LONG*)&ref);
|
||
|
}
|
||
|
|
||
|
size_t DeviceSupportedCommandStore::Release()
|
||
|
{
|
||
|
if (0 == ref)
|
||
|
return ref;
|
||
|
|
||
|
LONG r = InterlockedDecrement((LONG*)&ref);
|
||
|
if (0 == r)
|
||
|
delete(this);
|
||
|
|
||
|
return r;
|
||
|
}
|
||
|
|
||
|
int DeviceSupportedCommandStore::QueryInterface(GUID interface_guid, void **object)
|
||
|
{
|
||
|
if (NULL == object) return E_POINTER;
|
||
|
|
||
|
if (IsEqualIID(interface_guid, IFC_DeviceSupportedCommandStore))
|
||
|
*object = static_cast<ifc_devicesupportedcommandstore*>(this);
|
||
|
else
|
||
|
{
|
||
|
*object = NULL;
|
||
|
return E_NOINTERFACE;
|
||
|
}
|
||
|
|
||
|
if (NULL == *object)
|
||
|
return E_UNEXPECTED;
|
||
|
|
||
|
AddRef();
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
void DeviceSupportedCommandStore::Lock()
|
||
|
{
|
||
|
EnterCriticalSection(&lock);
|
||
|
}
|
||
|
|
||
|
void DeviceSupportedCommandStore::Unlock()
|
||
|
{
|
||
|
LeaveCriticalSection(&lock);
|
||
|
}
|
||
|
|
||
|
int
|
||
|
DeviceSupportedCommandStore::SortCallback(const void *element1, const void *element2)
|
||
|
{
|
||
|
DeviceSupportedCommand *command1, *command2;
|
||
|
|
||
|
command1 = *(DeviceSupportedCommand**)element1;
|
||
|
command2 = *(DeviceSupportedCommand**)element2;
|
||
|
|
||
|
return CompareStringA(CSTR_INVARIANT, 0, command1->GetName(), -1, command2->GetName(), -1) - 2;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
DeviceSupportedCommandStore::SearchCallback(const void *key, const void *element)
|
||
|
{
|
||
|
const char *name;
|
||
|
DeviceSupportedCommand *command;
|
||
|
|
||
|
name = (const char*)key;
|
||
|
command = *(DeviceSupportedCommand**)element;
|
||
|
|
||
|
return CompareStringA(CSTR_INVARIANT, 0, name, -1, command->GetName(), -1) - 2;
|
||
|
}
|
||
|
|
||
|
DeviceSupportedCommand *DeviceSupportedCommandStore::Find(const char *name, size_t *indexOut)
|
||
|
{
|
||
|
DeviceSupportedCommand *command;
|
||
|
int length;
|
||
|
size_t index, count;
|
||
|
|
||
|
if (NULL == name || '\0' == *name)
|
||
|
return NULL;
|
||
|
|
||
|
length = lstrlenA(name);
|
||
|
|
||
|
count = commandList.size();
|
||
|
for(index = 0; index < count; index++)
|
||
|
{
|
||
|
command = commandList[index];
|
||
|
if (CSTR_EQUAL == CompareStringA(CSTR_INVARIANT, 0, name, length, command->GetName(), -1))
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (count == index)
|
||
|
return NULL;
|
||
|
|
||
|
if (NULL != indexOut)
|
||
|
*indexOut = index;
|
||
|
|
||
|
return command;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT DeviceSupportedCommandStore::Add(const char *name, DeviceCommandFlags flags)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
DeviceSupportedCommand *command;
|
||
|
|
||
|
|
||
|
hr = DeviceSupportedCommand::CreateInstance(name, &command);
|
||
|
if (FAILED(hr))
|
||
|
return hr;
|
||
|
|
||
|
Lock();
|
||
|
|
||
|
if (NULL == Find(name, NULL))
|
||
|
{
|
||
|
command->SetFlags(flags, flags);
|
||
|
commandList.push_back(command);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
command->Release();
|
||
|
hr = S_FALSE;
|
||
|
}
|
||
|
|
||
|
Unlock();
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT DeviceSupportedCommandStore::Remove(const char *name)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
size_t index;
|
||
|
DeviceSupportedCommand *command;
|
||
|
|
||
|
Lock();
|
||
|
|
||
|
command = Find(name, &index);
|
||
|
if (NULL != command)
|
||
|
{
|
||
|
commandList.erase(commandList.begin() + index);
|
||
|
command->Release();
|
||
|
hr = S_OK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = S_FALSE;
|
||
|
}
|
||
|
|
||
|
Unlock();
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT DeviceSupportedCommandStore::RemoveAll()
|
||
|
{
|
||
|
Lock();
|
||
|
|
||
|
size_t index = commandList.size();
|
||
|
while(index--)
|
||
|
{
|
||
|
DeviceSupportedCommand *command = commandList[index];
|
||
|
command->Release();
|
||
|
}
|
||
|
|
||
|
commandList.clear();
|
||
|
|
||
|
Unlock();
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
HRESULT DeviceSupportedCommandStore::GetFlags(const char *name, DeviceCommandFlags *flagsOut)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
DeviceSupportedCommand *command;
|
||
|
|
||
|
if (NULL == flagsOut)
|
||
|
return E_POINTER;
|
||
|
|
||
|
Lock();
|
||
|
|
||
|
command = Find(name, NULL);
|
||
|
hr = (NULL != command) ? command->GetFlags(flagsOut) : E_FAIL;
|
||
|
|
||
|
Unlock();
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT DeviceSupportedCommandStore::SetFlags(const char *name, DeviceCommandFlags mask, DeviceCommandFlags value)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
DeviceSupportedCommand *command;
|
||
|
|
||
|
Lock();
|
||
|
|
||
|
command = Find(name, NULL);
|
||
|
hr = (NULL != command) ? command->SetFlags(mask, value) : E_FAIL;
|
||
|
|
||
|
Unlock();
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT DeviceSupportedCommandStore::Get(const char *name, ifc_devicesupportedcommand **command)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
|
||
|
if (NULL == command)
|
||
|
return E_POINTER;
|
||
|
|
||
|
Lock();
|
||
|
|
||
|
*command = Find(name, NULL);
|
||
|
if (NULL != *command)
|
||
|
{
|
||
|
(*command)->AddRef();
|
||
|
hr = S_OK;
|
||
|
}
|
||
|
else
|
||
|
hr = E_FAIL;
|
||
|
|
||
|
Unlock();
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT DeviceSupportedCommandStore::GetActive(ifc_devicesupportedcommand **command)
|
||
|
{
|
||
|
return E_NOTIMPL;
|
||
|
}
|
||
|
|
||
|
HRESULT DeviceSupportedCommandStore::Enumerate(ifc_devicesupportedcommandenum **enumerator)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
|
||
|
Lock();
|
||
|
hr = DeviceSupportedCommandEnum::CreateInstance(
|
||
|
reinterpret_cast<ifc_devicesupportedcommand**>(commandList.size() ? &commandList.at(0) : nullptr),
|
||
|
commandList.size(),
|
||
|
reinterpret_cast<DeviceSupportedCommandEnum**>(enumerator));
|
||
|
|
||
|
|
||
|
Unlock();
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT DeviceSupportedCommandStore::Clone(ifc_devicesupportedcommandstore **instance, BOOL fullCopy)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
DeviceSupportedCommandStore *clone;
|
||
|
DeviceSupportedCommand *command;
|
||
|
|
||
|
if (NULL == instance)
|
||
|
return E_POINTER;
|
||
|
|
||
|
Lock();
|
||
|
|
||
|
hr = CreateInstance(&clone);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
size_t index, count;
|
||
|
|
||
|
count = commandList.size();
|
||
|
|
||
|
for(index = 0; index < count; index++)
|
||
|
{
|
||
|
command = commandList[index];
|
||
|
if (FALSE != fullCopy)
|
||
|
{
|
||
|
DeviceSupportedCommand *commandClone;
|
||
|
|
||
|
hr = command->Clone(&commandClone);
|
||
|
if(SUCCEEDED(hr))
|
||
|
command = commandClone;
|
||
|
else
|
||
|
break;
|
||
|
}
|
||
|
else
|
||
|
command->AddRef();
|
||
|
|
||
|
clone->commandList.push_back(command);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Unlock();
|
||
|
|
||
|
if (FAILED(hr) && NULL != clone)
|
||
|
{
|
||
|
clone->Release();
|
||
|
*instance = NULL;
|
||
|
}
|
||
|
else
|
||
|
*instance = clone;
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
#define CBCLASS DeviceSupportedCommandStore
|
||
|
START_DISPATCH;
|
||
|
CB(ADDREF, AddRef)
|
||
|
CB(RELEASE, Release)
|
||
|
CB(QUERYINTERFACE, QueryInterface)
|
||
|
CB(API_ADD, Add)
|
||
|
CB(API_REMOVE, Remove)
|
||
|
CB(API_REMOVEALL, RemoveAll)
|
||
|
CB(API_GETFLAGS, GetFlags)
|
||
|
CB(API_SETFLAGS, SetFlags)
|
||
|
CB(API_GET, Get)
|
||
|
CB(API_GETACTIVE, GetActive)
|
||
|
CB(API_ENUMERATE, Enumerate)
|
||
|
CB(API_CLONE, Clone)
|
||
|
END_DISPATCH;
|
||
|
#undef CBCLASS
|