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:
Delegate()27 Delegate() : BReferenceable() {}
~Delegate()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
DriverParameterIterator()37 DriverParameterIterator::DriverParameterIterator()
38 : fDelegate(NULL)
39 {
40 }
41
42 // constructor
DriverParameterIterator(Delegate * delegate)43 DriverParameterIterator::DriverParameterIterator(Delegate* delegate)
44 : fDelegate(delegate)
45 {
46 }
47
48 // copy constructor
DriverParameterIterator(const DriverParameterIterator & other)49 DriverParameterIterator::DriverParameterIterator(
50 const DriverParameterIterator& other)
51 : fDelegate(NULL)
52 {
53 _SetTo(other.fDelegate, true);
54 }
55
56 // destructor
~DriverParameterIterator()57 DriverParameterIterator::~DriverParameterIterator()
58 {
59 _SetTo(NULL, false);
60 }
61
62 // HasNext
63 bool
HasNext() const64 DriverParameterIterator::HasNext() const
65 {
66 return (fDelegate ? fDelegate->HasNext() : false);
67 }
68
69 // GetNext
70 bool
GetNext(DriverParameter * parameter)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&
operator =(const DriverParameterIterator & other)86 DriverParameterIterator::operator=(const DriverParameterIterator& other)
87 {
88 _SetTo(other.fDelegate, true);
89 return *this;
90 }
91
92 // _SetTo
93 void
_SetTo(Delegate * delegate,bool addReference)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:
Iterator(const driver_parameter * parameters,int32 count)111 Iterator(const driver_parameter* parameters, int32 count)
112 : Delegate(),
113 fParameters(parameters),
114 fCount(count)
115 {
116 }
117
~Iterator()118 virtual ~Iterator()
119 {
120 }
121
Clone() const122 virtual Delegate* Clone() const
123 {
124 return new(std::nothrow) Iterator(fParameters, fCount);
125 }
126
HasNext() const127 virtual bool HasNext() const
128 {
129 return (fParameters && fCount > 0);
130 }
131
GetNext(DriverParameter * parameter)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:
NameIterator(const driver_parameter * parameters,int32 count,const char * name)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
~NameIterator()163 virtual ~NameIterator()
164 {
165 }
166
Clone() const167 virtual Delegate* Clone() const
168 {
169 return new(std::nothrow) NameIterator(fParameters, fCount,
170 fName.GetString());
171 }
172
HasNext() const173 virtual bool HasNext() const
174 {
175 return (fParameters && fCount > 0);
176 }
177
GetNext(DriverParameter * parameter)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:
_FindNext(bool skipCurrent)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
DriverParameterContainer()211 DriverParameterContainer::DriverParameterContainer()
212 {
213 }
214
215 // destructor
~DriverParameterContainer()216 DriverParameterContainer::~DriverParameterContainer()
217 {
218 }
219
220 // CountParameters
221 int32
CountParameters() const222 DriverParameterContainer::CountParameters() const
223 {
224 int32 count;
225 return (GetParametersAndCount(&count) ? count : 0);
226
227 }
228
229 // GetParameters
230 const driver_parameter*
GetParameters() const231 DriverParameterContainer::GetParameters() const
232 {
233 int32 count;
234 return GetParametersAndCount(&count);
235 }
236
237 // GetParameterAt
238 bool
GetParameterAt(int32 index,DriverParameter * parameter) const239 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
FindParameter(const char * name,DriverParameter * parameter) const255 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
GetParameterIterator() const275 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
GetParameterIterator(const char * name) const287 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*
GetParameterValue(const char * name,const char * unknownValue,const char * noValue) const301 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
GetBoolParameterValue(const char * name,bool unknownValue,bool noValue) const312 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
GetInt32ParameterValue(const char * name,int32 unknownValue,int32 noValue) const323 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
GetInt64ParameterValue(const char * name,int64 unknownValue,int64 noValue) const334 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
DriverSettings()348 DriverSettings::DriverSettings()
349 : DriverParameterContainer(),
350 fSettingsHandle(NULL),
351 fSettings(NULL)
352 {
353 }
354
355 // destructor
~DriverSettings()356 DriverSettings::~DriverSettings()
357 {
358 Unset();
359 }
360
361 // Load
362 status_t
Load(const char * driverName)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
Unset()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*
GetParametersAndCount(int32 * count) const389 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
DriverParameter()402 DriverParameter::DriverParameter()
403 : DriverParameterContainer(),
404 fParameter(NULL)
405 {
406 }
407
408 // destructor
~DriverParameter()409 DriverParameter::~DriverParameter()
410 {
411 }
412
413 // SetTo
414 void
SetTo(const driver_parameter * parameter)415 DriverParameter::SetTo(const driver_parameter* parameter)
416 {
417 fParameter = parameter;
418 }
419
420 // GetName
421 const char*
GetName() const422 DriverParameter::GetName() const
423 {
424 return (fParameter ? fParameter->name : NULL);
425 }
426
427 // CountValues
428 int32
CountValues() const429 DriverParameter::CountValues() const
430 {
431 return (fParameter ? fParameter->value_count : 0);
432 }
433
434 // GetValues
435 const char* const*
GetValues() const436 DriverParameter::GetValues() const
437 {
438 return (fParameter ? fParameter->values : 0);
439 }
440
441 // ValueAt
442 const char*
ValueAt(int32 index,const char * noValue) const443 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
BoolValueAt(int32 index,bool noValue) const452 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
Int32ValueAt(int32 index,int32 noValue) const466 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
Int64ValueAt(int32 index,int64 noValue) const476 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*
GetParametersAndCount(int32 * count) const486 DriverParameter::GetParametersAndCount(int32* count) const
487 {
488 if (!fParameter)
489 return NULL;
490 *count = fParameter->parameter_count;
491 return fParameter->parameters;
492 }
493
494