xref: /haiku/src/add-ons/kernel/file_systems/userlandfs/shared/DriverSettings.cpp (revision 2f470aec1c92ce6917b8a903e343795dc77af41f)
1 // DriverSettings.cpp
2 
3 #include <new>
4 #include <stdlib.h>
5 #include <string.h>
6 
7 #include <driver_settings.h>
8 
9 #include "DriverSettings.h"
10 #include "Referencable.h"
11 #include "String.h"
12 
13 // The parameter values that shall be evaluated to true.
14 static const char* kTrueValueStrings[]
15 	= { "1", "true", "yes", "on", "enable", "enabled" };
16 static const int32 kTrueValueStringCount
17 	= sizeof(kTrueValueStrings) / sizeof(const char*);
18 
19 
20 // #pragma mark -
21 // #pragma mark ----- DriverParameterIterator -----
22 
23 // Delegate
24 class DriverParameterIterator::Delegate : public Referencable {
25 public:
26 								Delegate() : Referencable(true) {}
27 	virtual						~Delegate() {}
28 
29 	virtual	Delegate*			Clone() const = 0;
30 
31 	virtual	bool				HasNext() const = 0;
32 	virtual	bool				GetNext(DriverParameter* parameter) = 0;
33 };
34 
35 // constructor
36 DriverParameterIterator::DriverParameterIterator()
37 	: fDelegate(NULL)
38 {
39 }
40 
41 // constructor
42 DriverParameterIterator::DriverParameterIterator(Delegate* delegate)
43 	: fDelegate(delegate)
44 {
45 }
46 
47 // copy constructor
48 DriverParameterIterator::DriverParameterIterator(
49 	const DriverParameterIterator& other)
50 	: fDelegate(NULL)
51 {
52 	_SetTo(other.fDelegate, true);
53 }
54 
55 // destructor
56 DriverParameterIterator::~DriverParameterIterator()
57 {
58 	_SetTo(NULL, false);
59 }
60 
61 // HasNext
62 bool
63 DriverParameterIterator::HasNext() const
64 {
65 	return (fDelegate ? fDelegate->HasNext() : false);
66 }
67 
68 // GetNext
69 bool
70 DriverParameterIterator::GetNext(DriverParameter* parameter)
71 {
72 	if (!fDelegate)
73 		return false;
74 	if (fDelegate->CountReferences() > 1) {
75 		Delegate* clone = fDelegate->Clone();
76 		if (!clone)
77 			return false;
78 		_SetTo(clone, false);
79 	}
80 	return fDelegate->GetNext(parameter);
81 }
82 
83 // =
84 DriverParameterIterator&
85 DriverParameterIterator::operator=(const DriverParameterIterator& other)
86 {
87 	_SetTo(other.fDelegate, true);
88 	return *this;
89 }
90 
91 // _SetTo
92 void
93 DriverParameterIterator::_SetTo(Delegate* delegate, bool addReference)
94 {
95 	if (fDelegate)
96 		fDelegate->RemoveReference();
97 	fDelegate = delegate;
98 	if (fDelegate && addReference)
99 		fDelegate->AddReference();
100 }
101 
102 
103 // #pragma mark -
104 // #pragma mark ----- DriverParameterContainer -----
105 
106 // Iterator
107 class DriverParameterContainer::Iterator
108 	: public DriverParameterIterator::Delegate {
109 public:
110 	Iterator(const driver_parameter* parameters, int32 count)
111 		: Delegate(),
112 		  fParameters(parameters),
113 		  fCount(count)
114 	{
115 	}
116 
117 	virtual ~Iterator()
118 	{
119 	}
120 
121 	virtual Delegate* Clone() const
122 	{
123 		return new(nothrow) Iterator(fParameters, fCount);
124 	}
125 
126 	virtual bool HasNext() const
127 	{
128 		return (fParameters && fCount > 0);
129 	}
130 
131 	virtual bool GetNext(DriverParameter* parameter)
132 	{
133 		if (fParameters && fCount > 0) {
134 			if (parameter)
135 				parameter->SetTo(fParameters);
136 			fParameters++;
137 			fCount--;
138 			return true;
139 		}
140 		return false;
141 	}
142 
143 private:
144 	const driver_parameter*	fParameters;
145 	int32					fCount;
146 };
147 
148 // NameIterator
149 class DriverParameterContainer::NameIterator
150 	: public DriverParameterIterator::Delegate {
151 public:
152 	NameIterator(const driver_parameter* parameters, int32 count,
153 		const char* name)
154 		: Delegate(),
155 		  fParameters(parameters),
156 		  fCount(count),
157 		  fName(name)
158 	{
159 		_FindNext(false);
160 	}
161 
162 	virtual ~NameIterator()
163 	{
164 	}
165 
166 	virtual Delegate* Clone() const
167 	{
168 		return new(nothrow) NameIterator(fParameters, fCount,
169 			fName.GetString());
170 	}
171 
172 	virtual bool HasNext() const
173 	{
174 		return (fParameters && fCount > 0);
175 	}
176 
177 	virtual bool GetNext(DriverParameter* parameter)
178 	{
179 		if (fParameters && fCount > 0) {
180 			if (parameter)
181 				parameter->SetTo(fParameters);
182 			_FindNext(true);
183 			return true;
184 		}
185 		return false;
186 	}
187 
188 private:
189 	void _FindNext(bool skipCurrent)
190 	{
191 		if (!fParameters || fCount < 1)
192 			return;
193 		if (skipCurrent) {
194 			fParameters++;
195 			fCount--;
196 		}
197 		while (fCount > 0 && fName != fParameters->name) {
198 			fParameters++;
199 			fCount--;
200 		}
201 	}
202 
203 private:
204 	const driver_parameter*	fParameters;
205 	int32					fCount;
206 	String					fName;
207 };
208 
209 // constructor
210 DriverParameterContainer::DriverParameterContainer()
211 {
212 }
213 
214 // destructor
215 DriverParameterContainer::~DriverParameterContainer()
216 {
217 }
218 
219 // CountParameters
220 int32
221 DriverParameterContainer::CountParameters() const
222 {
223 	int32 count;
224 	return (GetParametersAndCount(&count) ? count : 0);
225 
226 }
227 
228 // GetParameters
229 const driver_parameter*
230 DriverParameterContainer::GetParameters() const
231 {
232 	int32 count;
233 	return GetParametersAndCount(&count);
234 }
235 
236 // GetParameterAt
237 bool
238 DriverParameterContainer::GetParameterAt(int32 index,
239 	DriverParameter* parameter) const
240 {
241 	int32 count;
242 	if (const driver_parameter* parameters = GetParametersAndCount(&count)) {
243 		if (index >= 0 && index < count) {
244 			if (parameter)
245 				parameter->SetTo(parameters + index);
246 			return true;
247 		}
248 	}
249 	return false;
250 }
251 
252 // FindParameter
253 bool
254 DriverParameterContainer::FindParameter(const char* name,
255 	DriverParameter* parameter) const
256 {
257 	if (!name)
258 		return false;
259 	int32 count;
260 	if (const driver_parameter* parameters = GetParametersAndCount(&count)) {
261 		for (int32 i = 0; i < count; i++) {
262 			if (strcmp(name, parameters[i].name) == 0) {
263 				if (parameter)
264 					parameter->SetTo(parameters + i);
265 				return true;
266 			}
267 		}
268 	}
269 	return false;
270 }
271 
272 // GetParameterIterator
273 DriverParameterIterator
274 DriverParameterContainer::GetParameterIterator() const
275 {
276 	int32 count;
277 	if (const driver_parameter* parameters = GetParametersAndCount(&count)) {
278 		if (Iterator* iterator = new(nothrow) Iterator(parameters, count))
279 			return DriverParameterIterator(iterator);
280 	}
281 	return DriverParameterIterator();
282 }
283 
284 // GetParameterIterator
285 DriverParameterIterator
286 DriverParameterContainer::GetParameterIterator(const char* name) const
287 {
288 	int32 count;
289 	if (const driver_parameter* parameters = GetParametersAndCount(&count)) {
290 		NameIterator* iterator = new(nothrow) NameIterator(parameters, count,
291 			name);
292 		if (iterator)
293 			return DriverParameterIterator(iterator);
294 	}
295 	return DriverParameterIterator();
296 }
297 
298 // GetParameterValue
299 const char*
300 DriverParameterContainer::GetParameterValue(const char* name,
301 	const char* unknownValue, const char* noValue) const
302 {
303 	DriverParameter parameter;
304 	if (!FindParameter(name, &parameter))
305 		return unknownValue;
306 	return parameter.ValueAt(0, noValue);
307 }
308 
309 // GetBoolParameterValue
310 bool
311 DriverParameterContainer::GetBoolParameterValue(const char* name,
312 	bool unknownValue, bool noValue) const
313 {
314 	DriverParameter parameter;
315 	if (!FindParameter(name, &parameter))
316 		return unknownValue;
317 	return parameter.BoolValueAt(0, noValue);
318 }
319 
320 // GetInt32ParameterValue
321 int32
322 DriverParameterContainer::GetInt32ParameterValue(const char* name,
323 	int32 unknownValue, int32 noValue) const
324 {
325 	DriverParameter parameter;
326 	if (!FindParameter(name, &parameter))
327 		return unknownValue;
328 	return parameter.Int32ValueAt(0, noValue);
329 }
330 
331 // GetInt64ParameterValue
332 int64
333 DriverParameterContainer::GetInt64ParameterValue(const char* name,
334 	int64 unknownValue, int64 noValue) const
335 {
336 	DriverParameter parameter;
337 	if (!FindParameter(name, &parameter))
338 		return unknownValue;
339 	return parameter.Int64ValueAt(0, noValue);
340 }
341 
342 
343 // #pragma mark -
344 // #pragma mark ----- DriverSettings -----
345 
346 // constructor
347 DriverSettings::DriverSettings()
348 	: DriverParameterContainer(),
349 	  fSettingsHandle(NULL),
350 	  fSettings(NULL)
351 {
352 }
353 
354 // destructor
355 DriverSettings::~DriverSettings()
356 {
357 	Unset();
358 }
359 
360 // Load
361 status_t
362 DriverSettings::Load(const char* driverName)
363 {
364 	Unset();
365 	fSettingsHandle = load_driver_settings(driverName);
366 	if (!fSettingsHandle)
367 		return B_ENTRY_NOT_FOUND;
368 	fSettings = get_driver_settings(fSettingsHandle);
369 	if (!fSettings) {
370 		Unset();
371 		return B_ERROR;
372 	}
373 	return B_OK;
374 }
375 
376 // Unset
377 void
378 DriverSettings::Unset()
379 {
380 	if (fSettingsHandle)
381 		unload_driver_settings(fSettingsHandle);
382 	fSettingsHandle = NULL;
383 	fSettings = NULL;
384 }
385 
386 // GetParametersAndCount
387 const driver_parameter*
388 DriverSettings::GetParametersAndCount(int32* count) const
389 {
390 	if (!fSettings)
391 		return NULL;
392 	*count = fSettings->parameter_count;
393 	return fSettings->parameters;
394 }
395 
396 
397 // #pragma mark -
398 // #pragma mark ----- DriverParameter -----
399 
400 // constructor
401 DriverParameter::DriverParameter()
402 	: DriverParameterContainer(),
403 	  fParameter(NULL)
404 {
405 }
406 
407 // destructor
408 DriverParameter::~DriverParameter()
409 {
410 }
411 
412 // SetTo
413 void
414 DriverParameter::SetTo(const driver_parameter* parameter)
415 {
416 	fParameter = parameter;
417 }
418 
419 // GetName
420 const char*
421 DriverParameter::GetName() const
422 {
423 	return (fParameter ? fParameter->name : NULL);
424 }
425 
426 // CountValues
427 int32
428 DriverParameter::CountValues() const
429 {
430 	return (fParameter ? fParameter->value_count : 0);
431 }
432 
433 // GetValues
434 const char* const*
435 DriverParameter::GetValues() const
436 {
437 	return (fParameter ? fParameter->values : 0);
438 }
439 
440 // ValueAt
441 const char*
442 DriverParameter::ValueAt(int32 index, const char* noValue) const
443 {
444 	if (!fParameter || index < 0 || index >= fParameter->value_count)
445 		return noValue;
446 	return fParameter->values[index];
447 }
448 
449 // BoolValueAt
450 bool
451 DriverParameter::BoolValueAt(int32 index, bool noValue) const
452 {
453 	const char* value = ValueAt(index, NULL);
454 	if (!value)
455 		return noValue;
456 	for (int32 i = 0; i < kTrueValueStringCount; i++) {
457 		if (strcmp(value, kTrueValueStrings[i]) == 0)
458 			return true;
459 	}
460 	return false;
461 }
462 
463 // Int32ValueAt
464 int32
465 DriverParameter::Int32ValueAt(int32 index, int32 noValue) const
466 {
467 	const char* value = ValueAt(index, NULL);
468 	if (!value)
469 		return noValue;
470 	return atol(value);
471 }
472 
473 // Int64ValueAt
474 int64
475 DriverParameter::Int64ValueAt(int32 index, int64 noValue) const
476 {
477 	const char* value = ValueAt(index, NULL);
478 	if (!value)
479 		return noValue;
480 	return strtoll(value, NULL, 10);
481 }
482 
483 // GetParametersAndCount
484 const driver_parameter*
485 DriverParameter::GetParametersAndCount(int32* count) const
486 {
487 	if (!fParameter)
488 		return NULL;
489 	*count = fParameter->parameter_count;
490 	return fParameter->parameters;
491 }
492 
493