persist_context.cpp

Go to the documentation of this file.
00001 /* $Id: persist_context.cpp 52533 2012-01-07 02:35:17Z shadowmaster $ */
00002 /*
00003    Copyright (C) 2010 - 2012 by Jody Northup
00004    Part of the Battle for Wesnoth Project http://www.wesnoth.org/
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY.
00012 
00013    See the COPYING file for more details.
00014 */
00015 
00016 #include "global.hpp"
00017 
00018 #include "filesystem.hpp"
00019 #include "log.hpp"
00020 #include "persist_context.hpp"
00021 #include "persist_manager.hpp"
00022 #include "serialization/binary_or_text.hpp"
00023 #include "serialization/parser.hpp"
00024 #include "util.hpp"
00025 
00026 config pack_scalar(const std::string &name, const t_string &val)
00027 {
00028     config cfg;
00029     cfg[name] = val;
00030     return cfg;
00031 }
00032 
00033 static std::string get_persist_cfg_name(const std::string &name_space) {
00034     return (get_dir(get_user_data_dir() + "/persist/") + name_space + ".cfg");
00035 }
00036 
00037 void persist_file_context::load() {
00038     std::string cfg_dir = get_dir(get_user_data_dir() + "/persist");
00039     create_directory_if_missing(cfg_dir);
00040 
00041     std::string cfg_name = get_persist_cfg_name(namespace_.root_);
00042     if (file_exists(cfg_name) && !is_directory(cfg_name)) {
00043         scoped_istream file_stream = istream_file(cfg_name);
00044         if (!(file_stream->fail())) {
00045             try {
00046                 read(cfg_,*file_stream);
00047             } catch (config::error &err) {
00048                 LOG_PERSIST << err.message;
00049             }
00050         }
00051     }
00052 }
00053 
00054 persist_file_context::persist_file_context(const std::string &name_space)
00055     : persist_context(name_space)
00056 {
00057     load();
00058     root_node_.init();
00059     active_ = &(root_node_.child(namespace_.next()));
00060 }
00061 
00062 bool persist_file_context::clear_var(const std::string &global, bool immediate)
00063 {
00064 //  if (cfg_.empty()) {
00065 //      load_persist_data(namespace_.root(),cfg_);
00066 //  }
00067 
00068     config bak;
00069     config bactive;
00070     if (immediate) {
00071         bak = cfg_;
00072         bactive = active_->cfg_.child_or_add("variables");
00073         load();
00074         root_node_.init();
00075     }
00076     config &cfg = active_->cfg_.child_or_add("variables");
00077     bool ret(cfg);
00078     if (ret) {
00079         bool exists = cfg.has_attribute(global);
00080         if (!exists) {
00081             if (cfg.child(global)) {
00082                 exists = true;
00083                 std::string::const_iterator index_start = std::find(global.begin(),global.end(),'[');
00084                 if (index_start != global.end())
00085                 {
00086                     const std::string::const_iterator index_end = std::find(global.begin(),global.end(),']');
00087                     const std::string index_str(index_start+1,index_end);
00088                     size_t index = static_cast<size_t>(lexical_cast_default<int>(index_str));
00089                     cfg.remove_child(global,index);
00090                     if (immediate) bactive.remove_child(global,index);
00091                 } else {
00092                     cfg.clear_children(global);
00093                     if (immediate) bactive.clear_children(global);
00094                 }
00095             }
00096         }
00097         if (exists) {
00098             cfg.remove_attribute(global);
00099             if (immediate) bactive.remove_attribute(global);
00100             if (cfg.empty()) {
00101                 active_->cfg_.clear_children("variables");
00102                 active_->cfg_.remove_attribute("variables");
00103                 while ((active_->cfg_.empty()) && (active_->parent_ != NULL)) {
00104                     active_ = active_->parent_;
00105                     active_->remove_child(namespace_.node_);
00106                     namespace_ = namespace_.prev();
00107                 }
00108             }
00109     //      dirty_ = true;
00110             if (!in_transaction_)
00111                 ret = save_context();
00112             else if (immediate) {
00113                 ret = save_context();
00114                 cfg_ = bak;
00115                 root_node_.init();
00116                 active_->cfg_.clear_children("variables");
00117                 active_->cfg_.remove_attribute("variables");
00118                 active_->cfg_.add_child("variables",bactive);
00119                 config &cfg = active_->cfg_.child("variables");
00120                 if (cfg.empty()) {
00121                     active_->cfg_.clear_children("variables");
00122                     active_->cfg_.remove_attribute("variables");
00123                     while ((active_->cfg_.empty()) && (active_->parent_ != NULL)) {
00124                         active_ = active_->parent_;
00125                         active_->remove_child(namespace_.node_);
00126                         namespace_ = namespace_.prev();
00127                     }
00128                 }
00129             } else
00130                 ret = true;
00131         } else {
00132             ret = exists;
00133         }
00134     }
00135     return ret;
00136 }
00137 
00138 config persist_file_context::get_var(const std::string &global) const
00139 {
00140     config ret;
00141 //  if (cfg_.empty()) {
00142 //      load_persist_data(namespace_,cfg_,false);
00143 //  }
00144 
00145     config &cfg = active_->cfg_.child("variables");
00146     if (cfg) {
00147         size_t arrsize = cfg.child_count(global);
00148         if (arrsize > 0) {
00149             for (size_t i = 0; i < arrsize; i++)
00150                 ret.add_child(global,cfg.child(global,i));
00151         } else {
00152             ret = pack_scalar(global,cfg[global]);
00153         }
00154     } else {
00155         ret = pack_scalar(global,"");
00156     }
00157     return ret;
00158 }
00159 bool persist_file_context::save_context() {
00160     bool success = false;
00161 
00162     std::string cfg_name = get_persist_cfg_name(namespace_.root_);
00163     if (!cfg_name.empty()) {
00164         if (cfg_.empty()) {
00165             success = delete_directory(cfg_name);
00166         } else {
00167             scoped_ostream out = ostream_file(cfg_name);
00168             if (!out->fail())
00169             {
00170                 config_writer writer(*out,false);
00171                 try {
00172                     writer.write(cfg_);
00173                     success = true;
00174                 } catch(config::error &err) {
00175                     LOG_PERSIST << err.message;
00176                     success = false;
00177                 }
00178             }
00179         }
00180     }
00181     return success;
00182 }
00183 bool persist_file_context::set_var(const std::string &global,const config &val, bool immediate)
00184 {
00185 //  if (cfg_.empty()) {
00186 //      load_persist_data(namespace_,cfg_);
00187 //  }
00188     config bak;
00189     config bactive;
00190     if (immediate) {
00191         bak = cfg_;
00192         bactive = active_->cfg_.child_or_add("variables");
00193         load();
00194         root_node_.init();
00195     }
00196 
00197     config &cfg = active_->cfg_.child_or_add("variables");
00198     if (val.has_attribute(global)) {
00199         if (val[global].empty()) {
00200             clear_var(global,immediate);
00201         } else {
00202             cfg[global] = val[global];
00203             if (immediate) bactive[global] = val[global];
00204         }
00205     } else {
00206         cfg.clear_children(global);
00207         cfg.append(val);
00208         if (immediate) {
00209             bactive.clear_children(global);
00210             bactive.append(val);
00211         }
00212     }
00213 //  dirty_ = true;
00214     if (!in_transaction_)
00215         return save_context();
00216     else if (immediate) {
00217         bool ret = save_context();
00218         cfg_ = bak;
00219         root_node_.init();
00220         active_->cfg_.clear_children("variables");
00221         active_->cfg_.remove_attribute("variables");
00222         active_->cfg_.add_child("variables",bactive);
00223         return ret;
00224     } else
00225         return true;
00226 }
00227 void persist_context::set_node(const std::string &name) {
00228     active_ = &(root_node_.child(name));
00229     namespace_ = name_space(namespace_.namespace_ + "." + name);
00230 }
00231 
00232 std::string persist_context::get_node() const
00233 {
00234     return namespace_.namespace_;
00235 }
00236 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Fri May 25 2012 01:03:07 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs