From bb5bb9aadf8878f0af27dba2a7eb4a27ddad2e02 Mon Sep 17 00:00:00 2001 From: Tomasz Iwanek Date: Mon, 25 Feb 2013 16:36:11 +0100 Subject: [PATCH] DPL path join for class Path to be introduced [Issue#] LINUXWRT-86 [Feature] Utilities before introducing class Path to utils DPL module [Cause] N/A [Solution] N/A [Verification] Build repository with tests. Run: wrt-commons-tests-core --output=text --regexp='String_Join' #join implementation for joining paths wrt-commons-tests-core --output=text --regexp='ScopedDir_Basic' #scoped dir for to simplify tests Change-Id: Ie7c3a4fad47cc7aa029a1ead15770b0d9f4b8a2c --- modules/core/config.cmake | 2 + modules/core/include/dpl/scoped_dir.h | 50 ++++++++++++++++ modules/core/include/dpl/string.h | 28 +++++++++ modules/core/src/scoped_dir.cpp | 106 ++++++++++++++++++++++++++++++++++ modules/utils/config.cmake | 1 - tests/core/CMakeLists.txt | 1 + tests/core/test_scoped_dir.cpp | 55 ++++++++++++++++++ tests/core/test_static_block.cpp | 2 +- tests/core/test_string.cpp | 24 ++++++++ 9 files changed, 267 insertions(+), 2 deletions(-) create mode 100644 modules/core/include/dpl/scoped_dir.h create mode 100644 modules/core/src/scoped_dir.cpp create mode 100644 tests/core/test_scoped_dir.cpp diff --git a/modules/core/config.cmake b/modules/core/config.cmake index b681dd5..b929c35 100644 --- a/modules/core/config.cmake +++ b/modules/core/config.cmake @@ -45,6 +45,7 @@ SET(DPL_CORE_SOURCES ${PROJECT_SOURCE_DIR}/modules/core/src/once.cpp ${PROJECT_SOURCE_DIR}/modules/core/src/read_write_mutex.cpp ${PROJECT_SOURCE_DIR}/modules/core/src/recursive_mutex.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/scoped_dir.cpp ${PROJECT_SOURCE_DIR}/modules/core/src/serialization.cpp ${PROJECT_SOURCE_DIR}/modules/core/src/single_instance.cpp ${PROJECT_SOURCE_DIR}/modules/core/src/singleton.cpp @@ -112,6 +113,7 @@ SET(DPL_CORE_HEADERS ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/scoped_resource.h ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/scoped_array.h ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/scoped_close.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/scoped_dir.h ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/scoped_fclose.h ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/scoped_free.h ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/scoped_ptr.h diff --git a/modules/core/include/dpl/scoped_dir.h b/modules/core/include/dpl/scoped_dir.h new file mode 100644 index 0000000..b10b4cc --- /dev/null +++ b/modules/core/include/dpl/scoped_dir.h @@ -0,0 +1,50 @@ +/* + * 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 scoped_dir.h + * @author Iwanek Tomasz (t.iwanek@smasung.com) + * @version 1.0 + * @brief This file is the implementation file of scoped directory existence + */ + +#ifndef DPL_SCOPED_DIR_H +#define DPL_SCOPED_DIR_H + +#include +#include +#include +#include + +namespace DPL { + +struct ScopedDirPolicy +{ + typedef std::string Type; + static Type NullValue(); + static void Destroy(Type ptr); +}; + +class ScopedDir : public ScopedResource +{ + typedef ScopedDirPolicy Policy; + typedef ScopedResource BaseType; + + public: + explicit ScopedDir(const std::string & str = Policy::NullValue(), mode_t mode = S_IRWXU|S_IRGRP|S_IXGRP); +}; +} // namespace DPL + +#endif // DPL_SCOPED_DIR_H diff --git a/modules/core/include/dpl/string.h b/modules/core/include/dpl/string.h index 59cd5e1..31132c1 100644 --- a/modules/core/include/dpl/string.h +++ b/modules/core/include/dpl/string.h @@ -25,6 +25,7 @@ #include #include #include +#include namespace DPL { // @brief DPL string @@ -105,6 +106,33 @@ void Tokenize(const StringType& str, nextSearchStart = pos + 1; } } + +namespace Utils { + +template class ConcatFunc : public std::binary_function +{ +public: + explicit ConcatFunc(const T & val) : m_delim(val) {} + T operator()(const T & arg1, const T & arg2) const + { + return arg1 + m_delim + arg2; + } +private: + T m_delim; +}; + +} + +template +typename ForwardIterator::value_type Join(ForwardIterator begin, ForwardIterator end, typename ForwardIterator::value_type delim) +{ + typedef typename ForwardIterator::value_type value; + if(begin == end) return value(); + Utils::ConcatFunc func(delim); + ForwardIterator init = begin; + return std::accumulate(++begin, end, *init, func); +} + } //namespace DPL std::ostream& operator<<(std::ostream& aStream, const DPL::String& aString); diff --git a/modules/core/src/scoped_dir.cpp b/modules/core/src/scoped_dir.cpp new file mode 100644 index 0000000..2639f7a --- /dev/null +++ b/modules/core/src/scoped_dir.cpp @@ -0,0 +1,106 @@ +/* + * 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 scoped_dir.cpp + * @author Iwanek Tomasz (t.iwanek@samsung.com) + * @version 1.0 + * @brief This file is the implementation scoped directory + */ +#include +#include + +#include +#include +#include + +namespace { + +bool removeRecusive(const char * path) +{ + FTS *fts; + FTSENT *ftsent; + bool rv = true; + char * const paths[] = { const_cast(path), NULL }; + if ((fts = fts_open(paths, FTS_PHYSICAL | FTS_NOCHDIR, NULL)) == NULL) { + return false; + } + while ((ftsent = fts_read(fts)) != NULL) { + switch (ftsent->fts_info) { + case FTS_D: + break; + case FTS_DP: + if (rmdir(ftsent->fts_accpath) != 0) { + rv = false; + } + break; + case FTS_DC: + case FTS_F: + case FTS_NSOK: + case FTS_SL: + case FTS_SLNONE: + case FTS_DEFAULT: + if (unlink(ftsent->fts_accpath) != 0) { + rv = false; + } + break; + case FTS_NS: + rv = false; + break; + case FTS_DOT: + case FTS_DNR: + case FTS_ERR: + default: + rv = false; + break; + } + } + if (fts_close(fts) == -1) { + rv = false; + } + return rv; +} + +} + +namespace DPL { + +ScopedDirPolicy::Type ScopedDirPolicy::NullValue() +{ + return std::string(); +} + +void ScopedDirPolicy::Destroy(Type str) +{ + if(!str.empty()) + { + bool status = removeRecusive(str.c_str()); + if(!status) + { + LogError("Error while removing recursively: " << str); + } + } +} + +ScopedDir::ScopedDir(const std::string & str, mode_t mode) : BaseType(str) +{ + if(!str.empty()) + { + mkdir(str.c_str(), mode); + } +} + +} // namespace DPL + diff --git a/modules/utils/config.cmake b/modules/utils/config.cmake index 2b0beca..aac2fce 100644 --- a/modules/utils/config.cmake +++ b/modules/utils/config.cmake @@ -30,7 +30,6 @@ SET(DPL_UTILS_SOURCES PARENT_SCOPE ) - SET(DPL_UTILS_HEADERS ${PROJECT_SOURCE_DIR}/modules/utils/include/dpl/utils/bash_utils.h ${PROJECT_SOURCE_DIR}/modules/utils/include/dpl/utils/folder_size.h diff --git a/tests/core/CMakeLists.txt b/tests/core/CMakeLists.txt index 73e7ec5..4348519 100644 --- a/tests/core/CMakeLists.txt +++ b/tests/core/CMakeLists.txt @@ -40,6 +40,7 @@ SET(DPL_TESTS_CORE_SOURCES ${TESTS_DIR}/core/test_serialization.cpp ${TESTS_DIR}/core/test_scoped_array.cpp ${TESTS_DIR}/core/test_scoped_close.cpp + ${TESTS_DIR}/core/test_scoped_dir.cpp ${TESTS_DIR}/core/test_scoped_fclose.cpp ${TESTS_DIR}/core/test_scoped_free.cpp ${TESTS_DIR}/core/test_scoped_ptr.cpp diff --git a/tests/core/test_scoped_dir.cpp b/tests/core/test_scoped_dir.cpp new file mode 100644 index 0000000..3669203 --- /dev/null +++ b/tests/core/test_scoped_dir.cpp @@ -0,0 +1,55 @@ +/* + * 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_scoped_dir.cpp + * @author Iwanek Tomasz (t.iwanek@smasung.com) + * @version 1.0 + * @brief Scoped directory test + */ +#include +#include + +#include +#include +#include + +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +/* +Name: ScopedDir_Basic +Description: tests if scoped directory is working +Expected: directory created and removed +*/ +RUNNER_TEST(ScopedDir_Basic) +{ + const char * path = "/tmp/wrttest123456"; + if(access(path, F_OK) == 0) + { + RUNNER_ASSERT_MSG(!remove(path), "Cannot remove test directory"); + } + + { + DPL::ScopedDir dir(path, S_IRUSR | S_IWUSR); + std::ostringstream command; + command << "touch " << path << "/" << "file.txt"; + system(command.str().c_str()); + RUNNER_ASSERT_MSG(access(path, R_OK) == 0, "Directory should be accessible"); + RUNNER_ASSERT_MSG(access(path, W_OK) == 0, "Directory should be writable"); + } + RUNNER_ASSERT_MSG(access(path, F_OK) != 0, "Directory should not exists"); +} diff --git a/tests/core/test_static_block.cpp b/tests/core/test_static_block.cpp index 0fc686e..b7596ef 100644 --- a/tests/core/test_static_block.cpp +++ b/tests/core/test_static_block.cpp @@ -41,7 +41,7 @@ struct A ok_class = true; } }; -STATIC_BLOCK_CLASS( A, init ); +STATIC_BLOCK_CLASS( A, init ) } /* diff --git a/tests/core/test_string.cpp b/tests/core/test_string.cpp index dd2bd8a..69a3e4a 100644 --- a/tests/core/test_string.cpp +++ b/tests/core/test_string.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -416,3 +417,26 @@ RUNNER_TEST(String_CompareCaseInsensitive) true) == 0); } +/* +Name: String_Join +Description: tests joining strings algorithm +Expected: join should take place correctly +*/ +RUNNER_TEST(String_Join) +{ + std::vector strings; + RUNNER_ASSERT(DPL::Join(strings.begin(), strings.end(), "/") == ""); + strings.push_back("one"); + RUNNER_ASSERT(DPL::Join(strings.begin(), strings.end(), "/") == "one"); + strings.push_back("two"); + RUNNER_ASSERT(DPL::Join(strings.begin(), strings.end(), "/") == "one/two"); + strings.push_back("three"); + RUNNER_ASSERT(DPL::Join(strings.begin(), strings.end(), "/") == "one/two/three"); + strings.push_back("four"); + RUNNER_ASSERT(DPL::Join(strings.begin(), strings.end(), "/") == "one/two/three/four"); + RUNNER_ASSERT(DPL::Join(++strings.begin(), --strings.end(), "/") == "two/three"); + + RUNNER_ASSERT(DPL::Join(strings.begin(), strings.end(), "+") == "one+two+three+four"); + RUNNER_ASSERT(DPL::Join(strings.begin(), strings.end(), "delim") == "onedelimtwodelimthreedelimfour"); +} + -- 2.7.4