aboutsummaryrefslogtreecommitdiff
path: root/Src/devices/deviceObjectStore.cpp
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/devices/deviceObjectStore.cpp
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/devices/deviceObjectStore.cpp')
-rw-r--r--Src/devices/deviceObjectStore.cpp356
1 files changed, 356 insertions, 0 deletions
diff --git a/Src/devices/deviceObjectStore.cpp b/Src/devices/deviceObjectStore.cpp
new file mode 100644
index 00000000..075270cd
--- /dev/null
+++ b/Src/devices/deviceObjectStore.cpp
@@ -0,0 +1,356 @@
+#include "main.h"
+#include "./deviceObjectStore.h"
+#include <algorithm>
+
+template <typename T>
+struct GenericComparator
+{
+ typedef const char* (T::*GETTER)();
+ GETTER m_getterFunc;
+ const char *m_data;
+ GenericComparator(GETTER getterFunc, const char *data)
+ {
+ m_getterFunc = getterFunc;
+ m_data = data;
+ }
+ bool operator()(const T& obj)
+ {
+ return strcmp(((obj).*m_getterFunc)(), m_data) == 0;
+ }
+};
+
+static ifc_deviceobject *
+DeviceObjectStore_FindLocation(const char *name, std::vector<ifc_deviceobject*> &list)
+{
+ if (FALSE != IS_STRING_EMPTY(name))
+ return NULL;
+
+ //size_t name_length;
+ //name_length = lstrlenA(name) * sizeof(char);
+ //
+ //return (ifc_deviceobject*)bsearch_s(name, buffer, length,
+ // sizeof(ifc_deviceobject*),
+ // DeviceObjectStore_FindComparer,
+ // (void*)name_length);
+
+ //auto it = std::find_if(list.begin(), list.begin(), GenericComparator<ifc_deviceobject>(&ifc_deviceobject::GetName, name));
+
+ const auto it = std::find_if(list.begin(), list.end(),
+ [&](ifc_deviceobject* upT) -> bool
+ {
+ return strcmp(upT->GetName(), name) == 0;
+ }
+ );
+ if (it != list.end())
+ {
+ return *it;
+ }
+ return nullptr;
+}
+
+int DeviceObjectComparer(const char* arg1, const char* arg2)
+{
+ return stricmp(arg1, arg2);
+}
+
+
+// Created for std::sort
+static bool DeviceObjectStore_SortComparer_V2(const void* element1, const void* element2)
+{
+ //return DeviceObjectStore_SortComparer(element1, element2) < 0;
+ const char* name1 = (((ifc_deviceobject*)element1))->GetName();
+ const char* name2 = (((ifc_deviceobject*)element2))->GetName();
+ return DeviceObjectComparer(name1, name2) < 0;
+}
+
+static ifc_deviceobject *
+DeviceObjectStore_FindUnsortedObject(const char *name, ifc_deviceobject **objects, size_t count)
+{
+ size_t index;
+ size_t length;
+
+ if (0 == count)
+ return NULL;
+
+ length = lstrlenA(name) * sizeof(char);
+
+ for(index = 0; index < count; index++)
+ {
+ //if (0 == DeviceObjectStore_NameCompare(name, length, objects[index]->GetName()))
+ if(0 == DeviceObjectComparer(name, objects[index]->GetName()))
+ return objects[index];
+ }
+
+ return NULL;
+}
+
+
+DeviceObjectStore::DeviceObjectStore(DeviceObjectCallback addCallback,
+ DeviceObjectCallback _removeCallback, void *callbackData)
+{
+ this->addCallback = addCallback;
+ this->removeCallback = _removeCallback;
+ this->callbackData = callbackData;
+
+ InitializeCriticalSection(&lock);
+}
+
+DeviceObjectStore::~DeviceObjectStore()
+{
+ RemoveAll();
+ DeleteCriticalSection(&lock);
+}
+
+void DeviceObjectStore::Lock()
+{
+ EnterCriticalSection(&lock);
+}
+
+void DeviceObjectStore::Unlock()
+{
+ LeaveCriticalSection(&lock);
+}
+
+CRITICAL_SECTION *DeviceObjectStore::GetLock()
+{
+ return &lock;
+}
+
+HRESULT DeviceObjectStore::Add(ifc_deviceobject *object)
+{
+ const char *name;
+
+ if (NULL == object)
+ return E_POINTER;
+
+ name = object->GetName();
+
+ if (NULL == name || '\0' == *name)
+ return E_INVALIDARG;
+
+ return (1 == AddRange(&object, 1)) ? S_OK : S_FALSE;
+}
+
+size_t DeviceObjectStore::AddRange(ifc_deviceobject **objects, size_t count)
+{
+ const char *name;
+ size_t index, registered, added;
+ ifc_deviceobject *object;
+
+
+ if (NULL == objects || 0 == count)
+ return 0;
+
+ Lock();
+
+ added = 0;
+ registered = list.size();
+
+ for(index = 0; index < count; index++)
+ {
+ object = objects[index];
+ if (NULL != object)
+ {
+ name = object->GetName();
+
+ if (NULL != name &&
+ '\0' != *name &&
+ NULL == DeviceObjectStore_FindLocation(name, list))
+ //&& NULL == DeviceObjectStore_FindUnsortedObject(name, buffer + registered, added))
+ {
+ list.push_back(object);
+ object->AddRef();
+
+ if (NULL != addCallback)
+ this->addCallback(this, object, callbackData);
+
+ added++;
+ }
+ }
+ }
+
+ if (0 != added)
+ {
+ //qsort(list.first(), list.size(),
+ // sizeof(ifc_deviceobject**),
+ // DeviceObjectStore_SortComparer);
+
+ std::sort(list.begin(), list.end(), DeviceObjectStore_SortComparer_V2);
+ }
+
+ Unlock();
+
+ return added;
+}
+
+size_t DeviceObjectStore::AddIndirect(const char **names, size_t count, DeviceObjectCreator callback, void *user)
+{
+ size_t index, registered, added;
+ ifc_deviceobject *object;
+
+ if (NULL == names || 0 == count || NULL == callback)
+ return 0;
+
+ Lock();
+
+ added = 0;
+ registered = list.size();
+
+
+ for(index = 0; index < count; index++)
+ {
+ const char *name = names[index];
+
+ if (NULL != name &&
+ '\0' != *name &&
+ NULL == DeviceObjectStore_FindLocation(name, list) )
+ //&& NULL == DeviceObjectStore_FindUnsortedObject(name, buffer + registered, added))
+ {
+ object = callback(name, user);
+ if (NULL != object)
+ {
+ list.push_back(object);
+
+ if (NULL != addCallback)
+ this->addCallback(this, object, callbackData);
+
+ added++;
+ }
+ }
+ }
+
+ if (0 != added)
+ {
+ //qsort(list.first(), list.size(),
+ // sizeof(ifc_deviceobject**),
+ // DeviceObjectStore_SortComparer);
+
+ std::sort(list.begin(), list.end(), DeviceObjectStore_SortComparer_V2);
+ }
+
+ Unlock();
+
+ return added;
+}
+
+HRESULT DeviceObjectStore::Remove(const char *name)
+{
+ HRESULT hr = hr = S_FALSE;
+
+ if (NULL == name || '\0' == *name)
+ return E_INVALIDARG;
+
+ Lock();
+
+ //object_ptr = DeviceObjectStore_FindLocation(name, list);
+ //if (NULL != object_ptr)
+ //{
+ // hr = S_OK;
+
+ // ifc_deviceobject *object = *object_ptr;
+
+ // size_t index = (size_t)(object_ptr - buffer);
+ // list.erase(list.begin() + index);
+
+ // if (NULL != removeCallback)
+ // removeCallback(this, object, callbackData);
+
+ // object->Release();
+ //}
+ //else
+ //{
+ // hr = S_FALSE;
+ //}
+
+ const auto it = std::find_if(list.begin(), list.end(),
+ [&](ifc_deviceobject* upT) -> bool
+ {
+ return strcmp(upT->GetName(), name) == 0;
+ }
+ );
+
+ if (it != list.end())
+ {
+ ifc_deviceobject* object = *it;
+ list.erase(it);
+ if (NULL != removeCallback)
+ {
+ removeCallback(this, object, callbackData);
+ }
+ object->Release();
+ hr = S_OK;
+ }
+ Unlock();
+
+ return hr;
+}
+
+void DeviceObjectStore::RemoveAll()
+{
+ Lock();
+
+ size_t index = list.size();
+ while(index--)
+ {
+ ifc_deviceobject *object = list[index];
+ if (NULL != removeCallback)
+ removeCallback(this, object, callbackData);
+
+ object->Release();
+ }
+
+ list.clear();
+ Unlock();
+}
+
+HRESULT DeviceObjectStore::Find(const char *name, ifc_deviceobject **object)
+{
+ HRESULT hr;
+ ifc_deviceobject *object_ptr;
+
+ if (NULL == name || '\0' == *name)
+ return E_INVALIDARG;
+
+ if (NULL == object)
+ return E_POINTER;
+
+ Lock();
+
+ object_ptr = DeviceObjectStore_FindLocation(name, list);
+
+ if (NULL != object_ptr)
+ {
+ if (NULL != object)
+ {
+ *object = object_ptr;
+ (*object)->AddRef();
+ }
+ hr = S_OK;
+ }
+ else
+ {
+ if (NULL != object)
+ *object = NULL;
+ hr = S_FALSE;
+ }
+
+ Unlock();
+
+ return hr;
+}
+
+HRESULT DeviceObjectStore::Enumerate(DeviceObjectEnum **enumerator)
+{
+ HRESULT hr;
+
+ if (NULL == enumerator)
+ return E_POINTER;
+
+ Lock();
+
+ hr = DeviceObjectEnum::CreateInstance(list.size() ? &list.at(0) : nullptr, list.size(), enumerator);
+
+ Unlock();
+
+ return hr;
+}