summaryrefslogtreecommitdiffstats
path: root/src/Common/UserLists
diff options
context:
space:
mode:
Diffstat (limited to 'src/Common/UserLists')
-rw-r--r--src/Common/UserLists/UserList.cpp129
-rw-r--r--src/Common/UserLists/UserList.h125
-rw-r--r--src/Common/UserLists/Util.cpp4
3 files changed, 255 insertions, 3 deletions
diff --git a/src/Common/UserLists/UserList.cpp b/src/Common/UserLists/UserList.cpp
new file mode 100644
index 0000000..a14111d
--- /dev/null
+++ b/src/Common/UserLists/UserList.cpp
@@ -0,0 +1,129 @@
+/*
+ * UserList.cpp
+ *
+ * Copyright (C) 2009 Matthias Schiffer <matthias@gamezock.de>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 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; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "UserList.h"
+
+namespace Mad {
+namespace Common {
+namespace UserLists {
+
+std::list<UserListEntry>::iterator UserList::findEntry(const std::string &name) {
+ for(std::list<UserListEntry>::iterator it = list.begin(); it != list.end(); ++it) {
+ if(it->getName() == name) {
+ return it;
+ }
+ }
+
+ return list.end();
+}
+
+std::list<UserListEntry>::const_iterator UserList::findEntry(const std::string &name) const {
+ for(std::list<UserListEntry>::const_iterator it = list.begin(); it != list.end(); ++it) {
+ if(it->getName() == name) {
+ return it;
+ }
+ }
+
+ return list.end();
+}
+
+UserList::iterator UserList::find(const std::string &name) {
+ if(!names.count(name))
+ return end();
+
+ return iterator(findEntry(name));
+}
+
+UserList::const_iterator UserList::find(const std::string &name) const {
+ if(!names.count(name))
+ return end();
+
+ return const_iterator(findEntry(name));
+}
+
+void UserList::registerEntry(const UserListEntry &entry) {
+ std::set<std::string> details = entry.getDetailList();
+
+ for(std::set<std::string>::iterator detail = details.begin(); detail != details.end(); ++detail) {
+ std::map<std::string, unsigned>::iterator it = detailCounts.find(*detail);
+ if(it == detailCounts.end())
+ detailCounts.insert(make_pair(*detail, 1));
+ else
+ ++it->second;
+ }
+}
+
+void UserList::unregisterEntry(const UserListEntry &entry) {
+ std::set<std::string> details = entry.getDetailList();
+
+ for(std::set<std::string>::iterator detail = details.begin(); detail != details.end(); ++detail) {
+ std::map<std::string, unsigned>::iterator it = detailCounts.find(*detail);
+ // TODO Assert
+ if(it == detailCounts.end())
+ continue;
+
+ if(it->second > 1)
+ --it->second;
+ else
+ detailCounts.erase(it);
+ }
+}
+
+
+bool UserList::addUser(const UserListEntry &entry) {
+ return insertUser(entry, end());
+}
+
+bool UserList::insertUser(const UserListEntry &entry, iterator after) {
+ if(!names.insert(entry.getName()).second)
+ return false;
+
+ list.insert(after.it, entry);
+ registerEntry(entry);
+ return true;
+}
+
+bool UserList::removeUser(const std::string &name) {
+ if(!names.erase(name))
+ return false;
+
+ std::list<UserListEntry>::iterator it = findEntry(name);
+ // TODO Assert
+
+ unregisterEntry(*it);
+ list.erase(it);
+ return true;
+}
+
+bool UserList::updateUser(const UserListEntry &entry) {
+ if(!names.count(entry.getName()))
+ return false;
+
+ std::list<UserListEntry>::iterator it = findEntry(entry.getName());
+ // TODO Assert
+
+ unregisterEntry(*it);
+ *it = entry;
+ registerEntry(entry);
+ return true;
+}
+
+}
+}
+}
diff --git a/src/Common/UserLists/UserList.h b/src/Common/UserLists/UserList.h
index e80abaf..9c5985d 100644
--- a/src/Common/UserLists/UserList.h
+++ b/src/Common/UserLists/UserList.h
@@ -20,16 +20,139 @@
#ifndef MAD_COMMON_USERLISTS_USERLIST_H_
#define MAD_COMMON_USERLISTS_USERLIST_H_
+#include "../export.h"
+
#include "UserListEntry.h"
#include <list>
+#include <map>
+#include <set>
namespace Mad {
namespace Common {
namespace UserLists {
-class UserList : public std::list<UserListEntry> {
+class MAD_COMMON_EXPORT UserList {
+ private:
+ template <typename Type, typename IteratorType>
+ class iterator_base {
+ public:
+ friend class UserList;
+
+ typedef Type value_type;
+
+ typedef value_type &reference;
+ typedef value_type *pointer;
+
+ typedef long difference_type;
+
+ private:
+ IteratorType it;
+
+ iterator_base(IteratorType it0) : it(it0) {}
+
+ public:
+ iterator_base() {}
+
+ reference operator*() const {
+ return *it;
+ }
+
+ iterator_base operator++(int) {
+ return iterator(it++);
+ }
+
+ iterator_base& operator++() {
+ ++it;
+ return *this;
+ }
+
+ iterator_base operator--(int) {
+ return iterator(it--);
+ }
+
+ iterator_base& operator--() {
+ --it;
+ return *this;
+ }
+
+ bool operator==(const iterator_base &it2) {
+ return it2.it == it;
+ }
+
+ bool operator!=(const iterator_base &it2) {
+ return it2.it != it;
+ }
+
+ pointer operator->() const {
+ return &*it;
+ }
+ };
+
+ std::set<std::string> names;
+ std::list<UserListEntry> list;
+
+ std::map<std::string, unsigned> detailCounts;
+
+ void registerEntry(const UserListEntry &entry);
+ void unregisterEntry(const UserListEntry &entry);
+
+ std::list<UserListEntry>::iterator findEntry(const std::string &name);
+ std::list<UserListEntry>::const_iterator findEntry(const std::string &name) const;
+
public:
+ typedef iterator_base<const UserListEntry, std::list<UserListEntry>::iterator> iterator;
+ typedef iterator_base<const UserListEntry, std::list<UserListEntry>::const_iterator> const_iterator;
+
+ iterator find(const std::string &name);
+ const_iterator find(const std::string &name) const;
+
+ iterator begin() {
+ return iterator(list.begin());
+ }
+
+ const_iterator begin() const {
+ return const_iterator(list.begin());
+ }
+
+ iterator end() {
+ return list.end();
+ }
+
+ const_iterator end() const {
+ return const_iterator(list.end());
+ }
+
+ bool isEmpty() const {
+ return list.empty();
+ }
+
+ size_t getLength() const {
+ return list.size();
+ }
+
+ std::set<std::string> getDetails() const {
+ std::set<std::string> ret;
+
+ for(std::map<std::string, unsigned>::const_iterator it = detailCounts.begin(); it != detailCounts.end(); ++it)
+ ret.insert(it->first);
+
+ return ret;
+ }
+
+ unsigned getDetailUsage(const std::string &detail) const {
+ std::map<std::string, unsigned>::const_iterator it = detailCounts.find(detail);
+ if(it == detailCounts.end())
+ return 0;
+ else
+ return it->second;
+ }
+
+ bool addUser(const UserListEntry &entry);
+ bool insertUser(const UserListEntry &entry, iterator after);
+ bool removeUser(const std::string &name);
+ bool updateUser(const UserListEntry &entry);
+
UserList() {}
};
diff --git a/src/Common/UserLists/Util.cpp b/src/Common/UserLists/Util.cpp
index 812c2c7..3c15956 100644
--- a/src/Common/UserLists/Util.cpp
+++ b/src/Common/UserLists/Util.cpp
@@ -39,7 +39,7 @@ UserListEntry Util::deserializeUserListEntry(XmlData::List::const_iterator entry
std::set<std::string> details = entry->getChildren();
for(std::set<std::string>::iterator detail = details.begin(); detail != details.end(); ++detail) {
- if(*detail == "user" || *detail == "group")
+ if(*detail == "name" || *detail == "group")
continue;
user.setDetail(*detail, entry->get<const std::string&>(*detail));
@@ -62,7 +62,7 @@ boost::shared_ptr<UserList> Util::deserializeUserList(const XmlData *data) {
if(userList) {
for(XmlData::List::const_iterator user = userList->begin(); user != userList->end(); ++user)
- users->push_back(deserializeUserListEntry(user));
+ users->addUser(deserializeUserListEntry(user));
}
return users;