changeset 1588:b5bc87a7212d

OrthancPluginReadFile, OrthancPluginWriteFile
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 26 Aug 2015 16:49:46 +0200
parents d7e569640d09
children 334d3a92ed83
files Core/Toolbox.cpp Core/Toolbox.h NEWS Plugins/Engine/OrthancPlugins.cpp Plugins/Include/orthanc/OrthancCPlugin.h Plugins/Samples/ServeFolders/Plugin.cpp
diffstat 6 files changed, 135 insertions(+), 54 deletions(-) [+]
line wrap: on
line diff
--- a/Core/Toolbox.cpp	Wed Aug 26 12:12:25 2015 +0200
+++ b/Core/Toolbox.cpp	Wed Aug 26 16:49:46 2015 +0200
@@ -230,7 +230,8 @@
   }
 
 
-  void Toolbox::WriteFile(const std::string& content,
+  void Toolbox::WriteFile(const void* content,
+                          size_t size,
                           const std::string& path)
   {
     boost::filesystem::ofstream f;
@@ -240,15 +241,22 @@
       throw OrthancException(ErrorCode_CannotWriteFile);
     }
 
-    if (content.size() != 0)
+    if (size != 0)
     {
-      f.write(content.c_str(), content.size());
+      f.write(reinterpret_cast<const char*>(content), size);
     }
 
     f.close();
   }
 
 
+  void Toolbox::WriteFile(const std::string& content,
+                          const std::string& path)
+  {
+    WriteFile(content.size() > 0 ? content.c_str() : NULL,
+              content.size(), path);
+  }
+
 
   void Toolbox::RemoveFile(const std::string& path)
   {
--- a/Core/Toolbox.h	Wed Aug 26 12:12:25 2015 +0200
+++ b/Core/Toolbox.h	Wed Aug 26 16:49:46 2015 +0200
@@ -69,6 +69,10 @@
     void WriteFile(const std::string& content,
                    const std::string& path);
 
+    void WriteFile(const void* content,
+                   size_t size,
+                   const std::string& path);
+
     void USleep(uint64_t microSeconds);
 
     void RemoveFile(const std::string& path);
--- a/NEWS	Wed Aug 26 12:12:25 2015 +0200
+++ b/NEWS	Wed Aug 26 16:49:46 2015 +0200
@@ -19,7 +19,9 @@
 Plugins
 -------
 
-* New function OrthancPluginBufferCompression() to (un)compress memory buffers
+* New function "OrthancPluginBufferCompression()" to (un)compress memory buffers
+* New function "OrthancPluginReadFile()" to read files from the filesystem
+* New function "OrthancPluginWriteFile()" to write files to the filesystem
 * Plugins have access to explicit error codes 
 
 Maintenance
--- a/Plugins/Engine/OrthancPlugins.cpp	Wed Aug 26 12:12:25 2015 +0200
+++ b/Plugins/Engine/OrthancPlugins.cpp	Wed Aug 26 16:49:46 2015 +0200
@@ -935,6 +935,8 @@
   bool OrthancPlugins::InvokeService(_OrthancPluginService service,
                                      const void* parameters)
   {
+    VLOG(1) << "Calling plugin service: " << service;
+
     boost::recursive_mutex::scoped_lock lock(pimpl_->invokeServiceMutex_);
 
     switch (service)
@@ -1198,6 +1200,26 @@
         return true;
       }
 
+      case _OrthancPluginService_ReadFile:
+      {
+        const _OrthancPluginReadFile& p =
+          *reinterpret_cast<const _OrthancPluginReadFile*>(parameters);
+
+        std::string content;
+        Toolbox::ReadFile(content, p.path);
+        CopyToMemoryBuffer(*p.target, content.size() > 0 ? content.c_str() : NULL, content.size());
+
+        return true;
+      }
+
+      case _OrthancPluginService_WriteFile:
+      {
+        const _OrthancPluginWriteFile& p =
+          *reinterpret_cast<const _OrthancPluginWriteFile*>(parameters);
+        Toolbox::WriteFile(p.data, p.size, p.path);
+        return true;
+      }
+
       default:
         // This service is unknown by the Orthanc plugin engine
         return false;
--- a/Plugins/Include/orthanc/OrthancCPlugin.h	Wed Aug 26 12:12:25 2015 +0200
+++ b/Plugins/Include/orthanc/OrthancCPlugin.h	Wed Aug 26 16:49:46 2015 +0200
@@ -352,6 +352,8 @@
     _OrthancPluginService_GetExpectedDatabaseVersion = 12,
     _OrthancPluginService_GetConfiguration = 13,
     _OrthancPluginService_BufferCompression = 14,
+    _OrthancPluginService_ReadFile = 15,
+    _OrthancPluginService_WriteFile = 16,
 
     /* Registration of callbacks */
     _OrthancPluginService_RegisterRestCallback = 1000,
@@ -2387,6 +2389,69 @@
   }
 
 
