1 /* 2 * Copyright 2004-2007, Waldemar Kornewald <wkornew@gmx.net> 3 * Distributed under the terms of the MIT License. 4 */ 5 6 #include "MessageDriverSettingsUtils.h" 7 8 #include <PPPDefs.h> 9 #include <settings_tools.h> 10 #include <File.h> 11 #include <Message.h> 12 #include <String.h> 13 14 #include <cstdio> 15 16 17 static bool AddParameters(const BMessage& message, driver_settings *to); 18 19 20 bool 21 FindMessageParameter(const char *name, const BMessage& message, BMessage *save, 22 int32 *startIndex) 23 { 24 // XXX: this should be removed when we can replace BMessage with something better 25 BString string; 26 int32 index = startIndex ? *startIndex : 0; 27 for (; message.FindMessage(MDSU_PARAMETERS, index, save) == B_OK; index++) { 28 if (save->FindString(MDSU_NAME, &string) == B_OK 29 && string.ICompare(name) == 0) { 30 if (startIndex) 31 *startIndex = index; 32 return true; 33 } 34 } 35 36 return false; 37 } 38 39 40 static 41 bool 42 AddValues(const BMessage& message, driver_parameter *parameter) 43 { 44 const char *value; 45 for (int32 index = 0; message.FindString(MDSU_VALUES, index, &value) == B_OK; 46 index++) 47 if (!add_driver_parameter_value(value, parameter)) 48 return false; 49 50 return true; 51 } 52 53 54 inline 55 bool 56 AddParameters(const BMessage& message, driver_parameter *to) 57 { 58 if (!to) 59 return false; 60 61 return AddParameters(message, 62 reinterpret_cast<driver_settings*>(&to->parameter_count)); 63 } 64 65 66 static 67 bool 68 AddParameters(const BMessage& message, driver_settings *to) 69 { 70 const char *name; 71 BMessage current; 72 driver_parameter *parameter; 73 for (int32 index = 0; message.FindMessage(MDSU_PARAMETERS, index, 74 ¤t) == B_OK; index++) { 75 name = current.FindString(MDSU_NAME); 76 parameter = new_driver_parameter(name); 77 if (!AddValues(current, parameter)) 78 return false; 79 80 AddParameters(current, parameter); 81 add_driver_parameter(parameter, to); 82 } 83 84 return true; 85 } 86 87 88 driver_settings* 89 MessageToDriverSettings(const BMessage& message) 90 { 91 driver_settings *settings = new_driver_settings(); 92 93 if (!AddParameters(message, settings)) { 94 free_driver_settings(settings); 95 return NULL; 96 } 97 98 return settings; 99 } 100 101 102 static 103 bool 104 AddParameter(const driver_parameter *parameter, BMessage *message) 105 { 106 if (!parameter || !message) 107 return false; 108 109 if (parameter->name) 110 message->AddString(MDSU_NAME, parameter->name); 111 else 112 return false; 113 114 for (int32 index = 0; index < parameter->value_count; index++) 115 if (parameter->values[index]) 116 message->AddString(MDSU_VALUES, parameter->values[index]); 117 118 for (int32 index = 0; index < parameter->parameter_count; index++) { 119 BMessage parameterMessage; 120 AddParameter(¶meter->parameters[index], ¶meterMessage); 121 message->AddMessage(MDSU_PARAMETERS, ¶meterMessage); 122 } 123 124 return true; 125 } 126 127 128 bool 129 ReadMessageDriverSettings(const char *name, BMessage *message) 130 { 131 if (!name || !message) 132 return false; 133 134 void *handle = load_driver_settings(name); 135 if (!handle) 136 return false; 137 const driver_settings *settings = get_driver_settings(handle); 138 if (!settings) { 139 unload_driver_settings(handle); 140 return false; 141 } 142 143 for (int32 index = 0; index < settings->parameter_count; index++) { 144 BMessage parameter; 145 AddParameter(&settings->parameters[index], ¶meter); 146 message->AddMessage(MDSU_PARAMETERS, ¶meter); 147 } 148 149 unload_driver_settings(handle); 150 151 return true; 152 } 153 154 155 static 156 void 157 EscapeWord(BString& word) 158 { 159 word.ReplaceAll("\\", "\\\\"); 160 word.ReplaceAll("#", "\\#"); 161 word.ReplaceAll("\"", "\\\""); 162 word.ReplaceAll("\'", "\\\'"); 163 } 164 165 166 static 167 bool 168 WriteParameter(BFile& file, const BMessage& parameter, int32 level) 169 { 170 const char *name; 171 if (parameter.FindString(MDSU_NAME, &name) != B_OK || !name) 172 return false; 173 174 BString line, word(name); 175 EscapeWord(word); 176 bool needsEscaping = word.FindFirst(' ') >= 0; 177 line.SetTo('\t', level); 178 if (needsEscaping) 179 line << '\"'; 180 line << word; 181 if (needsEscaping) 182 line << '\"'; 183 184 for (int32 index = 0; parameter.FindString(MDSU_VALUES, index, &name) == B_OK; 185 index++) 186 if (name) { 187 line << ' '; 188 word = name; 189 EscapeWord(word); 190 needsEscaping = word.FindFirst(' ') >= 0; 191 if (needsEscaping) 192 line << '\"'; 193 line << word; 194 if (needsEscaping) 195 line << '\"'; 196 } 197 198 type_code type; 199 int32 parameterCount; 200 parameter.GetInfo(MDSU_PARAMETERS, &type, ¶meterCount); 201 202 if (parameterCount > 0) 203 line << " {"; 204 205 line << '\n'; 206 file.Write(line.String(), line.Length()); 207 208 if (parameterCount > 0) { 209 BMessage subParameter; 210 for (int32 index = 0; parameter.FindMessage(MDSU_PARAMETERS, index, 211 &subParameter) == B_OK; index++) 212 WriteParameter(file, subParameter, level + 1); 213 214 line.SetTo('\t', level); 215 line << "}\n"; 216 file.Write(line.String(), line.Length()); 217 } 218 219 return true; 220 } 221 222 223 bool 224 WriteMessageDriverSettings(BFile& file, const BMessage& message) 225 { 226 if (file.InitCheck() != B_OK || !file.IsWritable()) 227 return false; 228 229 file.SetSize(0); 230 file.Seek(0, SEEK_SET); 231 232 BMessage parameter; 233 for (int32 index = 0; message.FindMessage(MDSU_PARAMETERS, index, ¶meter) == B_OK; 234 index++) { 235 if (index > 0) 236 file.Write("\n", 1); 237 WriteParameter(file, parameter, 0); 238 } 239 240 return true; 241 } 242