1 /* 2 * Copyright 2006-2013, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Axel Dörfler, axeld@pinc-software.de 7 * Michael Lotz <mmlr@mlotz.ch> 8 */ 9 10 11 #include "DriverSettingsMessageAdapter.h" 12 13 #include <stdio.h> 14 #include <stdlib.h> 15 16 #include <File.h> 17 #include <String.h> 18 19 20 DriverSettingsMessageAdapter::DriverSettingsMessageAdapter() 21 { 22 } 23 24 25 DriverSettingsMessageAdapter::~DriverSettingsMessageAdapter() 26 { 27 } 28 29 30 status_t 31 DriverSettingsMessageAdapter::ConvertFromDriverSettings( 32 const driver_settings& settings, const settings_template* settingsTemplate, 33 BMessage& message) 34 { 35 message.MakeEmpty(); 36 37 for (int32 i = 0; i < settings.parameter_count; i++) { 38 status_t status = _ConvertFromDriverParameter(settings.parameters[i], 39 settingsTemplate, message); 40 if (status == B_BAD_VALUE) { 41 // ignore unknown entries 42 continue; 43 } 44 if (status != B_OK) 45 return status; 46 } 47 48 return B_OK; 49 } 50 51 52 status_t 53 DriverSettingsMessageAdapter::ConvertFromDriverSettings(const char* path, 54 const settings_template* settingsTemplate, BMessage& message) 55 { 56 void* handle = load_driver_settings(path); 57 if (handle == NULL) 58 return B_ENTRY_NOT_FOUND; 59 60 const driver_settings* settings = get_driver_settings(handle); 61 status_t status; 62 if (settings != NULL) { 63 status = ConvertFromDriverSettings(*settings, settingsTemplate, 64 message); 65 } else 66 status = B_BAD_DATA; 67 68 unload_driver_settings(handle); 69 return status; 70 } 71 72 73 status_t 74 DriverSettingsMessageAdapter::ConvertToDriverSettings( 75 const settings_template* settingsTemplate, BString& settings, 76 const BMessage& message) 77 { 78 int32 index = 0; 79 char *name = NULL; 80 type_code type; 81 int32 count = 0; 82 83 while (message.GetInfo(B_ANY_TYPE, index++, &name, &type, &count) == B_OK) { 84 status_t result = _AppendSettings(settingsTemplate, settings, message, 85 name, type, count); 86 if (result != B_OK) 87 return result; 88 } 89 90 return B_OK; 91 } 92 93 94 status_t 95 DriverSettingsMessageAdapter::ConvertToDriverSettings(const char* path, 96 const settings_template* settingsTemplate, const BMessage& message) 97 { 98 BString settings; 99 status_t status = ConvertToDriverSettings(settingsTemplate, settings, 100 message); 101 if (status != B_OK) 102 return status; 103 104 settings.RemoveFirst("\n"); 105 BFile settingsFile(path, B_WRITE_ONLY | B_ERASE_FILE | B_CREATE_FILE); 106 107 ssize_t written = settingsFile.Write(settings.String(), settings.Length()); 108 if (written < 0) 109 return written; 110 111 return written == settings.Length() ? B_OK : B_ERROR; 112 } 113 114 115 // #pragma mark - 116 117 118 const settings_template* 119 DriverSettingsMessageAdapter::_FindSettingsTemplate( 120 const settings_template* settingsTemplate, const char* name) 121 { 122 while (settingsTemplate->name != NULL) { 123 if (!strcmp(name, settingsTemplate->name)) 124 return settingsTemplate; 125 126 settingsTemplate++; 127 } 128 129 return NULL; 130 } 131 132 133 const settings_template* 134 DriverSettingsMessageAdapter::_FindParentValueTemplate( 135 const settings_template* settingsTemplate) 136 { 137 settingsTemplate = settingsTemplate->sub_template; 138 if (settingsTemplate == NULL) 139 return NULL; 140 141 while (settingsTemplate->name != NULL) { 142 if (settingsTemplate->parent_value) 143 return settingsTemplate; 144 145 settingsTemplate++; 146 } 147 148 return NULL; 149 } 150 151 152 status_t 153 DriverSettingsMessageAdapter::_AddParameter(const driver_parameter& parameter, 154 const char* name, uint32 type, BMessage& message) 155 { 156 for (int32 i = 0; i < parameter.value_count; i++) { 157 switch (type) { 158 case B_STRING_TYPE: 159 message.AddString(name, parameter.values[i]); 160 break; 161 case B_INT32_TYPE: 162 message.AddInt32(name, atoi(parameter.values[i])); 163 break; 164 case B_BOOL_TYPE: 165 if (!strcasecmp(parameter.values[i], "true") 166 || !strcasecmp(parameter.values[i], "on") 167 || !strcasecmp(parameter.values[i], "enabled") 168 || !strcasecmp(parameter.values[i], "1")) 169 message.AddBool(name, true); 170 else 171 message.AddBool(name, false); 172 break; 173 } 174 } 175 if (type == B_BOOL_TYPE && parameter.value_count == 0) { 176 // boolean parameters are always true 177 message.AddBool(name, true); 178 } 179 180 return B_OK; 181 } 182 183 184 status_t 185 DriverSettingsMessageAdapter::_ConvertFromDriverParameter( 186 const driver_parameter& parameter, 187 const settings_template* settingsTemplate, BMessage& message) 188 { 189 settingsTemplate = _FindSettingsTemplate(settingsTemplate, parameter.name); 190 if (settingsTemplate == NULL) { 191 fprintf(stderr, "unknown parameter %s\n", parameter.name); 192 return B_BAD_VALUE; 193 } 194 195 _AddParameter(parameter, parameter.name, settingsTemplate->type, message); 196 197 if (settingsTemplate->type == B_MESSAGE_TYPE 198 && parameter.parameter_count > 0) { 199 status_t status = B_OK; 200 BMessage subMessage; 201 for (int32 j = 0; j < parameter.parameter_count; j++) { 202 status = _ConvertFromDriverParameter(parameter.parameters[j], 203 settingsTemplate->sub_template, subMessage); 204 if (status != B_OK) 205 break; 206 207 const settings_template* parentValueTemplate 208 = _FindParentValueTemplate(settingsTemplate); 209 if (parentValueTemplate != NULL) { 210 _AddParameter(parameter, parentValueTemplate->name, 211 parentValueTemplate->type, subMessage); 212 } 213 } 214 if (status == B_OK) 215 message.AddMessage(parameter.name, &subMessage); 216 } 217 218 return B_OK; 219 } 220 221 222 status_t 223 DriverSettingsMessageAdapter::_AppendSettings( 224 const settings_template* settingsTemplate, BString& settings, 225 const BMessage& message, const char* name, type_code type, int32 count, 226 const char* settingName) 227 { 228 const settings_template* valueTemplate 229 = _FindSettingsTemplate(settingsTemplate, name); 230 if (valueTemplate == NULL) { 231 fprintf(stderr, "unknown field %s\n", name); 232 return B_BAD_VALUE; 233 } 234 235 if (valueTemplate->type != type) { 236 fprintf(stderr, "field type mismatch %s\n", name); 237 return B_BAD_VALUE; 238 } 239 240 if (settingName == NULL) 241 settingName = name; 242 243 if (type != B_MESSAGE_TYPE) { 244 settings.Append("\n"); 245 settings.Append(settingName); 246 settings.Append("\t"); 247 } 248 249 for (int32 valueIndex = 0; valueIndex < count; valueIndex++) { 250 if (valueIndex > 0 && type != B_MESSAGE_TYPE) 251 settings.Append(" "); 252 253 switch (type) { 254 case B_BOOL_TYPE: 255 { 256 bool value; 257 status_t result = message.FindBool(name, valueIndex, &value); 258 if (result != B_OK) 259 return result; 260 261 settings.Append(value ? "true" : "false"); 262 break; 263 } 264 265 case B_STRING_TYPE: 266 { 267 const char* value = NULL; 268 status_t result = message.FindString(name, valueIndex, &value); 269 if (result != B_OK) 270 return result; 271 272 settings.Append(value); 273 break; 274 } 275 276 case B_INT32_TYPE: 277 { 278 int32 value; 279 status_t result = message.FindInt32(name, valueIndex, &value); 280 if (result != B_OK) 281 return result; 282 283 char buffer[100]; 284 snprintf(buffer, sizeof(buffer), "%" B_PRId32, value); 285 settings.Append(buffer, sizeof(buffer)); 286 break; 287 } 288 289 case B_MESSAGE_TYPE: 290 { 291 BMessage subMessage; 292 status_t result = message.FindMessage(name, valueIndex, 293 &subMessage); 294 if (result != B_OK) 295 return result; 296 297 const settings_template* parentValueTemplate 298 = _FindParentValueTemplate(valueTemplate); 299 if (parentValueTemplate != NULL) { 300 _AppendSettings(valueTemplate->sub_template, settings, 301 subMessage, parentValueTemplate->name, 302 parentValueTemplate->type, 1, name); 303 subMessage.RemoveName(parentValueTemplate->name); 304 } 305 306 BString subSettings; 307 ConvertToDriverSettings(valueTemplate->sub_template, 308 subSettings, subMessage); 309 subSettings.ReplaceAll("\n", "\n\t"); 310 subSettings.RemoveFirst("\n"); 311 312 settings.Append(" {\n"); 313 settings.Append(subSettings); 314 settings.Append("\n}"); 315 } 316 } 317 } 318 319 return B_OK; 320 } 321