summaryrefslogtreecommitdiff
path: root/src/components/utils/src/file_system.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/utils/src/file_system.cc')
-rw-r--r--src/components/utils/src/file_system.cc423
1 files changed, 423 insertions, 0 deletions
diff --git a/src/components/utils/src/file_system.cc b/src/components/utils/src/file_system.cc
new file mode 100644
index 0000000000..5eb2457a09
--- /dev/null
+++ b/src/components/utils/src/file_system.cc
@@ -0,0 +1,423 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "utils/file_system.h"
+#include "utils/logger.h"
+
+#include <sys/statvfs.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sstream>
+
+#include <dirent.h>
+#include <unistd.h>
+// TODO(VS): lint error: Streams are highly discouraged.
+#include <fstream>
+#include <cstddef>
+#include <algorithm>
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "Utils")
+
+uint64_t file_system::GetAvailableDiskSpace(const std::string& path) {
+ struct statvfs fsInfo;
+ memset(reinterpret_cast<void*>(&fsInfo), 0, sizeof(fsInfo));
+ if (statvfs(path.c_str(), &fsInfo) == 0) {
+ return fsInfo.f_bsize * fsInfo.f_bfree;
+ } else {
+ return 0;
+ }
+}
+
+int64_t file_system::FileSize(const std::string &path) {
+ if (file_system::FileExists(path)) {
+ struct stat file_info;
+ memset(reinterpret_cast<void*>(&file_info), 0, sizeof(file_info));
+ stat(path.c_str(), &file_info);
+ return file_info.st_size;
+ }
+ return 0;
+}
+
+size_t file_system::DirectorySize(const std::string& path) {
+ size_t size = 0;
+ int32_t return_code = 0;
+ DIR* directory = NULL;
+
+#ifndef __QNXNTO__
+ struct dirent dir_element_;
+ struct dirent* dir_element = &dir_element_;
+#else
+ char* direntbuffer =
+ new char[offsetof(struct dirent, d_name) +
+ pathconf(path.c_str(), _PC_NAME_MAX) + 1];
+ struct dirent* dir_element = new(direntbuffer) dirent;
+#endif
+ struct dirent* result = NULL;
+ struct stat file_info;
+ directory = opendir(path.c_str());
+ if (NULL != directory) {
+ return_code = readdir_r(directory, dir_element, &result);
+ for (; NULL != result && 0 == return_code;
+ return_code = readdir_r(directory, dir_element, &result)) {
+ if (0 == strcmp(result->d_name, "..")
+ || 0 == strcmp(result->d_name, ".")) {
+ continue;
+ }
+ std::string full_element_path = path + "/" + result->d_name;
+ if (file_system::IsDirectory(full_element_path)) {
+ size += DirectorySize(full_element_path);
+ } else {
+ memset(reinterpret_cast<void*>(&file_info), 0, sizeof(file_info));
+ stat(full_element_path.c_str(), &file_info);
+ size += file_info.st_size;
+ }
+ }
+ }
+ closedir(directory);
+#ifdef __QNXNTO__
+ delete[] direntbuffer;
+#endif
+ return size;
+}
+
+std::string file_system::CreateDirectory(const std::string& name) {
+ if (!DirectoryExists(name)) {
+ mkdir(name.c_str(), S_IRWXU);
+ }
+
+ return name;
+}
+
+bool file_system::CreateDirectoryRecursively(const std::string& path) {
+ size_t pos = 0;
+ bool ret_val = true;
+
+ while (ret_val == true && pos <= path.length()) {
+ pos = path.find('/', pos + 1);
+ if (!DirectoryExists(path.substr(0, pos))) {
+ if (0 != mkdir(path.substr(0, pos).c_str(), S_IRWXU)) {
+ ret_val = false;
+ }
+ }
+ }
+
+ return ret_val;
+}
+
+bool file_system::IsDirectory(const std::string& name) {
+ struct stat status;
+ memset(&status, 0, sizeof(status));
+
+ if (-1 == stat(name.c_str(), &status)) {
+ return false;
+ }
+
+ return S_ISDIR(status.st_mode);
+}
+
+bool file_system::DirectoryExists(const std::string& name) {
+ struct stat status;
+ memset(&status, 0, sizeof(status));
+
+ if (-1 == stat(name.c_str(), &status) || !S_ISDIR(status.st_mode)) {
+ return false;
+ }
+
+ return true;
+}
+
+bool file_system::FileExists(const std::string& name) {
+ struct stat status;
+ memset(&status, 0, sizeof(status));
+
+ if (-1 == stat(name.c_str(), &status)) {
+ return false;
+ }
+ return true;
+}
+
+bool file_system::Write(
+ const std::string& file_name, const std::vector<uint8_t>& data,
+ std::ios_base::openmode mode) {
+ std::ofstream file(file_name.c_str(), std::ios_base::binary | mode);
+ if (file.is_open()) {
+ for (uint32_t i = 0; i < data.size(); ++i) {
+ file << data[i];
+ }
+ file.close();
+ return true;
+ }
+ return false;
+}
+
+std::ofstream* file_system::Open(const std::string& file_name,
+ std::ios_base::openmode mode) {
+
+
+ std::ofstream* file = new std::ofstream();
+ file->open( file_name.c_str(),std::ios_base::binary | mode);
+ if (file->is_open()) {
+
+ return file;
+ }
+
+ return NULL;
+}
+
+bool file_system::Write(std::ofstream* const file_stream,
+ const uint8_t* data,
+ uint32_t data_size) {
+ bool result = false;
+ if (file_stream) {
+ for (size_t i = 0; i < data_size; ++i) {
+ (*file_stream) << data[i];
+ }
+ result = true;
+ }
+ return result;
+}
+
+void file_system::Close(std::ofstream* file_stream) {
+ if (file_stream) {
+ file_stream->close();
+ }
+}
+
+std::string file_system::CurrentWorkingDirectory() {
+ size_t filename_max_lenght = 1024;
+ char currentAppPath[filename_max_lenght];
+ memset(currentAppPath, 0, filename_max_lenght);
+ if (0 == getcwd(currentAppPath, filename_max_lenght)) {
+ LOG4CXX_WARN(logger_, "Could not get CWD");
+ }
+
+ char path[filename_max_lenght];
+ memset(path, 0, filename_max_lenght);
+ snprintf(path, filename_max_lenght - 1, "%s", currentAppPath);
+ return std::string(path);
+}
+
+bool file_system::DeleteFile(const std::string& name) {
+ if (FileExists(name) && IsAccessible(name, W_OK)) {
+ return !remove(name.c_str());
+ }
+ return false;
+}
+
+void file_system::remove_directory_content(const std::string& directory_name) {
+ int32_t return_code = 0;
+ DIR* directory = NULL;
+#ifndef __QNXNTO__
+ struct dirent dir_element_;
+ struct dirent* dir_element = &dir_element_;
+#else
+ char* direntbuffer =
+ new char[offsetof(struct dirent, d_name) +
+ pathconf(directory_name.c_str(), _PC_NAME_MAX) + 1];
+ struct dirent* dir_element = new(direntbuffer) dirent;
+#endif
+ struct dirent* result = NULL;
+
+ directory = opendir(directory_name.c_str());
+
+ if (NULL != directory) {
+ return_code = readdir_r(directory, dir_element, &result);
+
+ for (; NULL != result && 0 == return_code;
+ return_code = readdir_r(directory, dir_element, &result)) {
+ if (0 == strcmp(result->d_name, "..")
+ || 0 == strcmp(result->d_name, ".")) {
+ continue;
+ }
+
+ std::string full_element_path = directory_name + "/" + result->d_name;
+
+ if (file_system::IsDirectory(full_element_path)) {
+ remove_directory_content(full_element_path);
+ rmdir(full_element_path.c_str());
+ } else {
+ remove(full_element_path.c_str());
+ }
+ }
+ }
+
+ closedir(directory);
+#ifdef __QNXNTO__
+ delete[] direntbuffer;
+#endif
+}
+
+bool file_system::RemoveDirectory(const std::string& directory_name,
+ bool is_recursively) {
+ if (DirectoryExists(directory_name)
+ && IsAccessible(directory_name, W_OK)) {
+ if (is_recursively) {
+ remove_directory_content(directory_name);
+ }
+
+ return !rmdir(directory_name.c_str());
+ }
+ return false;
+}
+
+bool file_system::IsAccessible(const std::string& name, int32_t how) {
+ return !access(name.c_str(), how);
+}
+
+bool file_system::IsWritingAllowed(const std::string& name) {
+ return IsAccessible(name, W_OK);
+}
+
+bool file_system::IsReadingAllowed(const std::string& name) {
+ return IsAccessible(name, R_OK);
+}
+
+std::vector<std::string> file_system::ListFiles(
+ const std::string& directory_name) {
+ std::vector<std::string> listFiles;
+ if (!DirectoryExists(directory_name)) {
+ return listFiles;
+ }
+
+ int32_t return_code = 0;
+ DIR* directory = NULL;
+#ifndef __QNXNTO__
+ struct dirent dir_element_;
+ struct dirent* dir_element = &dir_element_;
+#else
+ char* direntbuffer =
+ new char[offsetof(struct dirent, d_name) +
+ pathconf(directory_name.c_str(), _PC_NAME_MAX) + 1];
+ struct dirent* dir_element = new(direntbuffer) dirent;
+#endif
+ struct dirent* result = NULL;
+
+ directory = opendir(directory_name.c_str());
+ if (NULL != directory) {
+ return_code = readdir_r(directory, dir_element, &result);
+
+ for (; NULL != result && 0 == return_code;
+ return_code = readdir_r(directory, dir_element, &result)) {
+ if (0 == strcmp(result->d_name, "..")
+ || 0 == strcmp(result->d_name, ".")) {
+ continue;
+ }
+
+ listFiles.push_back(std::string(result->d_name));
+ }
+
+ closedir(directory);
+#ifdef __QNXNTO__
+ delete[] direntbuffer;
+#endif
+ }
+
+ return listFiles;
+}
+
+bool file_system::WriteBinaryFile(const std::string& name,
+ const std::vector<uint8_t>& contents) {
+ using namespace std;
+ ofstream output(name.c_str(), ios_base::binary|ios_base::trunc);
+ output.write(reinterpret_cast<const char*>(&contents.front()),
+ contents.size());
+ return output.good();
+}
+
+bool file_system::ReadBinaryFile(const std::string& name,
+ std::vector<uint8_t>& result) {
+ if (!FileExists(name) || !IsAccessible(name, R_OK)) {
+ return false;
+ }
+
+ std::ifstream file(name.c_str(), std::ios_base::binary);
+ std::ostringstream ss;
+ ss << file.rdbuf();
+ const std::string& s = ss.str();
+
+ result.resize(s.length());
+ std::copy(s.begin(), s.end(), result.begin());
+ return true;
+}
+
+bool file_system::ReadFile(const std::string& name, std::string& result) {
+ if (!FileExists(name) || !IsAccessible(name, R_OK)) {
+ return false;
+ }
+
+ std::ifstream file(name.c_str());
+ std::ostringstream ss;
+ ss << file.rdbuf();
+ result = ss.str();
+ return true;
+}
+
+const std::string file_system::ConvertPathForURL(const std::string& path) {
+ std::string::const_iterator it_path = path.begin();
+ std::string::const_iterator it_path_end = path.end();
+
+ const std::string reserved_symbols = "!#$&'()*+,:;=?@[] ";
+ std::string::const_iterator it_sym = reserved_symbols.begin();
+ std::string::const_iterator it_sym_end = reserved_symbols.end();
+
+ std::string converted_path;
+ while (it_path != it_path_end) {
+
+ it_sym = reserved_symbols.begin();
+ for (; it_sym != it_sym_end; ++it_sym) {
+
+ if (*it_path == *it_sym) {
+ size_t size = 100;
+ char percent_value[size];
+ snprintf(percent_value, size, "%%%x", *it_path);
+ converted_path += percent_value;
+ ++it_path;
+ continue;
+ }
+ }
+
+ converted_path += *it_path;
+ ++it_path;
+ }
+
+ return converted_path;
+}
+
+bool file_system::CreateFile(const std::string& path) {
+ std::ofstream file(path);
+ if (!(file.is_open())) {
+ return false;
+ } else {
+ file.close();
+ return true;
+ }
+}