changeset 61:147bd6dc28db

refactoring using new items in the plugin toolbox of Orthanc
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 25 Nov 2016 17:15:55 +0100
parents a59fdb848a7b
children f45cec2c32e2
files Applications/CMakeLists.txt Applications/DicomToTiff.cpp Framework/DicomizerParameters.cpp Framework/DicomizerParameters.h Framework/Inputs/DicomPyramid.cpp Framework/Inputs/DicomPyramid.h Framework/Inputs/DicomPyramidInstance.cpp Framework/Inputs/DicomPyramidInstance.h Framework/Inputs/DicomPyramidLevel.cpp Framework/Inputs/DicomPyramidLevel.h Framework/Messaging/CurlOrthancConnection.cpp Framework/Messaging/CurlOrthancConnection.h Framework/Messaging/FolderTarget.cpp Framework/Messaging/FolderTarget.h Framework/Messaging/IFileTarget.h Framework/Messaging/IOrthancConnection.cpp Framework/Messaging/IOrthancConnection.h Framework/Messaging/OrthancConnectionBase.cpp Framework/Messaging/OrthancConnectionBase.h Framework/Messaging/OrthancTarget.cpp Framework/Messaging/OrthancTarget.h Framework/Messaging/PluginOrthancConnection.cpp Framework/Messaging/PluginOrthancConnection.h Framework/Outputs/DicomPyramidWriter.h Framework/Targets/FolderTarget.cpp Framework/Targets/FolderTarget.h Framework/Targets/IFileTarget.h Framework/Targets/OrthancTarget.cpp Framework/Targets/OrthancTarget.h Resources/Orthanc/Plugins/Samples/Common/FullOrthancDataset.cpp Resources/Orthanc/Plugins/Samples/Common/FullOrthancDataset.h Resources/Orthanc/Plugins/Samples/Common/IOrthancConnection.h Resources/Orthanc/Plugins/Samples/Common/SimplifiedOrthancDataset.cpp Resources/Orthanc/Plugins/Samples/Common/SimplifiedOrthancDataset.h Resources/SyncOrthancFolder.py ViewerPlugin/CMakeLists.txt ViewerPlugin/Plugin.cpp
diffstat 37 files changed, 338 insertions(+), 824 deletions(-) [+]
line wrap: on
line diff
--- a/Applications/CMakeLists.txt	Fri Nov 25 16:38:09 2016 +0100
+++ b/Applications/CMakeLists.txt	Fri Nov 25 17:15:55 2016 +0100
@@ -87,6 +87,7 @@
   -DORTHANC_ENABLE_PLUGINS=1  # To enable class Orthanc::SharedLibrary
   -DORTHANC_ENABLE_PUGIXML=0
   -DORTHANC_SANDBOXED=0
+  -DHAS_ORTHANC_EXCEPTION=1
   )
 
 
@@ -109,7 +110,6 @@
 #####################################################################
 
 set(ORTHANC_WSI_SOURCES
-  #${ORTHANC_WSI_DIR}/Framework/Messaging/PluginOrthancConnection.cpp
   ${ORTHANC_WSI_DIR}/Framework/Algorithms/PyramidReader.cpp
   ${ORTHANC_WSI_DIR}/Framework/Algorithms/ReconstructPyramidCommand.cpp
   ${ORTHANC_WSI_DIR}/Framework/Algorithms/TranscodeTileCommand.cpp
@@ -130,11 +130,8 @@
   ${ORTHANC_WSI_DIR}/Framework/Inputs/TiledPyramidStatistics.cpp
   ${ORTHANC_WSI_DIR}/Framework/Jpeg2000Reader.cpp
   ${ORTHANC_WSI_DIR}/Framework/Jpeg2000Writer.cpp
-  ${ORTHANC_WSI_DIR}/Framework/Messaging/CurlOrthancConnection.cpp
-  ${ORTHANC_WSI_DIR}/Framework/Messaging/FolderTarget.cpp
-  ${ORTHANC_WSI_DIR}/Framework/Messaging/IOrthancConnection.cpp
-  ${ORTHANC_WSI_DIR}/Framework/Messaging/OrthancConnectionBase.cpp
-  ${ORTHANC_WSI_DIR}/Framework/Messaging/OrthancTarget.cpp
+  ${ORTHANC_WSI_DIR}/Framework/Targets/FolderTarget.cpp
+  ${ORTHANC_WSI_DIR}/Framework/Targets/OrthancTarget.cpp
   ${ORTHANC_WSI_DIR}/Framework/Outputs/DicomPyramidWriter.cpp
   ${ORTHANC_WSI_DIR}/Framework/Outputs/HierarchicalTiffWriter.cpp
   ${ORTHANC_WSI_DIR}/Framework/Outputs/InMemoryTiledImage.cpp
@@ -171,7 +168,18 @@
   ${ORTHANC_ROOT}/OrthancServer/FromDcmtkBridge.cpp
   ${ORTHANC_ROOT}/OrthancServer/ServerEnumerations.cpp
   ${ORTHANC_ROOT}/OrthancServer/ToDcmtkBridge.cpp
+
   ${ORTHANC_ROOT}/Plugins/Engine/SharedLibrary.cpp
+  ${ORTHANC_ROOT}/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp
+  ${ORTHANC_ROOT}/Plugins/Samples/Common/DicomDatasetReader.cpp
+  ${ORTHANC_ROOT}/Plugins/Samples/Common/DicomPath.cpp
+  ${ORTHANC_ROOT}/Plugins/Samples/Common/DicomTag.cpp
+  ${ORTHANC_ROOT}/Plugins/Samples/Common/FullOrthancDataset.cpp
+  ${ORTHANC_ROOT}/Plugins/Samples/Common/IOrthancConnection.cpp
+  ${ORTHANC_ROOT}/Plugins/Samples/Common/OrthancHttpConnection.cpp
+  ${ORTHANC_ROOT}/Plugins/Samples/Common/OrthancPluginConnection.cpp
+  ${ORTHANC_ROOT}/Plugins/Samples/Common/SimplifiedOrthancDataset.cpp
+
   ${ORTHANC_ROOT}/Resources/ThirdParty/base64/base64.cpp
   )
 
