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:
Delegate()39 Delegate() : BReferenceable() {}
~Delegate()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
BDriverParameterIterator()49 BDriverParameterIterator::BDriverParameterIterator()
50 :
51 fDelegate(NULL)
52 {
53 }
54
55
BDriverParameterIterator(Delegate * delegate)56 BDriverParameterIterator::BDriverParameterIterator(Delegate* delegate)
57 :
58 fDelegate(delegate)
59 {
60 }
61
62
BDriverParameterIterator(const BDriverParameterIterator & other)63 BDriverParameterIterator::BDriverParameterIterator(
64 const BDriverParameterIterator& other)
65 :
66 fDelegate(NULL)
67 {
68 _SetTo(other.fDelegate, true);
69 }
70
71
~BDriverParameterIterator()72 BDriverParameterIterator::~BDriverParameterIterator()
73 {
74 _SetTo(NULL, false);
75 }
76
77
78 bool
HasNext() const79 BDriverParameterIterator::HasNext() const
80 {
81 return fDelegate != NULL ? fDelegate->HasNext() : false;
82 }
83
84
85 BDriverParameter
Next()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&
operator =(const BDriverParameterIterator & other)103 BDriverParameterIterator::operator=(const BDriverParameterIterator& other)
104 {
105 _SetTo(other.fDelegate, true);
106 return *this;
107 }
108
109
110 void
_SetTo(Delegate * delegate,bool addReference)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:
Iterator(const driver_parameter * parameters,int32 count)127 Iterator(const driver_parameter* parameters, int32 count)
128 :
129 Delegate(),
130 fParameters(parameters),
131 fCount(count)
132 {
133 }
134
~Iterator()135 virtual ~Iterator()
136 {
137 }
138
Clone() const139 virtual Delegate* Clone() const
140 {
141 return new(std::nothrow) Iterator(fParameters, fCount);
142 }
143
HasNext() const144 virtual bool HasNext() const
145 {
146 return fParameters != NULL && fCount > 0;
147 }
148
Next()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:
NameIterator(const driver_parameter * parameters,int32 count,const BString & name)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
~NameIterator()178 virtual ~NameIterator()
179 {
180 }
181
Clone() const182 virtual Delegate* Clone() const
183 {
184 return new(std::nothrow) NameIterator(fParameters, fCount, fName);
185 }
186
HasNext() const187 virtual bool HasNext() const
188 {
189 return fParameters != NULL && fCount > 0;
190 }
191
Next()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:
_FindNext(bool skipCurrent)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
BDriverParameterContainer()224 BDriverParameterContainer::BDriverParameterContainer()
225 {
226 }
227
228
~BDriverParameterContainer()229 BDriverParameterContainer::~BDriverParameterContainer()
230 {
231 }
232
233
234 int32
CountParameters() const235 BDriverParameterContainer::CountParameters() const
236 {
237 int32 count;
238 return GetParametersAndCount(count) != NULL ? count : 0;
239
240 }
241
242
243 const driver_parameter*
Parameters() const244 BDriverParameterContainer::Parameters() const
245 {
246 int32 count;
247 return GetParametersAndCount(count);
248 }
249
250
251 BDriverParameter
ParameterAt(int32 index) const252 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
FindParameter(const char * name,BDriverParameter * _parameter) const264 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
GetParameter(const char * name) const285 BDriverParameterContainer::GetParameter(const char* name) const
286 {
287 BDriverParameter parameter;
288 FindParameter(name, ¶meter);
289 return parameter;
290 }
291
292
293 BDriverParameterIterator
ParameterIterator() const294 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
ParameterIterator(const char * name) const306 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*
GetParameterValue(const char * name,const char * unknownValue,const char * noValue) const320 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
GetBoolParameterValue(const char * name,bool unknownValue,bool noValue) const331 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
GetInt32ParameterValue(const char * name,int32 unknownValue,int32 noValue) const342 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
GetInt64ParameterValue(const char * name,int64 unknownValue,int64 noValue) const353 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
BDriverSettings()366 BDriverSettings::BDriverSettings()
367 :
368 BDriverParameterContainer(),
369 fSettingsHandle(NULL),
370 fSettings(NULL)
371 {
372 }
373
374
~BDriverSettings()375 BDriverSettings::~BDriverSettings()
376 {
377 Unset();
378 }
379
380
381 status_t
Load(const char * driverNameOrAbsolutePath)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
Load(const entry_ref & ref)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
SetToString(const char * string)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
Unset()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*
GetParametersAndCount(int32 & _count) const442 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
BDriverParameter()455 BDriverParameter::BDriverParameter()
456 :
457 BDriverParameterContainer(),
458 fParameter(NULL)
459 {
460 }
461
462
BDriverParameter(const driver_parameter * parameter)463 BDriverParameter::BDriverParameter(const driver_parameter* parameter)
464 :
465 BDriverParameterContainer(),
466 fParameter(parameter)
467 {
468 }
469
470
BDriverParameter(const BDriverParameter & other)471 BDriverParameter::BDriverParameter(const BDriverParameter& other)
472 :
473 BDriverParameterContainer(),
474 fParameter(other.fParameter)
475 {
476 }
477
478
~BDriverParameter()479 BDriverParameter::~BDriverParameter()
480 {
481 }
482
483
484 void
SetTo(const driver_parameter * parameter)485 BDriverParameter::SetTo(const driver_parameter* parameter)
486 {
487 fParameter = parameter;
488 }
489
490
491 bool
IsValid() const492 BDriverParameter::IsValid() const
493 {
494 return fParameter != NULL;
495 }
496
497
498 const char*
Name() const499 BDriverParameter::Name() const
500 {
501 return fParameter != NULL ? fParameter->name : NULL;
502 }
503
504
505 int32
CountValues() const506 BDriverParameter::CountValues() const
507 {
508 return fParameter != NULL ? fParameter->value_count : 0;
509 }
510
511
512 const char* const*
Values() const513 BDriverParameter::Values() const
514 {
515 return fParameter != NULL ? fParameter->values : 0;
516 }
517
518
519 const char*
ValueAt(int32 index,const char * noValue) const520 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
BoolValueAt(int32 index,bool noValue) const529 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
Int32ValueAt(int32 index,int32 noValue) const544 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
Int64ValueAt(int32 index,int64 noValue) const554 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*
GetParametersAndCount(int32 & _count) const564 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&
operator =(const BDriverParameter & other)575 BDriverParameter::operator=(const BDriverParameter& other)
576 {
577 fParameter = other.fParameter;
578 return *this;
579 }
580
581
582 } // namespace BPrivate
583