${PROJECT_SOURCE_DIR}/modules/test/include/dpl/test/test_runner_child.h
${PROJECT_SOURCE_DIR}/modules/test/include/dpl/test/test_runner_multiprocess.h
${PROJECT_SOURCE_DIR}/modules/test/include/dpl/test/process_pipe.h
+ ${PROJECT_SOURCE_DIR}/modules/test/include/dpl/test/abstract_input_parser.h
+ ${PROJECT_SOURCE_DIR}/modules/test/include/dpl/test/abstract_input_reader.h
+ ${PROJECT_SOURCE_DIR}/modules/test/include/dpl/test/abstract_input_tokenizer.h
PARENT_SCOPE
)
--- /dev/null
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file abstract_input_parser.h
+ * @author Tomasz Iwanek (t.iwanek@samsung.com)
+ * @brief Simple parser abstraction to be included into reader
+ */
+
+#ifndef ABSTRACT_INPUT_PARSER_H
+#define ABSTRACT_INPUT_PARSER_H
+
+#include <dpl/exception.h>
+
+#include <memory>
+
+namespace DPL {
+
+/**
+ * Abstract class of parser that produces some higher level abstraction
+ * basing on incoming tokens
+ */
+template<class Result, class Token> class AbstractInputParser
+{
+public:
+ class Exception
+ {
+ public:
+ DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, ParserError)
+ };
+
+ typedef Result ResultType;
+ typedef Token TokenType;
+
+ virtual ~AbstractInputParser() {}
+
+ virtual void ConsumeToken(std::unique_ptr<Token> && token) = 0;
+ virtual bool IsStateValid() = 0;
+ virtual Result GetResult() const = 0;
+};
+
+}
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file abstract_input_reader.h
+ * @author Tomasz Iwanek (t.iwanek@samsung.com)
+ * @brief Simple output reader template
+ *
+ * This generic skeleton for parser which assume being composed from abstract two logical components:
+ *
+ * - parser,
+ * - tokenizer/lexer,
+ * which implements token flow logic. Logic of components may be arbitrary. See depending change for uses.
+ *
+ * Components are created at start time of reader (constructor which moves arguments).
+ * Virtuality (abstract base classes) are for enforcing same token type.
+ * I assumed it's more clear than writen static asserts in code enforcing this.
+ */
+
+#ifndef ABSTRACT_INPUT_READER_H
+#define ABSTRACT_INPUT_READER_H
+
+#include <memory>
+
+#include <dpl/optional.h>
+#include <dpl/test/abstract_input_tokenizer.h>
+#include <dpl/test/abstract_input_parser.h>
+#include <dpl/abstract_input.h>
+
+namespace DPL {
+
+/**
+ * Base reader class that can be used with any AbstractInput instance
+ *
+ * This class is encapsulation class for tokenizer and reader subelements
+ * and contains basic calculation pattern
+ *
+ * There a waste in form of virtuality for parser and tokenizer
+ * -> this for forcing same tokenT type in both components
+ */
+template<class ResultT, class TokenT> class AbstractInputReader
+{
+public:
+ typedef ResultT TokenType;
+ typedef TokenT ResultType;
+ typedef AbstractInputParser<ResultT, TokenT> ParserBase;
+ typedef AbstractInputTokenizer<TokenT> TokenizerBase;
+
+ class Exception
+ {
+ public:
+ typedef typename TokenizerBase::Exception::TokenizerError TokenizerError;
+ typedef typename ParserBase::Exception::ParserError ParserError;
+ };
+
+ AbstractInputReader(std::shared_ptr<AbstractInput> ia,
+ std::unique_ptr<ParserBase> && parser,
+ std::unique_ptr<TokenizerBase> && tokenizer)
+ : m_parser(std::move(parser)), m_tokenizer(std::move(tokenizer))
+ {
+ m_tokenizer->Reset(ia);
+ }
+
+ virtual ~AbstractInputReader() {}
+
+ ResultT ReadInput()
+ {
+ typedef typename Exception::TokenizerError TokenizerError;
+ typedef typename Exception::ParserError ParserError;
+
+ while(true)
+ {
+ std::unique_ptr<TokenT> token = m_tokenizer->GetNextToken();
+ if(!token)
+ {
+ if(!m_tokenizer->IsStateValid())
+ {
+ ThrowMsg(TokenizerError, "Tokenizer error");
+ }
+ if(!m_parser->IsStateValid())
+ {
+ ThrowMsg(ParserError, "Parser error");
+ }
+
+ return m_parser->GetResult();
+ }
+ m_parser->ConsumeToken(std::move(token));
+ }
+ }
+
+protected:
+ std::unique_ptr<ParserBase> m_parser;
+ std::unique_ptr<TokenizerBase> m_tokenizer;
+};
+
+}
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file abstract_input_tokenizer.h
+ * @author Tomasz Iwanek (t.iwanek@samsung.com)
+ * @brief Simple tokenizer abstraction
+ */
+
+#ifndef ABSTRACT_INPUT_TOKENIZER_H
+#define ABSTRACT_INPUT_TOKENIZER_H
+
+#include <memory>
+#include <string>
+
+#include <dpl/abstract_input.h>
+#include <dpl/optional.h>
+#include <dpl/exception.h>
+
+namespace DPL {
+
+/**
+ * Tokenizer abstract base class
+ *
+ * This class is supposed to accept AbstractInput in constructor
+ * and produce tokens until end of source. If parsing ends in invalid state
+ * then IsStateValid() should return false
+ */
+template<class Token> class AbstractInputTokenizer
+{
+public:
+ class Exception
+ {
+ public:
+ DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, TokenizerError)
+ };
+
+ typedef Token TokenType;
+
+ AbstractInputTokenizer() {}
+ virtual ~AbstractInputTokenizer() {}
+
+ /**
+ * @brief Reset resets data source
+ * @param wia AbstractWaitableInputAdapter instance
+ */
+ virtual void Reset(std::shared_ptr<AbstractInput> wia)
+ {
+ m_input = wia;
+ }
+
+ /**
+ * @brief GetNextToken
+ *
+ * Parses next token.
+ * Returns pointer to token
+ * @throw TokenizerError in condition of input source error
+ * If returned empty pointer IsStateValid() == true -> end of input
+ * IsStateValid() == false -> error
+ *
+ * @param token token to be set
+ * @return
+ */
+ virtual std::unique_ptr<Token> GetNextToken() = 0;
+ virtual bool IsStateValid() = 0;
+
+protected:
+ std::shared_ptr<AbstractInput> m_input;
+};
+
+}
+
+#endif
${TESTS_DIR}/test/runner_multiprocess.cpp
${TESTS_DIR}/test/runner_child.cpp
${TESTS_DIR}/test/test_process_pipe.cpp
+ ${TESTS_DIR}/test/test_abstract_input_reader.cpp
)
#WRT_TEST_ADD_INTERNAL_DEPENDENCIES(${TARGET_NAME} ${TARGET_DPL_UTILS_EFL})
--- /dev/null
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file test_abstract_input_reader.h
+ * @author Tomasz Iwanek (t.iwanek@samsung.com)
+ * @brief tests for AbstractInputReader
+ */
+
+#include <cstring>
+#include <string>
+
+#include <dpl/test/abstract_input_reader.h>
+#include <dpl/abstract_input.h>
+#include <dpl/test/test_runner.h>
+#include <dpl/binary_queue.h>
+#include <dpl/optional.h>
+
+using namespace DPL;
+
+namespace {
+
+// TOKENIZER
+
+class DigitTokenizer : public AbstractInputTokenizer<int>
+{
+public:
+ DigitTokenizer() : m_valid(true) {}
+
+ std::unique_ptr<int> GetNextToken()
+ {
+ typedef AbstractInputTokenizer<int>::Exception::TokenizerError TokenizerError;
+
+ std::unique_ptr<int> token;
+
+ char buffer;
+ BinaryQueueAutoPtr baptr = m_input->Read(1); //not effective but it's test...
+ if(baptr.get() == NULL)
+ {
+ ThrowMsg(TokenizerError, "Input reading failed");
+ }
+ if(baptr->Empty()) //end of source
+ {
+ return token;
+ }
+ baptr->FlattenConsume(&buffer,1);
+ if(!isdigit(buffer))
+ {
+ ThrowMsg(TokenizerError, "Input source contains no digit characters/bytes");
+ }
+ token.reset(new int(static_cast<int>(buffer)));
+ return token;
+ }
+
+ void Reset(std::shared_ptr<AbstractInput> ia)
+ {
+ AbstractInputTokenizer<int>::Reset(ia);
+ m_valid = true;
+ }
+
+ bool IsStateValid()
+ {
+ return true;
+ }
+
+private:
+ bool m_valid;
+};
+
+// PARSER
+
+class SumatorParser : public AbstractInputParser<int, int>
+{
+public:
+ SumatorParser() : m_sum(0) {}
+
+ void ConsumeToken(std::unique_ptr<int> && token)
+ {
+ m_sum += (*token - '0');
+ }
+
+ bool IsStateValid()
+ {
+ return true;
+ }
+
+ int GetResult() const
+ {
+ return m_sum;
+ }
+
+private:
+ int m_sum;
+};
+
+// READER
+
+class Sumator : public AbstractInputReader<int, int>
+{
+public:
+ Sumator(std::shared_ptr<AbstractInput> ia)
+ : AbstractInputReader<int, int>(ia,
+ std::unique_ptr<ParserBase>(new SumatorParser()),
+ std::unique_ptr<TokenizerBase>(new DigitTokenizer()))
+ {}
+};
+
+}
+
+RUNNER_TEST_GROUP_INIT(AbstractInputReader)
+
+RUNNER_TEST(AbstractInputReader_ByteSumatorInstance_Sum)
+{
+ const std::string data("1234567890");
+ std::shared_ptr<AbstractInput> mem(new BinaryQueue());
+ dynamic_cast<BinaryQueue*>(mem.get())->AppendCopy(data.c_str(), data.size());
+ Sumator sum(mem);
+ int result = sum.ReadInput();
+ RUNNER_ASSERT_MSG(result == 45, "Sum is invalid");
+}
+
+RUNNER_TEST(AbstractInputReader_ByteSumatorInstance_Exception)
+{
+ const std::string data("12345string90");
+ std::shared_ptr<AbstractInput> mem(new BinaryQueue());
+ dynamic_cast<BinaryQueue*>(mem.get())->AppendCopy(data.c_str(), data.size());
+ Sumator sum(mem);
+ Try
+ {
+ sum.ReadInput();
+ }
+ Catch(Sumator::Exception::TokenizerError)
+ {
+ return;
+ }
+ RUNNER_ASSERT_MSG(false, "Tokenizer exception should be thrown");
+}