//============================================================================= // // File : KviRegisteredChannelDataBase.cpp // Creation date : Wed Dec 29 2010 03:28:05 CEST by Elvio Basello // // This file is part of the KVIrc IRC client distribution // Copyright (C) 2010 Elvio Basello (hellvis69 at gmail dot com) // // This program is FREE software. You can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // 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 General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, write to the Free Software Foundation, // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // //============================================================================= #include "KviRegisteredChannelDataBase.h" #include "KviConfigurationFile.h" #include "KviQString.h" #include KviRegisteredChannelDataBase::KviRegisteredChannelDataBase() { m_pChannelDict = new QHash(); } KviRegisteredChannelDataBase::~KviRegisteredChannelDataBase() { qDeleteAll(*m_pChannelDict); delete m_pChannelDict; } void KviRegisteredChannelDataBase::load(const QString & filename) { KviConfigurationFile cfg(filename, KviConfigurationFile::Read); qDeleteAll(*m_pChannelDict); m_pChannelDict->clear(); KviConfigurationFileIterator it(*(cfg.dict())); while(KviConfigurationFileGroup * d = it.current()) { QString szMask = it.currentKey(); QString szChan = KviQString::leftToLast(szMask, QChar('@'), false); KviQString::cutToLast(szMask, QChar('@'), true); KviRegisteredChannel * c = new KviRegisteredChannel(szChan, szMask); add(c); KviConfigurationFileGroupIterator sit(*d); while(QString * s = sit.current()) { c->setProperty(sit.currentKey(), *s); ++sit; } ++it; } } void KviRegisteredChannelDataBase::save(const QString & filename) { KviConfigurationFile cfg(filename, KviConfigurationFile::Write); cfg.clear(); cfg.preserveEmptyGroups(true); for(QHash::Iterator it = m_pChannelDict->begin(); it != m_pChannelDict->end(); ++it) { KviRegisteredChannelList * l = it.value(); KVI_ASSERT(l); for(KviRegisteredChannel * c = l->first(); c; c = l->next()) { QString szGroup = QString::fromUtf8("%1@%2").arg(c->name(), c->netMask()); cfg.setGroup(szGroup); QHash * pPropertyDict = c->propertyDict(); KVI_ASSERT(pPropertyDict); for(QHash::Iterator it2 = pPropertyDict->begin(); it2 != pPropertyDict->end(); ++it2) cfg.writeEntry(it2.key(), it2.value()); } } } KviRegisteredChannel * KviRegisteredChannelDataBase::find(const QString & name, const QString & net) { KviRegisteredChannelList * l = m_pChannelDict->value(name); if(!l) return nullptr; for(KviRegisteredChannel * c = l->first(); c; c = l->next()) { if(KviQString::matchWildExpressions(c->netMask(), net)) return c; } return nullptr; } KviRegisteredChannel * KviRegisteredChannelDataBase::findExact(const QString & name, const QString & netmask) { KviRegisteredChannelList * l = m_pChannelDict->value(name); if(!l) return nullptr; for(KviRegisteredChannel * c = l->first(); c; c = l->next()) { if(KviQString::equalCI(c->netMask(), netmask)) return c; } return nullptr; } void KviRegisteredChannelDataBase::remove(KviRegisteredChannel * c) { KVI_TRACE_FUNCTION; KviRegisteredChannelList * l = m_pChannelDict->value(c->name()); if(!l) return; for(KviRegisteredChannel * ch = l->first(); ch; ch = l->next()) { if(ch == c) { if(l->count() <= 1) { m_pChannelDict->remove(c->name()); delete l; // will kill the channel too } else { l->removeRef(c); } return; } } } void KviRegisteredChannelDataBase::add(KviRegisteredChannel * c) { KviRegisteredChannel * old = findExact(c->name(), c->netMask()); if(old) { // merge properties QHash * pPropertyDict = old->propertyDict(); KVI_ASSERT(pPropertyDict); for(QHash::Iterator it = pPropertyDict->begin(); it != pPropertyDict->end(); ++it) { if(!c->property(it.key()).isEmpty()) c->setProperty(it.key(), it.value()); } remove(old); } KviRegisteredChannelList * l = m_pChannelDict->value(c->name()); if(!l) { l = new KviRegisteredChannelList(); l->setAutoDelete(true); m_pChannelDict->insert(c->name(), l); } // insert where there are less wildcards int o = c->netMask().count(QChar('*')); int idx = 0; for(KviRegisteredChannel * rc = l->first(); rc; rc = l->next()) { if(rc->netMask().count(QChar('*')) > o) { // the existing has more wildcards, insert here! l->insert(idx, c); return; } idx++; } l->append(c); }