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 | |
23 | namespace 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 | |
29 | template<class T> |
30 | class SYNDICATION_EXPORT ParserCollectionImpl : public ParserCollection<T> |
31 | { |
32 | public: |
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 | |
45 | private: |
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 | |
58 | template<class T> |
59 | ParserCollectionImpl<T>::ParserCollectionImpl() |
60 | { |
61 | } |
62 | |
63 | template<class T> |
64 | ParserCollectionImpl<T>::~ParserCollectionImpl() |
65 | { |
66 | // Delete the values |
67 | qDeleteAll(c: m_parsers); |
68 | qDeleteAll(m_mappers); |
69 | } |
70 | |
71 | template<class T> |
72 | bool 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 | } |
83 | template<class T> |
84 | void ParserCollectionImpl<T>::changeMapper(const QString &format, Mapper<T> *mapper) |
85 | { |
86 | m_mappers[format] = mapper; |
87 | } |
88 | |
89 | template<class T> |
90 | QSharedPointer<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 | |
126 | template<class T> |
127 | Syndication::ErrorCode ParserCollectionImpl<T>::lastError() const |
128 | { |
129 | return m_lastError; |
130 | } |
131 | |
132 | template<class T> |
133 | ParserCollectionImpl<T>::ParserCollectionImpl(const ParserCollectionImpl &) |
134 | { |
135 | } |
136 | |
137 | template<class T> |
138 | ParserCollectionImpl<T> &ParserCollectionImpl<T>::operator=(const ParserCollectionImpl &) |
139 | { |
140 | return *this; |
141 | } |
142 | |
143 | } // namespace Syndication |
144 | |
145 | #endif // SYNDICATION_PARSERCOLLECTIONIMPL_H |
146 | |