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:
parent
a79b8422b6
commit
11732907dc
2 changed files with 90 additions and 23 deletions
|
@ -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);
|
||||
|
|
|
@ -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_;
|
||||
|
|
Loading…
Add table
Reference in a new issue