Skip to content

Commit

Permalink
allow to write multiple configs in a network package.
Browse files Browse the repository at this point in the history
It is now possible to write multiple config objects in a single package,
the server reads them then as one big config. Prevoulsy if people wanted
to do that they had to copy both configs into a new config which is
slow, specially if those configs are very big becasue they contain a
whole scenario or an era.
  • Loading branch information
gfgtdf committed Jun 5, 2016
1 parent dca57bd commit 033f3c9
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 11 deletions.
47 changes: 47 additions & 0 deletions src/configr_assign.hpp
@@ -0,0 +1,47 @@
/*
Copyright (C) 2014 - 2016 by David White <dave@whitevine.net>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#pragma once

#include <string>
#include "config.hpp"
#include <boost/variant.hpp>

//Similar to config_of but it stores references to configs (instead of cyoping them).
struct configr_of
{
template <typename AT>
configr_of(const std::string& attrname, AT value)
{
this->operator()(attrname, value);
}

configr_of(const config& cfg)
{
this->operator()(cfg);
}

configr_of& operator()(const config& cfg)
{
data_ = &cfg;
return *this;
}

configr_of& operator()(const std::string& tagname, const configr_of& child)
{
subtags_.push_back(std::make_pair(&tagname, &child));
return *this;
}
std::vector<std::pair<const std::string*, const configr_of*>> subtags_;
const config* data_;
};
29 changes: 25 additions & 4 deletions src/serialization/parser.cpp
Expand Up @@ -597,14 +597,35 @@ static void write_internal(config const &cfg, std::ostream &out, std::string& te
}
}

void write(std::ostream &out, config const &cfg, unsigned int level)
static void write_internal(configr_of const &cfg, std::ostream &out, std::string& textdomain, size_t tab = 0)
{
if (tab > max_recursion_levels)
throw config::error("Too many recursion levels in config write");
if (cfg.data_) {
write_internal(*cfg.data_, out, textdomain, tab);
}

for (const auto &pair: cfg.subtags_)
{
assert(pair.first && pair.second);
if (!config::valid_id(*pair.first)) {
ERR_CF << "Config contains invalid tag name '" << *pair.first << "', skipping...\n";
continue;
}
write_open_child(out, *pair.first, tab);
write_internal(*pair.second, out, textdomain, tab + 1);
write_close_child(out, *pair.first, tab);
}
}

void write(std::ostream &out, configr_of const &cfg, unsigned int level)
{
std::string textdomain = PACKAGE;
write_internal(cfg, out, textdomain, level);
}

template <typename compressor>
void write_compressed(std::ostream &out, config const &cfg)
void write_compressed(std::ostream &out, configr_of const &cfg)
{
boost::iostreams::filtering_stream<boost::iostreams::output> filter;
filter.push(compressor());
Expand All @@ -615,12 +636,12 @@ void write_compressed(std::ostream &out, config const &cfg)
filter << "\n";
}

void write_gz(std::ostream &out, config const &cfg)
void write_gz(std::ostream &out, configr_of const &cfg)
{
write_compressed<boost::iostreams::gzip_compressor>(out, cfg);
}

void write_bz2(std::ostream &out, config const &cfg)
void write_bz2(std::ostream &out, configr_of const &cfg)
{
write_compressed<boost::iostreams::bzip2_compressor>(out, cfg);
}
8 changes: 4 additions & 4 deletions src/serialization/parser.hpp
Expand Up @@ -20,7 +20,7 @@

#include "global.hpp"
#include "config.hpp"

#include "configr_assign.hpp"

class abstract_validator;
// Read data in, clobbering existing data.
Expand All @@ -33,9 +33,9 @@ void read_gz(config &cfg, std::istream &in,
void read_bz2(config &cfg, std::istream &in,
abstract_validator * validator = nullptr);

void write(std::ostream &out, config const &cfg, unsigned int level=0);
void write_gz(std::ostream &out, config const &cfg);
void write_bz2(std::ostream &out, config const &cfg);
void write(std::ostream &out, configr_of const &cfg, unsigned int level=0);
void write_gz(std::ostream &out, configr_of const &cfg);
void write_bz2(std::ostream &out, configr_of const &cfg);
void write_key_val(std::ostream &out, const std::string &key, const config::attribute_value &value, unsigned level, std::string &textdomain);
void write_open_child(std::ostream &out, const std::string &child, unsigned int level);
void write_close_child(std::ostream &out, const std::string &child, unsigned int level);
Expand Down
2 changes: 1 addition & 1 deletion src/wesnothd_connection.cpp
Expand Up @@ -111,7 +111,7 @@ void twesnothd_connection::handle_handshake(const error_code& ec)
recv();
}

void twesnothd_connection::send_data(const config& request)
void twesnothd_connection::send_data(const configr_of& request)
{
poll();
send_queue_.emplace_back();
Expand Down
4 changes: 2 additions & 2 deletions src/wesnothd_connection.hpp
Expand Up @@ -33,7 +33,7 @@
#include <list>
#include "exceptions.hpp"
#include "wesnothd_connection_error.hpp"

#include "configr_assign.hpp"
class config;

/** A class that represents a TCP/IP connection to the wesnothd server. */
Expand All @@ -50,7 +50,7 @@ class twesnothd_connection : boost::noncopyable
*/
twesnothd_connection(const std::string& host, const std::string& service);

void send_data(const config& request);
void send_data(const configr_of& request);

bool receive_data(config& result);

Expand Down

0 comments on commit 033f3c9

Please sign in to comment.