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