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