From fed4baac8362bd3d9a00c072119411f298629a82 Mon Sep 17 00:00:00 2001
From: Carsten Patzke <carsten.patzke@desy.de>
Date: Wed, 29 Nov 2017 12:21:10 +0100
Subject: [PATCH] *

---
 CMakeModules/astyle.cmake                     |   2 +-
 common/cpp/CMakeLists.txt                     |   2 +-
 common/cpp/include/common/networking.h        |   3 +-
 common/cpp/unittests/test_common.cpp          |   9 +-
 producer/api/CMakeLists.txt                   |   2 +-
 .../inotify-event-detector-cpp/CMakeLists.txt |  10 +-
 .../Inotify_event_detector.h                  |  25 ++++
 .../inotify_helper.h                          |  16 ++-
 .../src/Inotify_event_detector.cpp            |  43 ++++++
 .../src/inotify_helper.cpp                    | 132 ++++++++++++------
 .../inotify-event-detector-cpp/src/main.cpp   |  15 +-
 11 files changed, 189 insertions(+), 70 deletions(-)
 create mode 100644 producer/inotify-event-detector-cpp/include/inotify-event-detector-cpp/Inotify_event_detector.h
 create mode 100644 producer/inotify-event-detector-cpp/src/Inotify_event_detector.cpp

diff --git a/CMakeModules/astyle.cmake b/CMakeModules/astyle.cmake
index 68c8ad10a..259cd6177 100644
--- a/CMakeModules/astyle.cmake
+++ b/CMakeModules/astyle.cmake
@@ -6,7 +6,7 @@ function(astyle target source_files)
                 TARGET ${target} PRE_BUILD
                 COMMAND
                 ${ASTYLE_EXECUTABLE} -n --style=1tbs --indent-namespaces --indent-preproc-block ${source_files}
-                WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} VERBATIM
+                WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
         )
     else()
         message("Unable to find astyle. Skipping code formatting for ${target}")
diff --git a/common/cpp/CMakeLists.txt b/common/cpp/CMakeLists.txt
index a291827b8..de0217a85 100644
--- a/common/cpp/CMakeLists.txt
+++ b/common/cpp/CMakeLists.txt
@@ -9,7 +9,7 @@ add_library(${TARGET_NAME} SHARED ${SOURCE_FILES})
 target_include_directories(${TARGET_NAME} PUBLIC include)
 set_target_properties(${TARGET_NAME} PROPERTIES LINKER_LANGUAGE CXX)
 
-astyle(${TARGET_NAME} ${SOURCE_FILES})
+astyle(${TARGET_NAME} "${SOURCE_FILES}")
 
 
 ################################