--- a/Applications/DicomToTiff.cpp	Fri Nov 25 16:38:09 2016 +0100
+++ b/Applications/DicomToTiff.cpp	Fri Nov 25 17:15:55 2016 +0100
@@ -22,11 +22,11 @@
 #include "../Framework/ImageToolbox.h"
 #include "../Framework/Inputs/DicomPyramid.h"
 #include "../Framework/Inputs/TiledPyramidStatistics.h"
-#include "../Framework/Messaging/CurlOrthancConnection.h"
 #include "../Framework/Outputs/HierarchicalTiffWriter.h"
 
 #include "../Resources/Orthanc/Core/Logging.h"
 #include "../Resources/Orthanc/Core/OrthancException.h"
+#include "../Resources/Orthanc/Plugins/Samples/Common/OrthancHttpConnection.h"
 
 #include "ApplicationToolbox.h"
 
@@ -299,7 +299,7 @@
         params.SetPassword(options["password"].as<std::string>());
       }
 
-      OrthancWSI::CurlOrthancConnection orthanc(params);
+      OrthancPlugins::OrthancHttpConnection orthanc(params);
       OrthancWSI::DicomPyramid source(orthanc, options["input"].as<std::string>());
 
       OrthancWSI::TiledPyramidStatistics stats(source);
--- a/Framework/DicomizerParameters.cpp	Fri Nov 25 16:38:09 2016 +0100
+++ b/Framework/DicomizerParameters.cpp	Fri Nov 25 17:15:55 2016 +0100
@@ -21,8 +21,8 @@
 #include "PrecompiledHeadersWSI.h"
 #include "DicomizerParameters.h"
 
-#include "Messaging/FolderTarget.h"
-#include "Messaging/OrthancTarget.h"
+#include "Targets/FolderTarget.h"
+#include "Targets/OrthancTarget.h"
 
 #include "../Resources/Orthanc/Core/OrthancException.h"
 
--- a/Framework/DicomizerParameters.h	Fri Nov 25 16:38:09 2016 +0100
+++ b/Framework/DicomizerParameters.h	Fri Nov 25 17:15:55 2016 +0100
@@ -22,7 +22,7 @@
 
 #include "Inputs/ITiledPyramid.h"
 #include "Outputs/IPyramidWriter.h"
-#include "Messaging/IFileTarget.h"
+#include "Targets/IFileTarget.h"
 #include "DicomToolbox.h"
 #include "../Resources/Orthanc/Core/WebServiceParameters.h"
 
