1 /* 2 Generic device list for use in drivers. 3 Copyright (C) 2008 Michael Lotz <mmlr@mlotz.ch> 4 Distributed under the terms of the MIT license. 5 */ 6 #include "DeviceList.h" 7 #include <util/kernel_cpp.h> 8 #include <stdlib.h> 9 #include <string.h> 10 #include <new> 11 12 struct device_list_entry { 13 char * name; 14 void * device; 15 device_list_entry * next; 16 }; 17 18 19 DeviceList::DeviceList() 20 : fDeviceList(NULL), 21 fDeviceCount(0), 22 fPublishList(NULL) 23 { 24 } 25 26 27 DeviceList::~DeviceList() 28 { 29 _FreePublishList(); 30 31 device_list_entry *current = fDeviceList; 32 while (current) { 33 device_list_entry *next = current->next; 34 free(current->name); 35 delete current; 36 current = next; 37 } 38 } 39 40 41 status_t 42 DeviceList::AddDevice(const char *name, void *device) 43 { 44 device_list_entry *entry = new(std::nothrow) device_list_entry; 45 if (entry == NULL) 46 return B_NO_MEMORY; 47 48 entry->name = strdup(name); 49 if (entry->name == NULL) { 50 delete entry; 51 return B_NO_MEMORY; 52 } 53 54 entry->device = device; 55 entry->next = NULL; 56 57 if (fDeviceList == NULL) 58 fDeviceList = entry; 59 else { 60 device_list_entry *current = fDeviceList; 61 while (current) { 62 if (current->next == NULL) { 63 current->next = entry; 64 break; 65 } 66 67 current = current->next; 68 } 69 } 70 71 fDeviceCount++; 72 return B_OK; 73 } 74 75 76 status_t 77 DeviceList::RemoveDevice(const char *name, void *device) 78 { 79 if (name == NULL && device == NULL) 80 return B_BAD_VALUE; 81 82 device_list_entry *previous = NULL; 83 device_list_entry *current = fDeviceList; 84 while (current) { 85 if ((name != NULL && strcmp(current->name, name) == 0) 86 || (device != NULL && current->device == device)) { 87 if (previous == NULL) 88 fDeviceList = current->next; 89 else 90 previous->next = current->next; 91 92 free(current->name); 93 delete current; 94 fDeviceCount--; 95 return B_OK; 96 } 97 98 previous = current; 99 current = current->next; 100 } 101 102 return B_ENTRY_NOT_FOUND; 103 } 104 105 106 void * 107 DeviceList::FindDevice(const char *name, void *device) 108 { 109 if (name == NULL && device == NULL) 110 return NULL; 111 112 device_list_entry *current = fDeviceList; 113 while (current) { 114 if ((name != NULL && strcmp(current->name, name) == 0) 115 || (device != NULL && current->device == device)) 116 return current->device; 117 118 current = current->next; 119 } 120 121 return NULL; 122 } 123 124 125 int32 126 DeviceList::CountDevices(const char *baseName) 127 { 128 if (baseName == NULL) 129 return fDeviceCount; 130 131 int32 count = 0; 132 int32 baseNameLength = strlen(baseName); 133 device_list_entry *current = fDeviceList; 134 while (current) { 135 if (strncmp(current->name, baseName, baseNameLength) == 0) 136 count++; 137 138 current = current->next; 139 } 140 141 return count; 142 } 143 144 145 void * 146 DeviceList::DeviceAt(int32 index) 147 { 148 device_list_entry *current = fDeviceList; 149 while (current) { 150 if (index-- == 0) 151 return current->device; 152 153 current = current->next; 154 } 155 156 return NULL; 157 } 158 159 160 const char ** 161 DeviceList::PublishDevices() 162 { 163 _FreePublishList(); 164 165 fPublishList = (char **)malloc((fDeviceCount + 1) * sizeof(char *)); 166 if (fPublishList == NULL) 167 return NULL; 168 169 int32 index = 0; 170 device_list_entry *current = fDeviceList; 171 while (current) { 172 fPublishList[index++] = strdup(current->name); 173 current = current->next; 174 } 175 176 fPublishList[index] = NULL; 177 return (const char **)fPublishList; 178 } 179 180 181 void 182 DeviceList::_FreePublishList() 183 { 184 if (fPublishList == NULL) 185 return; 186 187 int32 index = 0; 188 while (fPublishList[index] != NULL) { 189 free(fPublishList[index]); 190 index++; 191 } 192 193 free(fPublishList); 194 fPublishList = NULL; 195 } 196