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. 25static const char* const kTrueValueStrings[] 26 = { "1", "true", "yes", "on", "enable", "enabled" }; 27static const int32 kTrueValueStringCount 28 = sizeof(kTrueValueStrings) / sizeof(const char*); 29 30 31namespace BPrivate { 32 33 34// #pragma mark - BDriverParameterIterator 35 36 37class BDriverParameterIterator::Delegate : public BReferenceable { 38public: 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 49BDriverParameterIterator::BDriverParameterIterator() 50 : 51 fDelegate(NULL) 52{ 53} 54 55 56BDriverParameterIterator::BDriverParameterIterator(Delegate* delegate) 57 : 58 fDelegate(delegate) 59{ 60} 61 62 63BDriverParameterIterator::BDriverParameterIterator( 64 const BDriverParameterIterator& other) 65 : 66 fDelegate(NULL) 67{ 68 _SetTo(other.fDelegate, true); 69} 70 71 72BDriverParameterIterator::~BDriverParameterIterator() 73{ 74 _SetTo(NULL, false); 75} 76 77 78bool 79BDriverParameterIterator::HasNext() const 80{ 81 return fDelegate != NULL ? fDelegate->HasNext() : false; 82} 83 84 85BDriverParameter 86BDriverParameterIterator::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 102BDriverParameterIterator& 103BDriverParameterIterator::operator=(const BDriverParameterIterator& other) 104{ 105 _SetTo(other.fDelegate, true); 106 return *this; 107} 108 109 110void 111BDriverParameterIterator::_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 124class BDriverParameterContainer::Iterator 125 : public BDriverParameterIterator::Delegate { 126public: 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 158private: 159 const driver_parameter* fParameters; 160 int32 fCount; 161}; 162 163 164class BDriverParameterContainer::NameIterator 165 : public BDriverParameterIterator::Delegate { 166public: 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 202private: 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 217private: 218 const driver_parameter* fParameters; 219 int32 fCount; 220 BString fName; 221}; 222 223 224BDriverParameterContainer::BDriverParameterContainer() 225{ 226} 227 228 229BDriverParameterContainer::~BDriverParameterContainer() 230{ 231} 232 233 234int32 235BDriverParameterContainer::CountParameters() const 236{ 237 int32 count; 238 return GetParametersAndCount(count) != NULL ? count : 0; 239 240} 241 242 243const driver_parameter* 244BDriverParameterContainer::Parameters() const 245{ 246 int32 count; 247 return GetParametersAndCount(count); 248} 249 250 251BDriverParameter 252BDriverParameterContainer::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 263bool 264BDriverParameterContainer::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 284BDriverParameter 285BDriverParameterContainer::GetParameter(const char* name) const 286{ 287 BDriverParameter parameter; 288 FindParameter(name, ¶meter); 289 return parameter; 290} 291 292 293BDriverParameterIterator 294BDriverParameterContainer::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 305BDriverParameterIterator 306BDriverParameterContainer::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 319const char* 320BDriverParameterContainer::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 330bool 331BDriverParameterContainer::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 341int32 342BDriverParameterContainer::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 352int64 353BDriverParameterContainer::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 366BDriverSettings::BDriverSettings() 367 : 368 BDriverParameterContainer(), 369 fSettingsHandle(NULL), 370 fSettings(NULL) 371{ 372} 373 374 375BDriverSettings::~BDriverSettings() 376{ 377 Unset(); 378} 379 380 381status_t 382BDriverSettings::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 400status_t 401BDriverSettings::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 411status_t 412BDriverSettings::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 430void 431BDriverSettings::Unset() 432{ 433 if (fSettingsHandle != NULL) 434 unload_driver_settings(fSettingsHandle); 435 436 fSettingsHandle = NULL; 437 fSettings = NULL; 438} 439 440 441const driver_parameter* 442BDriverSettings::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 455BDriverParameter::BDriverParameter() 456 : 457 BDriverParameterContainer(), 458 fParameter(NULL) 459{ 460} 461 462 463BDriverParameter::BDriverParameter(const driver_parameter* parameter) 464 : 465 BDriverParameterContainer(), 466 fParameter(parameter) 467{ 468} 469 470 471BDriverParameter::BDriverParameter(const BDriverParameter& other) 472 : 473 BDriverParameterContainer(), 474 fParameter(other.fParameter) 475{ 476} 477 478 479BDriverParameter::~BDriverParameter() 480{ 481} 482 483 484void 485BDriverParameter::SetTo(const driver_parameter* parameter) 486{ 487 fParameter = parameter; 488} 489 490 491bool 492BDriverParameter::IsValid() const 493{ 494 return fParameter != NULL; 495} 496 497 498const char* 499BDriverParameter::Name() const 500{ 501 return fParameter != NULL ? fParameter->name : NULL; 502} 503 504 505int32 506BDriverParameter::CountValues() const 507{ 508 return fParameter != NULL ? fParameter->value_count : 0; 509} 510 511 512const char* const* 513BDriverParameter::Values() const 514{ 515 return fParameter != NULL ? fParameter->values : 0; 516} 517 518 519const char* 520BDriverParameter::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 528bool 529BDriverParameter::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 543int32 544BDriverParameter::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 553int64 554BDriverParameter::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 563const driver_parameter* 564BDriverParameter::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 574BDriverParameter& 575BDriverParameter::operator=(const BDriverParameter& other) 576{ 577 fParameter = other.fParameter; 578 return *this; 579} 580 581 582} // namespace BPrivate 583