tizen 2.4 release
[framework/web/wrt-commons.git] / modules / test / include / dpl / test / abstract_input_reader.h
1 /*
2  * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 /*
17  * @file        abstract_input_reader.h
18  * @author      Tomasz Iwanek (t.iwanek@samsung.com)
19  * @brief       Simple output reader template
20  *
21  * This generic skeleton for parser which assume being composed from abstract two logical components:
22  *
23  *  -  parser,
24  *  -  tokenizer/lexer,
25  *     which implements token flow logic. Logic of components may be arbitrary. See depending change for uses.
26  *
27  * Components are created at start time of reader (constructor which moves arguments).
28  * Virtuality (abstract base classes) are for enforcing same token type.
29  * I assumed it's more clear than writen static asserts in code enforcing this.
30  */
31
32 #ifndef ABSTRACT_INPUT_READER_H
33 #define ABSTRACT_INPUT_READER_H
34
35 #include <memory>
36
37 #include <dpl/test/abstract_input_tokenizer.h>
38 #include <dpl/test/abstract_input_parser.h>
39 #include <dpl/abstract_input.h>
40
41 namespace DPL {
42
43 /**
44  * Base reader class that can be used with any AbstractInput instance
45  *
46  * This class is encapsulation class for tokenizer and reader subelements
47  * and contains basic calculation pattern
48  *
49  * There a waste in form of virtuality for parser and tokenizer
50  * -> this for forcing same tokenT type in both components
51  */
52 template<class ResultT, class TokenT> class AbstractInputReader
53 {
54 public:
55     typedef ResultT TokenType;
56     typedef TokenT ResultType;
57     typedef AbstractInputParser<ResultT, TokenT> ParserBase;
58     typedef AbstractInputTokenizer<TokenT> TokenizerBase;
59
60     class Exception
61     {
62     public:
63         typedef typename TokenizerBase::Exception::TokenizerError TokenizerError;
64         typedef typename ParserBase::Exception::ParserError ParserError;
65     };
66
67     AbstractInputReader(std::shared_ptr<AbstractInput> ia,
68                         std::unique_ptr<ParserBase> && parser,
69                         std::unique_ptr<TokenizerBase> && tokenizer)
70         : m_parser(std::move(parser)), m_tokenizer(std::move(tokenizer))
71     {
72         m_tokenizer->Reset(ia);
73     }
74
75     virtual ~AbstractInputReader() {}
76
77     ResultT ReadInput()
78     {
79         typedef typename Exception::TokenizerError TokenizerError;
80         typedef typename Exception::ParserError ParserError;
81
82         while(true)
83         {
84             std::unique_ptr<TokenT> token = m_tokenizer->GetNextToken();
85             if(!token)
86             {
87                 if(!m_tokenizer->IsStateValid())
88                 {
89                     ThrowMsg(TokenizerError, "Tokenizer error");
90                 }
91                 if(!m_parser->IsStateValid())
92                 {
93                     ThrowMsg(ParserError, "Parser error");
94                 }
95
96                 return m_parser->GetResult();
97             }
98             m_parser->ConsumeToken(std::move(token));
99         }
100     }
101
102 protected:
103     std::unique_ptr<ParserBase> m_parser;
104     std::unique_ptr<TokenizerBase> m_tokenizer;
105 };
106
107 }
108
109 #endif