00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "ini_configurator.h"
00016 #include "application_configuration.h"
00017 #include "variable_tokenizer.h"
00018
00019 #include <application/windoze_helper.h>
00020 #include <basis/astring.h>
00021 #include <basis/environment.h>
00022 #include <basis/functions.h>
00023 #include <basis/mutex.h>
00024 #include <basis/utf_conversion.h>
00025 #include <filesystem/byte_filer.h>
00026 #include <filesystem/directory.h>
00027 #include <filesystem/filename.h>
00028 #include <structures/static_memory_gremlin.h>
00029 #include <structures/string_array.h>
00030 #include <structures/string_table.h>
00031 #include <structures/symbol_table.h>
00032
00033 #undef LOG
00034 #define LOG(to_print) printf("%s::%s: %s\n", static_class_name(), func, astring(to_print).s())
00035
00036 using namespace basis;
00037 using namespace filesystem;
00038 using namespace structures;
00039
00040 namespace configuration {
00041
00042
00043
00044
00045 const int MAXIMUM_LINE_INI_CONFIG = 16384;
00046
00047
00048 SAFE_STATIC_CONST(astring, ini_configurator::ini_str_fake_default, ("NoTomatoesNorPotatoesNorQuayle"))
00049
00050 ini_configurator::ini_configurator(const astring &ini_filename,
00051 treatment_of_defaults behavior, file_location_default where)
00052 : configurator(behavior),
00053 _ini_name(new filename),
00054 #ifdef __UNIX__
00055 _parser(new ini_parser("", behavior)),
00056 #endif
00057 _where(where),
00058 _add_spaces(false)
00059 {
00060 name(ini_filename);
00061 }
00062
00063 ini_configurator::~ini_configurator()
00064 {
00065 WHACK(_ini_name);
00066 #ifdef __UNIX__
00067 WHACK(_parser);
00068 #endif
00069 }
00070
00071 astring ini_configurator::name() const { return _ini_name->raw(); }
00072
00073 void ini_configurator::refresh()
00074 {
00075 #ifdef __UNIX__
00076 write_ini_file();
00077 WHACK(_parser);
00078 _parser = new ini_parser("", behavior());
00079 #endif
00080 }
00081
00082 void ini_configurator::name(const astring &name)
00083 {
00084 *_ini_name = name;
00085
00086 bool use_appdir = true;
00087
00088
00089 if (_where == OS_DIRECTORY) use_appdir = false;
00090 if (_where == ALL_USERS_DIRECTORY) use_appdir = false;
00091 #ifndef __WIN32__
00092 use_appdir = true;
00093 #endif
00094
00095 if (!_ini_name->had_directory()) {
00096 if (use_appdir) {
00097
00098
00099 *_ini_name = filename(application_configuration::application_directory(),
00100 _ini_name->basename());
00101 } else if (!use_appdir && (_where == ALL_USERS_DIRECTORY) ) {
00102
00103
00104 directory::make_directory(environment::get("ALLUSERSPROFILE")
00105 + "/" + application_configuration::software_product_name());
00106 *_ini_name = filename(environment::get("ALLUSERSPROFILE")
00107 + "/" + application_configuration::software_product_name(),
00108 _ini_name->basename());
00109 }
00110 }
00111 #ifdef __UNIX__
00112
00113 read_ini_file();
00114 #endif
00115 }
00116
00117 void ini_configurator::sections(string_array &list)
00118 {
00119 list = string_array();
00120
00121 byte_filer section8(*_ini_name, "rb");
00122 if (!section8.good()) return;
00123 astring line_found;
00124
00125
00126 while (section8.read(line_found, MAXIMUM_LINE_INI_CONFIG) > 0) {
00127
00128
00129 line_found.strip_white_spaces();
00130 if (line_found[0] != '[') continue;
00131 line_found.zap(0, 0);
00132 int close_brack_indy = line_found.find(']');
00133 if (negative(close_brack_indy)) continue;
00134 line_found.zap(close_brack_indy, line_found.end());
00135 list += line_found;
00136 }
00137 }
00138
00139
00140 bool ini_configurator::section_exists(const astring §ion)
00141 {
00142 #ifdef __WIN32__
00143 string_table infos;
00144
00145 return get_section(section, infos);
00146 #else
00147 return _parser->section_exists(section);
00148 #endif
00149 }
00150
00151 #ifdef __UNIX__
00152 void ini_configurator::read_ini_file()
00153 {
00154 #ifdef DEBUG_INI_CONFIGURATOR
00155 FUNCDEF("read_ini_file");
00156 #endif
00157 _parser->reset("");
00158 byte_filer ini_file;
00159 bool open_ret = ini_file.open(*_ini_name, "rb");
00160 #ifdef DEBUG_INI_CONFIGURATOR
00161 if (!open_ret) LOG(astring("failed to open ini file: ") + *_ini_name);
00162 if (!ini_file.good()) LOG(astring("ini file not good: ") + *_ini_name);
00163 #endif
00164 if (!open_ret || !ini_file.good()) {
00165 return;
00166 }
00167 int file_size = ini_file.length();
00168
00169 astring contents(' ', file_size + 3);
00170 int bytes_read = ini_file.read((abyte *)contents.observe(), file_size);
00171 contents.zap(bytes_read + 1, contents.end());
00172 _parser->reset(contents);
00173 }
00174
00175 void ini_configurator::write_ini_file()
00176 {
00177 #ifdef DEBUG_INI_CONFIGURATOR
00178 FUNCDEF("write_ini_file");
00179 #endif
00180
00181
00182
00183
00184
00185 byte_filer ini_file;
00186 bool open_ret = ini_file.open(*_ini_name, "wb");
00187
00188 #ifdef DEBUG_INI_CONFIGURATOR
00189 if (!open_ret) LOG(astring("failed to open ini file: ") + *_ini_name);
00190 if (!ini_file.good()) LOG(astring("ini file not good: ") + *_ini_name);
00191 #endif
00192 if (!open_ret || !ini_file.good()) return;
00193
00194
00195 astring text;
00196 _parser->restate(text, _add_spaces);
00197 ini_file.write((abyte *)text.observe(), text.length());
00198 }
00199 #endif //UNIX
00200
00201 bool ini_configurator::delete_section(const astring §ion)
00202 {
00203 #ifdef __WIN32__
00204 return put_profile_string(section, "", "");
00205 #else
00206
00207 bool to_return = _parser->delete_section(section);
00208
00209 write_ini_file();
00210 return to_return;
00211 #endif
00212 }
00213
00214 bool ini_configurator::delete_entry(const astring §ion, const astring &ent)
00215 {
00216 #ifdef __WIN32__
00217 return put_profile_string(section, ent, "");
00218 #else
00219
00220 bool to_return = _parser->delete_entry(section, ent);
00221
00222 write_ini_file();
00223 return to_return;
00224 #endif
00225 }
00226
00227 bool ini_configurator::put(const astring §ion, const astring &entry,
00228 const astring &to_store)
00229 {
00231 if (!to_store.length()) return delete_entry(section, entry);
00232 else if (!entry.length()) return delete_section(section);
00233 else if (!section.length()) return false;
00234 #ifdef __WIN32__
00235 return put_profile_string(section, entry, to_store);
00236 #else
00237
00238 bool to_return = _parser->put(section, entry, to_store);
00239
00240 write_ini_file();
00241 return to_return;
00242 #endif
00243 }
00244
00245 bool ini_configurator::get(const astring §ion, const astring &entry,
00246 astring &found)
00247 {
00248 #ifndef __WIN32__
00249 return _parser->get(section, entry, found);
00250 #else
00251 flexichar temp_buffer[MAXIMUM_LINE_INI_CONFIG];
00252 temp_buffer[0] = 0;
00253 get_profile_string(section, entry, ini_str_fake_default(),
00254 temp_buffer, MAXIMUM_LINE_INI_CONFIG - 1);
00255 found = from_unicode_temp(temp_buffer);
00256 return !(ini_str_fake_default() == found);
00257 #endif
00258 }
00259
00260 bool ini_configurator::get_section(const astring §ion, string_table &info)
00261 {
00263 #ifndef __WIN32__
00264 return _parser->get_section(section, info);
00265 #else
00266 info.reset();
00267 const int buffer_size = 200000;
00268
00269 flexichar low_buff[buffer_size + 3];
00270 int read_len = GetPrivateProfileSection(to_unicode_temp(section.observe()),
00271 low_buff, buffer_size - 1, to_unicode_temp(name()));
00272 if (!read_len) return false;
00273
00274 low_buff[read_len] = '\1';
00275 low_buff[read_len + 1] = '\0';
00276
00277 bool last_was_nil = false;
00278
00279
00280 for (int i = 0; i < read_len; i++) {
00281 if (!low_buff[i] && last_was_nil) {
00282
00283
00284 break;
00285 } else if (!low_buff[i]) {
00286 low_buff[i] = '\1';
00287 last_was_nil = true;
00288 } else last_was_nil = false;
00289 }
00290
00291
00292 astring buff = from_unicode_temp(low_buff);
00293 int length = buff.length();
00294 buff.shrink();
00295 variable_tokenizer parser("\1", "=");
00296 parser.parse(buff);
00297 info = parser.table();
00298 return true;
00299 #endif
00300 }
00301
00302 bool ini_configurator::put_section(const astring §ion,
00303 const string_table &info)
00304 {
00305 #ifdef __WIN32__
00306 variable_tokenizer parser("\1", "=");
00307 parser.table() = info;
00308 astring flat = parser.text_form();
00309 flat += "\1\1";
00310 int len = flat.length();
00311 for (int i = 0; i < len; i++) {
00312 if (flat[i] == '\1') {
00313 flat[i] = '\0';
00314 if (flat[i+1] == ' ') {
00315
00316
00317 flat[i] = ' ';
00318 flat[i + 1] = '\0';
00319 }
00320 }
00321 }
00322 return WritePrivateProfileSection(to_unicode_temp(section),
00323 to_unicode_temp(flat), to_unicode_temp(name()));
00324 #else
00325
00326 bool to_return = _parser->put_section(section, info);
00327
00328 write_ini_file();
00329 return to_return;
00330 #endif
00331 }
00332
00333 #ifdef __WIN32__
00334 bool ini_configurator::put_profile_string(const astring §ion,
00335 const astring &entry, const astring &to_store)
00336 {
00337 return bool(WritePrivateProfileString(to_unicode_temp(section),
00338 entry.length() ? (flexichar *)to_unicode_temp(entry) : NIL,
00339 to_store.length() ? (flexichar *)to_unicode_temp(to_store) : NIL,
00340 to_unicode_temp(name())));
00341 }
00342
00343 void ini_configurator::get_profile_string(const astring §ion,
00344 const astring &entry, const astring &default_value,
00345 flexichar *return_buffer, int buffer_size)
00346 {
00347 GetPrivateProfileString(section.length() ?
00348 (flexichar *)to_unicode_temp(section) : NIL,
00349 entry.length() ? (flexichar *)to_unicode_temp(entry) : NIL,
00350 to_unicode_temp(default_value),
00351 return_buffer, buffer_size, to_unicode_temp(name()));
00352 }
00353 #endif
00354
00355 }
00356
00357