fix to memory leak in wesnothd
This commit is contained in:
parent
36fa12d2d9
commit
a5ba61e6ed
3 changed files with 27 additions and 22 deletions
|
@ -252,7 +252,7 @@ void game::update_side_data() {
|
|||
if (!lg::debug.dont_log(log_server)) {
|
||||
for (simple_wml::node::child_list::const_iterator side = level_sides.begin();
|
||||
side != level_sides.end(); ++side)
|
||||
DBG_GAME << "[side]\n" << (**side).output() << "[/side]\n";
|
||||
DBG_GAME << "[side]\n" << simple_wml::node_to_string(**side) << "[/side]\n";
|
||||
}
|
||||
// For each user:
|
||||
// * Find the username.
|
||||
|
@ -763,7 +763,7 @@ bool game::process_turn(simple_wml::document& data, const player_map::const_iter
|
|||
if (!is_current_player(user->first)
|
||||
&& !is_legal_command(**command, player)) {
|
||||
LOG_GAME << "ILLEGAL COMMAND in game: " << id_ << " ((("
|
||||
<< (**command).output() << ")))\n";
|
||||
<< simple_wml::node_to_string(**command) << ")))\n";
|
||||
std::stringstream msg;
|
||||
msg << "Removing illegal command '" << (**command).first_child().to_string()
|
||||
<< "' from: " << user->second.name()
|
||||
|
@ -942,7 +942,6 @@ bool game::add_player(const network::connection player, bool observer) {
|
|||
user->second.set_status((observer || became_observer) ? player::OBSERVING : player::PLAYING);
|
||||
DBG_GAME << debug_player_info();
|
||||
// Send the user the game data.
|
||||
//std::cerr << "SENDING LEVEL {{{" << level_.output() << "}}}\n";
|
||||
if (!wesnothd::send_to_one(level_, player)) return false;
|
||||
|
||||
if(started_) {
|
||||
|
@ -1224,7 +1223,7 @@ void game::save_replay() {
|
|||
const simple_wml::node::child_list& turn_list = (*i)->root().children("turn");
|
||||
for (simple_wml::node::child_list::const_iterator turn = turn_list.begin();
|
||||
turn != turn_list.end(); ++turn) {
|
||||
replay_commands += (*turn)->output();
|
||||
replay_commands += simple_wml::node_to_string(**turn);
|
||||
}
|
||||
delete *i;
|
||||
}
|
||||
|
|
|
@ -691,11 +691,13 @@ void node::shift_buffers(ptrdiff_t offset)
|
|||
}
|
||||
}
|
||||
|
||||
void node::output(char*& buf)
|
||||
void node::output(char*& buf, CACHE_STATUS cache_status)
|
||||
{
|
||||
if(output_cache_.empty() == false) {
|
||||
memcpy(buf, output_cache_.begin(), output_cache_.size());
|
||||
shift_buffers(buf - output_cache_.begin());
|
||||
if(cache_status == REFRESH_CACHE) {
|
||||
shift_buffers(buf - output_cache_.begin());
|
||||
}
|
||||
buf += output_cache_.size();
|
||||
return;
|
||||
}
|
||||
|
@ -726,7 +728,7 @@ void node::output(char*& buf)
|
|||
buf += attr.size();
|
||||
*buf++ = ']';
|
||||
*buf++ = '\n';
|
||||
children_[i->child_map_index].second[i->child_list_index]->output(buf);
|
||||
children_[i->child_map_index].second[i->child_list_index]->output(buf, cache_status);
|
||||
*buf++ = '[';
|
||||
*buf++ = '/';
|
||||
memcpy(buf, attr.begin(), attr.size());
|
||||
|
@ -735,20 +737,21 @@ void node::output(char*& buf)
|
|||
*buf++ = '\n';
|
||||
}
|
||||
|
||||
output_cache_ = string_span(begin, buf - begin);
|
||||
if(cache_status == REFRESH_CACHE) {
|
||||
output_cache_ = string_span(begin, buf - begin);
|
||||
}
|
||||
}
|
||||
const char* node::output() {
|
||||
const char* out;
|
||||
|
||||
const int buf_size = output_size() + 1;
|
||||
char* buf = new char[buf_size];
|
||||
out = buf;
|
||||
|
||||
output(buf);
|
||||
*buf++ = 0;
|
||||
assert(buf == out + buf_size);
|
||||
|
||||
return out;
|
||||
std::string node_to_string(const node& n)
|
||||
{
|
||||
//calling output with status=DO_NOT_MODIFY_CACHE really doesn't modify the
|
||||
//node, so we can do it safely
|
||||
node& mutable_node = const_cast<node&>(n);
|
||||
std::vector<char> v(mutable_node.output_size());
|
||||
char* ptr = &v[0];
|
||||
mutable_node.output(ptr, node::DO_NOT_MODIFY_CACHE);
|
||||
assert(ptr == &v[0] + v.size());
|
||||
return std::string(v.begin(), v.end());
|
||||
}
|
||||
|
||||
void node::copy_into(node& n) const
|
||||
|
@ -1004,7 +1007,7 @@ const char* document::output()
|
|||
buffers_.push_back(buf);
|
||||
output_ = buf;
|
||||
|
||||
root_->output(buf);
|
||||
root_->output(buf, node::REFRESH_CACHE);
|
||||
*buf++ = 0;
|
||||
assert(buf == output_ + buf_size);
|
||||
|
||||
|
|
|
@ -140,9 +140,10 @@ public:
|
|||
|
||||
bool is_dirty() const { return output_cache_.is_null(); }
|
||||
|
||||
enum CACHE_STATUS { REFRESH_CACHE, DO_NOT_MODIFY_CACHE };
|
||||
|
||||
int output_size() const;
|
||||
void output(char*& buf);
|
||||
const char* output();
|
||||
void output(char*& buf, CACHE_STATUS status=DO_NOT_MODIFY_CACHE);
|
||||
|
||||
void copy_into(node& n) const;
|
||||
|
||||
|
@ -203,6 +204,8 @@ private:
|
|||
string_span output_cache_;
|
||||
};
|
||||
|
||||
std::string node_to_string(const node& n);
|
||||
|
||||
enum INIT_BUFFER_CONTROL { INIT_TAKE_OWNERSHIP };
|
||||
|
||||
enum INIT_STATE { INIT_COMPRESSED, INIT_STATIC };
|
||||
|
|
Loading…
Add table
Reference in a new issue