File indexing completed on 2024-06-16 05:01:09

0001 /*
0002     bodypartformatterfactory.cpp
0003 
0004     This file is part of KMail, the KDE mail client.
0005     Copyright (c) 2004 Marc Mutz <mutz@kde.org>,
0006                        Ingo Kloecker <kloecker@kde.org>
0007 
0008     KMail is free software; you can redistribute it and/or modify it
0009     under the terms of the GNU General Public License as published by
0010     the Free Software Foundation; either version 2 of the License, or
0011     (at your option) any later version.
0012 
0013     KMail is distributed in the hope that it will be useful, but
0014     WITHOUT ANY WARRANTY; without even the implied warranty of
0015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0016     General Public License for more details.
0017 
0018     You should have received a copy of the GNU General Public License
0019     along with this program; if not, write to the Free Software
0020     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
0021 
0022     In addition, as a special exception, the copyright holders give
0023     permission to link the code of this program with any edition of
0024     the Qt library by Trolltech AS, Norway (or with modified versions
0025     of Qt that use the same license as Qt), and distribute linked
0026     combinations including the two.  You must obey the GNU General
0027     Public License in all respects for all of the code used other than
0028     Qt.  If you modify this file, you may extend this exception to
0029     your version of the file, but you are not obligated to do so.  If
0030     you do not wish to do so, delete this exception statement from
0031     your version.
0032 */
0033 
0034 #include "bodypartformatterbasefactory.h"
0035 #include "bodypartformatterbasefactory_p.h"
0036 #include "bodypartformatter.h"
0037 #include "mimetreeparser_debug.h"
0038 
0039 #include <assert.h>
0040 
0041 using namespace MimeTreeParser;
0042 
0043 BodyPartFormatterBaseFactoryPrivate::BodyPartFormatterBaseFactoryPrivate(BodyPartFormatterBaseFactory *factory)
0044     : q(factory)
0045     , all(nullptr)
0046 {
0047 }
0048 
0049 BodyPartFormatterBaseFactoryPrivate::~BodyPartFormatterBaseFactoryPrivate()
0050 {
0051     if (all) {
0052         delete all;
0053         all = nullptr;
0054     }
0055 }
0056 
0057 void BodyPartFormatterBaseFactoryPrivate::setup()
0058 {
0059     if (!all) {
0060         all = new TypeRegistry();
0061         messageviewer_create_builtin_bodypart_formatters();
0062     }
0063 }
0064 
0065 void BodyPartFormatterBaseFactoryPrivate::insert(const char *type, const char *subtype, Interface::BodyPartFormatter *formatter)
0066 {
0067     if (!type || !*type || !subtype || !*subtype || !formatter || !all) {
0068         return;
0069     }
0070 
0071     TypeRegistry::iterator type_it = all->find(type);
0072     if (type_it == all->end()) {
0073         type_it = all->insert(std::make_pair(type, SubtypeRegistry())).first;
0074         assert(type_it != all->end());
0075     }
0076 
0077     SubtypeRegistry &subtype_reg = type_it->second;
0078 
0079     subtype_reg.insert(std::make_pair(subtype, formatter));
0080 }
0081 
0082 BodyPartFormatterBaseFactory::BodyPartFormatterBaseFactory()
0083     : d(new BodyPartFormatterBaseFactoryPrivate(this))
0084 {
0085 }
0086 
0087 BodyPartFormatterBaseFactory::~BodyPartFormatterBaseFactory()
0088 {
0089     delete d;
0090 }
0091 
0092 void BodyPartFormatterBaseFactory::insert(const char *type, const char *subtype, Interface::BodyPartFormatter *formatter)
0093 {
0094     d->insert(type, subtype, formatter);
0095 }
0096 
0097 const SubtypeRegistry &BodyPartFormatterBaseFactory::subtypeRegistry(const char *type) const
0098 {
0099     if (!type || !*type) {
0100         type = "*";    //krazy:exclude=doublequote_chars
0101     }
0102 
0103     d->setup();
0104     assert(d->all);
0105 
0106     static SubtypeRegistry emptyRegistry;
0107     if (d->all->empty()) {
0108         return emptyRegistry;
0109     }
0110 
0111     TypeRegistry::const_iterator type_it = d->all->find(type);
0112     if (type_it == d->all->end()) {
0113         type_it = d->all->find("*");
0114     }
0115     if (type_it == d->all->end()) {
0116         return emptyRegistry;
0117     }
0118 
0119     const SubtypeRegistry &subtype_reg = type_it->second;
0120     if (subtype_reg.empty()) {
0121         return emptyRegistry;
0122     }
0123     return subtype_reg;
0124 }
0125 
0126 SubtypeRegistry::const_iterator BodyPartFormatterBaseFactory::createForIterator(const char *type, const char *subtype) const
0127 {
0128     if (!type || !*type) {
0129         type = "*";    //krazy:exclude=doublequote_chars
0130     }
0131     if (!subtype || !*subtype) {
0132         subtype = "*";    //krazy:exclude=doublequote_chars
0133     }
0134 
0135     d->setup();
0136     assert(d->all);
0137 
0138     if (d->all->empty()) {
0139         return SubtypeRegistry::const_iterator();
0140     }
0141 
0142     TypeRegistry::const_iterator type_it = d->all->find(type);
0143     if (type_it == d->all->end()) {
0144         type_it = d->all->find("*");
0145     }
0146     if (type_it == d->all->end()) {
0147         return SubtypeRegistry::const_iterator();
0148     }
0149 
0150     const SubtypeRegistry &subtype_reg = type_it->second;
0151     if (subtype_reg.empty()) {
0152         return SubtypeRegistry::const_iterator();
0153     }
0154 
0155     SubtypeRegistry::const_iterator subtype_it = subtype_reg.find(subtype);
0156     qCWarning(MIMETREEPARSER_LOG) << type << subtype << subtype_reg.size();
0157     if (subtype_it == subtype_reg.end()) {
0158         subtype_it = subtype_reg.find("*");
0159     }
0160     if (subtype_it == subtype_reg.end()) {
0161         return SubtypeRegistry::const_iterator();
0162     }
0163 
0164     if (!(*subtype_it).second) {
0165         qCWarning(MIMETREEPARSER_LOG) << "BodyPartFormatterBaseFactory: a null bodypart formatter sneaked in for \""
0166                                       << type << "/" << subtype << "\"!";
0167     }
0168 
0169     return subtype_it;
0170 }
0171