FDStore class for binary serialization 67/28367/10
authorJan Olszak <j.olszak@samsung.com>
Fri, 3 Oct 2014 16:16:59 +0000 (18:16 +0200)
committerJan Olszak <j.olszak@samsung.com>
Tue, 7 Oct 2014 15:47:31 +0000 (17:47 +0200)
[Bug/Feature]   Class for writing and reading binary data to a file descriptor
[Cause]         N/A
[Solution]      N/A
[Verification]  Build, install, run tests

Change-Id: I18713366449c77a17970eeb7f0f6b3ae1feac656

src/config/fdstore.cpp [new file with mode: 0644]
src/config/fdstore.hpp [new file with mode: 0644]
src/config/from-fdstore-visitor.hpp [new file with mode: 0644]
src/config/manager.hpp
src/config/to-fdstore-visitor.hpp [new file with mode: 0644]

diff --git a/src/config/fdstore.cpp b/src/config/fdstore.cpp
new file mode 100644 (file)
index 0000000..050e99f
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ *  Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jan Olszak <j.olszak@samsung.com>
+ *
+ *  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
+ * @author Jan Olszak (j.olszak@samsung.com)
+ * @brief  Definition of a class for writing and reading data from a file descriptor
+ */
+
+#include "config.hpp"
+
+#include "config/fdstore.hpp"
+#include "config/exception.hpp"
+
+#include <cstring>
+#include <cerrno>
+#include <unistd.h>
+
+namespace config {
+
+
+FDStore::FDStore(int fd)
+    : mFD(fd)
+{
+}
+
+FDStore::FDStore(const FDStore& store)
+    : mFD(store.mFD)
+{
+}
+
+FDStore::~FDStore()
+{
+}
+
+void FDStore::write(const void* bufferPtr, const size_t size)
+{
+    size_t nTotal = 0;
+    int n;
+
+    do {
+        n  = ::write(mFD,
+                     reinterpret_cast<const char*>(bufferPtr) + nTotal,
+                     size - nTotal);
+        if (n < 0) {
+            if (errno == EINTR) {
+                continue;
+            }
+            throw ConfigException("Error during witting: " + std::string(strerror(errno)));
+        }
+        nTotal += n;
+    } while (nTotal < size);
+}
+
+void FDStore::read(void* bufferPtr, const size_t size)
+{
+    size_t nTotal = 0;
+    int n;
+
+    do {
+        n  = ::read(mFD,
+                    reinterpret_cast<char*>(bufferPtr) + nTotal,
+                    size - nTotal);
+        if (n < 0) {
+            if (errno == EINTR) {
+                continue;
+            }
+            throw ConfigException("Error during reading: " + std::string(strerror(errno)));
+        }
+        nTotal += n;
+    } while (nTotal < size);
+}
+
+} // namespace config
diff --git a/src/config/fdstore.hpp b/src/config/fdstore.hpp
new file mode 100644 (file)
index 0000000..d99971d
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ *  Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jan Olszak <j.olszak@samsung.com>
+ *
+ *  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
+ * @author Jan Olszak (j.olszak@samsung.com)
+ * @brief  Declaration of a class for writing and reading data from a file descriptor
+ */
+
+#ifndef COMMON_CONFIG_FDSTORE_HPP
+#define COMMON_CONFIG_FDSTORE_HPP
+
+#include <cstddef>
+
+namespace config {
+
+class FDStore {
+
+public:
+    /**
+     * Constructor. One can pass any kind of file descriptor.
+     * Serialization is NOT written for network purposes,
+     * rather local communication.
+     *
+     * @param fd file descriptor
+     */
+    FDStore(int fd = -1);
+    FDStore(const FDStore& store);
+    ~FDStore();
+
+    /**
+     * Write data using the file descriptor
+     *
+     * @param bufferPtr buffer with the data
+     * @param size size of the buffer
+     */
+    void write(const void* bufferPtr, const size_t size);
+
+    /**
+     * Reads a value of the given type.
+     *
+     * @param bufferPtr buffer with the data
+     * @param size size of the buffer
+     */
+    void read(void* bufferPtr, const size_t size);
+
+private:
+    int mFD;
+};
+
+} // namespace config
+
+#endif // COMMON_CONFIG_FDSTORE_HPP
+
+
diff --git a/src/config/from-fdstore-visitor.hpp b/src/config/from-fdstore-visitor.hpp
new file mode 100644 (file)
index 0000000..4266255
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ *  Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jan Olszak (j.olszak@samsung.com)
+ *
+ *  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
+ * @author  Jan Olszak (j.olszak@samsung.com)
+ * @brief   Visitor for loading from FDStore
+ */
+
+#ifndef CONFIG_FROM_FDSTORE_VISITOR_HPP
+#define CONFIG_FROM_FDSTORE_VISITOR_HPP
+
+#include "config/is-visitable.hpp"
+#include "config/fdstore.hpp"
+
+#include <string>
+
+namespace config {
+
+class FromFDStoreVisitor {
+public:
+    explicit FromFDStoreVisitor(int fd)
+        : mStore(fd)
+    {
+    }
+
+    FromFDStoreVisitor(const FromFDStoreVisitor& visitor) = default;
+
+    FromFDStoreVisitor& operator=(const FromFDStoreVisitor&) = delete;
+
+    template<typename T>
+    void visit(const std::string& name, T& value)
+    {
+        readInternal(value);
+    }
+
+private:
+    FDStore mStore;
+
+    void readInternal(std::string& value)
+    {
+        size_t size;
+        readInternal(size);
+        value.resize(size);
+        mStore.read(&value.front(), size);
+    }
+
+    template<typename T, typename std::enable_if<std::is_arithmetic<T>::value, int>::type = 0>
+    void readInternal(T& value)
+    {
+        mStore.read(&value, sizeof(T));
+    }
+
+    template<typename T, typename std::enable_if<isVisitable<T>::value, int>::type = 0>
+    void readInternal(T& value)
+    {
+        FromFDStoreVisitor visitor(*this);
+        value.accept(visitor);
+    }
+
+    template<typename T>
+    void readInternal(std::vector<T>& values)
+    {
+        size_t vectorSize;
+        readInternal(vectorSize);
+        values.resize(vectorSize);
+
+        for (T& value : values) {
+            readInternal(value);
+        }
+    }
+};
+
+} // namespace config
+
+#endif // CONFIG_FROM_FDSTORE_VISITOR_HPP
index 688bc54..a2623ea 100644 (file)
 
 #include "config/to-json-visitor.hpp"
 #include "config/to-kvstore-visitor.hpp"
