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