xref: /haiku/src/kits/storage/DriverSettings.cpp (revision e81a954787e50e56a7f06f72705b7859b6ab06d1)
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:
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 
49 BDriverParameterIterator::BDriverParameterIterator()
50 	:
51 	fDelegate(NULL)
52 {
53 }
54 
55 
56 BDriverParameterIterator::BDriverParameterIterator(Delegate* delegate)
57 	:
58 	fDelegate(delegate)
59 {
60 }
61 
62 
63 BDriverParameterIterator::BDriverParameterIterator(
64 	const BDriverParameterIterator& other)
65 	:
66 	fDelegate(NULL)
67 {
68 	_SetTo(other.fDelegate, true);
69 }
70 
71 
72 BDriverParameterIterator::~BDriverParameterIterator()
73 {
74 	_SetTo(NULL, false);
75 }
76 
77 
78 bool
79 BDriverParameterIterator::HasNext() const
80 {
81 	return fDelegate != NULL ? fDelegate->HasNext() : false;
82 }
83 
84 
85 BDriverParameter
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&
103 BDriverParameterIterator::operator=(const BDriverParameterIterator& other)
104 {
105 	_SetTo(other.fDelegate, true);
106 	return *this;
107 }
108 
109 
110 void
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:
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 
158 private:
159 	const driver_parameter*	fParameters;
160 	int32					fCount;
161 };
162 
163 
164 class BDriverParameterContainer::NameIterator
165 	: public BDriverParameterIterator::Delegate {
166 public:
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 
202 private:
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 
224 BDriverParameterContainer::BDriverParameterContainer()
225 {
226 }
227 
228 
229 BDriverParameterContainer::~BDriverParameterContainer()
230 {
231 }
232 
233 
234 int32
235 BDriverParameterContainer::CountParameters() const
236 {
237 	int32 count;
238 	return GetParametersAndCount(count) != NULL ? count : 0;
239 
240 }
241 
242 
243 const driver_parameter*
244 BDriverParameterContainer::Parameters() const
245 {
246 	int32 count;
247 	return GetParametersAndCount(count);
248 }
249 
250 
251 BDriverParameter
252 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
264 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
285 BDriverParameterContainer::GetParameter(const char* name) const
286 {
287 	BDriverParameter parameter;
288 	FindParameter(name, &parameter);
289 	return parameter;
290 }
291 
292 
293 BDriverParameterIterator
294 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
306 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*
320 BDriverParameterContainer::GetParameterValue(const char* name,
321 	const char* unknownValue, const char* noValue) const
322 {
323 	BDriverParameter parameter;
324 	if (!FindParameter(name, &parameter))
325 		return unknownValue;
326 	return parameter.ValueAt(0, noValue);
327 }
328 
329 
330 bool
331 BDriverParameterContainer::GetBoolParameterValue(const char* name,
332 	bool unknownValue, bool noValue) const
333 {
334 	BDriverParameter parameter;
335 	if (!FindParameter(name, &parameter))
336 		return unknownValue;
337 	return parameter.BoolValueAt(0, noValue);
338 }
339 
340 
341 int32
342 BDriverParameterContainer::GetInt32ParameterValue(const char* name,
343 	int32 unknownValue, int32 noValue) const
344 {
345 	BDriverParameter parameter;
346 	if (!FindParameter(name, &parameter))
347 		return unknownValue;
348 	return parameter.Int32ValueAt(0, noValue);
349 }
350 
351 
352 int64
353 BDriverParameterContainer::GetInt64ParameterValue(const char* name,
354 	int64 unknownValue, int64 noValue) const
355 {
356 	BDriverParameter parameter;
357 	if (!FindParameter(name, &parameter))
358 		return unknownValue;
359 	return parameter.Int64ValueAt(0, noValue);
360 }
361 
362 
363 // #pragma mark - BDriverSettings
364 
365 
366 BDriverSettings::BDriverSettings()
367 	:
368 	BDriverParameterContainer(),
369 	fSettingsHandle(NULL),
370 	fSettings(NULL)
371 {
372 }
373 
374 
375 BDriverSettings::~BDriverSettings()
376 {
377 	Unset();
378 }
379 
380 
381 status_t
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
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
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
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*
442 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 
455 BDriverParameter::BDriverParameter()
456 	:
457 	BDriverParameterContainer(),
458 	fParameter(NULL)
459 {
460 }
461 
462 
463 BDriverParameter::BDriverParameter(const driver_parameter* parameter)
464 	:
465 	BDriverParameterContainer(),
466 	fParameter(parameter)
467 {
468 }
469 
470 
471 BDriverParameter::BDriverParameter(const BDriverParameter& other)
472 	:
473 	BDriverParameterContainer(),
474 	fParameter(other.fParameter)
475 {
476 }
477 
478 
479 BDriverParameter::~BDriverParameter()
480 {
481 }
482 
483 
484 void
485 BDriverParameter::SetTo(const driver_parameter* parameter)
486 {
487 	fParameter = parameter;
488 }
489 
490 
491 bool
492 BDriverParameter::IsValid() const
493 {
494 	return fParameter != NULL;
495 }
496 
497 
498 const char*
499 BDriverParameter::Name() const
500 {
501 	return fParameter != NULL ? fParameter->name : NULL;
502 }
503 
504 
505 int32
506 BDriverParameter::CountValues() const
507 {
508 	return fParameter != NULL ? fParameter->value_count : 0;
509 }
510 
511 
512 const char* const*
513 BDriverParameter::Values() const
514 {
515 	return fParameter != NULL ? fParameter->values : 0;
516 }
517 
518 
519 const char*
520 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
529 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
544 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
554 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*
564 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&
575 BDriverParameter::operator=(const BDriverParameter& other)
576 {
577 	fParameter = other.fParameter;
578 	return *this;
579 }
580 
581 
582 }	// namespace BPrivate
583