xref: /haiku/src/add-ons/kernel/file_systems/userlandfs/shared/DriverSettings.cpp (revision 88e38c178a96634d52920e2de8bb3cbd49869f93)
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, &parameter))
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, &parameter))
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, &parameter))
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, &parameter))
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