IWORKContainerContext.h
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /*
3 * This file is part of the libetonyek project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
9
10 #ifndef IWORKCONTAINERCONTEXT_H_INCLUDED
11 #define IWORKCONTAINERCONTEXT_H_INCLUDED
12
13 #include <cassert>
14 #include <deque>
15
16 #include <boost/optional.hpp>
17
18 #include "IWORKTypes_fwd.h"
19 #include "IWORKRefContext.h"
20 #include "IWORKXMLContextBase.h"
21
22 namespace libetonyek
23 {
24
25 template<typename Type, class NestedParser, template<typename T, class C> class Collector, unsigned Id, unsigned RefId = 0>
26 class IWORKContainerContext : public IWORKXMLElementContextBase
27 {
28 typedef std::unordered_map<ID_t, Type> Dict_t;
29
30 public:
31 IWORKContainerContext(IWORKXMLParserState &state, std::deque<Type> &elements)
32 : IWORKXMLElementContextBase(state)
33 , m_dict(nullptr)
34 , m_elements(elements)
35 , m_collector(elements)
36 {
37 }
38
39 IWORKContainerContext(IWORKXMLParserState &state, Dict_t &dict, std::deque<Type> &elements)
40 : IWORKXMLElementContextBase(state)
41 , m_dict(&dict)
42 , m_elements(elements)
43 , m_collector(elements)
44 {
45 }
46
47 protected:
48 IWORKXMLContextPtr_t element(const int name) override
49 {
50 if (m_ref && m_dict)
51 handleRef();
52 else if (m_collector.pending())
53 m_collector.push();
54
55 if (name == Id)
56 return m_collector.template makeContext<NestedParser>(getState());
57 else if ((RefId != 0) && (name == RefId))
58 return makeContext<IWORKRefContext>(getState(), m_ref);
59 return IWORKXMLContextPtr_t();
60 }
61
62 void endOfElement() override
63 {
64 if (m_ref && m_dict)
65 handleRef();
66 else if (m_collector.pending())
67 m_collector.push();
68 }
69
70 private:
71 void handleRef()
72 {
73 assert(m_dict);
74
75 const typename Dict_t::const_iterator it = m_dict->find(get(m_ref));
76 if (it == m_dict->end())
77 m_elements.push_back(Type());
78 else
79 m_elements.push_back(it->second);
80 }
81
82 private:
83 Dict_t *const m_dict;
84 boost::optional<ID_t> m_ref;
85 std::deque<Type> &m_elements;
86 Collector<Type, std::deque<Type> > m_collector;
87 };
88
89 }
90
91 #endif // IWORKCONTAINERCONTEXT_H_INCLUDED
92
93 /* vim:set shiftwidth=2 softtabstop=2 expandtab: */
libetonyek
Definition: IWORKBezierElement.cpp:18
libetonyek::IWORKContainerContext::m_collector
Collector< Type, std::deque< Type > > m_collector
Definition: IWORKContainerContext.h:86
libetonyek::IWORKXMLContextPtr_t
std::shared_ptr< IWORKXMLContext > IWORKXMLContextPtr_t
Definition: IWORKXMLContext.h:18
libetonyek::IWORKContainerContext::m_elements
std::deque< Type > & m_elements
Definition: IWORKContainerContext.h:85
libetonyek::KEY1Token::dict
Definition: KEY1Token.h:49
IWORKXMLContextBase.h
libetonyek::IWORKContainerContext::Dict_t
std::unordered_map< ID_t, Type > Dict_t
Definition: IWORKContainerContext.h:28
libetonyek::IWORKContainerContext::element
IWORKXMLContextPtr_t element(const int name) override
Definition: IWORKContainerContext.h:48
IWORKTypes_fwd.h
libetonyek::IWORKContainerContext::m_dict
Dict_t *const m_dict
Definition: IWORKContainerContext.h:83
libetonyek::IWORKContainerContext::IWORKContainerContext
IWORKContainerContext(IWORKXMLParserState &state, std::deque< Type > &elements)
Definition: IWORKContainerContext.h:31
libetonyek::IWORKXMLContextBase::getState
State & getState()
Definition: IWORKXMLContextBase.h:43
name
const char * name
Definition: IWORKToken.cpp:43
IWORKRefContext.h
libetonyek::IWORKContainerContext::handleRef
void handleRef()
Definition: IWORKContainerContext.h:71
libetonyek::IWORKContainerContext
Definition: IWORKContainerContext.h:26
libetonyek::IWORKXMLContextBase
Definition: IWORKXMLContextBase.h:27
libetonyek::IWORKXMLParserState
Definition: IWORKXMLParserState.h:30
libetonyek::IWORKContainerContext::m_ref
boost::optional< ID_t > m_ref
Definition: IWORKContainerContext.h:84
libetonyek::IWORKContainerContext::IWORKContainerContext
IWORKContainerContext(IWORKXMLParserState &state, Dict_t &dict, std::deque< Type > &elements)
Definition: IWORKContainerContext.h:39
libetonyek::IWORKContainerContext::endOfElement
void endOfElement() override
Definition: IWORKContainerContext.h:62