diff --git a/libuavcan_drivers/include/posix_tools/file_storage_backend.hpp b/libuavcan_drivers/include/posix_tools/file_storage_backend.hpp new file mode 100644 index 0000000000..67762606ac --- /dev/null +++ b/libuavcan_drivers/include/posix_tools/file_storage_backend.hpp @@ -0,0 +1,137 @@ +/**************************************************************************** +* +* Copyright (c) 2015 PX4 Development Team. All rights reserved. +* Author: Pavel Kirienko +* David Sidrane +* +****************************************************************************/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace uavcan_posix +{ +namespace dynamic_node_id_server +{ +/** + * This interface implements a POSIX compliant IStorageBackend interface + */ +class FileStorageBackend : public uavcan::dynamic_node_id_server::IStorageBackend +{ + /** + * Maximum length of full path including / and key max + */ + + enum { MaxPathLength = 128 }; + + + /** + * This type is used for the path + */ + typedef uavcan::Array, + uavcan::ArrayModeDynamic, MaxPathLength> PathString; + + + PathString base_path; + +public: + + FileStorageBackend() { } + + + virtual String get(const String& key) const + { + using namespace std; + PathString path = base_path.c_str(); + path += key; + String value; + int fd = open(path.c_str(), O_RDONLY); + if (fd >= 0) + { + char buffer[MaxStringLength + 1]; + memset(buffer, 0, sizeof(buffer)); + int len = read(fd, buffer, MaxStringLength); + close(fd); + if (len > 0) + { + for (int i = 0; i < len; i++) + { + if (buffer[i] == ' ' || buffer[i] == '\n' || buffer[i] == '\r' ) + { + buffer[i] = '\0'; + break; + } + } + } + } + return value; + + } + + virtual void set(const String& key, const String& value) + { + using namespace std; + PathString path = base_path.c_str(); + path += key; + int fd = open(path.c_str(), O_WRONLY | O_CREAT | O_TRUNC); + if (fd >= 0) + { + write(fd, value.c_str(), value.size()); + close(fd); + } + } + + /** + * Initializes the File based back end storage by passing to a path to + * the directory where the key named files will be stored. + * This the return result should be 0 on success. + * If it is -EFBIG then the the path name is too long to + * Accommodate the trailing slash and max key length; + * + */ + + int init(const String & path) + { + using namespace std; + + int rv = -EINVAL; + + if (path.size() > 0) + { + + base_path = path.c_str(); + + if (base_path.back() == '/') + { + base_path.pop_back(); + } + + struct stat sb; + + if (stat(base_path.c_str(), &sb) != 0 || !S_ISDIR(sb.st_mode)) + { + rv = mkdir(base_path.c_str(), S_IRWXU | S_IRWXG | S_IRWXO); + } + base_path.push_back('/'); + if ((base_path.size() + MaxStringLength) > MaxPathLength) + { + rv = -EFBIG; + } + } + return rv; + + } + +}; + +} +}