mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-04 19:25:29 +00:00
Now the preprocessor output is also a stream, and so is the parser input, ...
...hence they can be plugged, yay. Also introduce a scoped_istream to prevent leaking descriptors in case of exceptions. Once again, the stream changes are purely on the interface level for the time being, so there can be a slight performance hit when no cache is present. But once the cache is built, everything should be fine, even faster than it was before the changes. And isn't that the point of a cache?
This commit is contained in:
parent
507183d9b2
commit
d21e4149d6
@ -44,7 +44,8 @@ private:
|
||||
|
||||
int campaign_server::load_config()
|
||||
{
|
||||
read(cfg_, read_file(file_));
|
||||
scoped_istream stream = stream_file(file_);
|
||||
read(cfg_, *stream);
|
||||
return lexical_cast_default<int>(cfg_["port"], 15002);
|
||||
}
|
||||
|
||||
@ -90,9 +91,8 @@ void campaign_server::run()
|
||||
network::send_data(construct_error("Campaign not found."),sock);
|
||||
} else {
|
||||
config cfg;
|
||||
std::istream *stream = stream_file((*campaign)["filename"]);
|
||||
scoped_istream stream = stream_file((*campaign)["filename"]);
|
||||
read_compressed(cfg, *stream);
|
||||
delete stream;
|
||||
network::queue_data(cfg,sock);
|
||||
|
||||
const int downloads = lexical_cast_default<int>((*campaign)["downloads"],0)+1;
|
||||
|
@ -99,7 +99,8 @@ map_editor::map_editor(display &gui, gamemap &map, config &theme, config &game_c
|
||||
// Perform some initializations that should only be performed
|
||||
// the first time the editor object is created.
|
||||
try {
|
||||
read(prefs_, read_file(prefs_filename));
|
||||
scoped_istream stream = stream_file(prefs_filename);
|
||||
read(prefs_, *stream);
|
||||
}
|
||||
catch (config::error e) {
|
||||
std::cerr << "Error when reading " << prefs_filename << ": "
|
||||
|
@ -227,7 +227,8 @@ int main(int argc, char** argv)
|
||||
//Read the configuration af
|
||||
config cfg;
|
||||
try {
|
||||
read(cfg, preprocess_file("data/game.cfg", &defines_map));
|
||||
scoped_istream stream = preprocess_file("data/game.cfg", &defines_map);
|
||||
read(cfg, *stream);
|
||||
}
|
||||
catch (config::error e) {
|
||||
std::cerr << "Error when reading game config: '" << e.message << "'" << std::endl;
|
||||
|
@ -825,3 +825,13 @@ std::string get_binary_file_location(const std::string& type, const std::string&
|
||||
return "";
|
||||
}
|
||||
|
||||
void scoped_istream::operator=(std::istream *s)
|
||||
{
|
||||
delete stream;
|
||||
stream = s;
|
||||
}
|
||||
|
||||
scoped_istream::~scoped_istream()
|
||||
{
|
||||
delete stream;
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@ -139,4 +140,14 @@ const std::vector<std::string>& get_binary_paths(const std::string& type);
|
||||
//the file isn't present
|
||||
std::string get_binary_file_location(const std::string& type, const std::string& filename);
|
||||
|
||||
class scoped_istream {
|
||||
std::istream *stream;
|
||||
public:
|
||||
scoped_istream(std::istream *s): stream(s) {}
|
||||
void operator=(std::istream *);
|
||||
std::istream &operator*() { return *stream; }
|
||||
std::istream *operator->() { return stream; }
|
||||
~scoped_istream();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1322,7 +1322,8 @@ bool load_font_config()
|
||||
//config when changing languages
|
||||
config cfg;
|
||||
try {
|
||||
read(cfg, preprocess_file("data/fonts.cfg"));
|
||||
scoped_istream stream = preprocess_file("data/fonts.cfg");
|
||||
read(cfg, *stream);
|
||||
} catch(config::error&) {
|
||||
std::cerr << "Could not read fonts.cfg\n";
|
||||
return false;
|
||||
|
25
src/game.cpp
25
src/game.cpp
@ -256,7 +256,8 @@ void read_game_cfg(preproc_map& defines, std::vector<line_source>& line_src, con
|
||||
try {
|
||||
if(file_exists(fname_checksum)) {
|
||||
config checksum_cfg;
|
||||
read(checksum_cfg, read_file(fname_checksum));
|
||||
scoped_istream stream = stream_file(fname_checksum);
|
||||
read(checksum_cfg, *stream);
|
||||
dir_checksum = file_tree_checksum(checksum_cfg);
|
||||
}
|
||||
} catch(config::error&) {
|
||||
@ -269,12 +270,9 @@ void read_game_cfg(preproc_map& defines, std::vector<line_source>& line_src, con
|
||||
if(use_cache && file_exists(fname) && file_create_time(fname) > data_tree_checksum().modified && dir_checksum == data_tree_checksum()) {
|
||||
std::cerr << "found valid cache at '" << fname << "' using it\n";
|
||||
log_scope("read cache");
|
||||
compression_schema schema;
|
||||
|
||||
try {
|
||||
std::istream *stream = stream_file(fname);
|
||||
read_compressed(cfg, *stream, schema);
|
||||
delete stream;
|
||||
scoped_istream stream = stream_file(fname);
|
||||
read_compressed(cfg, *stream);
|
||||
return;
|
||||
} catch(config::error&) {
|
||||
std::cerr << "cache is corrupt. Loading from files\n";
|
||||
@ -286,10 +284,10 @@ void read_game_cfg(preproc_map& defines, std::vector<line_source>& line_src, con
|
||||
std::cerr << "no valid cache found. Writing cache to '" << fname << "'\n";
|
||||
|
||||
//read the file and then write to the cache
|
||||
read(cfg, preprocess_file("data/game.cfg", &defines, &line_src), &line_src);
|
||||
scoped_istream stream = preprocess_file("data/game.cfg", &defines, &line_src);
|
||||
read(cfg, *stream, &line_src);
|
||||
try {
|
||||
compression_schema schema;
|
||||
write_file(fname, write_compressed(cfg, schema));
|
||||
write_file(fname, write_compressed(cfg));
|
||||
|
||||
config checksum_cfg;
|
||||
data_tree_checksum().write(checksum_cfg);
|
||||
@ -305,7 +303,8 @@ void read_game_cfg(preproc_map& defines, std::vector<line_source>& line_src, con
|
||||
}
|
||||
|
||||
std::cerr << "caching cannot be done. Reading file\n";
|
||||
read(cfg, preprocess_file("data/game.cfg", &defines, &line_src), &line_src);
|
||||
scoped_istream stream = preprocess_file("data/game.cfg", &defines, &line_src);
|
||||
read(cfg, *stream, &line_src);
|
||||
}
|
||||
|
||||
bool less_campaigns_rank(const config* a, const config* b) {
|
||||
@ -1525,8 +1524,8 @@ int play_game(int argc, char** argv)
|
||||
const std::string input(argv[arg+1]);
|
||||
const std::string output(argv[arg+2]);
|
||||
|
||||
const std::string in(read_file(input));
|
||||
if(in == "") {
|
||||
scoped_istream stream = stream_file(input);
|
||||
if (stream->fail()) {
|
||||
std::cerr << "could not read file '" << input << "'\n";
|
||||
return 0;
|
||||
}
|
||||
@ -1535,7 +1534,7 @@ int play_game(int argc, char** argv)
|
||||
|
||||
const bool compress = val == "--compress";
|
||||
try {
|
||||
const bool is_compressed = detect_format_and_read(cfg, in);
|
||||
const bool is_compressed = detect_format_and_read(cfg, *stream);
|
||||
if(is_compressed && compress) {
|
||||
std::cerr << input << " is already compressed\n";
|
||||
return 0;
|
||||
|
@ -418,13 +418,12 @@ void read_save_file(const std::string& name, config& cfg)
|
||||
std::replace(modified_name.begin(),modified_name.end(),' ','_');
|
||||
|
||||
//try reading the file both with and without underscores
|
||||
std::string file_data = read_file(get_saves_dir() + "/" + modified_name);
|
||||
if(file_data.empty()) {
|
||||
file_data = read_file(get_saves_dir() + "/" + name);
|
||||
}
|
||||
scoped_istream file_stream = stream_file(get_saves_dir() + "/" + modified_name);
|
||||
if (file_stream->fail())
|
||||
file_stream = stream_file(get_saves_dir() + "/" + name);
|
||||
|
||||
cfg.clear();
|
||||
detect_format_and_read(cfg, file_data);
|
||||
detect_format_and_read(cfg, *file_stream);
|
||||
|
||||
if(cfg.empty()) {
|
||||
std::cerr << "Could not parse file data into config\n";
|
||||
@ -479,7 +478,8 @@ config& save_index()
|
||||
{
|
||||
if(save_index_loaded == false) {
|
||||
try {
|
||||
detect_format_and_read(save_index_cfg, read_file(get_save_index_file()));
|
||||
scoped_istream stream = stream_file(get_save_index_file());
|
||||
detect_format_and_read(save_index_cfg, *stream);
|
||||
} catch(io_exception& e) {
|
||||
std::cerr << "error reading save index: '" << e.what() << "'\n";
|
||||
} catch(config::error&) {
|
||||
|
@ -1677,7 +1677,8 @@ void help_text_area::set_items() {
|
||||
// Should be parsed as WML.
|
||||
try {
|
||||
config cfg;
|
||||
read(cfg, *it);
|
||||
std::istringstream stream(*it);
|
||||
read(cfg, stream);
|
||||
config *child = cfg.child("ref");
|
||||
if (child != NULL) {
|
||||
handle_ref_cfg(*child);
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "global.hpp"
|
||||
|
||||
#include "config.hpp"
|
||||
#include "filesystem.hpp"
|
||||
#include "gettext.hpp"
|
||||
#include "language.hpp"
|
||||
#include "preferences.hpp"
|
||||
@ -158,7 +159,8 @@ bool set_language(const language_def& locale)
|
||||
|
||||
// fill string_table (should be moved somwhere else some day)
|
||||
try {
|
||||
read(cfg, preprocess_file("data/translations/english.cfg"));
|
||||
scoped_istream stream = preprocess_file("data/translations/english.cfg");
|
||||
read(cfg, *stream);
|
||||
} catch(config::error& e) {
|
||||
std::cerr << "Could not read english.cfg\n";
|
||||
throw e;
|
||||
|
@ -68,7 +68,8 @@ namespace preferences {
|
||||
|
||||
manager::manager()
|
||||
{
|
||||
read(prefs, read_file(get_prefs_file()));
|
||||
scoped_istream stream = stream_file(get_prefs_file());
|
||||
read(prefs, *stream);
|
||||
set_music_volume(music_volume());
|
||||
set_sound_volume(sound_volume());
|
||||
|
||||
|
@ -26,7 +26,8 @@ void setup_dirs()
|
||||
|
||||
void get_campaign_info(const std::string& campaign_name, config& cfg)
|
||||
{
|
||||
read(cfg, read_file(campaign_dir() + "/" + campaign_name + ".pbl"));
|
||||
scoped_istream stream = stream_file(campaign_dir() + "/" + campaign_name + ".pbl");
|
||||
read(cfg, *stream);
|
||||
}
|
||||
|
||||
void set_campaign_info(const std::string& campaign_name, const config& cfg)
|
||||
|
@ -16,17 +16,14 @@
|
||||
#include "serialization/binary_wml.hpp"
|
||||
#include "serialization/parser.hpp"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
bool detect_format_and_read(config &cfg, std::string const &data)
|
||||
bool detect_format_and_read(config &cfg, std::istream &in)
|
||||
{
|
||||
try {
|
||||
std::istringstream stream(data);
|
||||
read_compressed(cfg, stream);
|
||||
read_compressed(cfg, in);
|
||||
return true;
|
||||
} catch (config::error &) {
|
||||
}
|
||||
|
||||
read(cfg, data);
|
||||
read(cfg, in);
|
||||
return false;
|
||||
}
|
||||
|
@ -50,8 +50,17 @@ line_source get_line_source(std::vector< line_source > const &line_src, int line
|
||||
return res;
|
||||
}
|
||||
|
||||
void read(config &cfg, std::string const &data, std::vector< line_source > const *line_sources)
|
||||
void read(config &cfg, std::istream &data_in, std::vector< line_source > const *line_sources)
|
||||
{
|
||||
std::string data_str;
|
||||
{
|
||||
//temporary, only here to accomodate the old parser
|
||||
std::stringstream tmp_in;
|
||||
tmp_in << data_in.rdbuf();
|
||||
data_str = tmp_in.str();
|
||||
}
|
||||
std::string const &data = data_str;
|
||||
|
||||
cfg.clear();
|
||||
|
||||
std::stack< std::string > element_names;
|
||||
|
@ -14,7 +14,7 @@
|
||||
#ifndef SERIALIZATION_PARSER_HPP_INCLUDED
|
||||
#define SERIALIZATION_PARSER_HPP_INCLUDED
|
||||
|
||||
#include <string>
|
||||
#include <iosfwd>
|
||||
#include <vector>
|
||||
|
||||
class config;
|
||||
@ -23,13 +23,13 @@ struct line_source;
|
||||
line_source get_line_source(std::vector< line_source > const &line_src, int line);
|
||||
|
||||
//read data in, clobbering existing data.
|
||||
void read(config &cfg, std::string const &data, std::vector< line_source > const *lines = 0); //throws config::error
|
||||
void read(config &cfg, std::istream &in, std::vector< line_source > const *lines = 0); //throws config::error
|
||||
|
||||
std::string write(config const &cfg);
|
||||
|
||||
//function which reads a file, and automatically detects whether it's compressed or not before
|
||||
//reading it. If it's not a valid file at all, it will throw an error as if it was trying to
|
||||
//read it as text WML. Returns true iff the format is compressed
|
||||
bool detect_format_and_read(config &cfg, std::string const &data); //throws config::error
|
||||
bool detect_format_and_read(config &cfg, std::istream &in); //throws config::error
|
||||
|
||||
#endif
|
||||
|
@ -389,7 +389,7 @@ void internal_preprocess_file(const std::string& fname,
|
||||
|
||||
} //end anonymous namespace
|
||||
|
||||
std::string preprocess_file(std::string const &fname,
|
||||
std::istream *preprocess_file(std::string const &fname,
|
||||
const preproc_map* defines,
|
||||
std::vector<line_source>* line_sources)
|
||||
{
|
||||
@ -401,5 +401,5 @@ std::string preprocess_file(std::string const &fname,
|
||||
std::vector<char> res;
|
||||
int linenum = 0;
|
||||
internal_preprocess_file(fname,defines_copy,0,res,line_sources,linenum);
|
||||
return std::string(res.begin(),res.end());
|
||||
return new std::istringstream(std::string(res.begin(), res.end()));
|
||||
}
|
||||
|
@ -14,6 +14,7 @@
|
||||
#ifndef SERIALIZATION_PREPROCESSOR_HPP_INCLUDED
|
||||
#define SERIALIZATION_PREPROCESSOR_HPP_INCLUDED
|
||||
|
||||
#include <iosfwd>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@ -48,8 +49,8 @@ typedef std::map< std::string, preproc_define > preproc_map;
|
||||
//function to use the WML preprocessor on a file, and returns the resulting
|
||||
//preprocessed file data. defines is a map of symbols defined. src is used
|
||||
//internally and should be set to NULL
|
||||
std::string preprocess_file(std::string const &fname,
|
||||
preproc_map const *defines = NULL,
|
||||
std::vector< line_source > *src = NULL);
|
||||
std::istream *preprocess_file(std::string const &fname,
|
||||
preproc_map const *defines = NULL,
|
||||
std::vector< line_source > *src = NULL);
|
||||
|
||||
#endif
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "cursor.hpp"
|
||||
#include "display.hpp"
|
||||
#include "events.hpp"
|
||||
#include "filesystem.hpp"
|
||||
#include "font.hpp"
|
||||
#include "game_config.hpp"
|
||||
#include "hotkeys.hpp"
|
||||
@ -126,7 +127,8 @@ const config get_tips_of_day()
|
||||
|
||||
std::cerr << "Loading tips of day\n";
|
||||
try {
|
||||
read(cfg, preprocess_file("data/tips.cfg"));
|
||||
scoped_istream stream = preprocess_file("data/tips.cfg");
|
||||
read(cfg, *stream);
|
||||
} catch(config::error&) {
|
||||
std::cerr << "Could not read tips.cfg\n";
|
||||
}
|
||||
|
@ -27,12 +27,12 @@ cutter::cutter() : verbose_(false)
|
||||
const config cutter::load_config(const std::string &filename)
|
||||
{
|
||||
const std::string conf_string = find_configuration(filename);
|
||||
const std::string pre_conf_string = preprocess_file(conf_string);
|
||||
|
||||
config res;
|
||||
|
||||
try {
|
||||
read(res, pre_conf_string);
|
||||
scoped_istream stream = preprocess_file(conf_string);
|
||||
read(res, *stream);
|
||||
} catch(config::error err) {
|
||||
throw exploder_failure("Unable to load the configuration for the file " + filename + ": "+ err.message);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user