loader.cpp (4609B)
1 // Copyright (c) 2003 - 2009 Anselm R Garbe <anselm@garbe.us> 2 // See LICENSE for license details. 3 4 extern "C" { 5 #include <sys/stat.h> 6 #include <sys/types.h> 7 } 8 9 #include <fstream> 10 #include <iostream> 11 #include <sstream> 12 13 #include "loader.h" 14 #include "util.h" 15 16 Loader::Loader() { 17 } 18 19 Loader::~Loader() { 20 } 21 22 bool Loader::load(MSettings *settings, string path, 23 bool suppressWarning, bool caseSensitive) 24 { 25 26 ifstream is(path.c_str()); 27 28 if (!is) { 29 if (!suppressWarning) { 30 cerr << "wmi[W " << Util::timestamp() 31 << "]: cannot open/read configuration file '" 32 << path << "', skipping" << endl; 33 } 34 return false; 35 } 36 37 string key = ""; 38 string value = ""; 39 string buf = ""; 40 bool comment = false; 41 bool ignoreWhitespaces = true; 42 bool escape = false; // provides using {#, ", =, \n} characters 43 int c; 44 45 while (!is.eof()) { 46 47 c = is.get(); 48 49 switch (c) { 50 case ' ': 51 case '\t': 52 if (!comment && !ignoreWhitespaces) { 53 buf += c; 54 } 55 escape = false; 56 break; 57 case '"': // toggle ignore whitespace/or escape this character 58 if (!comment) { 59 if (escape) { 60 buf += c; 61 } 62 else { 63 ignoreWhitespaces = !ignoreWhitespaces; 64 } 65 } 66 escape = false; 67 break; 68 case '\\': // escape 69 if (!comment) { 70 if (escape) { 71 buf += c; 72 escape = false; 73 } 74 else { 75 escape = true; 76 } 77 } 78 break; 79 case '#': // comment 80 if (escape) { 81 buf += c; 82 } 83 else { 84 comment = true; 85 } 86 escape = false; 87 break; 88 case '=': 89 if (!comment) { 90 if (escape) { 91 buf += c; 92 } 93 else { 94 key = buf; 95 buf = ""; 96 } 97 } 98 escape = false; 99 break; 100 case '\n': 101 102 #define ENDLINE \ 103 if (!escape) { \ 104 comment = false; \ 105 ignoreWhitespaces = true; \ 106 value = buf; \ 107 if ((key != "") && (value != "")) { \ 108 value = buf; \ 109 if (caseSensitive) { \ 110 (*settings)[key] = value; \ 111 } \ 112 else { \ 113 (*settings)[Util::lowerCase(key)] = value; \ 114 } \ 115 } \ 116 buf = key = value = ""; \ 117 } \ 118 escape = false; \ 119 break; \ 120 121 ENDLINE 122 case EOF : 123 ENDLINE 124 default: 125 if (!comment) { 126 buf += c; 127 } 128 escape = false; 129 break; 130 } 131 } 132 is.close(); 133 134 return true; 135 } 136 137 bool Loader::saveSettings(MSettings *settings, string path) { 138 139 ostringstream content; 140 141 for (MSettings::iterator it = settings->begin(); 142 it != settings->end(); it++) 143 { 144 string value = Util::encodeEscapes((*it).second); 145 if (Util::containsWhitespaces(value)) { 146 content << (*it).first << "=\"" << value << "\"" << endl; 147 } 148 else { 149 content << (*it).first << "=" << value << endl; 150 } 151 } 152 153 return saveFile(path, content.str()); 154 } 155 156 bool Loader::saveFile(string path, string content) { 157 158 string dir = Util::canonicalDir(path); 159 if (!Util::exists(dir.c_str())) { 160 161 mode_t mode = umask(0); 162 mode = (mode ^ (S_IRWXU | S_IRWXG | S_IRWXO)) | S_IWUSR | S_IXUSR; 163 if (mkdir(dir.c_str(), mode) != 0) { 164 cerr << "wmi[W " << Util::timestamp() 165 << "]: cannot create non-existing directory '" 166 << dir << "', skipping" << endl; 167 } 168 } 169 170 ofstream os(path.c_str()); 171 172 if (!os) { 173 cerr << "wmi[W " << Util::timestamp() 174 << "]: cannot open/write configuration file '" 175 << path << "', skipping" << endl; 176 return false; 177 } 178 179 os << content; 180 os.close(); 181 182 return true; 183 184 } 185 186 void Loader::print(MSettings *settings) { 187 188 MSettings::iterator it = settings->begin(); 189 while (it != settings->end()) { 190 cout << (*it).first << "=" << (*it).second << endl; 191 it++; 192 } 193 }