${PROJECT_SOURCE_DIR}/modules/test/src/test_runner_child.cpp
${PROJECT_SOURCE_DIR}/modules/test/src/test_runner_multiprocess.cpp
${PROJECT_SOURCE_DIR}/modules/test/src/process_pipe.cpp
+ ${PROJECT_SOURCE_DIR}/modules/test/src/value_separated_policies.cpp
+ ${PROJECT_SOURCE_DIR}/modules/test/src/value_separated_tokens.cpp
PARENT_SCOPE
)
${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
+ ${PROJECT_SOURCE_DIR}/modules/test/include/dpl/test/value_separated_parser.h
+ ${PROJECT_SOURCE_DIR}/modules/test/include/dpl/test/value_separated_policies.h
+ ${PROJECT_SOURCE_DIR}/modules/test/include/dpl/test/value_separated_reader.h
+ ${PROJECT_SOURCE_DIR}/modules/test/include/dpl/test/value_separated_tokenizer.h
+ ${PROJECT_SOURCE_DIR}/modules/test/include/dpl/test/value_separated_tokens.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 value_separated_parser.h
+ * @author Tomasz Iwanek (t.iwanek@samsung.com)
+ * @brief Parser for some value seperated files/data
+ */
+
+#ifndef VALUE_SEPARATED_PARSER_H
+#define VALUE_SEPARATED_PARSER_H
+
+#include<string>
+#include<vector>
+#include<memory>
+
+#include<dpl/test/value_separated_tokens.h>
+#include<dpl/test/abstract_input_parser.h>
+
+namespace DPL {
+
+typedef std::vector<std::string> VSLine;
+typedef std::vector<VSLine> VSResult;
+typedef std::shared_ptr<VSResult> VSResultPtr;
+
+/**
+ * Value Seperated parser
+ *
+ * Requires following policy class:
+ *
+ * template<VSResultPtr>
+ * struct CSVParserPolicy
+ * {
+ * static bool SkipLine(VSLine & );
+ * static bool Validate(VSResultPtr& result);
+ * };
+ */
+template<class ParserPolicy>
+class VSParser : public AbstractInputParser<VSResultPtr, VSToken>
+{
+public:
+ VSParser() : m_switchLine(true), m_result(new VSResult()) {}
+
+ void ConsumeToken(std::unique_ptr<VSToken> && token)
+ {
+ if(m_switchLine)
+ {
+ m_result->push_back(VSLine());
+ m_switchLine = false;
+ }
+ if(token->isNewLine())
+ {
+ if(ParserPolicy::SkipLine(*m_result->rbegin()))
+ {
+ m_result->pop_back();
+ }
+ m_switchLine = true;
+ }
+ else
+ {
+ m_result->rbegin()->push_back(token->cell());
+ }
+ }
+
+ bool IsStateValid()
+ {
+ return ParserPolicy::Validate(m_result);
+ }
+
+ VSResultPtr GetResult() const
+ {
+ return m_result;
+ }
+
+private:
+ bool m_switchLine;
+ VSResultPtr m_result;
+};
+
+}
+
+#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 value_separated_policies.h
+ * @author Tomasz Iwanek (t.iwanek@samsung.com)
+ * @brief Example policy classes for some value seperated files/data
+ */
+
+#ifndef VALUE_SEPARATED_POLICIES_H
+#define VALUE_SEPARATED_POLICIES_H
+
+#include<string>
+#include<vector>
+#include<memory>
+
+namespace DPL {
+
+struct CSVTokenizerPolicy
+{
+ static std::string GetSeperators(); //cells in line are separated by given characters
+ static bool SkipEmpty(); //if cell is empty, shoudl I skip?
+ static void PrepareValue(std::string &); //transform each value
+ static bool TryAgainAtEnd(int); //read is nonblocking so dat may not be yet available, should I retry?
+};
+
+struct CSVParserPolicy
+{
+ static bool SkipLine(const std::vector<std::string> & ); //should I skip whole readline?
+ static bool Validate(std::shared_ptr<std::vector<std::vector<std::string> > > & result); //validate and adjust output data
+};
+
+}
+
+#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 value_separated_reader.h
+ * @author Tomasz Iwanek (t.iwanek@samsung.com)
+ * @brief Reader for some value seperated files/data
+ *
+ * This is parser for files containing lines with values seperated with custom charaters.
+ * Purpose of this is to parse output similar to csv and hide (no need for rewriting)
+ * buffers, reads, code errors. Result is two dimensional array.
+ *
+ * Reader is designed as class configured with policies classes:
+ * http://en.wikipedia.org/wiki/Policy-based_design
+ */
+
+#ifndef VALUE_SEPARATED_READER_H
+#define VALUE_SEPARATED_READER_H
+
+#include<dpl/test/abstract_input_reader.h>
+#include<dpl/test/value_separated_tokenizer.h>
+#include<dpl/test/value_separated_parser.h>
+#include<dpl/test/value_separated_tokens.h>
+#include<dpl/test/value_separated_policies.h>
+
+namespace DPL {
+
+/**
+ * Reader for input with values separated with defined characters
+ *
+ * Usage:
+ * - define both policies classes for defining and customize exact behaviour of reader
+ * - make typedef for VSReader template instance with your policies
+ *
+ */
+template<class ParserPolicy, class TokenizerPolicy>
+class VSReader : public AbstractInputReader<VSResultPtr, VSToken>
+{
+public:
+ VSReader(std::shared_ptr<AbstractInput> wia)
+ : AbstractInputReader<VSResultPtr, VSToken>(wia,
+ std::unique_ptr<ParserBase>(new VSParser<ParserPolicy>()),
+ std::unique_ptr<TokenizerBase>(new VSTokenizer<TokenizerPolicy>()))
+ {}
+};
+
+typedef VSReader<CSVParserPolicy, CSVTokenizerPolicy> CSVReader;
+
+}
+
+#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 value_separated_tokenizer.h
+ * @author Tomasz Iwanek (t.iwanek@samsung.com)
+ * @brief Tokenizer for some value seperated files/data
+ */
+
+#ifndef VALUE_SEPARATED_TOKENIZER_H
+#define VALUE_SEPARATED_TOKENIZER_H
+
+#include<dpl/test/abstract_input_tokenizer.h>
+#include<dpl/test/value_separated_tokens.h>
+#include<dpl/binary_queue.h>
+
+
+namespace DPL {
+
+/**
+ * Value Sperated tokenizer
+ *
+ * Requires following policy class:
+ *
+ * struct TokenizerPolicy
+ * {
+ * static std::string GetSeperators();
+ * static bool SkipEmpty();
+ * static void PrepareValue(std::string & value);
+ * };
+ */
+template<class TokenizerPolicy>
+class VSTokenizer : public AbstractInputTokenizer<VSToken>
+{
+public:
+ VSTokenizer() {}
+
+ void Reset(std::shared_ptr<AbstractInput> ia)
+ {
+ AbstractInputTokenizer<VSToken>::Reset(ia);
+ m_queue.Clear();
+ m_finished = false;
+ m_newline = false;
+ }
+
+ std::unique_ptr<VSToken> GetNextToken()
+ {
+ std::unique_ptr<VSToken> token;
+ std::string data;
+ char byte;
+ int tryNumber = 0;
+
+ while(true)
+ {
+ //check if newline was approched
+ if(m_newline)
+ {
+ token.reset(new VSToken());
+ m_newline = false;
+ return token;
+ }
+
+ //read next data
+ if(m_queue.Empty())
+ {
+ if(m_finished)
+ {
+ return token;
+ }
+ else
+ {
+ auto baptr = m_input->Read(4096);
+ if(baptr.get() == 0)
+ {
+ ThrowMsg(Exception::TokenizerError, "Input read failed");
+ }
+ if(baptr->Empty())
+ {
+ if(TokenizerPolicy::TryAgainAtEnd(tryNumber))
+ {
+ ++tryNumber;
+ continue;
+ }
+ m_finished = true;
+ return token;
+ }
+ m_queue.AppendMoveFrom(*baptr);
+ }
+ }
+
+ //process
+ m_queue.FlattenConsume(&byte, 1); //queue uses pointer to consume bytes, this do not causes reallocations
+ if(byte == '\n')
+ {
+ m_newline = true;
+ if(!data.empty() || !TokenizerPolicy::SkipEmpty())
+ {
+ ProduceString(token, data);
+ return token;
+ }
+ }
+ else if(TokenizerPolicy::GetSeperators().find(byte) != std::string::npos)
+ {
+ if(!data.empty() || !TokenizerPolicy::SkipEmpty())
+ {
+ ProduceString(token, data);
+ return token;
+ }
+ }
+ else
+ {
+ data += byte;
+ }
+ }
+ }
+
+ bool IsStateValid()
+ {
+ if(!m_queue.Empty() && m_finished) return false;
+ return true;
+ }
+
+protected:
+ void ProduceString(std::unique_ptr<VSToken> & token, std::string & data)
+ {
+ TokenizerPolicy::PrepareValue(data);
+ token.reset(new VSToken(data));
+ }
+
+ BinaryQueue m_queue;
+ bool m_finished;
+ bool m_newline;
+};
+
+}
+
+#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 value_separated_tokens.h
+ * @author Tomasz Iwanek (t.iwanek@samsung.com)
+ * @brief Token class for some value seperated files/data
+ */
+
+#ifndef VALUE_SEPARATED_TOKENS_H
+#define VALUE_SEPARATED_TOKENS_H
+
+#include<string>
+
+namespace DPL {
+
+class VSToken
+{
+public:
+ VSToken(const std::string & c);
+ VSToken(); //newline token - no new class to simplify
+ const std::string & cell() const;
+
+ bool isNewLine();
+private:
+ bool m_newline;
+ std::string m_cell;
+};
+
+}
+
+#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 value_separated_policies.cpp
+ * @author Tomasz Iwanek (t.iwanek@samsung.com)
+ * @brief ...
+ */
+
+#include<dpl/test/value_separated_policies.h>
+#include<dpl/foreach.h>
+#include<dpl/log/log.h>
+
+namespace DPL {
+
+std::string CSVTokenizerPolicy::GetSeperators()
+{
+ return ",";
+}
+
+bool CSVTokenizerPolicy::SkipEmpty()
+{
+ return false;
+}
+
+void CSVTokenizerPolicy::PrepareValue(std::string &)
+{
+}
+
+bool CSVTokenizerPolicy::TryAgainAtEnd(int)
+{
+ return false;
+}
+
+bool CSVParserPolicy::SkipLine(const std::vector<std::string> & )
+{
+ return false;
+}
+
+bool CSVParserPolicy::Validate(std::shared_ptr<std::vector<std::vector<std::string> > > & result)
+{
+ int num = -1;
+ FOREACH(r, *result)
+ {
+ int size = r->size();
+ if(num != -1 && num != size)
+ {
+ LogError("Columns not matches");
+ return false;
+ }
+ num = size;
+ }
+ return true;
+}
+
+}
--- /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 value_separated_tokens.cpp
+ * @author Tomasz Iwanek (t.iwanek@samsung.com)
+ * @brief ...
+ */
+
+#include <dpl/test/value_separated_tokens.h>
+
+namespace DPL {
+
+VSToken::VSToken(const std::string & c) : m_newline(false), m_cell(c)
+{
+}
+
+VSToken::VSToken() : m_newline(true)
+{
+}
+
+const std::string & VSToken::cell() const
+{
+ return m_cell;
+}
+
+bool VSToken::isNewLine()
+{
+ return m_newline;
+}
+
+}
${TESTS_DIR}/test/runner_child.cpp
${TESTS_DIR}/test/test_process_pipe.cpp
${TESTS_DIR}/test/test_abstract_input_reader.cpp
+ ${TESTS_DIR}/test/test_value_separated_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_value_separated_reader.cpp
+ * @author Tomasz Iwanek (t.iwanek@samsung.com)
+ * @brief tests for VSReader
+ */
+
+#include<dpl/test/value_separated_reader.h>
+#include<dpl/abstract_input.h>
+#include<dpl/test/test_runner.h>
+
+#include<string>
+
+using namespace DPL;
+
+RUNNER_TEST_GROUP_INIT(ValueSeparatedReader)
+
+RUNNER_TEST(ValueSeparatedReader_readValidCSV)
+{
+ std::string data;
+ data += "1-1,1-2,1-3,1-4\n";
+ data += "2-1,2-2,2-3,2-4\n";
+ data += "3-1,3-2,3-3,3-4\n";
+ data += "4-1,4-2,4-3,4-4\n";
+ std::shared_ptr<AbstractInput> mem(new BinaryQueue());
+ dynamic_cast<BinaryQueue*>(mem.get())->AppendCopy(data.data(), data.size());
+ CSVReader csv(mem);
+ VSResultPtr result = csv.ReadInput();
+ RUNNER_ASSERT_MSG((*result)[0][0] == "1-1", "Wrong value");
+ RUNNER_ASSERT_MSG((*result)[0][1] == "1-2", "Wrong value");
+ RUNNER_ASSERT_MSG((*result)[0][2] == "1-3", "Wrong value");
+ RUNNER_ASSERT_MSG((*result)[0][3] == "1-4", "Wrong value");
+
+ RUNNER_ASSERT_MSG((*result)[1][0] == "2-1", "Wrong value");
+ RUNNER_ASSERT_MSG((*result)[1][1] == "2-2", "Wrong value");
+ RUNNER_ASSERT_MSG((*result)[1][2] == "2-3", "Wrong value");
+ RUNNER_ASSERT_MSG((*result)[1][3] == "2-4", "Wrong value");
+
+ RUNNER_ASSERT_MSG((*result)[2][0] == "3-1", "Wrong value");
+ RUNNER_ASSERT_MSG((*result)[2][1] == "3-2", "Wrong value");
+ RUNNER_ASSERT_MSG((*result)[2][2] == "3-3", "Wrong value");
+ RUNNER_ASSERT_MSG((*result)[2][3] == "3-4", "Wrong value");
+
+ RUNNER_ASSERT_MSG((*result)[3][0] == "4-1", "Wrong value");
+ RUNNER_ASSERT_MSG((*result)[3][1] == "4-2", "Wrong value");
+ RUNNER_ASSERT_MSG((*result)[3][2] == "4-3", "Wrong value");
+ RUNNER_ASSERT_MSG((*result)[3][3] == "4-4", "Wrong value");
+}
+
+RUNNER_TEST(ValueSeparatedReader_readInvalidCSV)
+{
+ Try
+ {
+ std::string data;
+ data += "1-1,1-2,1-3,1-4\n";
+ data += "2-1,2-2,2-3,2-4\n";
+ data += "3-1,3-2,3-3\n";
+ data += "4-1,4-2,4-3,4-4\n";
+ std::shared_ptr<AbstractInput> mem(new BinaryQueue());
+ dynamic_cast<BinaryQueue*>(mem.get())->AppendCopy(data.data(), data.size());
+ CSVReader csv(mem);
+ VSResultPtr result = csv.ReadInput();
+ }
+ Catch(CSVReader::Exception::ParserError)
+ {
+ return;
+ }
+ RUNNER_ASSERT_MSG(false, "Should throw parser error");
+}