diff --git a/common/cpp/include/common/networking.h b/common/cpp/include/common/networking.h
index d3ba01bad..ca2a547bc 100644
--- a/common/cpp/include/common/networking.h
+++ b/common/cpp/include/common/networking.h
@@ -6,7 +6,8 @@
 
 namespace HIDRA2
 {
-    namespace Networking {
+    namespace Networking
+    {
         enum OP_CODE : uint8_t {
             OP_CODE__HELLO,
             OP_CODE__PREPARE_SEND_DATA,
diff --git a/common/cpp/unittests/test_common.cpp b/common/cpp/unittests/test_common.cpp
index 5f7937f18..df599cf0c 100644
--- a/common/cpp/unittests/test_common.cpp
+++ b/common/cpp/unittests/test_common.cpp
@@ -1,6 +1,11 @@
 #include <gtest/gtest.h>
+#include <common/networking.h>
 
-TEST(EMPTY, REMOVEME)
+TEST(Networking, CheckIfNoErrorIsNull)
 {
-    EXPECT_EQ(1, 1);
+    /*
+     * To ensure that developers can use
+     * if(!response->error_code)
+     */
+    EXPECT_EQ((uint16_t)HIDRA2::Networking::ERR__NO_ERROR, 0);
 }
diff --git a/producer/api/CMakeLists.txt b/producer/api/CMakeLists.txt
index 57fda5855..aa0ba89d8 100644
--- a/producer/api/CMakeLists.txt
+++ b/producer/api/CMakeLists.txt
@@ -10,7 +10,7 @@ target_include_directories(${TARGET_NAME} PUBLIC include)
 target_link_libraries(${TARGET_NAME} common)
 set_target_properties(${TARGET_NAME} PROPERTIES LINKER_LANGUAGE CXX)
 
-astyle(${TARGET_NAME} ${SOURCE_FILES})
+astyle(${TARGET_NAME} "${SOURCE_FILES}")
 
 
 ################################
diff --git a/producer/inotify-event-detector-cpp/CMakeLists.txt b/producer/inotify-event-detector-cpp/CMakeLists.txt
index 0be339671..b59280162 100644
--- a/producer/inotify-event-detector-cpp/CMakeLists.txt
+++ b/producer/inotify-event-detector-cpp/CMakeLists.txt
@@ -1,5 +1,9 @@
 set(TARGET_NAME inotify-event-detector-cpp)
-set(SOURCE_FILES src/main.cpp src/inotify_helper.cpp include/inotify-event-detector-cpp/inotify_helper.h)
+set(SOURCE_FILES
+        src/main.cpp
+        src/inotify_helper.cpp include/inotify-event-detector-cpp/inotify_helper.h
+        src/Inotify_event_detector.cpp include/inotify-event-detector-cpp/Inotify_event_detector.h
+        )
 
 
 ################################
@@ -7,10 +11,10 @@ set(SOURCE_FILES src/main.cpp src/inotify_helper.cpp include/inotify-event-detec
 ################################
 add_executable(${TARGET_NAME} ${SOURCE_FILES})
 target_include_directories(${TARGET_NAME} PRIVATE include)
-target_link_libraries(${TARGET_NAME} common producer-api)
+target_link_libraries(${TARGET_NAME} pthread common producer-api)
 set_target_properties(${TARGET_NAME} PROPERTIES LINKER_LANGUAGE CXX)
 
-astyle(${TARGET_NAME} ${SOURCE_FILES})
+astyle(${TARGET_NAME} "${SOURCE_FILES}")
 
 
 ################################
diff --git a/producer/inotify-event-detector-cpp/include/inotify-event-detector-cpp/Inotify_event_detector.h b/producer/inotify-event-detector-cpp/include/inotify-event-detector-cpp/Inotify_event_detector.h
new file mode 100644
index 000000000..2cac05b1d
--- /dev/null
+++ b/producer/inotify-event-detector-cpp/include/inotify-event-detector-cpp/Inotify_event_detector.h
@@ -0,0 +1,25 @@
+#ifndef HIDRA2__INOTIFYEVENTDETECTOR_INOTIFYEVENTDETECTOR_H
+#define HIDRA2__INOTIFYEVENTDETECTOR_INOTIFYEVENTDETECTOR_H
+
+#include <sys/inotify.h>
+
+namespace HIDRA2
+{
+    namespace inotifyeventdetector
+    {
+        class InotifyEventDetector
+        {
+        public:
+            InotifyEventDetector(const InotifyEventDetector&) = delete;
+            InotifyEventDetector& operator=(const InotifyEventDetector&) = delete;
+            InotifyEventDetector() = default;
+
+            int main(int argc, char* argv[]);
+        private:
+            void event_handler_(inotify_event* event);
+        };
+    }
+}
+
+
+#endif //HIDRA2__INOTIFYEVENTDETECTOR_INOTIFYEVENTDETECTOR_H
diff --git a/producer/inotify-event-detector-cpp/include/inotify-event-detector-cpp/inotify_helper.h b/producer/inotify-event-detector-cpp/include/inotify-event-detector-cpp/inotify_helper.h
index f071cb121..f46e8b9ac 100644
--- a/producer/inotify-event-detector-cpp/include/inotify-event-detector-cpp/inotify_helper.h
+++ b/producer/inotify-event-detector-cpp/include/inotify-event-detector-cpp/inotify_helper.h
@@ -21,27 +21,35 @@ namespace HIDRA2
 
         };
 
+        enum INOTIFY_WATCH_MASK : uint32_t {
+            INOTIFY_WATCH_MASK__IN_CLOSE_WRITE = IN_CLOSE_WRITE,
+            INOTIFY_WATCH_MASK__IN_CLOSE_NOWRITE = IN_CLOSE_NOWRITE,
+            INOTIFY_WATCH_MASK__IN_CLOSE = IN_CLOSE,
+        };
+
         class InotifyHelper
         {
         public:
-            typedef void on_event_function(inotify_event*);
+            typedef void on_event_function_t (void* arg1, inotify_event*);
 
             InotifyHelper(const InotifyHelper&) = delete;
             InotifyHelper& operator=(const InotifyHelper&) = delete;
             ~InotifyHelper();
 
-            static INOTIFY_ERR create(InotifyHelper* ref, std::string watch_folder_path, uint32_t watch_mask, on_event_function on_event);
+            static INOTIFY_ERR create(InotifyHelper*& ref, std::string watch_folder_path, INOTIFY_WATCH_MASK watch_mask, on_event_function_t on_event, void* on_event_arg1);
             void start();
             void stop();
+            void free_event(inotify_event* event);
+
         private:
             InotifyHelper() = default;
 
             bool running_;
 
-            on_event_function on_event_;
+            on_event_function_t* on_event_;
+            void* on_event_arg1_;
             int file_descriptor_;
             int watch_descriptor_;
-            int error_ = 0;
 
             std::thread* internal_thread_handle_;
             void internal_thread_();
diff --git a/producer/inotify-event-detector-cpp/src/Inotify_event_detector.cpp b/producer/inotify-event-detector-cpp/src/Inotify_event_detector.cpp
new file mode 100644
index 000000000..96c3a05bb
--- /dev/null
+++ b/producer/inotify-event-detector-cpp/src/Inotify_event_detector.cpp
@@ -0,0 +1,43 @@
+#include <inotify-event-detector-cpp/Inotify_event_detector.h>
+#include <producer/producer.h>
+#include <iostream>
+#include <inotify-event-detector-cpp/inotify_helper.h>
+
+namespace HIDRA2
+{
+    int inotifyeventdetector::InotifyEventDetector::main(int argc, char** argv)
+    {
+
+        std::cout << "Running producer version: " << Producer::kVersion << std::endl;
+
+        Producer* producer = HIDRA2::Producer::CreateProducer("127.0.0.1");
+        if (!producer) {
+            std::cerr << "Fail to create producer" << std::endl;
+            return 1;
+        }
+
+        inotifyeventdetector::InotifyHelper* inotify_helper;
+
+        //inotifyeventdetector::InotifyHelper::on_event_function_t a = std::bind(inotifyeventdetector::InotifyEventDetector::event_handler_, this);
+        typedef void (*FPtr)(void);
+        FPtr p = inotifyeventdetector::InotifyEventDetector::event_handler_;
+
+
+        if (!inotify_helper->create(inotify_helper, "/tmp/data", inotifyeventdetector::INOTIFY_WATCH_MASK__IN_CLOSE_WRITE,
+                                    (InotifyHelper::on_event_function_t) p, this));
+
+        inotify_helper->start();
+
+        std::cout << "Successfully create producer " << std::hex << producer << std::endl;
+        sleep(10);
+
+        inotify_helper->stop();
+
+        return 0;
+    }
+
+    void inotifyeventdetector::InotifyEventDetector::event_handler_(inotify_event* event)
+    {
+        std::cout << "File was edited: '" << event->name << "'" << std::endl;
+    }
+}
diff --git a/producer/inotify-event-detector-cpp/src/inotify_helper.cpp b/producer/inotify-event-detector-cpp/src/inotify_helper.cpp
index d6199241c..0e18b980b 100644
--- a/producer/inotify-event-detector-cpp/src/inotify_helper.cpp
+++ b/producer/inotify-event-detector-cpp/src/inotify_helper.cpp
@@ -1,61 +1,101 @@
 #include <inotify-event-detector-cpp/inotify_helper.h>
+#include <iostream>
+#include <cstring>
 
-HIDRA2::inotifyeventdetector::InotifyHelper::~InotifyHelper() {
-    inotify_rm_watch(file_descriptor_, watch_descriptor_);
-    close(file_descriptor_);
-    stop();
-}
+namespace HIDRA2
+{
+    namespace inotifyeventdetector
+    {
+        InotifyHelper::~InotifyHelper()
+        {
+            inotify_rm_watch(file_descriptor_, watch_descriptor_);
+            close(file_descriptor_);
+            stop();
+        }
 
+        INOTIFY_ERR
+        InotifyHelper::create(InotifyHelper*& ref,
+                              std::string watch_folder_path, INOTIFY_WATCH_MASK watch_mask,
+                              InotifyHelper::on_event_function_t on_event, void* on_event_arg1)
+        {
+            auto* self = new InotifyHelper();
+            self->file_descriptor_ = inotify_init();
+            if (self->file_descriptor_ < 0) {
+                return INOTIFY_ERR__FAIL_TO_CREATE_INOTIFY_FILE_DESCRITPTOR;
+            }
 
-HIDRA2::inotifyeventdetector::INOTIFY_ERR
-HIDRA2::inotifyeventdetector::InotifyHelper::create(HIDRA2::inotifyeventdetector::InotifyHelper *ref,
-                                                    std::string watch_folder_path, uint32_t watch_mask,
-                                                    HIDRA2::inotifyeventdetector::InotifyHelper::on_event_function on_event) {
-    auto* self = new InotifyHelper();
-    self->file_descriptor_ = inotify_init();
-    if (self->file_descriptor_ < 0) {
-        return INOTIFY_ERR__FAIL_TO_CREATE_INOTIFY_FILE_DESCRITPTOR;
-    }
+            self->watch_descriptor_ = inotify_add_watch(self->file_descriptor_, watch_folder_path.c_str(), watch_mask);
+            if (self->watch_descriptor_ < 0) {
+                return INOTIFY_ERR__FAIL_TO_CREATE_WATCH_DESCRIPTOR;
+            }
 
-    self->watch_descriptor_ = inotify_add_watch(self->file_descriptor_, watch_folder_path.c_str(), watch_mask);
-    if (self->watch_descriptor_ < 0) {
-        return INOTIFY_ERR__FAIL_TO_CREATE_WATCH_DESCRIPTOR;
-    }
+            self->running_ = false;
+            self->on_event_ = on_event;
+            self->on_event_arg1_ = on_event_arg1;
 
-    self->on_event_ = on_event;
-    return INOTIFY_ERR__OK;
-}
+            ref = self;
+            return INOTIFY_ERR__OK;
+        }
 
-void HIDRA2::inotifyeventdetector::InotifyHelper::start() {
-    if(running_) {
-        return;
-    }
-    running_ = true;
-    internal_thread_handle_ = new std::thread(internal_thread_);
-}
+        void InotifyHelper::start()
+        {
+            if(running_) {
+                return;
+            }
+            running_ = true;
+            internal_thread_handle_ = new std::thread(&InotifyHelper::internal_thread_, this);
+        }
 
-void HIDRA2::inotifyeventdetector::InotifyHelper::stop() {
-    running_ = false;
-    if(internal_thread_handle_){
-        internal_thread_handle_->join();
-    }
-}
+        void InotifyHelper::stop()
+        {
+            running_ = false;
+            if(internal_thread_handle_) {
+                internal_thread_handle_->join();
+            }
+        }
+
+        void InotifyHelper::internal_thread_()
+        {
+            std::cout << "Hello world" << std::endl;
+            char buffer[EVENT_BUF_LEN];
+            ssize_t length;
+            while(running_) {
+                fd_set read_fds, write_fds, except_fds;
+                FD_ZERO(&read_fds);
+                FD_ZERO(&write_fds);
+                FD_ZERO(&except_fds);
+                FD_SET(file_descriptor_, &read_fds);
+
+                struct timeval timeout;
+                timeout.tv_sec = 1;
+                timeout.tv_usec = 0;
+
+                if (select(file_descriptor_ + 1, &read_fds, &write_fds, &except_fds, &timeout) == 1) {
+                    length = read(file_descriptor_, buffer, EVENT_BUF_LEN);
+                } else {
+                    continue;// A timeout occurred
+                }
+
+                int event_pointer = 0;
 
-void HIDRA2::inotifyeventdetector::InotifyHelper::internal_thread_() {
-    char buffer[EVENT_BUF_LEN];
-    while(running_) {
-        ssize_t length = read(file_descriptor_, buffer, EVENT_BUF_LEN);//TODO if !running_ close read stream
-        int event_pointer = 0;
+                /*checking for error*/
+                if (length < 0) {
+                    perror("read");
+                }
 
-        /*checking for error*/
-        if (length < 0) {
-            perror("read");
+                while (event_pointer < length && running_) {
+                    inotify_event* event = (inotify_event*) &(buffer[event_pointer]);
+                    inotify_event* copy = (inotify_event *) malloc(sizeof(inotify_event) + event->len);
+                    memmove(copy, event, sizeof(inotify_event) + event->len);
+                    on_event_(on_event_arg1_, copy);
+                    event_pointer += EVENT_SIZE + event->len;
+                }
+            }
         }
 
-        while (event_pointer < length && running_) {
-            inotify_event* event = (inotify_event*) &(buffer[event_pointer]);
-            on_event_(event);
-            event_pointer += EVENT_SIZE + event->len;
+        void InotifyHelper::free_event(inotify_event* event)
+        {
+            free(event);
         }
     }
 }
diff --git a/producer/inotify-event-detector-cpp/src/main.cpp b/producer/inotify-event-detector-cpp/src/main.cpp
index df37455cd..e7227d82b 100644
--- a/producer/inotify-event-detector-cpp/src/main.cpp
+++ b/producer/inotify-event-detector-cpp/src/main.cpp
@@ -1,17 +1,10 @@
 #include <producer/producer.h>
+#include <inotify-event-detector-cpp/inotify_helper.h>
+#include <inotify-event-detector-cpp/Inotify_event_detector.h>
 #include <iostream>
 
 int main (int argc, char* argv[])
 {
-    std::cout << "Running producer version: " << HIDRA2::Producer::kVersion << std::endl;
-
-    HIDRA2::Producer* producer = HIDRA2::Producer::CreateProducer("127.0.0.1");
-    if(!producer) {
-        std::cerr << "Fail to create producer" << std::endl;
-        return 1;
-    }
-
-    std::cout << "Successfully create producer " << std::hex << producer << std::endl;
-
-    return 0;
+    HIDRA2::inotifyeventdetector::InotifyEventDetector* inotify_event_detector;
+    return inotify_event_detector->main(argc, argv);
 }
-- 
GitLab