diff options
author | Matthias Schiffer <matthias@gamezock.de> | 2009-09-24 21:50:11 +0200 |
---|---|---|
committer | Matthias Schiffer <matthias@gamezock.de> | 2009-09-24 21:50:11 +0200 |
commit | 9f962123be30da94add3f966bb46962f8bfdea88 (patch) | |
tree | ed1a210da3d5ba5d8d7d0807dd4e6ed4de4172f4 /src/Common/UserLists | |
parent | 1cf531a5949cad1f68575188cf00d147478e029c (diff) | |
download | mad-9f962123be30da94add3f966bb46962f8bfdea88.tar mad-9f962123be30da94add3f966bb46962f8bfdea88.zip |
UserList: Encapsulate list
Diffstat (limited to 'src/Common/UserLists')
-rw-r--r-- | src/Common/UserLists/UserList.cpp | 129 | ||||
-rw-r--r-- | src/Common/UserLists/UserList.h | 125 | ||||
-rw-r--r-- | src/Common/UserLists/Util.cpp | 4 |
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; |