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. 15 static const char* kTrueValueStrings[] 16 = { "1", "true", "yes", "on", "enable", "enabled" }; 17 static const int32 kTrueValueStringCount 18 = sizeof(kTrueValueStrings) / sizeof(const char*); 19 20 21 // #pragma mark - 22 // #pragma mark ----- DriverParameterIterator ----- 23 24 // Delegate 25 class DriverParameterIterator::Delegate : public BReferenceable { 26 public: 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 37 DriverParameterIterator::DriverParameterIterator() 38 : fDelegate(NULL) 39 { 40 } 41 42 // constructor 43 DriverParameterIterator::DriverParameterIterator(Delegate* delegate) 44 : fDelegate(delegate) 45 { 46 } 47 48 // copy constructor 49 DriverParameterIterator::DriverParameterIterator( 50 const DriverParameterIterator& other) 51 : fDelegate(NULL) 52 { 53 _SetTo(other.fDelegate, true); 54 } 55 56 // destructor 57 DriverParameterIterator::~DriverParameterIterator() 58 { 59 _SetTo(NULL, false); 60 } 61 62 // HasNext 63 bool 64 DriverParameterIterator::HasNext() const 65 { 66 return (fDelegate ? fDelegate->HasNext() : false); 67 } 68 69 // GetNext 70 bool 71 DriverParameterIterator::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 // = 85 DriverParameterIterator& 86 DriverParameterIterator::operator=(const DriverParameterIterator& other) 87 { 88 _SetTo(other.fDelegate, true); 89 return *this; 90 } 91 92 // _SetTo 93 void 94 DriverParameterIterator::_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 108 class DriverParameterContainer::Iterator 109 : public DriverParameterIterator::Delegate { 110 public: 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 144 private: 145 const driver_parameter* fParameters; 146 int32 fCount; 147 }; 148 149 // NameIterator 150 class DriverParameterContainer::NameIterator 151 : public DriverParameterIterator::Delegate { 152 public: 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 189 private: 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 204 private: 205 const driver_parameter* fParameters; 206 int32 fCount; 207 String fName; 208 }; 209 210 // constructor 211 DriverParameterContainer::DriverParameterContainer() 212 { 213 } 214 215 // destructor 216 DriverParameterContainer::~DriverParameterContainer() 217 { 218 } 219 220 // CountParameters 221 int32 222 DriverParameterContainer::CountParameters() const 223 { 224 int32 count; 225 return (GetParametersAndCount(&count) ? count : 0); 226 227 } 228 229 // GetParameters 230 const driver_parameter* 231 DriverParameterContainer::GetParameters() const 232 { 233 int32 count; 234 return GetParametersAndCount(&count); 235 } 236 237 // GetParameterAt 238 bool 239 DriverParameterContainer::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 254 bool 255 DriverParameterContainer::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 274 DriverParameterIterator 275 DriverParameterContainer::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 286 DriverParameterIterator 287 DriverParameterContainer::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 300 const char* 301 DriverParameterContainer::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 311 bool 312 DriverParameterContainer::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 322 int32 323 DriverParameterContainer::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 333 int64 334 DriverParameterContainer::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 348 DriverSettings::DriverSettings() 349 : DriverParameterContainer(), 350 fSettingsHandle(NULL), 351 fSettings(NULL) 352 { 353 } 354 355 // destructor 356 DriverSettings::~DriverSettings() 357 { 358 Unset(); 359 } 360 361 // Load 362 status_t 363 DriverSettings::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 378 void 379 DriverSettings::Unset() 380 { 381 if (fSettingsHandle) 382 unload_driver_settings(fSettingsHandle); 383 fSettingsHandle = NULL; 384 fSettings = NULL; 385 } 386 387 // GetParametersAndCount 388 const driver_parameter* 389 DriverSettings::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 402 DriverParameter::DriverParameter() 403 : DriverParameterContainer(), 404 fParameter(NULL) 405 { 406 } 407 408 // destructor 409 DriverParameter::~DriverParameter() 410 { 411 } 412 413 // SetTo 414 void 415 DriverParameter::SetTo(const driver_parameter* parameter) 416 { 417 fParameter = parameter; 418 } 419 420 // GetName 421 const char* 422 DriverParameter::GetName() const 423 { 424 return (fParameter ? fParameter->name : NULL); 425 } 426 427 // CountValues 428 int32 429 DriverParameter::CountValues() const 430 { 431 return (fParameter ? fParameter->value_count : 0); 432 } 433 434 // GetValues 435 const char* const* 436 DriverParameter::GetValues() const 437 { 438 return (fParameter ? fParameter->values : 0); 439 } 440 441 // ValueAt 442 const char* 443 DriverParameter::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 451 bool 452 DriverParameter::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 465 int32 466 DriverParameter::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 475 int64 476 DriverParameter::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 485 const driver_parameter* 486 DriverParameter::GetParametersAndCount(int32* count) const 487 { 488 if (!fParameter) 489 return NULL; 490 *count = fParameter->parameter_count; 491 return fParameter->parameters; 492 } 493 494