/* Generic device list for use in drivers. Copyright (C) 2008 Michael Lotz Distributed under the terms of the MIT license. */ #include "DeviceList.h" #include #include #include #include struct device_list_entry { char * name; void * device; device_list_entry * next; }; DeviceList::DeviceList() : fDeviceList(NULL), fDeviceCount(0), fPublishList(NULL) { } DeviceList::~DeviceList() { _FreePublishList(); device_list_entry *current = fDeviceList; while (current) { device_list_entry *next = current->next; free(current->name); delete current; current = next; } } status_t DeviceList::AddDevice(const char *name, void *device) { device_list_entry *entry = new(std::nothrow) device_list_entry; if (entry == NULL) return B_NO_MEMORY; entry->name = strdup(name); if (entry->name == NULL) { delete entry; return B_NO_MEMORY; } entry->device = device; entry->next = NULL; if (fDeviceList == NULL) fDeviceList = entry; else { device_list_entry *current = fDeviceList; while (current) { if (current->next == NULL) { current->next = entry; break; } current = current->next; } } fDeviceCount++; return B_OK; } status_t DeviceList::RemoveDevice(const char *name, void *device) { if (name == NULL && device == NULL) return B_BAD_VALUE; device_list_entry *previous = NULL; device_list_entry *current = fDeviceList; while (current) { if ((name != NULL && strcmp(current->name, name) == 0) || (device != NULL && current->device == device)) { if (previous == NULL) fDeviceList = current->next; else previous->next = current->next; free(current->name); delete current; fDeviceCount--; return B_OK; } previous = current; current = current->next; } return B_ENTRY_NOT_FOUND; } void * DeviceList::FindDevice(const char *name, void *device) { if (name == NULL && device == NULL) return NULL; device_list_entry *current = fDeviceList; while (current) { if ((name != NULL && strcmp(current->name, name) == 0) || (device != NULL && current->device == device)) return current->device; current = current->next; } return NULL; } int32 DeviceList::CountDevices(const char *baseName) { if (baseName == NULL) return fDeviceCount; int32 count = 0; int32 baseNameLength = strlen(baseName); device_list_entry *current = fDeviceList; while (current) { if (strncmp(current->name, baseName, baseNameLength) == 0) count++; current = current->next; } return count; } void * DeviceList::DeviceAt(int32 index) { device_list_entry *current = fDeviceList; while (current) { if (index-- == 0) return current->device; current = current->next; } return NULL; } const char ** DeviceList::PublishDevices() { _FreePublishList(); fPublishList = (char **)malloc((fDeviceCount + 1) * sizeof(char *)); if (fPublishList == NULL) return NULL; int32 index = 0; device_list_entry *current = fDeviceList; while (current) { fPublishList[index++] = strdup(current->name); current = current->next; } fPublishList[index] = NULL; return (const char **)fPublishList; } void DeviceList::_FreePublishList() { if (fPublishList == NULL) return; int32 index = 0; while (fPublishList[index] != NULL) { free(fPublishList[index]); index++; } free(fPublishList); fPublishList = NULL; }