--- a/Framework/Inputs/DicomPyramid.cpp	Fri Nov 25 16:38:09 2016 +0100
+++ b/Framework/Inputs/DicomPyramid.cpp	Fri Nov 25 17:15:55 2016 +0100
@@ -63,7 +63,7 @@
   void DicomPyramid::RegisterInstances(const std::string& seriesId)
   {
     Json::Value series;
-    IOrthancConnection::RestApiGet(series, orthanc_, "/series/" + seriesId);
+    OrthancPlugins::IOrthancConnection::RestApiGet(series, orthanc_, "/series/" + seriesId);
 
     if (series.type() != Json::objectValue)
     {
@@ -135,7 +135,7 @@
   }
 
 
-  DicomPyramid::DicomPyramid(IOrthancConnection& orthanc,
+  DicomPyramid::DicomPyramid(OrthancPlugins::IOrthancConnection& orthanc,
                              const std::string& seriesId) :
     orthanc_(orthanc),
     seriesId_(seriesId)
--- a/Framework/Inputs/DicomPyramid.h	Fri Nov 25 16:38:09 2016 +0100
+++ b/Framework/Inputs/DicomPyramid.h	Fri Nov 25 17:15:55 2016 +0100
@@ -31,10 +31,10 @@
   private:
     struct Comparator;
 
-    IOrthancConnection&                 orthanc_;
-    std::string                         seriesId_;
-    std::vector<DicomPyramidInstance*>  instances_;
-    std::vector<DicomPyramidLevel*>     levels_;
+    OrthancPlugins::IOrthancConnection&  orthanc_;
+    std::string                          seriesId_;
+    std::vector<DicomPyramidInstance*>   instances_;
+    std::vector<DicomPyramidLevel*>      levels_;
 
     void Clear();
 
@@ -45,7 +45,7 @@
     void CheckLevel(size_t level) const;
 
   public:
-    DicomPyramid(IOrthancConnection& orthanc,
+    DicomPyramid(OrthancPlugins::IOrthancConnection& orthanc,
                  const std::string& seriesId);
 
     virtual ~DicomPyramid()
--- a/Framework/Inputs/DicomPyramidInstance.cpp	Fri Nov 25 16:38:09 2016 +0100
+++ b/Framework/Inputs/DicomPyramidInstance.cpp	Fri Nov 25 17:15:55 2016 +0100
@@ -92,7 +92,7 @@
   }
 
 
-  ImageCompression  DicomPyramidInstance::GetImageCompression(IOrthancConnection& orthanc)
+  ImageCompression  DicomPyramidInstance::GetImageCompression(OrthancPlugins::IOrthancConnection& orthanc)
   {
     /**
      * Lazy detection of the image compression using the transfer
@@ -106,7 +106,8 @@
     if (!hasCompression_)
     {
       Json::Value header;
-      IOrthancConnection::RestApiGet(header, orthanc, "/instances/" + instanceId_ + "/header?simplify");
+      OrthancPlugins::IOrthancConnection::RestApiGet
+        (header, orthanc, "/instances/" + instanceId_ + "/header?simplify");
 
       hasCompression_ = true;
       compression_ = DetectImageCompression(header);
@@ -116,13 +117,14 @@
   }
 
   
-  DicomPyramidInstance::DicomPyramidInstance(IOrthancConnection&  orthanc,
+  DicomPyramidInstance::DicomPyramidInstance(OrthancPlugins::IOrthancConnection&  orthanc,
                                              const std::string& instanceId) :
     instanceId_(instanceId),
     hasCompression_(false)
   {
     Json::Value dicom;
-    IOrthancConnection::RestApiGet(dicom, orthanc, "/instances/" + instanceId + "/tags?simplify");
+    OrthancPlugins::IOrthancConnection::RestApiGet
+      (dicom, orthanc, "/instances/" + instanceId + "/tags?simplify");
 
     if (DicomToolbox::GetMandatoryStringTag(dicom, "SOPClassUID") != "1.2.840.10008.5.1.4.1.1.77.1.6" ||
         DicomToolbox::GetMandatoryStringTag(dicom, "Modality") != "SM")
--- a/Framework/Inputs/DicomPyramidInstance.h	Fri Nov 25 16:38:09 2016 +0100
+++ b/Framework/Inputs/DicomPyramidInstance.h	Fri Nov 25 17:15:55 2016 +0100
@@ -21,7 +21,7 @@
 #pragma once
 
 #include "../Enumerations.h"
-#include "../Messaging/IOrthancConnection.h"
+#include "../../Resources/Orthanc/Plugins/Samples/Common/IOrthancConnection.h"
 
 #include <boost/noncopyable.hpp>
 #include <vector>
@@ -44,7 +44,7 @@
     std::vector<FrameLocation>  frames_;
 
   public:
-    DicomPyramidInstance(IOrthancConnection&  orthanc,
+    DicomPyramidInstance(OrthancPlugins::IOrthancConnection&  orthanc,
                          const std::string& instanceId);
 
     const std::string& GetInstanceId() const
@@ -52,7 +52,7 @@
       return instanceId_;
     }
 
-    ImageCompression GetImageCompression(IOrthancConnection& orthanc);
+    ImageCompression GetImageCompression(OrthancPlugins::IOrthancConnection& orthanc);
 
     Orthanc::PixelFormat GetPixelFormat() const
     {
--- a/Framework/Inputs/DicomPyramidLevel.cpp	Fri Nov 25 16:38:09 2016 +0100
+++ b/Framework/Inputs/DicomPyramidLevel.cpp	Fri Nov 25 17:15:55 2016 +0100
@@ -119,7 +119,7 @@
   bool DicomPyramidLevel::DownloadRawTile(std::string& raw /* out */,
                                           Orthanc::PixelFormat& format /* out */,
                                           ImageCompression& compression /* out */,
-                                          IOrthancConnection& orthanc,
+                                          OrthancPlugins::IOrthancConnection& orthanc,
                                           unsigned int tileX,
                                           unsigned int tileY) const
   {
--- a/Framework/Inputs/DicomPyramidLevel.h	Fri Nov 25 16:38:09 2016 +0100
+++ b/Framework/Inputs/DicomPyramidLevel.h	Fri Nov 25 17:15:55 2016 +0100
@@ -87,7 +87,7 @@
     bool DownloadRawTile(std::string& raw /* out */,
                          Orthanc::PixelFormat& format /* out */,
                          ImageCompression& compression /* out */,
-                         IOrthancConnection& orthanc,
+                         OrthancPlugins::IOrthancConnection& orthanc,
                          unsigned int tileX,
                          unsigned int tileY) const;
   };
--- a/Framework/Messaging/CurlOrthancConnection.cpp	Fri Nov 25 16:38:09 2016 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/**
- * Orthanc - A Lightweight, RESTful DICOM Store
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "../PrecompiledHeadersWSI.h"
-#include "CurlOrthancConnection.h"
-
-#include "../../Resources/Orthanc/Core/OrthancException.h"
-
-namespace OrthancWSI
-{
-  void CurlOrthancConnection::ApplyGet(std::string& result,
-                                       const std::string& uri)
-  {
-    Orthanc::HttpClient client(parameters_, uri);
-
-    // Don't follow 3xx HTTP (avoid redirections to "unsupported.png" in Orthanc)
-    client.SetRedirectionFollowed(false);  
-   
-    if (!client.Apply(result))
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_UnknownResource);
-    }
-  }
-
-  void CurlOrthancConnection::ApplyPost(std::string& result,
-                                        const std::string& uri,
-                                        const std::string& body)
-  {
-    Orthanc::HttpClient client(parameters_, uri);
-
-    client.SetMethod(Orthanc::HttpMethod_Post);
-    client.SetBody(body);
-
-    // Don't follow 3xx HTTP (avoid redirections to "unsupported.png" in Orthanc)
-    client.SetRedirectionFollowed(false);  
-   
-    if (!client.Apply(result))
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_UnknownResource);
-    }
-  }
-}
--- a/Framework/Messaging/CurlOrthancConnection.h	Fri Nov 25 16:38:09 2016 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/**
- * Orthanc - A Lightweight, RESTful DICOM Store
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "OrthancConnectionBase.h"
-
-#include "../../Resources/Orthanc/Core/HttpClient.h"
-
-namespace OrthancWSI
-{
-  class CurlOrthancConnection : public OrthancConnectionBase
-  {
-  private:
-    Orthanc::WebServiceParameters  parameters_;
-
-  protected:
-    virtual void ApplyGet(std::string& result,
-                          const std::string& uri);
-
-    virtual void ApplyPost(std::string& result,
-                           const std::string& uri,
-                           const std::string& body);
-
-  public:
-    CurlOrthancConnection(const Orthanc::WebServiceParameters& parameters) :
-      parameters_(parameters)
-    {
-    }
-
-    const Orthanc::WebServiceParameters& GetParameters() const
-    {
-      return parameters_;
-    }
-  };
-}
--- a/Framework/Messaging/FolderTarget.cpp	Fri Nov 25 16:38:09 2016 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/**
- * Orthanc - A Lightweight, RESTful DICOM Store
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "../PrecompiledHeadersWSI.h"
-#include "FolderTarget.h"
-
-#include "../../Resources/Orthanc/Core/SystemToolbox.h"
-#include "../../Resources/Orthanc/Core/Logging.h"
-
-#include <stdio.h>
-
-namespace OrthancWSI
-{
-  void FolderTarget::Write(const std::string& file)
-  {
-    std::string path;
-    path.resize(pattern_.size() + 16);
-
-    {
-      boost::mutex::scoped_lock lock(mutex_);
-      sprintf(&path[0], pattern_.c_str(), count_);
-      count_ += 1;
-    }
-
-    LOG(INFO) << "Writing file " << path;
-    Orthanc::SystemToolbox::WriteFile(file, path);
-  }
-}
--- a/Framework/Messaging/FolderTarget.h	Fri Nov 25 16:38:09 2016 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/**
- * Orthanc - A Lightweight, RESTful DICOM Store
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "IFileTarget.h"
-
-#include <boost/thread.hpp>
-
-namespace OrthancWSI
-{
-  class FolderTarget : public IFileTarget
-  {
-  private:
-    boost::mutex  mutex_;
-    unsigned int  count_;
-    std::string   pattern_;
-
-  public:
-    FolderTarget(const std::string& pattern) : 
-      count_(0),
-      pattern_(pattern)
-    {
-    }
-
-    virtual void Write(const std::string& file);
-  };
-}
--- a/Framework/Messaging/IFileTarget.h	Fri Nov 25 16:38:09 2016 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/**
- * Orthanc - A Lightweight, RESTful DICOM Store
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include <boost/noncopyable.hpp>
-#include <string>
-
-namespace OrthancWSI
-{
-  class IFileTarget : public boost::noncopyable
-  {
-  public:
-    virtual ~IFileTarget()
-    {
-    }
-
-    virtual void Write(const std::string& file) = 0;
-  };
-}
--- a/Framework/Messaging/IOrthancConnection.cpp	Fri Nov 25 16:38:09 2016 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/**
- * Orthanc - A Lightweight, RESTful DICOM Store
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "../PrecompiledHeadersWSI.h"
-#include "IOrthancConnection.h"
-
-#include "../../Resources/Orthanc/Core/Logging.h"
-#include "../../Resources/Orthanc/Core/OrthancException.h"
-
-#include <json/reader.h>
-
-
-namespace OrthancWSI
-{
-  void IOrthancConnection::RestApiGet(Json::Value& result,
-                                      IOrthancConnection& orthanc,
-                                      const std::string& uri)
-  {
-    std::string content;
-    orthanc.RestApiGet(content, uri);
-
-    Json::Reader reader;
-    if (!reader.parse(content, result))
-    {
-      LOG(ERROR) << "Cannot parse a JSON file";
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
-    }
-  }
-
-
-  void IOrthancConnection::RestApiPost(Json::Value& result,
-                                       IOrthancConnection& orthanc,
-                                       const std::string& uri,
-                                       const std::string& body)
-  {
-    std::string content;
-    orthanc.RestApiPost(content, uri, body);
-
-    Json::Reader reader;
-    if (!reader.parse(content, result))
-    {
-      LOG(ERROR) << "Cannot parse a JSON file";
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
-    }
-  }
-}
--- a/Framework/Messaging/IOrthancConnection.h	Fri Nov 25 16:38:09 2016 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/**
- * Orthanc - A Lightweight, RESTful DICOM Store
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include <boost/noncopyable.hpp>
-#include <json/value.h>
-
-namespace OrthancWSI
-{
-  // Derived classes must be thread-safe
-  class IOrthancConnection : public boost::noncopyable
-  {
-  public:
-    virtual ~IOrthancConnection()
-    {
-    }
-
-    virtual void RestApiGet(std::string& result,
-                            const std::string& uri) = 0;
-
-    virtual void RestApiPost(std::string& result, 
-                             const std::string& uri,
-                             const std::string& body) = 0;
-
-    static void RestApiGet(Json::Value& result,
-                           IOrthancConnection& orthanc,
-                           const std::string& uri);
-
-    static void RestApiPost(Json::Value& result,
-                            IOrthancConnection& orthanc,
-                            const std::string& uri,
-                            const std::string& body);
-  };
-}
--- a/Framework/Messaging/OrthancConnectionBase.cpp	Fri Nov 25 16:38:09 2016 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-/**
- * Orthanc - A Lightweight, RESTful DICOM Store
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "../PrecompiledHeadersWSI.h"
-#include "OrthancConnectionBase.h"
-
-namespace OrthancWSI
-{
-  void OrthancConnectionBase::RestApiGet(std::string& result,
-                                         const std::string& uri)
-  {
-    boost::mutex::scoped_lock  lock_;
-    ApplyGet(result, uri);
-  }
-
-
-  void OrthancConnectionBase::RestApiPost(std::string& result,
-                                          const std::string& uri,
-                                          const std::string& body)
-  {
-    boost::mutex::scoped_lock  lock_;
-    ApplyPost(result, uri, body);
-  }
-}
--- a/Framework/Messaging/OrthancConnectionBase.h	Fri Nov 25 16:38:09 2016 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-/**
- * Orthanc - A Lightweight, RESTful DICOM Store
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "IOrthancConnection.h"
-
-#include <boost/thread/mutex.hpp>
-
-namespace OrthancWSI
-{
-  class OrthancConnectionBase : public IOrthancConnection
-  {
-  private:
-    boost::mutex  mutex_;
-
-  protected:
-    // Will be invoked in mutual exclusion
-    virtual void ApplyGet(std::string& result,
-                          const std::string& uri) = 0;
-
-    virtual void ApplyPost(std::string& result,
-                           const std::string& uri,
-                           const std::string& body) = 0;
-
-  public:
-    virtual void RestApiGet(std::string& result,
-                            const std::string& uri);
-
-    virtual void RestApiPost(std::string& result, 
-                             const std::string& uri,
-                             const std::string& body);
-  };
-}
--- a/Framework/Messaging/OrthancTarget.cpp	Fri Nov 25 16:38:09 2016 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/**
- * Orthanc - A Lightweight, RESTful DICOM Store
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "../PrecompiledHeadersWSI.h"
-#include "OrthancTarget.h"
-
-#include "CurlOrthancConnection.h"
-#include "../DicomToolbox.h"
-#include "../../Resources/Orthanc/Core/OrthancException.h"
-#include "../../Resources/Orthanc/Core/Logging.h"
-
-namespace OrthancWSI
-{
-  OrthancTarget::OrthancTarget(const Orthanc::WebServiceParameters& parameters) :
-    orthanc_(new CurlOrthancConnection(parameters)),
-    first_(true)
-  {
-  }
-
-
-  void OrthancTarget::Write(const std::string& file)
-  {
-    Json::Value result;
-    IOrthancConnection::RestApiPost(result, *orthanc_, "/instances", file);
-
-    std::string instanceId = DicomToolbox::GetMandatoryStringTag(result, "ID");
-
-    if (first_)
-    {
-      Json::Value instance;
-      IOrthancConnection::RestApiGet(instance, *orthanc_, "/instances/" + instanceId);
-
-      std::string seriesId = DicomToolbox::GetMandatoryStringTag(instance, "ParentSeries");
-
-      LOG(WARNING) << "ID of the whole-slide image series in Orthanc: " << seriesId;
-      first_ = false;
-    }
-
-    LOG(INFO) << "New instance was added to Orthanc: " << instanceId;
-  }
-}
--- a/Framework/Messaging/OrthancTarget.h	Fri Nov 25 16:38:09 2016 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/**
- * Orthanc - A Lightweight, RESTful DICOM Store
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "IFileTarget.h"
-#include "IOrthancConnection.h"
-#include "../../Resources/Orthanc/Core/WebServiceParameters.h"
-
-#include <memory>
-
-namespace OrthancWSI
-{
-  class OrthancTarget : public IFileTarget
-  {
-  private:
-    std::auto_ptr<IOrthancConnection>  orthanc_;
-    bool                               first_;
-
-  public:
-    OrthancTarget(const Orthanc::WebServiceParameters& parameters);
-
-    OrthancTarget(IOrthancConnection* orthanc) :   // Takes ownership
-      orthanc_(orthanc),
-      first_(true)
-    {
-    }
-
-    virtual void Write(const std::string& file);
-  };
-}
--- a/Framework/Messaging/PluginOrthancConnection.cpp	Fri Nov 25 16:38:09 2016 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,133 +0,0 @@
-/**
- * Orthanc - A Lightweight, RESTful DICOM Store
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "../PrecompiledHeadersWSI.h"
-#include "PluginOrthancConnection.h"
-
-#include "../../Resources/Orthanc/Core/OrthancException.h"
-
-namespace OrthancWSI
-{
-  class PluginOrthancConnection::MemoryBuffer : public boost::noncopyable
-  {
-  private:
-    OrthancPluginContext*      context_;
-    OrthancPluginMemoryBuffer  buffer_;
-
-    void Clear()
-    {
-      if (buffer_.data != NULL)
-      {
-        OrthancPluginFreeMemoryBuffer(context_, &buffer_);
-        buffer_.data = NULL;
-        buffer_.size = 0;
-      }
-    }
-
-
-  public:
-    MemoryBuffer(OrthancPluginContext* context) : 
-      context_(context)
-    {
-      buffer_.data = NULL;
-      buffer_.size = 0;
-    }
-
-    ~MemoryBuffer()
-    {
-      Clear();
-    }
-
-    void RestApiGet(const std::string& uri)
-    {
-      Clear();
-
-      OrthancPluginErrorCode error = OrthancPluginRestApiGet(context_, &buffer_, uri.c_str());
-
-      if (error == OrthancPluginErrorCode_Success)
-      {
-        // OK, success
-      }
-      else if (error == OrthancPluginErrorCode_UnknownResource ||
-               error == OrthancPluginErrorCode_InexistentItem)
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_UnknownResource);
-      }
-      else
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_Plugin);
-      }
-    }
-
-    void RestApiPost(const std::string& uri,
-                     const std::string& body)
-    {
-      Clear();
-
-      OrthancPluginErrorCode error = OrthancPluginRestApiPost(context_, &buffer_, uri.c_str(), body.c_str(), body.size());
-
-      if (error == OrthancPluginErrorCode_Success)
-      {
-        // OK, success
-      }
-      else if (error == OrthancPluginErrorCode_UnknownResource ||
-               error == OrthancPluginErrorCode_InexistentItem)
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_UnknownResource);
-      }
-      else
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_Plugin);
-      }
-    }
-
-    void ToString(std::string& target) const
-    {
-      if (buffer_.size == 0)
-      {
-        target.clear();
-      }
-      else
-      {
-        target.assign(reinterpret_cast<const char*>(buffer_.data), buffer_.size);
-      }
-    }
-  };
-
-
-
-  void PluginOrthancConnection::ApplyGet(std::string& result,
-                                         const std::string& uri)
-  {
-    MemoryBuffer buffer(context_);
-    buffer.RestApiGet(uri);
-    buffer.ToString(result);
-  }
-
-    
-  void PluginOrthancConnection::ApplyPost(std::string& result,
-                                          const std::string& uri,
-                                          const std::string& body)
-  {
-    MemoryBuffer buffer(context_);
-    buffer.RestApiPost(uri, body);
-    buffer.ToString(result);
-  }
-}
--- a/Framework/Messaging/PluginOrthancConnection.h	Fri Nov 25 16:38:09 2016 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/**
- * Orthanc - A Lightweight, RESTful DICOM Store
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "OrthancConnectionBase.h"
-
-#include <orthanc/OrthancCPlugin.h>
-
-namespace OrthancWSI
-{
-  class PluginOrthancConnection : public OrthancConnectionBase
-  {
-  private:
-    class MemoryBuffer;
-
-    OrthancPluginContext*   context_;
-
-  protected:
-    virtual void ApplyGet(std::string& result,
-                          const std::string& uri);
-
-    virtual void ApplyPost(std::string& result,
-                           const std::string& uri,
-                           const std::string& body);
-
-  public:
-    PluginOrthancConnection(OrthancPluginContext* context) :
-      context_(context)
-    {
-    }
-  };
-}
--- a/Framework/Outputs/DicomPyramidWriter.h	Fri Nov 25 16:38:09 2016 +0100
+++ b/Framework/Outputs/DicomPyramidWriter.h	Fri Nov 25 17:15:55 2016 +0100
@@ -22,7 +22,7 @@
 
 #include "PyramidWriterBase.h"
 #include "MultiframeDicomWriter.h"
-#include "../Messaging/IFileTarget.h"
+#include "../Targets/IFileTarget.h"
 #include "../ImagedVolumeParameters.h"
 
 namespace OrthancWSI
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Framework/Targets/FolderTarget.cpp	Fri Nov 25 17:15:55 2016 +0100
@@ -0,0 +1,45 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Affero General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#include "../PrecompiledHeadersWSI.h"
+#include "FolderTarget.h"
+
+#include "../../Resources/Orthanc/Core/SystemToolbox.h"
+#include "../../Resources/Orthanc/Core/Logging.h"
+
+#include <stdio.h>
+
+namespace OrthancWSI
+{
+  void FolderTarget::Write(const std::string& file)
+  {
+    std::string path;
+    path.resize(pattern_.size() + 16);
+
+    {
+      boost::mutex::scoped_lock lock(mutex_);
+      sprintf(&path[0], pattern_.c_str(), count_);
+      count_ += 1;
+    }
+
+    LOG(INFO) << "Writing file " << path;
+    Orthanc::SystemToolbox::WriteFile(file, path);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Framework/Targets/FolderTarget.h	Fri Nov 25 17:15:55 2016 +0100
@@ -0,0 +1,45 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Affero General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+#include "IFileTarget.h"
+
+#include <boost/thread.hpp>
+
+namespace OrthancWSI
+{
+  class FolderTarget : public IFileTarget
+  {
+  private:
+    boost::mutex  mutex_;
+    unsigned int  count_;
+    std::string   pattern_;
+
+  public:
+    FolderTarget(const std::string& pattern) : 
+      count_(0),
+      pattern_(pattern)
+    {
+    }
+
+    virtual void Write(const std::string& file);
+  };
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Framework/Targets/IFileTarget.h	Fri Nov 25 17:15:55 2016 +0100
@@ -0,0 +1,37 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Affero General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+#include <boost/noncopyable.hpp>
+#include <string>
+
+namespace OrthancWSI
+{
+  class IFileTarget : public boost::noncopyable
+  {
+  public:
+    virtual ~IFileTarget()
+    {
+    }
+
+    virtual void Write(const std::string& file) = 0;
+  };
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Framework/Targets/OrthancTarget.cpp	Fri Nov 25 17:15:55 2016 +0100
@@ -0,0 +1,58 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Affero General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#include "../PrecompiledHeadersWSI.h"
+#include "OrthancTarget.h"
+
+#include "../DicomToolbox.h"
+#include "../../Resources/Orthanc/Core/OrthancException.h"
+#include "../../Resources/Orthanc/Core/Logging.h"
+#include "../../Resources/Orthanc/Plugins/Samples/Common/OrthancHttpConnection.h"
+
+namespace OrthancWSI
+{
+  OrthancTarget::OrthancTarget(const Orthanc::WebServiceParameters& parameters) :
+    orthanc_(new OrthancPlugins::OrthancHttpConnection(parameters)),
+    first_(true)
+  {
+  }
+
+
+  void OrthancTarget::Write(const std::string& file)
+  {
+    Json::Value result;
+    OrthancPlugins::IOrthancConnection::RestApiPost(result, *orthanc_, "/instances", file);
+
+    std::string instanceId = DicomToolbox::GetMandatoryStringTag(result, "ID");
+
+    if (first_)
+    {
+      Json::Value instance;
+      OrthancPlugins::IOrthancConnection::RestApiGet(instance, *orthanc_, "/instances/" + instanceId);
+
+      std::string seriesId = DicomToolbox::GetMandatoryStringTag(instance, "ParentSeries");
+
+      LOG(WARNING) << "ID of the whole-slide image series in Orthanc: " << seriesId;
+      first_ = false;
+    }
+
+    LOG(INFO) << "New instance was added to Orthanc: " << instanceId;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Framework/Targets/OrthancTarget.h	Fri Nov 25 17:15:55 2016 +0100
@@ -0,0 +1,48 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Affero General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+#include "IFileTarget.h"
+#include "../../Resources/Orthanc/Core/WebServiceParameters.h"
+#include "../../Resources/Orthanc/Plugins/Samples/Common/IOrthancConnection.h"
+
+#include <memory>
+
+namespace OrthancWSI
+{
+  class OrthancTarget : public IFileTarget
+  {
+  private:
+    std::auto_ptr<OrthancPlugins::IOrthancConnection>  orthanc_;
+    bool  first_;
+
+  public:
+    OrthancTarget(const Orthanc::WebServiceParameters& parameters);
+
+    OrthancTarget(OrthancPlugins::IOrthancConnection* orthanc) :   // Takes ownership
+      orthanc_(orthanc),
+      first_(true)
+    {
+    }
+
+    virtual void Write(const std::string& file);
+  };
+}
--- a/Resources/Orthanc/Plugins/Samples/Common/FullOrthancDataset.cpp	Fri Nov 25 16:38:09 2016 +0100
+++ b/Resources/Orthanc/Plugins/Samples/Common/FullOrthancDataset.cpp	Fri Nov 25 17:15:55 2016 +0100
@@ -34,22 +34,8 @@
 
 #include "OrthancPluginCppWrapper.h"
 
-#include <json/reader.h>
-
 namespace OrthancPlugins
 {
-  void FullOrthancDataset::Parse(const std::string& source)
-  {
-    Json::Reader reader;
-
-    if (!reader.parse(source, root_) ||
-        root_.type() != Json::objectValue)
-    {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat);
-    }
-  }
-
-
   static const Json::Value* AccessTag(const Json::Value& dataset,
                                       const DicomTag& tag) 
   {
@@ -152,12 +138,27 @@
   }
 
 
+  void FullOrthancDataset::CheckRoot() const
+  {
+    if (root_.type() != Json::objectValue)
+    {
+      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat);
+    }
+  }
+
+
   FullOrthancDataset::FullOrthancDataset(IOrthancConnection& orthanc,
                                          const std::string& uri)
   {
-    std::string content;
-    orthanc.RestApiGet(content, uri);
-    Parse(content);
+    IOrthancConnection::RestApiGet(root_, orthanc, uri);
+    CheckRoot();
+  }
+
+
+  FullOrthancDataset::FullOrthancDataset(const std::string& content)
+  {
+    IOrthancConnection::ParseJson(root_, content);
+    CheckRoot();
   }
 
 
--- a/Resources/Orthanc/Plugins/Samples/Common/FullOrthancDataset.h	Fri Nov 25 16:38:09 2016 +0100
+++ b/Resources/Orthanc/Plugins/Samples/Common/FullOrthancDataset.h	Fri Nov 25 17:15:55 2016 +0100
@@ -44,18 +44,15 @@
   private:
     Json::Value   root_;
 
-    void Parse(const std::string& source);
+    const Json::Value* LookupPath(const DicomPath& path) const;
 
-    const Json::Value* LookupPath(const DicomPath& path) const;
+    void CheckRoot() const;
 
   public:
     FullOrthancDataset(IOrthancConnection& orthanc,
                        const std::string& uri);
 
-    FullOrthancDataset(const std::string& content)
-    {
-      Parse(content);
-    }
+    FullOrthancDataset(const std::string& content);
 
     virtual bool GetStringValue(std::string& result,
                                 const DicomPath& path) const;
--- a/Resources/Orthanc/Plugins/Samples/Common/IOrthancConnection.h	Fri Nov 25 16:38:09 2016 +0100
+++ b/Resources/Orthanc/Plugins/Samples/Common/IOrthancConnection.h	Fri Nov 25 17:15:55 2016 +0100
@@ -36,6 +36,7 @@
 
 #include <boost/noncopyable.hpp>
 #include <string>
+#include <json/value.h>
 
 namespace OrthancPlugins
 {
@@ -52,5 +53,17 @@
     virtual void RestApiPost(std::string& result,
                              const std::string& uri,
                              const std::string& body) = 0;
+
+    static void ParseJson(Json::Value& result,
+                          const std::string& content);
+
+    static void RestApiGet(Json::Value& result,
+                           IOrthancConnection& orthanc,
+                           const std::string& uri);
+
+    static void RestApiPost(Json::Value& result,
+                            IOrthancConnection& orthanc,
+                            const std::string& uri,
+                            const std::string& body);
   };
 }
--- a/Resources/Orthanc/Plugins/Samples/Common/SimplifiedOrthancDataset.cpp	Fri Nov 25 16:38:09 2016 +0100
+++ b/Resources/Orthanc/Plugins/Samples/Common/SimplifiedOrthancDataset.cpp	Fri Nov 25 17:15:55 2016 +0100
@@ -34,22 +34,8 @@
 
 #include "OrthancPluginCppWrapper.h"
 
-#include <json/reader.h>
-
 namespace OrthancPlugins
 {
-  void SimplifiedOrthancDataset::Parse(const std::string& source)
-  {
-    Json::Reader reader;
-
-    if (!reader.parse(source, root_) ||
-        root_.type() != Json::objectValue)
-    {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat);
-    }
-  }
-
-
   const Json::Value* SimplifiedOrthancDataset::LookupPath(const DicomPath& path) const
   {
     const Json::Value* content = &root_;
@@ -101,12 +87,27 @@
   }
 
 
+  void SimplifiedOrthancDataset::CheckRoot() const
+  {
+    if (root_.type() != Json::objectValue)
+    {
+      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat);
+    }
+  }
+
+
   SimplifiedOrthancDataset::SimplifiedOrthancDataset(IOrthancConnection& orthanc,
                                                      const std::string& uri)
   {
-    std::string content;
-    orthanc.RestApiGet(content, uri);
-    Parse(content);
+    IOrthancConnection::RestApiGet(root_, orthanc, uri);
+    CheckRoot();
+  }
+
+
+  SimplifiedOrthancDataset::SimplifiedOrthancDataset(const std::string& content)
+  {
+    IOrthancConnection::ParseJson(root_, content);
+    CheckRoot();
   }
 
 
--- a/Resources/Orthanc/Plugins/Samples/Common/SimplifiedOrthancDataset.h	Fri Nov 25 16:38:09 2016 +0100
+++ b/Resources/Orthanc/Plugins/Samples/Common/SimplifiedOrthancDataset.h	Fri Nov 25 17:15:55 2016 +0100
@@ -35,8 +35,6 @@
 #include "IOrthancConnection.h"
 #include "IDicomDataset.h"
 
-#include <json/value.h>
-
 namespace OrthancPlugins
 {
   class SimplifiedOrthancDataset : public IDicomDataset
@@ -44,18 +42,15 @@
   private:
     Json::Value   root_;
 
-    void Parse(const std::string& source);
+    const Json::Value* LookupPath(const DicomPath& path) const;
 
-    const Json::Value* LookupPath(const DicomPath& path) const;
+    void CheckRoot() const;
 
   public:
     SimplifiedOrthancDataset(IOrthancConnection& orthanc,
                              const std::string& uri);
 
-    SimplifiedOrthancDataset(const std::string& content)
-    {
-      Parse(content);
-    }
+    SimplifiedOrthancDataset(const std::string& content);
 
     virtual bool GetStringValue(std::string& result,
                                 const DicomPath& path) const;
--- a/Resources/SyncOrthancFolder.py	Fri Nov 25 16:38:09 2016 +0100
+++ b/Resources/SyncOrthancFolder.py	Fri Nov 25 17:15:55 2016 +0100
@@ -96,6 +96,7 @@
     'Plugins/Samples/Common/FullOrthancDataset.cpp',
     'Plugins/Samples/Common/FullOrthancDataset.h',
     'Plugins/Samples/Common/IDicomDataset.h',
+    'Plugins/Samples/Common/IOrthancConnection.cpp',
     'Plugins/Samples/Common/IOrthancConnection.h',
     'Plugins/Samples/Common/OrthancHttpConnection.cpp',
     'Plugins/Samples/Common/OrthancHttpConnection.h',
--- a/ViewerPlugin/CMakeLists.txt	Fri Nov 25 16:38:09 2016 +0100
+++ b/ViewerPlugin/CMakeLists.txt	Fri Nov 25 17:15:55 2016 +0100
@@ -168,9 +168,6 @@
   ${ORTHANC_WSI_DIR}/Framework/Inputs/PyramidWithRawTiles.cpp
   ${ORTHANC_WSI_DIR}/Framework/Jpeg2000Reader.cpp
   ${ORTHANC_WSI_DIR}/Framework/Jpeg2000Writer.cpp
-  ${ORTHANC_WSI_DIR}/Framework/Messaging/IOrthancConnection.cpp
-  ${ORTHANC_WSI_DIR}/Framework/Messaging/OrthancConnectionBase.cpp
-  ${ORTHANC_WSI_DIR}/Framework/Messaging/PluginOrthancConnection.cpp
   )
 
 set(ORTHANC_CORE_SOURCES
@@ -190,6 +187,8 @@
   ${ORTHANC_ROOT}/Core/MultiThreading/Semaphore.cpp
   ${ORTHANC_ROOT}/Core/SystemToolbox.cpp
   ${ORTHANC_ROOT}/Core/Toolbox.cpp
+  ${ORTHANC_ROOT}/Plugins/Samples/Common/IOrthancConnection.cpp
+  ${ORTHANC_ROOT}/Plugins/Samples/Common/OrthancPluginConnection.cpp
   ${ORTHANC_ROOT}/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp
   )
 
--- a/ViewerPlugin/Plugin.cpp	Fri Nov 25 16:38:09 2016 +0100
+++ b/ViewerPlugin/Plugin.cpp	Fri Nov 25 17:15:55 2016 +0100
@@ -21,13 +21,13 @@
 #include "../Framework/PrecompiledHeadersWSI.h"
 #include "../Framework/Inputs/DicomPyramid.h"
 #include "../Framework/Jpeg2000Reader.h"
-#include "../Framework/Messaging/PluginOrthancConnection.h"
 
 #include "../Resources/Orthanc/Core/Images/ImageProcessing.h"
 #include "../Resources/Orthanc/Core/Images/PngWriter.h"
 #include "../Resources/Orthanc/Core/MultiThreading/Semaphore.h"
 #include "../Resources/Orthanc/Core/OrthancException.h"
 #include "../Resources/Orthanc/Plugins/Samples/Common/OrthancPluginCppWrapper.h"
+#include "../Resources/Orthanc/Plugins/Samples/Common/OrthancPluginConnection.h"
 
 #include <EmbeddedResources.h>
 
@@ -41,9 +41,9 @@
   class DicomPyramidCache : public boost::noncopyable
   {
   private:
-    boost::mutex                  mutex_;
-    IOrthancConnection&           orthanc_;
-    std::auto_ptr<DicomPyramid>   pyramid_;
+    boost::mutex                         mutex_;
+    OrthancPlugins::IOrthancConnection&  orthanc_;
+    std::auto_ptr<DicomPyramid>          pyramid_;
 
     DicomPyramid& GetPyramid(const std::string& seriesId)
     {
@@ -64,7 +64,7 @@
     }
 
   public:
-    DicomPyramidCache(IOrthancConnection& orthanc) :
+    DicomPyramidCache(OrthancPlugins::IOrthancConnection& orthanc) :
       orthanc_(orthanc)
     {
     }
@@ -105,10 +105,9 @@
 
 OrthancPluginContext* context_ = NULL;
 
-std::auto_ptr<OrthancWSI::PluginOrthancConnection>  orthanc_;
-std::auto_ptr<OrthancWSI::DicomPyramidCache>        cache_;
-std::auto_ptr<Orthanc::Semaphore>                   transcoderSemaphore_;
-std::string                                         sparseTile_;
+std::auto_ptr<OrthancPlugins::OrthancPluginConnection>  orthanc_;
+std::auto_ptr<OrthancWSI::DicomPyramidCache>            cache_;
+std::auto_ptr<Orthanc::Semaphore>                       transcoderSemaphore_;
 
 
 static void AnswerSparseTile(OrthancPluginRestOutput* output,
@@ -378,7 +377,7 @@
 
     OrthancPluginSetDescription(context, "Provides a Web viewer of whole-slide microscopic images within Orthanc.");
 
-    orthanc_.reset(new OrthancWSI::PluginOrthancConnection(context));
+    orthanc_.reset(new OrthancPlugins::OrthancPluginConnection(context));
     cache_.reset(new OrthancWSI::DicomPyramidCache(*orthanc_));
 
     OrthancPluginRegisterOnChangeCallback(context_, OnChangeCallback);