die foul wesnothd bug die!!

merged from trunk:

2008-03-29T03:51:32Z!davewx7@gmail.com 
2008-03-29T07:06:33Z!davewx7@gmail.com 
2008-03-29T17:23:19Z!davewx7@gmail.com
This commit is contained in:
Martin Renold 2008-03-29 18:05:38 +00:00
parent a79b8422b6
commit 11732907dc
2 changed files with 90 additions and 23 deletions

View file

@ -120,7 +120,8 @@ std::ostream& operator<<(std::ostream& o, const string_span& s)
node::node(document& doc, node* parent)
: doc_(&doc), parent_(parent)
{}
{
}
node::node(document& doc, node* parent, const char** str, int depth)
: doc_(&doc), parent_(parent)
@ -152,7 +153,7 @@ node::node(document& doc, node* parent, const char** str, int depth)
throw error("unterminated element");
}
child_list& list = children_[string_span(s, end - s)];
child_list& list = get_children(string_span(s, end - s));
s = end + 1;
@ -329,7 +330,7 @@ node& node::add_child_at(const char* name, size_t index)
{
set_dirty();
child_list& list = children_[string_span(name)];
child_list& list = get_children(name);
if(index > list.size()) {
index = list.size();
}
@ -343,7 +344,7 @@ node& node::add_child(const char* name)
{
set_dirty();
child_list& list = children_[string_span(name)];
child_list& list = get_children(name);
list.push_back(new node(*doc_, this));
return *list.back();
}
@ -352,13 +353,23 @@ void node::remove_child(const string_span& name, size_t index)
{
set_dirty();
child_list& list = children_[name];
//if we don't already have a vector for this item we don't want to add one.
child_map::iterator itor = find_in_map(children_, name);
if(itor == children_.end()) {
return;
}
child_list& list = itor->second;
if(index >= list.size()) {
return;
}
delete list[index];
list.erase(list.begin() + index);
if(list.empty()) {
children_.erase(itor);
}
}
void node::remove_child(const char* name, size_t index)
@ -368,33 +379,82 @@ void node::remove_child(const char* name, size_t index)
node* node::child(const char* name)
{
child_map::iterator itor = children_.find(string_span(name));
if(itor == children_.end() || itor->second.empty()) {
return NULL;
for(child_map::iterator i = children_.begin(); i != children_.end(); ++i) {
if(i->first == name) {
assert(i->second.empty() == false);
return i->second.front();
}
}
return itor->second.front();
return NULL;
}
const node* node::child(const char* name) const
{
child_map::const_iterator itor = children_.find(string_span(name));
if(itor == children_.end() || itor->second.empty()) {
return NULL;
for(child_map::const_iterator i = children_.begin(); i != children_.end(); ++i) {
if(i->first == name) {
if(i->second.empty()) {
return NULL;
} else {
return i->second.front();
}
}
}
return itor->second.front();
return NULL;
}
const node::child_list& node::children(const char* name) const
{
static const node::child_list empty;
child_map::const_iterator itor = children_.find(string_span(name));
if(itor == children_.end()) {
return empty;
for(child_map::const_iterator i = children_.begin(); i != children_.end(); ++i) {
if(i->first == name) {
return i->second;
}
}
return itor->second;
static const node::child_list empty;
return empty;
}
node::child_list& node::get_children(const char* name)
{
return get_children(string_span(name));
}
node::child_list& node::get_children(const string_span& name)
{
for(child_map::iterator i = children_.begin(); i != children_.end(); ++i) {
if(i->first == name) {
return i->second;
}
}
children_.push_back(child_pair(string_span(name), child_list()));
return children_.back().second;
}
node::child_map::const_iterator node::find_in_map(const child_map& m, const string_span& attr)
{
child_map::const_iterator i = m.begin();
for(; i != m.end(); ++i) {
if(i->first == attr) {
break;
}
}
return i;
}
node::child_map::iterator node::find_in_map(child_map& m, const string_span& attr)
{
child_map::iterator i = m.begin();
for(; i != m.end(); ++i) {
if(i->first == attr) {
break;
}
}
return i;
}
const string_span& node::first_child() const
@ -440,7 +500,7 @@ void node::shift_buffers(ptrdiff_t offset)
}
for(child_map::iterator i = children_.begin(); i != children_.end(); ++i) {
string_span& key = const_cast<string_span&>(i->first);
string_span& key = i->first;
key = string_span(key.begin() + offset, key.size());
for(child_list::iterator j = i->second.begin(); j != i->second.end(); ++j) {
(*j)->shift_buffers(offset);
@ -473,10 +533,11 @@ void node::output(char*& buf)
}
for(child_map::iterator i = children_.begin(); i != children_.end(); ++i) {
assert(i->second.empty() == false);
for(child_list::iterator j = i->second.begin(); j != i->second.end(); ++j) {
*buf++ = '[';
memcpy(buf, i->first.begin(), i->first.size());
const_cast<string_span&>(i->first) = string_span(buf, i->first.size());
i->first = string_span(buf, i->first.size());
buf += i->first.size();
*buf++ = ']';
*buf++ = '\n';
@ -549,7 +610,7 @@ void node::apply_diff(const node& diff)
for(child_map::const_iterator j = (*i)->children_.begin(); j != (*i)->children_.end(); ++j) {
const string_span& name = j->first;
for(child_list::const_iterator k = j->second.begin(); k != j->second.end(); ++k) {
child_map::iterator itor = children_.find(name);
child_map::iterator itor = find_in_map(children_, name);
if(itor != children_.end()) {
if(index < itor->second.size()) {
itor->second[index]->apply_diff(**k);

View file

@ -144,8 +144,10 @@ private:
node(const node&);
void operator=(const node&);
void set_dirty();
child_list& get_children(const string_span& name);
child_list& get_children(const char* name);
void set_dirty();
void shift_buffers(ptrdiff_t offset);
document* doc_;
@ -155,7 +157,11 @@ private:
node* parent_;
typedef std::map<string_span, child_list> child_map;
typedef std::pair<string_span, child_list> child_pair;
typedef std::vector<child_pair> child_map;
static child_map::const_iterator find_in_map(const child_map& m, const string_span& attr);
static child_map::iterator find_in_map(child_map& m, const string_span& attr);
child_map children_;
string_span output_cache_;