+
+  typedef struct
+  {
+    OrthancPluginMemoryBuffer*  target;
+    const char*                 path;
+  } _OrthancPluginReadFile;
+
+  /**
+   * @brief Read a file.
+   * 
+   * Read the content of a file on the filesystem, and returns it into
+   * a newly allocated memory buffer.
+   * 
+   * @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
+   * @param target The target memory buffer.
+   * @param path The path of the file to be read.
+   * @return 0 if success, or the error code if failure.
+   **/
+  ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode  OrthancPluginReadFile(
+    OrthancPluginContext*       context,
+    OrthancPluginMemoryBuffer*  target,
+    const char*                 path)
+  {
+    _OrthancPluginReadFile params;
+    params.target = target;
+    params.path = path;
+    return context->InvokeService(context, _OrthancPluginService_ReadFile, &params);
+  }
+
+
+
+  typedef struct
+  {
+    const char*  path;
+    const void*  data;
+    uint32_t     size;
+  } _OrthancPluginWriteFile;
+
+  /**
+   * @brief Write a file.
+   * 
+   * Write the content of a memory buffer to the filesystem.
+   * 
+   * @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
+   * @param path The path of the file to be written.
+   * @param data The content of the memory buffer.
+   * @param size The size of the memory buffer.
+   * @return 0 if success, or the error code if failure.
+   **/
+  ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode  OrthancPluginWriteFile(
+    OrthancPluginContext*  context,
+    const char*            path,
+    const void*            data,
+    uint32_t               size)
+  {
+    _OrthancPluginWriteFile params;
+    params.path = path;
+    params.data = data;
+    params.size = size;
+    return context->InvokeService(context, _OrthancPluginService_WriteFile, &params);
+  }
+
+
 #ifdef  __cplusplus
 }
 #endif
--- a/Plugins/Samples/ServeFolders/Plugin.cpp	Wed Aug 26 12:12:25 2015 +0200
+++ b/Plugins/Samples/ServeFolders/Plugin.cpp	Wed Aug 26 16:49:46 2015 +0200
@@ -89,52 +89,20 @@
 }
 
 
-
-static bool ReadFile(std::string& content,
+static bool ReadFile(std::string& target,
                      const std::string& path)
 {
-  struct stat s;
-  if (stat(path.c_str(), &s) != 0 ||
-      !(s.st_mode & S_IFREG))
-  {
-    // Either the path does not exist, or it is not a regular file
-    return false;
-  }
-
-  FILE* fp = fopen(path.c_str(), "rb");
-  if (fp == NULL)
+  OrthancPluginMemoryBuffer buffer;
+  if (OrthancPluginReadFile(context_, &buffer, path.c_str()))
   {
     return false;
   }
-
-  long size;
-
-  if (fseek(fp, 0, SEEK_END) == -1 ||
-      (size = ftell(fp)) < 0)
-  {
-    fclose(fp);
-    return false;
-  }
-
-  content.resize(size);
-      
-  if (fseek(fp, 0, SEEK_SET) == -1)
+  else
   {
-    fclose(fp);
-    return false;
+    target.assign(reinterpret_cast<const char*>(buffer.data), buffer.size);
+    OrthancPluginFreeMemoryBuffer(context_, &buffer);
+    return true;
   }
-
-  bool ok = true;
-
-  if (size > 0 &&
-      fread(&content[0], size, 1, fp) != 1)
-  {
-    ok = false;
-  }
-
-  fclose(fp);
-
-  return ok;
 }
 
 
@@ -210,9 +178,9 @@
 }
 
 
-static int32_t IndexCallback(OrthancPluginRestOutput* output,
-                             const char* url,
-                             const OrthancPluginHttpRequest* request)
+static int32_t ListServedFolders(OrthancPluginRestOutput* output,
+                                 const char* url,
+                                 const OrthancPluginHttpRequest* request)
 {
   if (request->method != OrthancPluginHttpMethod_Get)
   {
@@ -296,23 +264,35 @@
     for (Json::Value::Members::const_iterator 
            it = members.begin(); it != members.end(); ++it)
     {
-      const std::string& baseUri = *it;
-      const std::string path = configuration["ServeFolders"][*it].asString();
-      const std::string regex = "(" + baseUri + ")/(.*)";
+      std::string baseUri = *it;
+
+      // Remove the heading and trailing slashes if any
+      while (!baseUri.empty() &&
+             *baseUri.begin() == '/')
+      {
+        baseUri = baseUri.substr(1);
+      }
 
-      if (baseUri.empty() ||
-          *baseUri.rbegin() == '/')
+      while (!baseUri.empty() &&
+             *baseUri.rbegin() == '/')
       {
-        std::string message = "The URI of a folder to be server cannot be empty or end with a '/': " + *it;
-        OrthancPluginLogWarning(context_, message.c_str());
+        baseUri.resize(baseUri.size() - 1);
+      }
+
+      if (baseUri.empty())
+      {
+        OrthancPluginLogError(context_, "The URI of a folder to be served cannot be empty");
         return -1;
       }
 
+      const std::string path = configuration["ServeFolders"][*it].asString();
+      const std::string regex = "/(" + baseUri + ")/(.*)";
+
       OrthancPluginRegisterRestCallback(context, regex.c_str(), FolderCallback);
       folders_[baseUri] = path;
     }
 
-    OrthancPluginRegisterRestCallback(context, INDEX_URI, IndexCallback);
+    OrthancPluginRegisterRestCallback(context, INDEX_URI, ListServedFolders);
     OrthancPluginSetRootUri(context, INDEX_URI);
 
     return 0;