1
0

deviceObjectStore.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. #include "main.h"
  2. #include "./deviceObjectStore.h"
  3. #include <algorithm>
  4. template <typename T>
  5. struct GenericComparator
  6. {
  7. typedef const char* (T::*GETTER)();
  8. GETTER m_getterFunc;
  9. const char *m_data;
  10. GenericComparator(GETTER getterFunc, const char *data)
  11. {
  12. m_getterFunc = getterFunc;
  13. m_data = data;
  14. }
  15. bool operator()(const T& obj)
  16. {
  17. return strcmp(((obj).*m_getterFunc)(), m_data) == 0;
  18. }
  19. };
  20. static ifc_deviceobject *
  21. DeviceObjectStore_FindLocation(const char *name, std::vector<ifc_deviceobject*> &list)
  22. {
  23. if (FALSE != IS_STRING_EMPTY(name))
  24. return NULL;
  25. //size_t name_length;
  26. //name_length = lstrlenA(name) * sizeof(char);
  27. //
  28. //return (ifc_deviceobject*)bsearch_s(name, buffer, length,
  29. // sizeof(ifc_deviceobject*),
  30. // DeviceObjectStore_FindComparer,
  31. // (void*)name_length);
  32. //auto it = std::find_if(list.begin(), list.begin(), GenericComparator<ifc_deviceobject>(&ifc_deviceobject::GetName, name));
  33. const auto it = std::find_if(list.begin(), list.end(),
  34. [&](ifc_deviceobject* upT) -> bool
  35. {
  36. return strcmp(upT->GetName(), name) == 0;
  37. }
  38. );
  39. if (it != list.end())
  40. {
  41. return *it;
  42. }
  43. return nullptr;
  44. }
  45. int DeviceObjectComparer(const char* arg1, const char* arg2)
  46. {
  47. return stricmp(arg1, arg2);
  48. }
  49. // Created for std::sort
  50. static bool DeviceObjectStore_SortComparer_V2(const void* element1, const void* element2)
  51. {
  52. //return DeviceObjectStore_SortComparer(element1, element2) < 0;
  53. const char* name1 = (((ifc_deviceobject*)element1))->GetName();
  54. const char* name2 = (((ifc_deviceobject*)element2))->GetName();
  55. return DeviceObjectComparer(name1, name2) < 0;
  56. }
  57. static ifc_deviceobject *
  58. DeviceObjectStore_FindUnsortedObject(const char *name, ifc_deviceobject **objects, size_t count)
  59. {
  60. size_t index;
  61. size_t length;
  62. if (0 == count)
  63. return NULL;
  64. length = lstrlenA(name) * sizeof(char);
  65. for(index = 0; index < count; index++)
  66. {
  67. //if (0 == DeviceObjectStore_NameCompare(name, length, objects[index]->GetName()))
  68. if(0 == DeviceObjectComparer(name, objects[index]->GetName()))
  69. return objects[index];
  70. }
  71. return NULL;
  72. }
  73. DeviceObjectStore::DeviceObjectStore(DeviceObjectCallback addCallback,
  74. DeviceObjectCallback _removeCallback, void *callbackData)
  75. {
  76. this->addCallback = addCallback;
  77. this->removeCallback = _removeCallback;
  78. this->callbackData = callbackData;
  79. InitializeCriticalSection(&lock);
  80. }
  81. DeviceObjectStore::~DeviceObjectStore()
  82. {
  83. RemoveAll();
  84. DeleteCriticalSection(&lock);
  85. }
  86. void DeviceObjectStore::Lock()
  87. {
  88. EnterCriticalSection(&lock);
  89. }
  90. void DeviceObjectStore::Unlock()
  91. {
  92. LeaveCriticalSection(&lock);
  93. }
  94. CRITICAL_SECTION *DeviceObjectStore::GetLock()
  95. {
  96. return &lock;
  97. }
  98. HRESULT DeviceObjectStore::Add(ifc_deviceobject *object)
  99. {
  100. const char *name;
  101. if (NULL == object)
  102. return E_POINTER;
  103. name = object->GetName();
  104. if (NULL == name || '\0' == *name)
  105. return E_INVALIDARG;
  106. return (1 == AddRange(&object, 1)) ? S_OK : S_FALSE;
  107. }
  108. size_t DeviceObjectStore::AddRange(ifc_deviceobject **objects, size_t count)
  109. {
  110. const char *name;
  111. size_t index, registered, added;
  112. ifc_deviceobject *object;
  113. if (NULL == objects || 0 == count)
  114. return 0;
  115. Lock();
  116. added = 0;
  117. registered = list.size();
  118. for(index = 0; index < count; index++)
  119. {
  120. object = objects[index];
  121. if (NULL != object)
  122. {
  123. name = object->GetName();
  124. if (NULL != name &&
  125. '\0' != *name &&
  126. NULL == DeviceObjectStore_FindLocation(name, list))
  127. //&& NULL == DeviceObjectStore_FindUnsortedObject(name, buffer + registered, added))
  128. {
  129. list.push_back(object);
  130. object->AddRef();
  131. if (NULL != addCallback)
  132. this->addCallback(this, object, callbackData);
  133. added++;
  134. }
  135. }
  136. }
  137. if (0 != added)
  138. {
  139. //qsort(list.first(), list.size(),
  140. // sizeof(ifc_deviceobject**),
  141. // DeviceObjectStore_SortComparer);
  142. std::sort(list.begin(), list.end(), DeviceObjectStore_SortComparer_V2);
  143. }
  144. Unlock();
  145. return added;
  146. }
  147. size_t DeviceObjectStore::AddIndirect(const char **names, size_t count, DeviceObjectCreator callback, void *user)
  148. {
  149. size_t index, registered, added;
  150. ifc_deviceobject *object;
  151. if (NULL == names || 0 == count || NULL == callback)
  152. return 0;
  153. Lock();
  154. added = 0;
  155. registered = list.size();
  156. for(index = 0; index < count; index++)
  157. {
  158. const char *name = names[index];
  159. if (NULL != name &&
  160. '\0' != *name &&
  161. NULL == DeviceObjectStore_FindLocation(name, list) )
  162. //&& NULL == DeviceObjectStore_FindUnsortedObject(name, buffer + registered, added))
  163. {
  164. object = callback(name, user);
  165. if (NULL != object)
  166. {
  167. list.push_back(object);
  168. if (NULL != addCallback)
  169. this->addCallback(this, object, callbackData);
  170. added++;
  171. }
  172. }
  173. }
  174. if (0 != added)
  175. {
  176. //qsort(list.first(), list.size(),
  177. // sizeof(ifc_deviceobject**),
  178. // DeviceObjectStore_SortComparer);
  179. std::sort(list.begin(), list.end(), DeviceObjectStore_SortComparer_V2);
  180. }
  181. Unlock();
  182. return added;
  183. }
  184. HRESULT DeviceObjectStore::Remove(const char *name)
  185. {
  186. HRESULT hr = hr = S_FALSE;
  187. if (NULL == name || '\0' == *name)
  188. return E_INVALIDARG;
  189. Lock();
  190. //object_ptr = DeviceObjectStore_FindLocation(name, list);
  191. //if (NULL != object_ptr)
  192. //{
  193. // hr = S_OK;
  194. // ifc_deviceobject *object = *object_ptr;
  195. // size_t index = (size_t)(object_ptr - buffer);
  196. // list.erase(list.begin() + index);
  197. // if (NULL != removeCallback)
  198. // removeCallback(this, object, callbackData);
  199. // object->Release();
  200. //}
  201. //else
  202. //{
  203. // hr = S_FALSE;
  204. //}
  205. const auto it = std::find_if(list.begin(), list.end(),
  206. [&](ifc_deviceobject* upT) -> bool
  207. {
  208. return strcmp(upT->GetName(), name) == 0;
  209. }
  210. );
  211. if (it != list.end())
  212. {
  213. ifc_deviceobject* object = *it;
  214. list.erase(it);
  215. if (NULL != removeCallback)
  216. {
  217. removeCallback(this, object, callbackData);
  218. }
  219. object->Release();
  220. hr = S_OK;
  221. }
  222. Unlock();
  223. return hr;
  224. }
  225. void DeviceObjectStore::RemoveAll()
  226. {
  227. Lock();
  228. size_t index = list.size();
  229. while(index--)
  230. {
  231. ifc_deviceobject *object = list[index];
  232. if (NULL != removeCallback)
  233. removeCallback(this, object, callbackData);
  234. object->Release();
  235. }
  236. list.clear();
  237. Unlock();
  238. }
  239. HRESULT DeviceObjectStore::Find(const char *name, ifc_deviceobject **object)
  240. {
  241. HRESULT hr;
  242. ifc_deviceobject *object_ptr;
  243. if (NULL == name || '\0' == *name)
  244. return E_INVALIDARG;
  245. if (NULL == object)
  246. return E_POINTER;
  247. Lock();
  248. object_ptr = DeviceObjectStore_FindLocation(name, list);
  249. if (NULL != object_ptr)
  250. {
  251. if (NULL != object)
  252. {
  253. *object = object_ptr;
  254. (*object)->AddRef();
  255. }
  256. hr = S_OK;
  257. }
  258. else
  259. {
  260. if (NULL != object)
  261. *object = NULL;
  262. hr = S_FALSE;
  263. }
  264. Unlock();
  265. return hr;
  266. }
  267. HRESULT DeviceObjectStore::Enumerate(DeviceObjectEnum **enumerator)
  268. {
  269. HRESULT hr;
  270. if (NULL == enumerator)
  271. return E_POINTER;
  272. Lock();
  273. hr = DeviceObjectEnum::CreateInstance(list.size() ? &list.at(0) : nullptr, list.size(), enumerator);
  274. Unlock();
  275. return hr;
  276. }