[Filesystem] FileSystemManager_mkdir native API
authorKamil Lysik <k.lysik@samsung.com>
Mon, 16 Feb 2015 15:23:17 +0000 (16:23 +0100)
committerWojciech Kosowicz <w.kosowicz@samsung.com>
Tue, 24 Feb 2015 07:59:35 +0000 (08:59 +0100)
Added API to create directory. This API create full path
when it is required. There are 2 versions: sync and async.

Change-Id: I81483c15bbd85d5501c3fd65b3f0399f3e2ad831
Signed-off-by: Kamil Lysik <k.lysik@samsung.com>
Signed-off-by: Pawel Sikorski <p.sikorski@samsung.com>
src/filesystem/filesystem_instance.cc
src/filesystem/filesystem_instance.h
src/filesystem/filesystem_manager.cc
src/filesystem/filesystem_manager.h
src/filesystem/filesystem_utils.cc
src/filesystem/filesystem_utils.h

index efcdfa0921a89875f84c411feb5a3d880e1de9ff..1140fd9c3b97cc770bcfe47b035f2f83f62fd20b 100644 (file)
@@ -37,6 +37,9 @@ FilesystemInstance::FilesystemInstance() {
   REGISTER_SYNC("Filesystem_getWidgetPaths", FilesystemGetWidgetPaths);
   REGISTER_SYNC("FileSystemManager_fetchStorages",
                 FileSystemManagerFetchStorages);
+  REGISTER_ASYNC("FileSystemManager_mkdir", FileSystemManagerMakeDirectory);
+  REGISTER_SYNC("FileSystemManager_mkdirSync",
+                FileSystemManagerMakeDirectorySync);
 #undef REGISTER_SYNC
 #undef REGISTER_ASYNC
 }
@@ -199,6 +202,48 @@ void FilesystemInstance::FileSystemManagerFetchStorages(
   FilesystemManager::GetInstance().FetchStorages(onSuccess, onError);
 }
 
+void FilesystemInstance::FileSystemManagerMakeDirectory(
+    const picojson::value& args,
+    picojson::object& out) {
+  LoggerD("enter");
+  CHECK_EXIST(args, "callbackId", out)
+  CHECK_EXIST(args, "location", out)
+
+  double callback_id = args.get("callbackId").get<double>();
+  const std::string& location = args.get("location").get<std::string>();
+
+  auto onResult = [this, callback_id](FilesystemError e) {
+    LoggerD("enter");
+    picojson::value response = picojson::value(picojson::object());
+    picojson::object& obj = response.get<picojson::object>();
+    obj["callbackId"] = picojson::value(callback_id);
+    PrepareError(e, obj);
+    PostMessage(response.serialize().c_str());
+  };
+
+  auto onAction = [location, onResult]() {
+    FilesystemManager::GetInstance().MakeDirectory(location, onResult);
+  };
+
+  common::TaskQueue::GetInstance().Async(onAction);
+}
+
+void FilesystemInstance::FileSystemManagerMakeDirectorySync(
+    const picojson::value& args,
+    picojson::object& out) {
+  LoggerD("enter");
+  CHECK_EXIST(args, "location", out)
+
+  const std::string& location = args.get("location").get<std::string>();
+
+  auto onResult = [&](FilesystemError e) {
+    LoggerD("enter");
+    PrepareError(e, out);
+  };
+
+  FilesystemManager::GetInstance().MakeDirectory(location, onResult);
+}
+
 void FilesystemInstance::PrepareError(const FilesystemError& error, picojson::object& out)
 {
   LoggerD("enter");
@@ -209,6 +254,12 @@ void FilesystemInstance::PrepareError(const FilesystemError& error, picojson::ob
     case FilesystemError::NotFound:
       ReportError(NotFoundException("PLATFORM ERROR"), out);
       break;
+    case FilesystemError::FileExists:
+      ReportError(IOException("File already exists"), out);
+      break;
+    case FilesystemError::DirectoryExists:
+      ReportError(IOException("Directory already exists"), out);
+      break;
     case FilesystemError::PermissionDenied:
       ReportError(IOException("Permission denied"), out);
       break;
index c2eb612026bcb715741656ba337fbe307010a6ef..889591b79c603d817cf827839c1e73c7c70a78c7 100644 (file)
@@ -25,7 +25,10 @@ class FilesystemInstance : public common::ParsedInstance {
                                 picojson::object& out);
   void FileSystemManagerFetchStorages(const picojson::value& args,
                                       picojson::object& out);
-
+  void FileSystemManagerMakeDirectory(const picojson::value& args,
+                                      picojson::object& out);
+  void FileSystemManagerMakeDirectorySync(const picojson::value& args,
+                                          picojson::object& out);
   void PrepareError(const FilesystemError& error, picojson::object& out);
 };
 
index db130a6b9da0e8ffc1cfc7e63029f56445409e12..455e262eea1753b15f1d9f859fd82faf46e0973b 100644 (file)
@@ -10,6 +10,8 @@
 #include <storage.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
 
 #include "common/logger.h"
 #include "common/scope_exit.h"
@@ -36,6 +38,35 @@ bool fetch_storages_cb(int storage_id,
   result->push_back(FilesystemStorage(storage_id, type, state, path));
   return true;
 }
+
+FilesystemError make_directory_worker(const std::string& path) {
+  LoggerD("enter: %s", path.c_str());
+  auto fsstat = FilesystemStat::getStat(path);
+  if (fsstat.valid) {
+    if (fsstat.isDirectory) {
+      LoggerD("Directory exists");
+      return FilesystemError::DirectoryExists;
+    } else {
+      LoggerD("It is a file and exists");
+      return FilesystemError::FileExists;
+    }
+  }
+
+  std::string parent_path = FilesystemUtils::get_dirname(path);
+  auto parent_result = make_directory_worker(parent_path);
+
+  if (parent_result == FilesystemError::DirectoryExists) {
+    LoggerD("Creating directrory: %s", path.c_str());
+    mode_t create_mode = S_IRWXU | S_IRWXG | S_IRWXO;
+    int r = mkdir(path.c_str(), create_mode);
+    if (r == 0) {
+      return FilesystemError::DirectoryExists;
+    }
+    LoggerD("Cannot create directory: %s", strerror(errno));
+    return FilesystemError::Other;
+  }
+  return parent_result;
+}
 }  // namespace
 
 void FilesystemManager::FetchStorages(
@@ -161,6 +192,13 @@ void FilesystemManager::CreateFile(
   }
 }
 
