DPL path join for class Path to be introduced
authorTomasz Iwanek <t.iwanek@samsung.com>
Mon, 25 Feb 2013 15:36:11 +0000 (16:36 +0100)
committerTomasz Iwanek <t.iwanek@samsung.com>
Wed, 6 Mar 2013 09:44:23 +0000 (10:44 +0100)
[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
modules/core/include/dpl/scoped_dir.h [new file with mode: 0644]
modules/core/include/dpl/string.h
modules/core/src/scoped_dir.cpp [new file with mode: 0644]
modules/utils/config.cmake
tests/core/CMakeLists.txt
tests/core/test_scoped_dir.cpp [new file with mode: 0644]
tests/core/test_static_block.cpp
tests/core/test_string.cpp

index b681dd5..b929c35 100644 (file)
@@ -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 (file)
index 0000000..b10b4cc
--- /dev/null
@@ -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 <sys/stat.h>
+#include <sys/types.h>
+#include <string>
+#include <dpl/scoped_resource.h>
+
+namespace DPL {
+
+struct ScopedDirPolicy
+{
+    typedef std::string Type;
+    static Type NullValue();
+    static void Destroy(Type ptr);
+};
+
+class ScopedDir : public ScopedResource<ScopedDirPolicy>
+{
+    typedef ScopedDirPolicy Policy;
+    typedef ScopedResource<Policy> 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
index 59cd5e1..31132c1 100644 (file)
@@ -25,6 +25,7 @@
 #include <dpl/char_traits.h>
 #include <string>
 #include <ostream>
+#include <numeric>
 
 namespace DPL {
 // @brief DPL string
@@ -105,6 +106,33 @@ void Tokenize(const StringType& str,
         nextSearchStart = pos + 1;
     }
 }
+
+namespace Utils {
+
+template<typename T> class ConcatFunc : public std::binary_function<T, T, T>
+{
+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>
+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<value> 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 (file)
index 0000000..2639f7a
--- /dev/null
@@ -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 <dpl/scoped_dir.h>
+#include <dpl/log/log.h>
+
+#include <fts.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+namespace {
+
+bool removeRecusive(const char * path)
+{
+    FTS *fts;
+    FTSENT *ftsent;
+    bool rv = true;
+    char * const paths[] = { const_cast<char * const>(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
+
index 2b0beca..aac2fce 100644 (file)
@@ -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
index 73e7ec5..4348519 100644 (file)
@@ -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 (file)
index 0000000..3669203
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#include <dpl/scoped_dir.h>
+
+#include <cstdio>
+#include <sstream>
+#include <cstdlib>
+
+#include <unistd.h>
+
+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");
+}
index 0fc686e..b7596ef 100644 (file)
@@ -41,7 +41,7 @@ struct A
         ok_class = true;
     }
 };
-STATIC_BLOCK_CLASS( A, init );
+STATIC_BLOCK_CLASS( A, init )
 }
 
 /*
index dd2bd8a..69a3e4a 100644 (file)
@@ -23,6 +23,7 @@
 #include <cmath>
 #include <cstring>
 #include <vector>
+#include <string>
 #include <dpl/test/test_runner.h>
 #include <dpl/string.h>
 #include <dpl/sstream.h>
@@ -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<std::string> 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");
+}
+