1/* ----------------------------------------------------------------------- 2 * Copyright (c) 2004 Waldemar Kornewald, Waldemar.Kornewald@web.de 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 * DEALINGS IN THE SOFTWARE. 21 * ----------------------------------------------------------------------- */ 22 23#include "MessageDriverSettingsUtils.h" 24 25#include <PPPDefs.h> 26#include <settings_tools.h> 27#include <File.h> 28#include <Message.h> 29#include <String.h> 30 31#include <cstdio> 32 33 34static bool AddParameters(const BMessage& message, driver_settings *to); 35 36 37bool 38FindMessageParameter(const char *name, const BMessage& message, BMessage *save, 39 int32 *startIndex) 40{ 41 // XXX: this should be removed when we can replace BMessage with something better 42 BString string; 43 int32 index = startIndex ? *startIndex : 0; 44 for(; message.FindMessage(MDSU_PARAMETERS, index, save) == B_OK; index++) { 45 if(save->FindString(MDSU_NAME, &string) == B_OK 46 && string.ICompare(name) == 0) { 47 if(startIndex) 48 *startIndex = index; 49 return true; 50 } 51 } 52 53 return false; 54} 55 56 57static 58bool 59AddValues(const BMessage& message, driver_parameter *parameter) 60{ 61 const char *value; 62 for(int32 index = 0; message.FindString(MDSU_VALUES, index, &value) == B_OK; 63 index++) 64 if(!add_driver_parameter_value(value, parameter)) 65 return false; 66 67 return true; 68} 69 70 71inline 72bool 73AddParameters(const BMessage& message, driver_parameter *to) 74{ 75 if(!to) 76 return false; 77 78 return AddParameters(message, 79 reinterpret_cast<driver_settings*>(&to->parameter_count)); 80} 81 82 83static 84bool 85AddParameters(const BMessage& message, driver_settings *to) 86{ 87 const char *name; 88 BMessage current; 89 driver_parameter *parameter; 90 for(int32 index = 0; message.FindMessage(MDSU_PARAMETERS, index, 91 ¤t) == B_OK; index++) { 92 name = current.FindString(MDSU_NAME); 93 parameter = new_driver_parameter(name); 94 if(!AddValues(current, parameter)) 95 return false; 96 97 AddParameters(current, parameter); 98 add_driver_parameter(parameter, to); 99 } 100 101 return true; 102} 103 104 105driver_settings* 106MessageToDriverSettings(const BMessage& message) 107{ 108 driver_settings *settings = new_driver_settings(); 109 110 if(!AddParameters(message, settings)) { 111 free_driver_settings(settings); 112 return NULL; 113 } 114 115 return settings; 116} 117 118 119static 120bool 121AddParameter(const driver_parameter *parameter, BMessage *message) 122{ 123 if(!parameter || !message) 124 return false; 125 126 if(parameter->name) 127 message->AddString(MDSU_NAME, parameter->name); 128 else 129 return false; 130 131 for(int32 index = 0; index < parameter->value_count; index++) 132 if(parameter->values[index]) 133 message->AddString(MDSU_VALUES, parameter->values[index]); 134 135 for(int32 index = 0; index < parameter->parameter_count; index++) { 136 BMessage parameterMessage; 137 AddParameter(¶meter->parameters[index], ¶meterMessage); 138 message->AddMessage(MDSU_PARAMETERS, ¶meterMessage); 139 } 140 141 return true; 142} 143 144 145bool 146ReadMessageDriverSettings(const char *name, BMessage *message) 147{ 148 if(!name || !message) 149 return false; 150 151 void *handle = load_driver_settings(name); 152 if(!handle) 153 return false; 154 const driver_settings *settings = get_driver_settings(handle); 155 if(!settings) { 156 unload_driver_settings(handle); 157 return false; 158 } 159 160 for(int32 index = 0; index < settings->parameter_count; index++) { 161 BMessage parameter; 162 AddParameter(&settings->parameters[index], ¶meter); 163 message->AddMessage(MDSU_PARAMETERS, ¶meter); 164 } 165 166 unload_driver_settings(handle); 167 168 return true; 169} 170 171 172static 173void 174EscapeWord(BString& word) 175{ 176 word.ReplaceAll("\\", "\\\\"); 177 word.ReplaceAll("#", "\\#"); 178 word.ReplaceAll("\"", "\\\""); 179 word.ReplaceAll("\'", "\\\'"); 180} 181 182 183static 184bool 185WriteParameter(BFile& file, const BMessage& parameter, int32 level) 186{ 187 const char *name; 188 if(parameter.FindString(MDSU_NAME, &name) != B_OK || !name) 189 return false; 190 191 BString line, word(name); 192 EscapeWord(word); 193 bool needsEscaping = word.FindFirst(' ') >= 0; 194 line.SetTo('\t', level); 195 if(needsEscaping) 196 line << '\"'; 197 line << word; 198 if(needsEscaping) 199 line << '\"'; 200 201 for(int32 index = 0; parameter.FindString(MDSU_VALUES, index, &name) == B_OK; 202 index++) 203 if(name) { 204 line << ' '; 205 word = name; 206 EscapeWord(word); 207 needsEscaping = word.FindFirst(' ') >= 0; 208 if(needsEscaping) 209 line << '\"'; 210 line << word; 211 if(needsEscaping) 212 line << '\"'; 213 } 214 215 type_code type; 216 int32 parameterCount; 217 parameter.GetInfo(MDSU_PARAMETERS, &type, ¶meterCount); 218 219 if(parameterCount > 0) 220 line << " {"; 221 222 line << '\n'; 223 file.Write(line.String(), line.Length()); 224 225 if(parameterCount > 0) { 226 BMessage subParameter; 227 for(int32 index = 0; parameter.FindMessage(MDSU_PARAMETERS, index, 228 &subParameter) == B_OK; index++) 229 WriteParameter(file, subParameter, level + 1); 230 231 line.SetTo('\t', level); 232 line << "}\n"; 233 file.Write(line.String(), line.Length()); 234 } 235 236 return true; 237} 238 239 240bool 241WriteMessageDriverSettings(BFile& file, const BMessage& message) 242{ 243 if(file.InitCheck() != B_OK || !file.IsWritable()) 244 return false; 245 246 file.SetSize(0); 247 file.Seek(0, SEEK_SET); 248 249 BMessage parameter; 250 for(int32 index = 0; message.FindMessage(MDSU_PARAMETERS, index, ¶meter) == B_OK; 251 index++) { 252 if(index > 0) 253 file.Write("\n", 1); 254 WriteParameter(file, parameter, 0); 255 } 256 257 return true; 258} 259