+#include "config/to-fdstore-visitor.hpp"
 #include "config/from-json-visitor.hpp"
 #include "config/from-kvstore-visitor.hpp"
+#include "config/from-fdstore-visitor.hpp"
 #include "config/is-visitable.hpp"
 #include "config/fs-utils.hpp"
 
@@ -121,7 +123,7 @@ void loadFromKVStore(const std::string& filename, Config& config, const std::str
  * Saves the config to a KVStore.
  *
  * @param filename   path to the KVStore db
- * @param config     visitable structure to load
+ * @param config     visitable structure to save
  * @param configName name of the config inside the KVStore db
  */
 template <class Config>
@@ -133,6 +135,36 @@ void saveToKVStore(const std::string& filename, const Config& config, const std:
     config.accept(visitor);
 }
 
+/**
+ * Load binary data from a file/socket/pipe represented by the fd
+ *
+ * @param fd file descriptor
+ * @param config visitable structure to load
+ */
+template <class Config>
+void loadFromFD(const int fd, Config& config)
+{
+    static_assert(isVisitable<Config>::value, "Use CONFIG_REGISTER macro");
+
+    FromFDStoreVisitor visitor(fd);
+    config.accept(visitor);
+}
+
+/**
+ * Save binary data to a file/socket/pipe represented by the fd
+ *
+ * @param fd file descriptor
+ * @param config visitable structure to save
+ */
+template <class Config>
+void saveToFD(const int fd, const Config& config)
+{
+    static_assert(isVisitable<Config>::value, "Use CONFIG_REGISTER macro");
+
+    ToFDStoreVisitor visitor(fd);
+    config.accept(visitor);
+}
+
 } // namespace config
 
 #endif // CONFIG_MANAGER_HPP
diff --git a/src/config/to-fdstore-visitor.hpp b/src/config/to-fdstore-visitor.hpp
new file mode 100644 (file)
index 0000000..7a2f358
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ *  Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jan Olszak (j.olszak@samsung.com)
+ *
+ *  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
+ * @author  Jan Olszak (j.olszak@samsung.com)
+ * @brief   Visitor for saving to FDStore
+ */
+
+#ifndef CONFIG_TO_FDSTORE_VISITOR_HPP
+#define CONFIG_TO_FDSTORE_VISITOR_HPP
+
+#include "config/is-visitable.hpp"
+#include "config/fdstore.hpp"
+
+#include <string>
+
+namespace config {
+
+class ToFDStoreVisitor {
+
+public:
+    ToFDStoreVisitor(int fd)
+        : mStore(fd)
+    {
+    }
+
+    ToFDStoreVisitor(const ToFDStoreVisitor& visitor) = default;
+
+    ToFDStoreVisitor& operator=(const ToFDStoreVisitor&) = delete;
+
+    template<typename T>
+    void visit(const std::string& name, const T& value)
+    {
+        writeInternal(value);
+    }
+
+private:
+    FDStore mStore;
+
+    void writeInternal(const std::string& value)
+    {
+        writeInternal(value.size());
+        mStore.write(value.c_str(), value.size());
+    }
+
+    template<typename T, typename std::enable_if<std::is_arithmetic<T>::value, int>::type = 0>
+    void writeInternal(const T& value)
+    {
+        mStore.write(&value, sizeof(T));
+    }
+
+    template<typename T, typename std::enable_if<isVisitable<T>::value, int>::type = 0>
+    void writeInternal(const T& value)
+    {
+        ToFDStoreVisitor visitor(*this);
+        value.accept(visitor);
+    }
+
+    template<typename T>
+    void writeInternal(const std::vector<T>& values)
+    {
+        writeInternal(values.size());
+        for (const T& value : values) {
+            writeInternal(value);
+        }
+    }
+
+};
+
+} // namespace config
+
+#endif // CONFIG_TO_FDSTORE_VISITOR_HPP