+void FilesystemManager::MakeDirectory(
+    const std::string& path,
+    const std::function<void(FilesystemError)>& result_cb) {
+  LoggerD("enter");
+  result_cb(make_directory_worker(path));
+}
+
 void FilesystemManager::Rename(
     const std::string& oldPath,
     const std::string& newPath,
index db82462a85ce5b4c1ed22d61a9eefb96e4b3fe3d..02a472c219d19f7bc08a2dee51f88a41ada6b38e 100644 (file)
@@ -44,6 +44,9 @@ class FilesystemManager {
               const std::string& newPath,
               const std::function<void(const FilesystemStat&)>& success_cb,
               const std::function<void(FilesystemError)>& error_cb);
+
+  void MakeDirectory(const std::string& path,
+                     const std::function<void(FilesystemError)>& result_cb);
 };
 }  // namespace filesystem
 }  // namespace extension
index c6bc60d1cd447fe6b46a825fc7f90785d6aeba07..32dfefeba1d553090b717bc7d4d84bc19d8fafd3 100644 (file)
@@ -4,6 +4,7 @@
 
 #include "filesystem_utils.h"
 
+#include <libgen.h>
 #include "common/logger.h"
 
 namespace std {
@@ -50,4 +51,16 @@ std::string get_storage_dir_path(int id, storage_directory_e typeToCheck) {
   free(platformPath);
   return path;
 }
+
+std::string get_dirname(const std::string& path) {
+  // dirname will modify content: pass a copy
+  std::string buf = path.c_str();
+  return std::string(dirname(const_cast<char*>(buf.c_str())));
+}
+
+std::string get_basename(const std::string& path) {
+  // basename will modify content: pass a copy
+  std::string buf = path.c_str();
+  return std::string(basename(const_cast<char*>(buf.c_str())));
+}
 }
index e83ae4069725f461e7ba8b29e6399f8210fd0cd8..2de420b18b53d20a357fdd9bb25162469bad4c87 100644 (file)
@@ -15,6 +15,8 @@ namespace filesystem {
 enum class FilesystemError {
   None,
   NotFound,
+  FileExists,
+  DirectoryExists,
   PermissionDenied,
   Other
 };
@@ -35,6 +37,9 @@ namespace FilesystemUtils {
  *
  */
 std::string get_storage_dir_path(int id, storage_directory_e typeToCheck);
+
+std::string get_dirname(const std::string& path);
+std::string get_basename(const std::string& path);
 }
 
 #endif  // FILESYSTEM_FILESYSTEM_UTILS_H