2 * Copyright 2006-2015, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
6 * Axel Dörfler, axeld@pinc-software.de
7 * Michael Lotz <mmlr@mlotz.ch>
11 #include "DriverSettingsMessageAdapter.h"
21 DriverSettingsConverter::DriverSettingsConverter()
26 DriverSettingsConverter::~DriverSettingsConverter()
32 DriverSettingsConverter::ConvertFromDriverSettings(
33 const driver_parameter
& parameter
, const char* name
, int32 index
,
34 uint32 type
, BMessage
& target
)
36 return B_NOT_SUPPORTED
;
41 DriverSettingsConverter::ConvertEmptyFromDriverSettings(
42 const driver_parameter
& parameter
, const char* name
, uint32 type
,
45 return B_NOT_SUPPORTED
;
50 DriverSettingsConverter::ConvertToDriverSettings(const BMessage
& source
,
51 const char* name
, int32 index
, uint32 type
, BString
& value
)
53 return B_NOT_SUPPORTED
;
60 DriverSettingsMessageAdapter::DriverSettingsMessageAdapter()
65 DriverSettingsMessageAdapter::~DriverSettingsMessageAdapter()
71 DriverSettingsMessageAdapter::ConvertFromDriverSettings(
72 const driver_settings
& settings
, const settings_template
* settingsTemplate
,
77 for (int32 i
= 0; i
< settings
.parameter_count
; i
++) {
78 status_t status
= _ConvertFromDriverParameter(settings
.parameters
[i
],
79 settingsTemplate
, message
);
80 if (status
== B_BAD_VALUE
) {
81 // ignore unknown entries
93 DriverSettingsMessageAdapter::ConvertFromDriverSettings(const char* path
,
94 const settings_template
* settingsTemplate
, BMessage
& message
)
96 void* handle
= load_driver_settings(path
);
98 return B_ENTRY_NOT_FOUND
;
100 const driver_settings
* settings
= get_driver_settings(handle
);
102 if (settings
!= NULL
) {
103 status
= ConvertFromDriverSettings(*settings
, settingsTemplate
,
108 unload_driver_settings(handle
);
114 DriverSettingsMessageAdapter::ConvertToDriverSettings(
115 const settings_template
* settingsTemplate
, BString
& settings
,
116 const BMessage
& message
)
123 while (message
.GetInfo(B_ANY_TYPE
, index
++, &name
, &type
, &count
) == B_OK
) {
124 status_t result
= _AppendSettings(settingsTemplate
, settings
, message
,
135 DriverSettingsMessageAdapter::ConvertToDriverSettings(const char* path
,
136 const settings_template
* settingsTemplate
, const BMessage
& message
)
139 status_t status
= ConvertToDriverSettings(settingsTemplate
, settings
,
144 settings
.RemoveFirst("\n");
145 BFile
settingsFile(path
, B_WRITE_ONLY
| B_ERASE_FILE
| B_CREATE_FILE
);
147 ssize_t written
= settingsFile
.Write(settings
.String(), settings
.Length());
151 return written
== settings
.Length() ? B_OK
: B_ERROR
;
158 const settings_template
*
159 DriverSettingsMessageAdapter::_FindSettingsTemplate(
160 const settings_template
* settingsTemplate
, const char* name
)
162 const settings_template
* wildcardTemplate
= NULL
;
164 while (settingsTemplate
->type
!= 0) {
165 if (settingsTemplate
->name
!= NULL
166 && !strcmp(name
, settingsTemplate
->name
))
167 return settingsTemplate
;
169 if (settingsTemplate
->name
== NULL
)
170 wildcardTemplate
= settingsTemplate
;
174 return wildcardTemplate
;
178 const settings_template
*
179 DriverSettingsMessageAdapter::_FindParentValueTemplate(
180 const settings_template
* settingsTemplate
)
182 settingsTemplate
= settingsTemplate
->sub_template
;
183 if (settingsTemplate
== NULL
)
186 while (settingsTemplate
->type
!= 0) {
187 if (settingsTemplate
->parent_value
)
188 return settingsTemplate
;
198 DriverSettingsMessageAdapter::_AddParameter(const driver_parameter
& parameter
,
199 const settings_template
& settingsTemplate
, BMessage
& message
)
201 const char* name
= settingsTemplate
.name
;
203 name
= parameter
.name
;
205 for (int32 i
= 0; i
< parameter
.value_count
; i
++) {
206 if (settingsTemplate
.converter
!= NULL
) {
208 = settingsTemplate
.converter
->ConvertFromDriverSettings(
209 parameter
, name
, i
, settingsTemplate
.type
, message
);
212 if (status
!= B_NOT_SUPPORTED
)
216 status_t status
= B_OK
;
218 switch (settingsTemplate
.type
) {
220 status
= message
.AddString(name
, parameter
.values
[i
]);
223 status
= message
.AddInt32(name
, atoi(parameter
.values
[i
]));
227 bool value
=!strcasecmp(parameter
.values
[i
], "true")
228 || !strcasecmp(parameter
.values
[i
], "on")
229 || !strcasecmp(parameter
.values
[i
], "yes")
230 || !strcasecmp(parameter
.values
[i
], "enabled")
231 || !strcasecmp(parameter
.values
[i
], "1");
232 status
= message
.AddBool(name
, value
);
236 // Is handled outside of this method
246 if (parameter
.value_count
== 0) {
247 if (settingsTemplate
.converter
!= NULL
) {
249 = settingsTemplate
.converter
->ConvertEmptyFromDriverSettings(
250 parameter
, name
, settingsTemplate
.type
, message
);
251 if (status
== B_NOT_SUPPORTED
)
253 } else if (settingsTemplate
.type
== B_BOOL_TYPE
) {
254 // Empty boolean parameters are always true
255 return message
.AddBool(name
, true);
264 DriverSettingsMessageAdapter::_ConvertFromDriverParameter(
265 const driver_parameter
& parameter
,
266 const settings_template
* settingsTemplate
, BMessage
& message
)
268 settingsTemplate
= _FindSettingsTemplate(settingsTemplate
, parameter
.name
);
269 if (settingsTemplate
== NULL
) {
270 // We almost silently ignore this kind of issues
271 fprintf(stderr
, "unknown parameter %s\n", parameter
.name
);
275 status_t status
= _AddParameter(parameter
, *settingsTemplate
, message
);
279 if (settingsTemplate
->type
== B_MESSAGE_TYPE
) {
281 for (int32 j
= 0; j
< parameter
.parameter_count
; j
++) {
282 status
= _ConvertFromDriverParameter(parameter
.parameters
[j
],
283 settingsTemplate
->sub_template
, subMessage
);
288 const settings_template
* parentValueTemplate
289 = _FindParentValueTemplate(settingsTemplate
);
290 if (parentValueTemplate
!= NULL
)
291 status
= _AddParameter(parameter
, *parentValueTemplate
, subMessage
);
293 status
= message
.AddMessage(parameter
.name
, &subMessage
);
301 DriverSettingsMessageAdapter::_AppendSettings(
302 const settings_template
* settingsTemplate
, BString
& settings
,
303 const BMessage
& message
, const char* name
, type_code type
, int32 count
,
304 const char* settingName
)
306 const settings_template
* valueTemplate
307 = _FindSettingsTemplate(settingsTemplate
, name
);
308 if (valueTemplate
== NULL
) {
309 fprintf(stderr
, "unknown field %s\n", name
);
313 if (valueTemplate
->type
!= type
) {
314 fprintf(stderr
, "field type mismatch %s\n", name
);
318 if (settingName
== NULL
)
321 if (type
!= B_MESSAGE_TYPE
) {
322 settings
.Append("\n");
323 settings
.Append(settingName
);
324 settings
.Append("\t");
327 for (int32 valueIndex
= 0; valueIndex
< count
; valueIndex
++) {
328 if (valueIndex
> 0 && type
!= B_MESSAGE_TYPE
)
329 settings
.Append(" ");
331 if (valueTemplate
->converter
!= NULL
) {
332 status_t status
= valueTemplate
->converter
->ConvertToDriverSettings(
333 message
, name
, type
, valueIndex
, settings
);
336 if (status
!= B_NOT_SUPPORTED
)
344 status_t result
= message
.FindBool(name
, valueIndex
, &value
);
348 settings
.Append(value
? "true" : "false");
354 const char* value
= NULL
;
355 status_t result
= message
.FindString(name
, valueIndex
, &value
);
359 settings
.Append(value
);
366 status_t result
= message
.FindInt32(name
, valueIndex
, &value
);
371 snprintf(buffer
, sizeof(buffer
), "%" B_PRId32
, value
);
372 settings
.Append(buffer
, sizeof(buffer
));
379 status_t result
= message
.FindMessage(name
, valueIndex
,
384 const settings_template
* parentValueTemplate
385 = _FindParentValueTemplate(valueTemplate
);
386 if (parentValueTemplate
!= NULL
) {
387 _AppendSettings(valueTemplate
->sub_template
, settings
,
388 subMessage
, parentValueTemplate
->name
,
389 parentValueTemplate
->type
, 1, name
);
390 subMessage
.RemoveName(parentValueTemplate
->name
);
394 ConvertToDriverSettings(valueTemplate
->sub_template
,
395 subSettings
, subMessage
);
396 subSettings
.ReplaceAll("\n", "\n\t");
397 subSettings
.RemoveFirst("\n");
399 if (!subSettings
.IsEmpty()) {
400 settings
.Append(" {\n");
401 settings
.Append(subSettings
);
402 settings
.Append("\n}");