1/*
2 This file is part of the syndication library
3 SPDX-FileCopyrightText: 2005 Frank Osterfeld <osterfeld@kde.org>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6*/
7
8#ifndef SYNDICATION_PARSERCOLLECTIONIMPL_H
9#define SYNDICATION_PARSERCOLLECTIONIMPL_H
10
11#include <syndication/abstractparser.h>
12#include <syndication/documentsource.h>
13#include <syndication/feed.h>
14#include <syndication/global.h>
15#include <syndication/mapper.h>
16#include <syndication/parsercollection.h>
17#include <syndication/specificdocument.h>
18
19#include <QDomDocument>
20#include <QHash>
21#include <QString>
22
23namespace Syndication
24{
25// default implementation of ParserCollection. This is separated
26// from the interface to move the implementation out of the public API
27// (template classes require implementations to be in the header)
28
29template<class T>
30class SYNDICATION_EXPORT ParserCollectionImpl : public ParserCollection<T>
31{
32public:
33 ParserCollectionImpl();
34
35 ~ParserCollectionImpl() override;
36
37 QSharedPointer<T> parse(const DocumentSource &source, const QString &formatHint = QString()) override;
38
39 bool registerParser(AbstractParser *parser, Mapper<T> *mapper) override;
40
41 void changeMapper(const QString &format, Mapper<T> *mapper) override;
42
43 ErrorCode lastError() const override;
44
45private:
46 ParserCollectionImpl(const ParserCollectionImpl &);
47 ParserCollectionImpl &operator=(const ParserCollectionImpl &);
48 QHash<QString, AbstractParser *> m_parsers;
49 QHash<QString, Mapper<T> *> m_mappers;
50 QList<AbstractParser *> m_parserList;
51
52 ErrorCode m_lastError;
53};
54
55// template <class T>
56// class ParserCollectionImpl<T>::ParserCollectionImplPrivate
57
58template<class T>
59ParserCollectionImpl<T>::ParserCollectionImpl()
60{
61}
62
63template<class T>
64ParserCollectionImpl<T>::~ParserCollectionImpl()
65{
66 // Delete the values
67 qDeleteAll(c: m_parsers);
68 qDeleteAll(m_mappers);
69}
70
71template<class T>
72bool ParserCollectionImpl<T>::registerParser(AbstractParser *parser, Mapper<T> *mapper)
73{
74 if (m_parsers.contains(key: parser->format())) {
75 return false;
76 }
77
78 m_parserList.append(t: parser);
79 m_parsers.insert(key: parser->format(), value: parser);
80 m_mappers.insert(parser->format(), mapper);
81 return true;
82}
83template<class T>
84void ParserCollectionImpl<T>::changeMapper(const QString &format, Mapper<T> *mapper)
85{
86 m_mappers[format] = mapper;
87}
88
89template<class T>
90QSharedPointer<T> ParserCollectionImpl<T>::parse(const DocumentSource &source, const QString &formatHint)
91{
92 m_lastError = Syndication::Success;
93
94 if (!formatHint.isNull() && m_parsers.contains(key: formatHint)) {
95 if (m_parsers[formatHint]->accept(source)) {
96 SpecificDocumentPtr doc = m_parsers[formatHint]->parse(source);
97 if (!doc->isValid()) {
98 m_lastError = InvalidFormat;
99 return FeedPtr();
100 }
101
102 return m_mappers[formatHint]->map(doc);
103 }
104 }
105
106 for (AbstractParser *i : std::as_const(t&: m_parserList)) {
107 if (i->accept(source)) {
108 SpecificDocumentPtr doc = i->parse(source);
109 if (!doc->isValid()) {
110 m_lastError = InvalidFormat;
111 return FeedPtr();
112 }
113
114 return m_mappers[i->format()]->map(doc);
115 }
116 }
117 if (source.asDomDocument().isNull()) {
118 m_lastError = InvalidXml;
119 } else {
120 m_lastError = XmlNotAccepted;
121 }
122
123 return FeedPtr();
124}
125
126template<class T>
127Syndication::ErrorCode ParserCollectionImpl<T>::lastError() const
128{
129 return m_lastError;
130}
131
132template<class T>
133ParserCollectionImpl<T>::ParserCollectionImpl(const ParserCollectionImpl &)
134{
135}
136
137template<class T>
138ParserCollectionImpl<T> &ParserCollectionImpl<T>::operator=(const ParserCollectionImpl &)
139{
140 return *this;
141}
142
143} // namespace Syndication
144
145#endif // SYNDICATION_PARSERCOLLECTIONIMPL_H
146

source code of syndication/src/parsercollectionimpl.h