1// DriverSettings.cpp 2 3#include <new> 4#include <stdlib.h> 5#include <string.h> 6 7#include <driver_settings.h> 8 9#include <Referenceable.h> 10 11#include "DriverSettings.h" 12#include "String.h" 13 14// The parameter values that shall be evaluated to true. 15static const char* kTrueValueStrings[] 16 = { "1", "true", "yes", "on", "enable", "enabled" }; 17static const int32 kTrueValueStringCount 18 = sizeof(kTrueValueStrings) / sizeof(const char*); 19 20 21// #pragma mark - 22// #pragma mark ----- DriverParameterIterator ----- 23 24// Delegate 25class DriverParameterIterator::Delegate : public BReferenceable { 26public: 27 Delegate() : BReferenceable() {} 28 virtual ~Delegate() {} 29 30 virtual Delegate* Clone() const = 0; 31 32 virtual bool HasNext() const = 0; 33 virtual bool GetNext(DriverParameter* parameter) = 0; 34}; 35 36// constructor 37DriverParameterIterator::DriverParameterIterator() 38 : fDelegate(NULL) 39{ 40} 41 42// constructor 43DriverParameterIterator::DriverParameterIterator(Delegate* delegate) 44 : fDelegate(delegate) 45{ 46} 47 48// copy constructor 49DriverParameterIterator::DriverParameterIterator( 50 const DriverParameterIterator& other) 51 : fDelegate(NULL) 52{ 53 _SetTo(other.fDelegate, true); 54} 55 56// destructor 57DriverParameterIterator::~DriverParameterIterator() 58{ 59 _SetTo(NULL, false); 60} 61 62// HasNext 63bool 64DriverParameterIterator::HasNext() const 65{ 66 return (fDelegate ? fDelegate->HasNext() : false); 67} 68 69// GetNext 70bool 71DriverParameterIterator::GetNext(DriverParameter* parameter) 72{ 73 if (!fDelegate) 74 return false; 75 if (fDelegate->CountReferences() > 1) { 76 Delegate* clone = fDelegate->Clone(); 77 if (!clone) 78 return false; 79 _SetTo(clone, false); 80 } 81 return fDelegate->GetNext(parameter); 82} 83 84// = 85DriverParameterIterator& 86DriverParameterIterator::operator=(const DriverParameterIterator& other) 87{ 88 _SetTo(other.fDelegate, true); 89 return *this; 90} 91 92// _SetTo 93void 94DriverParameterIterator::_SetTo(Delegate* delegate, bool addReference) 95{ 96 if (fDelegate) 97 fDelegate->ReleaseReference(); 98 fDelegate = delegate; 99 if (fDelegate && addReference) 100 fDelegate->AcquireReference(); 101} 102 103 104// #pragma mark - 105// #pragma mark ----- DriverParameterContainer ----- 106 107// Iterator 108class DriverParameterContainer::Iterator 109 : public DriverParameterIterator::Delegate { 110public: 111 Iterator(const driver_parameter* parameters, int32 count) 112 : Delegate(), 113 fParameters(parameters), 114 fCount(count) 115 { 116 } 117 118 virtual ~Iterator() 119 { 120 } 121 122 virtual Delegate* Clone() const 123 { 124 return new(std::nothrow) Iterator(fParameters, fCount); 125 } 126 127 virtual bool HasNext() const 128 { 129 return (fParameters && fCount > 0); 130 } 131 132 virtual bool GetNext(DriverParameter* parameter) 133 { 134 if (fParameters && fCount > 0) { 135 if (parameter) 136 parameter->SetTo(fParameters); 137 fParameters++; 138 fCount--; 139 return true; 140 } 141 return false; 142 } 143 144private: 145 const driver_parameter* fParameters; 146 int32 fCount; 147}; 148 149// NameIterator 150class DriverParameterContainer::NameIterator 151 : public DriverParameterIterator::Delegate { 152public: 153 NameIterator(const driver_parameter* parameters, int32 count, 154 const char* name) 155 : Delegate(), 156 fParameters(parameters), 157 fCount(count), 158 fName(name) 159 { 160 _FindNext(false); 161 } 162 163 virtual ~NameIterator() 164 { 165 } 166 167 virtual Delegate* Clone() const 168 { 169 return new(std::nothrow) NameIterator(fParameters, fCount, 170 fName.GetString()); 171 } 172 173 virtual bool HasNext() const 174 { 175 return (fParameters && fCount > 0); 176 } 177 178 virtual bool GetNext(DriverParameter* parameter) 179 { 180 if (fParameters && fCount > 0) { 181 if (parameter) 182 parameter->SetTo(fParameters); 183 _FindNext(true); 184 return true; 185 } 186 return false; 187 } 188 189private: 190 void _FindNext(bool skipCurrent) 191 { 192 if (!fParameters || fCount < 1) 193 return; 194 if (skipCurrent) { 195 fParameters++; 196 fCount--; 197 } 198 while (fCount > 0 && fName != fParameters->name) { 199 fParameters++; 200 fCount--; 201 } 202 } 203 204private: 205 const driver_parameter* fParameters; 206 int32 fCount; 207 String fName; 208}; 209 210// constructor 211DriverParameterContainer::DriverParameterContainer() 212{ 213} 214 215// destructor 216DriverParameterContainer::~DriverParameterContainer() 217{ 218} 219 220// CountParameters 221int32 222DriverParameterContainer::CountParameters() const 223{ 224 int32 count; 225 return (GetParametersAndCount(&count) ? count : 0); 226 227} 228 229// GetParameters 230const driver_parameter* 231DriverParameterContainer::GetParameters() const 232{ 233 int32 count; 234 return GetParametersAndCount(&count); 235} 236 237// GetParameterAt 238bool 239DriverParameterContainer::GetParameterAt(int32 index, 240 DriverParameter* parameter) const 241{ 242 int32 count; 243 if (const driver_parameter* parameters = GetParametersAndCount(&count)) { 244 if (index >= 0 && index < count) { 245 if (parameter) 246 parameter->SetTo(parameters + index); 247 return true; 248 } 249 } 250 return false; 251} 252 253// FindParameter 254bool 255DriverParameterContainer::FindParameter(const char* name, 256 DriverParameter* parameter) const 257{ 258 if (!name) 259 return false; 260 int32 count; 261 if (const driver_parameter* parameters = GetParametersAndCount(&count)) { 262 for (int32 i = 0; i < count; i++) { 263 if (strcmp(name, parameters[i].name) == 0) { 264 if (parameter) 265 parameter->SetTo(parameters + i); 266 return true; 267 } 268 } 269 } 270 return false; 271} 272 273// GetParameterIterator 274DriverParameterIterator 275DriverParameterContainer::GetParameterIterator() const 276{ 277 int32 count; 278 if (const driver_parameter* parameters = GetParametersAndCount(&count)) { 279 if (Iterator* iterator = new(std::nothrow) Iterator(parameters, count)) 280 return DriverParameterIterator(iterator); 281 } 282 return DriverParameterIterator(); 283} 284 285// GetParameterIterator 286DriverParameterIterator 287DriverParameterContainer::GetParameterIterator(const char* name) const 288{ 289 int32 count; 290 if (const driver_parameter* parameters = GetParametersAndCount(&count)) { 291 NameIterator* iterator = new(std::nothrow) NameIterator(parameters, count, 292 name); 293 if (iterator) 294 return DriverParameterIterator(iterator); 295 } 296 return DriverParameterIterator(); 297} 298 299// GetParameterValue 300const char* 301DriverParameterContainer::GetParameterValue(const char* name, 302 const char* unknownValue, const char* noValue) const 303{ 304 DriverParameter parameter; 305 if (!FindParameter(name, ¶meter)) 306 return unknownValue; 307 return parameter.ValueAt(0, noValue); 308} 309 310// GetBoolParameterValue 311bool 312DriverParameterContainer::GetBoolParameterValue(const char* name, 313 bool unknownValue, bool noValue) const 314{ 315 DriverParameter parameter; 316 if (!FindParameter(name, ¶meter)) 317 return unknownValue; 318 return parameter.BoolValueAt(0, noValue); 319} 320 321// GetInt32ParameterValue 322int32 323DriverParameterContainer::GetInt32ParameterValue(const char* name, 324 int32 unknownValue, int32 noValue) const 325{ 326 DriverParameter parameter; 327 if (!FindParameter(name, ¶meter)) 328 return unknownValue; 329 return parameter.Int32ValueAt(0, noValue); 330} 331 332// GetInt64ParameterValue 333int64 334DriverParameterContainer::GetInt64ParameterValue(const char* name, 335 int64 unknownValue, int64 noValue) const 336{ 337 DriverParameter parameter; 338 if (!FindParameter(name, ¶meter)) 339 return unknownValue; 340 return parameter.Int64ValueAt(0, noValue); 341} 342 343 344// #pragma mark - 345// #pragma mark ----- DriverSettings ----- 346 347// constructor 348DriverSettings::DriverSettings() 349 : DriverParameterContainer(), 350 fSettingsHandle(NULL), 351 fSettings(NULL) 352{ 353} 354 355// destructor 356DriverSettings::~DriverSettings() 357{ 358 Unset(); 359} 360 361// Load 362status_t 363DriverSettings::Load(const char* driverName) 364{ 365 Unset(); 366 fSettingsHandle = load_driver_settings(driverName); 367 if (!fSettingsHandle) 368 return B_ENTRY_NOT_FOUND; 369 fSettings = get_driver_settings(fSettingsHandle); 370 if (!fSettings) { 371 Unset(); 372 return B_ERROR; 373 } 374 return B_OK; 375} 376 377// Unset 378void 379DriverSettings::Unset() 380{ 381 if (fSettingsHandle) 382 unload_driver_settings(fSettingsHandle); 383 fSettingsHandle = NULL; 384 fSettings = NULL; 385} 386 387// GetParametersAndCount 388const driver_parameter* 389DriverSettings::GetParametersAndCount(int32* count) const 390{ 391 if (!fSettings) 392 return NULL; 393 *count = fSettings->parameter_count; 394 return fSettings->parameters; 395} 396 397 398// #pragma mark - 399// #pragma mark ----- DriverParameter ----- 400 401// constructor 402DriverParameter::DriverParameter() 403 : DriverParameterContainer(), 404 fParameter(NULL) 405{ 406} 407 408// destructor 409DriverParameter::~DriverParameter() 410{ 411} 412 413// SetTo 414void 415DriverParameter::SetTo(const driver_parameter* parameter) 416{ 417 fParameter = parameter; 418} 419 420// GetName 421const char* 422DriverParameter::GetName() const 423{ 424 return (fParameter ? fParameter->name : NULL); 425} 426 427// CountValues 428int32 429DriverParameter::CountValues() const 430{ 431 return (fParameter ? fParameter->value_count : 0); 432} 433 434// GetValues 435const char* const* 436DriverParameter::GetValues() const 437{ 438 return (fParameter ? fParameter->values : 0); 439} 440 441// ValueAt 442const char* 443DriverParameter::ValueAt(int32 index, const char* noValue) const 444{ 445 if (!fParameter || index < 0 || index >= fParameter->value_count) 446 return noValue; 447 return fParameter->values[index]; 448} 449 450// BoolValueAt 451bool 452DriverParameter::BoolValueAt(int32 index, bool noValue) const 453{ 454 const char* value = ValueAt(index, NULL); 455 if (!value) 456 return noValue; 457 for (int32 i = 0; i < kTrueValueStringCount; i++) { 458 if (strcmp(value, kTrueValueStrings[i]) == 0) 459 return true; 460 } 461 return false; 462} 463 464// Int32ValueAt 465int32 466DriverParameter::Int32ValueAt(int32 index, int32 noValue) const 467{ 468 const char* value = ValueAt(index, NULL); 469 if (!value) 470 return noValue; 471 return atol(value); 472} 473 474// Int64ValueAt 475int64 476DriverParameter::Int64ValueAt(int32 index, int64 noValue) const 477{ 478 const char* value = ValueAt(index, NULL); 479 if (!value) 480 return noValue; 481 return strtoll(value, NULL, 10); 482} 483 484// GetParametersAndCount 485const driver_parameter* 486DriverParameter::GetParametersAndCount(int32* count) const 487{ 488 if (!fParameter) 489 return NULL; 490 *count = fParameter->parameter_count; 491 return fParameter->parameters; 492} 493 494