Mercurial > hg > orthanc
annotate OrthancServer/Sources/ServerJobs/ArchiveJob.cpp @ 4921:309fb4f02704
fix signature of OrthancPluginIncomingCStoreInstanceFilter
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 23 Feb 2022 11:09:43 +0100 |
parents | df86d2505df8 |
children | a386dfb5b386 |
rev | line source |
---|---|
2632 | 1 /** |
2 * Orthanc - A Lightweight, RESTful DICOM Store | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
4870
43e613a7756b
upgrade to year 2022
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4831
diff
changeset
|
5 * Copyright (C) 2017-2022 Osimis S.A., Belgium |
43e613a7756b
upgrade to year 2022
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4831
diff
changeset
|
6 * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium |
2632 | 7 * |
8 * This program is free software: you can redistribute it and/or | |
9 * modify it under the terms of the GNU General Public License as | |
10 * published by the Free Software Foundation, either version 3 of the | |
11 * License, or (at your option) any later version. | |
12 * | |
13 * This program is distributed in the hope that it will be useful, but | |
14 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 * General Public License for more details. | |
17 * | |
18 * You should have received a copy of the GNU General Public License | |
19 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
20 **/ | |
21 | |
22 | |
23 #include "../PrecompiledHeadersServer.h" | |
24 #include "ArchiveJob.h" | |
25 | |
4045 | 26 #include "../../../OrthancFramework/Sources/Cache/SharedArchive.h" |
27 #include "../../../OrthancFramework/Sources/Compression/HierarchicalZipWriter.h" | |
28 #include "../../../OrthancFramework/Sources/DicomParsing/DicomDirWriter.h" | |
29 #include "../../../OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.h" | |
30 #include "../../../OrthancFramework/Sources/Logging.h" | |
31 #include "../../../OrthancFramework/Sources/OrthancException.h" | |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
32 #include "../../../OrthancFramework/Sources/MultiThreading/Semaphore.h" |
3181
6fd38327e777
Fix issue #130 (Orthanc failed to start when /tmp partition was full)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3095
diff
changeset
|
33 #include "../OrthancConfiguration.h" |
3095
beeeb6096f27
removing dependencies upon ServerContext
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3060
diff
changeset
|
34 #include "../ServerContext.h" |
2632 | 35 |
36 #include <stdio.h> | |
37 | |
38 #if defined(_MSC_VER) | |
39 #define snprintf _snprintf | |
40 #endif | |
41 | |
42 static const uint64_t MEGA_BYTES = 1024 * 1024; | |
43 static const uint64_t GIGA_BYTES = 1024 * 1024 * 1024; | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
44 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
45 static const char* const MEDIA_IMAGES_FOLDER = "IMAGES"; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
46 static const char* const KEY_DESCRIPTION = "Description"; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
47 static const char* const KEY_INSTANCES_COUNT = "InstancesCount"; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
48 static const char* const KEY_UNCOMPRESSED_SIZE_MB = "UncompressedSizeMB"; |
4341
977c2759eb0a
Archive/media jobs report the size of the created ZIP file in content field "ArchiveSizeMB"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4205
diff
changeset
|
49 static const char* const KEY_ARCHIVE_SIZE_MB = "ArchiveSizeMB"; |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
50 static const char* const KEY_UNCOMPRESSED_SIZE = "UncompressedSize"; |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
51 static const char* const KEY_ARCHIVE_SIZE = "ArchiveSize"; |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
52 static const char* const KEY_TRANSCODE = "Transcode"; |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
53 |
2632 | 54 |
55 namespace Orthanc | |
56 { | |
57 static bool IsZip64Required(uint64_t uncompressedSize, | |
58 unsigned int countInstances) | |
59 { | |
60 static const uint64_t SAFETY_MARGIN = 64 * MEGA_BYTES; // Should be large enough to hold DICOMDIR | |
61 static const unsigned int FILES_MARGIN = 10; | |
62 | |
63 /** | |
64 * Determine whether ZIP64 is required. Original ZIP format can | |
65 * store up to 2GB of data (some implementation supporting up to | |
66 * 4GB of data), and up to 65535 files. | |
67 * https://en.wikipedia.org/wiki/Zip_(file_format)#ZIP64 | |
68 **/ | |
69 | |
70 const bool isZip64 = (uncompressedSize >= 2 * GIGA_BYTES - SAFETY_MARGIN || | |
71 countInstances >= 65535 - FILES_MARGIN); | |
72 | |
73 LOG(INFO) << "Creating a ZIP file with " << countInstances << " files of size " | |
74 << (uncompressedSize / MEGA_BYTES) << "MB using the " | |
75 << (isZip64 ? "ZIP64" : "ZIP32") << " file format"; | |
76 | |
77 return isZip64; | |
78 } | |
79 | |
80 | |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
81 class ArchiveJob::InstanceLoader : public boost::noncopyable |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
82 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
83 protected: |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
84 ServerContext& context_; |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
85 public: |
4815 | 86 explicit InstanceLoader(ServerContext& context) |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
87 : context_(context) |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
88 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
89 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
90 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
91 virtual ~InstanceLoader() |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
92 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
93 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
94 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
95 virtual void PrepareDicom(const std::string& instanceId) |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
96 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
97 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
98 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
99 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
100 virtual void GetDicom(std::string& dicom, const std::string& instanceId) = 0; |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
101 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
102 virtual void Clear() |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
103 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
104 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
105 }; |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
106 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
107 class ArchiveJob::SynchronousInstanceLoader : public ArchiveJob::InstanceLoader |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
108 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
109 public: |
4815 | 110 explicit SynchronousInstanceLoader(ServerContext& context) |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
111 : InstanceLoader(context) |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
112 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
113 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
114 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
115 virtual void GetDicom(std::string& dicom, const std::string& instanceId) ORTHANC_OVERRIDE |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
116 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
117 context_.ReadDicom(dicom, instanceId); |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
118 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
119 }; |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
120 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
121 class InstanceId : public Orthanc::IDynamicObject |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
122 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
123 private: |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
124 std::string id_; |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
125 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
126 public: |
4815 | 127 explicit InstanceId(const std::string& id) : id_(id) |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
128 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
129 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
130 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
131 virtual ~InstanceId() ORTHANC_OVERRIDE |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
132 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
133 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
134 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
135 std::string GetId() const {return id_;}; |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
136 }; |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
137 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
138 class ArchiveJob::ThreadedInstanceLoader : public ArchiveJob::InstanceLoader |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
139 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
140 Semaphore availableInstancesSemaphore_; |
4814
46bfa3a4fd63
fix compatibility with LSB compiler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4810
diff
changeset
|
141 std::map<std::string, boost::shared_ptr<std::string> > availableInstances_; |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
142 boost::mutex availableInstancesMutex_; |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
143 SharedMessageQueue instancesToPreload_; |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
144 std::vector<boost::thread*> threads_; |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
145 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
146 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
147 public: |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
148 ThreadedInstanceLoader(ServerContext& context, size_t threadCount) |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
149 : InstanceLoader(context), |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
150 availableInstancesSemaphore_(0) |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
151 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
152 for (size_t i = 0; i < threadCount; i++) |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
153 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
154 threads_.push_back(new boost::thread(PreloaderWorkerThread, this)); |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
155 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
156 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
157 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
158 virtual ~ThreadedInstanceLoader() |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
159 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
160 Clear(); |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
161 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
162 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
163 virtual void Clear() ORTHANC_OVERRIDE |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
164 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
165 for (size_t i = 0; i < threads_.size(); i++) |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
166 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
167 instancesToPreload_.Enqueue(NULL); |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
168 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
169 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
170 for (size_t i = 0; i < threads_.size(); i++) |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
171 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
172 if (threads_[i]->joinable()) |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
173 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
174 threads_[i]->join(); |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
175 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
176 delete threads_[i]; |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
177 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
178 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
179 threads_.clear(); |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
180 availableInstances_.clear(); |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
181 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
182 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
183 static void PreloaderWorkerThread(ThreadedInstanceLoader* that) |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
184 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
185 while (true) |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
186 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
187 std::unique_ptr<InstanceId> instanceId(dynamic_cast<InstanceId*>(that->instancesToPreload_.Dequeue(0))); |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
188 if (instanceId.get() == NULL) // that's the signal to exit the thread |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
189 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
190 return; |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
191 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
192 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
193 try |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
194 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
195 boost::shared_ptr<std::string> dicomContent(new std::string()); |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
196 that->context_.ReadDicom(*dicomContent, instanceId->GetId()); |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
197 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
198 boost::mutex::scoped_lock lock(that->availableInstancesMutex_); |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
199 that->availableInstances_[instanceId->GetId()] = dicomContent; |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
200 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
201 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
202 that->availableInstancesSemaphore_.Release(); |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
203 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
204 catch (OrthancException& e) |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
205 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
206 boost::mutex::scoped_lock lock(that->availableInstancesMutex_); |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
207 // store a NULL result to notify that we could not read the instance |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
208 that->availableInstances_[instanceId->GetId()] = boost::shared_ptr<std::string>(); |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
209 that->availableInstancesSemaphore_.Release(); |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
210 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
211 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
212 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
213 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
214 virtual void PrepareDicom(const std::string& instanceId) ORTHANC_OVERRIDE |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
215 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
216 instancesToPreload_.Enqueue(new InstanceId(instanceId)); |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
217 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
218 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
219 virtual void GetDicom(std::string& dicom, const std::string& instanceId) ORTHANC_OVERRIDE |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
220 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
221 while (true) |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
222 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
223 // wait for an instance to be available but this might not be the one we are waiting for ! |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
224 availableInstancesSemaphore_.Acquire(); |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
225 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
226 boost::shared_ptr<std::string> dicomContent; |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
227 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
228 if (availableInstances_.find(instanceId) != availableInstances_.end()) |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
229 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
230 // this is the instance we were waiting for |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
231 dicomContent = availableInstances_[instanceId]; |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
232 availableInstances_.erase(instanceId); |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
233 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
234 if (dicomContent.get() == NULL) // there has been an error while reading the file |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
235 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
236 throw OrthancException(ErrorCode_InexistentItem); |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
237 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
238 dicom.swap(*dicomContent); |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
239 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
240 if (availableInstances_.size() > 0) |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
241 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
242 // we have just read the instance we were waiting for but there are still other instances available -> |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
243 // make sure the next GetDicom call does not wait ! |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
244 availableInstancesSemaphore_.Release(); |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
245 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
246 return; |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
247 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
248 // we have not found the expected instance, simply wait for the next loader thread to signal the semaphore when |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
249 // a new instance is available |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
250 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
251 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
252 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
253 }; |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
254 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
255 |
2632 | 256 class ArchiveJob::ResourceIdentifiers : public boost::noncopyable |
257 { | |
258 private: | |
259 ResourceType level_; | |
260 std::string patient_; | |
261 std::string study_; | |
262 std::string series_; | |
263 std::string instance_; | |
264 | |
265 static void GoToParent(ServerIndex& index, | |
266 std::string& current) | |
267 { | |
268 std::string tmp; | |
269 | |
270 if (index.LookupParent(tmp, current)) | |
271 { | |
272 current = tmp; | |
273 } | |
274 else | |
275 { | |
276 throw OrthancException(ErrorCode_UnknownResource); | |
277 } | |
278 } | |
279 | |
280 | |
281 public: | |
282 ResourceIdentifiers(ServerIndex& index, | |
283 const std::string& publicId) | |
284 { | |
285 if (!index.LookupResourceType(level_, publicId)) | |
286 { | |
287 throw OrthancException(ErrorCode_UnknownResource); | |
288 } | |
289 | |
290 std::string current = publicId;; | |
291 switch (level_) // Do not add "break" below! | |
292 { | |
293 case ResourceType_Instance: | |
294 instance_ = current; | |
295 GoToParent(index, current); | |
296 | |
297 case ResourceType_Series: | |
298 series_ = current; | |
299 GoToParent(index, current); | |
300 | |
301 case ResourceType_Study: | |
302 study_ = current; | |
303 GoToParent(index, current); | |
304 | |
305 case ResourceType_Patient: | |
306 patient_ = current; | |
307 break; | |
308 | |
309 default: | |
310 throw OrthancException(ErrorCode_InternalError); | |
311 } | |
312 } | |
313 | |
314 ResourceType GetLevel() const | |
315 { | |
316 return level_; | |
317 } | |
318 | |
319 const std::string& GetIdentifier(ResourceType level) const | |
320 { | |
321 // Some sanity check to ensure enumerations are not altered | |
322 assert(ResourceType_Patient < ResourceType_Study); | |
323 assert(ResourceType_Study < ResourceType_Series); | |
324 assert(ResourceType_Series < ResourceType_Instance); | |
325 | |
326 if (level > level_) | |
327 { | |
328 throw OrthancException(ErrorCode_InternalError); | |
329 } | |
330 | |
331 switch (level) | |
332 { | |
333 case ResourceType_Patient: | |
334 return patient_; | |
335 | |
336 case ResourceType_Study: | |
337 return study_; | |
338 | |
339 case ResourceType_Series: | |
340 return series_; | |
341 | |
342 case ResourceType_Instance: | |
343 return instance_; | |
344 | |
345 default: | |
346 throw OrthancException(ErrorCode_InternalError); | |
347 } | |
348 } | |
349 }; | |
350 | |
351 | |
352 class ArchiveJob::IArchiveVisitor : public boost::noncopyable | |
353 { | |
354 public: | |
355 virtual ~IArchiveVisitor() | |
356 { | |
357 } | |
358 | |
359 virtual void Open(ResourceType level, | |
360 const std::string& publicId) = 0; | |
361 | |
362 virtual void Close() = 0; | |
363 | |
364 virtual void AddInstance(const std::string& instanceId, | |
4510
a3635a01a945
fix signature of virtual method
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4509
diff
changeset
|
365 uint64_t uncompressedSize) = 0; |
2632 | 366 }; |
367 | |
368 | |
369 class ArchiveJob::ArchiveIndex : public boost::noncopyable | |
370 { | |
371 private: | |
372 struct Instance | |
373 { | |
374 std::string id_; | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
375 uint64_t uncompressedSize_; |
2632 | 376 |
377 Instance(const std::string& id, | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
378 uint64_t uncompressedSize) : |
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
379 id_(id), |
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
380 uncompressedSize_(uncompressedSize) |
2632 | 381 { |
382 } | |
383 }; | |
384 | |
385 // A "NULL" value for ArchiveIndex indicates a non-expanded node | |
386 typedef std::map<std::string, ArchiveIndex*> Resources; | |
387 | |
388 ResourceType level_; | |
389 Resources resources_; // Only at patient/study/series level | |
390 std::list<Instance> instances_; // Only at instance level | |
391 | |
392 | |
393 void AddResourceToExpand(ServerIndex& index, | |
394 const std::string& id) | |
395 { | |
396 if (level_ == ResourceType_Instance) | |
397 { | |
398 FileInfo tmp; | |
4627
f7d5372b59b3
handling revisions of attachments
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4591
diff
changeset
|
399 int64_t revision; // ignored |
f7d5372b59b3
handling revisions of attachments
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4591
diff
changeset
|
400 if (index.LookupAttachment(tmp, revision, id, FileContentType_Dicom)) |
2632 | 401 { |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
402 instances_.push_back(Instance(id, tmp.GetUncompressedSize())); |
2632 | 403 } |
404 } | |
405 else | |
406 { | |
407 resources_[id] = NULL; | |
408 } | |
409 } | |
410 | |
411 | |
412 public: | |
4205 | 413 explicit ArchiveIndex(ResourceType level) : |
2632 | 414 level_(level) |
415 { | |
416 } | |
417 | |
418 ~ArchiveIndex() | |
419 { | |
420 for (Resources::iterator it = resources_.begin(); | |
421 it != resources_.end(); ++it) | |
422 { | |
423 delete it->second; | |
424 } | |
425 } | |
426 | |
427 | |
428 void Add(ServerIndex& index, | |
429 const ResourceIdentifiers& resource) | |
430 { | |
431 const std::string& id = resource.GetIdentifier(level_); | |
432 Resources::iterator previous = resources_.find(id); | |
433 | |
434 if (level_ == ResourceType_Instance) | |
435 { | |
436 AddResourceToExpand(index, id); | |
437 } | |
438 else if (resource.GetLevel() == level_) | |
439 { | |
440 // Mark this resource for further expansion | |
441 if (previous != resources_.end()) | |
442 { | |
443 delete previous->second; | |
444 } | |
445 | |
446 resources_[id] = NULL; | |
447 } | |
448 else if (previous == resources_.end()) | |
449 { | |
450 // This is the first time we meet this resource | |
3712
2a170a8f1faf
replacing std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
451 std::unique_ptr<ArchiveIndex> child(new ArchiveIndex(GetChildResourceType(level_))); |
2632 | 452 child->Add(index, resource); |
453 resources_[id] = child.release(); | |
454 } | |
455 else if (previous->second != NULL) | |
456 { | |
457 previous->second->Add(index, resource); | |
458 } | |
459 else | |
460 { | |
461 // Nothing to do: This item is marked for further expansion | |
462 } | |
463 } | |
464 | |
465 | |
466 void Expand(ServerIndex& index) | |
467 { | |
468 if (level_ == ResourceType_Instance) | |
469 { | |
470 // Expanding an instance node makes no sense | |
471 return; | |
472 } | |
473 | |
474 for (Resources::iterator it = resources_.begin(); | |
475 it != resources_.end(); ++it) | |
476 { | |
477 if (it->second == NULL) | |
478 { | |
479 // This is resource is marked for expansion | |
480 std::list<std::string> children; | |
481 index.GetChildren(children, it->first); | |
482 | |
3712
2a170a8f1faf
replacing std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
483 std::unique_ptr<ArchiveIndex> child(new ArchiveIndex(GetChildResourceType(level_))); |
2632 | 484 |
485 for (std::list<std::string>::const_iterator | |
486 it2 = children.begin(); it2 != children.end(); ++it2) | |
487 { | |
488 child->AddResourceToExpand(index, *it2); | |
489 } | |
490 | |
491 it->second = child.release(); | |
492 } | |
493 | |
494 assert(it->second != NULL); | |
495 it->second->Expand(index); | |
496 } | |
497 } | |
498 | |
499 | |
500 void Apply(IArchiveVisitor& visitor) const | |
501 { | |
502 if (level_ == ResourceType_Instance) | |
503 { | |
504 for (std::list<Instance>::const_iterator | |
505 it = instances_.begin(); it != instances_.end(); ++it) | |
506 { | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
507 visitor.AddInstance(it->id_, it->uncompressedSize_); |
2632 | 508 } |
509 } | |
510 else | |
511 { | |
512 for (Resources::const_iterator it = resources_.begin(); | |
513 it != resources_.end(); ++it) | |
514 { | |
515 assert(it->second != NULL); // There must have been a call to "Expand()" | |
516 visitor.Open(level_, it->first); | |
517 it->second->Apply(visitor); | |
518 visitor.Close(); | |
519 } | |
520 } | |
521 } | |
522 }; | |
523 | |
524 | |
525 | |
526 class ArchiveJob::ZipCommands : public boost::noncopyable | |
527 { | |
528 private: | |
529 enum Type | |
530 { | |
531 Type_OpenDirectory, | |
532 Type_CloseDirectory, | |
533 Type_WriteInstance | |
534 }; | |
535 | |
536 class Command : public boost::noncopyable | |
537 { | |
538 private: | |
539 Type type_; | |
540 std::string filename_; | |
541 std::string instanceId_; | |
542 | |
543 public: | |
544 explicit Command(Type type) : | |
545 type_(type) | |
546 { | |
547 assert(type_ == Type_CloseDirectory); | |
548 } | |
549 | |
550 Command(Type type, | |
551 const std::string& filename) : | |
552 type_(type), | |
553 filename_(filename) | |
554 { | |
555 assert(type_ == Type_OpenDirectory); | |
556 } | |
557 | |
558 Command(Type type, | |
559 const std::string& filename, | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
560 const std::string& instanceId) : |
2632 | 561 type_(type), |
562 filename_(filename), | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
563 instanceId_(instanceId) |
2632 | 564 { |
565 assert(type_ == Type_WriteInstance); | |
566 } | |
567 | |
568 void Apply(HierarchicalZipWriter& writer, | |
569 ServerContext& context, | |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
570 InstanceLoader& instanceLoader, |
2632 | 571 DicomDirWriter* dicomDir, |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
572 const std::string& dicomDirFolder, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
573 bool transcode, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
574 DicomTransferSyntax transferSyntax) const |
2632 | 575 { |
576 switch (type_) | |
577 { | |
578 case Type_OpenDirectory: | |
579 writer.OpenDirectory(filename_.c_str()); | |
580 break; | |
581 | |
582 case Type_CloseDirectory: | |
583 writer.CloseDirectory(); | |
584 break; | |
585 | |
586 case Type_WriteInstance: | |
587 { | |
588 std::string content; | |
589 | |
590 try | |
591 { | |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
592 instanceLoader.GetDicom(content, instanceId_); |
2632 | 593 } |
594 catch (OrthancException& e) | |
595 { | |
596 LOG(WARNING) << "An instance was removed after the job was issued: " << instanceId_; | |
597 return; | |
598 } | |
2636 | 599 |
600 //boost::this_thread::sleep(boost::posix_time::milliseconds(300)); | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
601 |
2632 | 602 writer.OpenFile(filename_.c_str()); |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
603 |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
604 bool transcodeSuccess = false; |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
605 |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
606 std::unique_ptr<ParsedDicomFile> parsed; |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
607 |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
608 if (transcode) |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
609 { |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
610 // New in Orthanc 1.7.0 |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
611 std::set<DicomTransferSyntax> syntaxes; |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
612 syntaxes.insert(transferSyntax); |
3945
0b3256c3ee14
simplified IDicomTranscoder
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3930
diff
changeset
|
613 |
0b3256c3ee14
simplified IDicomTranscoder
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3930
diff
changeset
|
614 IDicomTranscoder::DicomImage source, transcoded; |
0b3256c3ee14
simplified IDicomTranscoder
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3930
diff
changeset
|
615 source.SetExternalBuffer(content); |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
616 |
3951
5fe8c6d3212e
removed useless information "hasSopInstanceUidChanged"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3945
diff
changeset
|
617 if (context.Transcode(transcoded, source, syntaxes, true /* allow new SOP instance UID */)) |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
618 { |
3945
0b3256c3ee14
simplified IDicomTranscoder
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3930
diff
changeset
|
619 writer.Write(transcoded.GetBufferData(), transcoded.GetBufferSize()); |
2632 | 620 |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
621 if (dicomDir != NULL) |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
622 { |
3945
0b3256c3ee14
simplified IDicomTranscoder
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3930
diff
changeset
|
623 std::unique_ptr<ParsedDicomFile> tmp(transcoded.ReleaseAsParsedDicomFile()); |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
624 dicomDir->Add(dicomDirFolder, filename_, *tmp); |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
625 } |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
626 |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
627 transcodeSuccess = true; |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
628 } |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
629 else |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
630 { |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
631 LOG(INFO) << "Cannot transcode instance " << instanceId_ |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
632 << " to transfer syntax: " << GetTransferSyntaxUid(transferSyntax); |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
633 } |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
634 } |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
635 |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
636 if (!transcodeSuccess) |
2632 | 637 { |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
638 writer.Write(content); |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
639 |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
640 if (dicomDir != NULL) |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
641 { |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
642 if (parsed.get() == NULL) |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
643 { |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
644 parsed.reset(new ParsedDicomFile(content)); |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
645 } |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
646 |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
647 dicomDir->Add(dicomDirFolder, filename_, *parsed); |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
648 } |
2632 | 649 } |
650 | |
651 break; | |
652 } | |
653 | |
654 default: | |
655 throw OrthancException(ErrorCode_InternalError); | |
656 } | |
657 } | |
658 }; | |
659 | |
660 std::deque<Command*> commands_; | |
661 uint64_t uncompressedSize_; | |
662 unsigned int instancesCount_; | |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
663 InstanceLoader& instanceLoader_; |
2632 | 664 |
665 | |
666 void ApplyInternal(HierarchicalZipWriter& writer, | |
667 ServerContext& context, | |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
668 InstanceLoader& instanceLoader, |
2632 | 669 size_t index, |
670 DicomDirWriter* dicomDir, | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
671 const std::string& dicomDirFolder, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
672 bool transcode, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
673 DicomTransferSyntax transferSyntax) const |
2632 | 674 { |
675 if (index >= commands_.size()) | |
676 { | |
677 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
678 } | |
679 | |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
680 commands_[index]->Apply(writer, context, instanceLoader, dicomDir, dicomDirFolder, transcode, transferSyntax); |
2632 | 681 } |
682 | |
683 public: | |
4815 | 684 explicit ZipCommands(InstanceLoader& instanceLoader) : |
2632 | 685 uncompressedSize_(0), |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
686 instancesCount_(0), |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
687 instanceLoader_(instanceLoader) |
2632 | 688 { |
689 } | |
690 | |
691 ~ZipCommands() | |
692 { | |
693 for (std::deque<Command*>::iterator it = commands_.begin(); | |
694 it != commands_.end(); ++it) | |
695 { | |
696 assert(*it != NULL); | |
697 delete *it; | |
698 } | |
699 } | |
700 | |
701 size_t GetSize() const | |
702 { | |
703 return commands_.size(); | |
704 } | |
705 | |
706 unsigned int GetInstancesCount() const | |
707 { | |
708 return instancesCount_; | |
709 } | |
710 | |
711 uint64_t GetUncompressedSize() const | |
712 { | |
713 return uncompressedSize_; | |
714 } | |
715 | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
716 // "media" flavor (with DICOMDIR) |
2632 | 717 void Apply(HierarchicalZipWriter& writer, |
718 ServerContext& context, | |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
719 InstanceLoader& instanceLoader, |
2632 | 720 size_t index, |
721 DicomDirWriter& dicomDir, | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
722 const std::string& dicomDirFolder, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
723 bool transcode, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
724 DicomTransferSyntax transferSyntax) const |
2632 | 725 { |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
726 ApplyInternal(writer, context, instanceLoader, index, &dicomDir, dicomDirFolder, transcode, transferSyntax); |
2632 | 727 } |
728 | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
729 // "archive" flavor (without DICOMDIR) |
2632 | 730 void Apply(HierarchicalZipWriter& writer, |
731 ServerContext& context, | |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
732 InstanceLoader& instanceLoader, |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
733 size_t index, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
734 bool transcode, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
735 DicomTransferSyntax transferSyntax) const |
2632 | 736 { |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
737 ApplyInternal(writer, context, instanceLoader, index, NULL, "", transcode, transferSyntax); |
2632 | 738 } |
739 | |
740 void AddOpenDirectory(const std::string& filename) | |
741 { | |
742 commands_.push_back(new Command(Type_OpenDirectory, filename)); | |
743 } | |
744 | |
745 void AddCloseDirectory() | |
746 { | |
747 commands_.push_back(new Command(Type_CloseDirectory)); | |
748 } | |
749 | |
750 void AddWriteInstance(const std::string& filename, | |
751 const std::string& instanceId, | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
752 uint64_t uncompressedSize) |
2632 | 753 { |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
754 instanceLoader_.PrepareDicom(instanceId); |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
755 commands_.push_back(new Command(Type_WriteInstance, filename, instanceId)); |
2632 | 756 instancesCount_ ++; |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
757 uncompressedSize_ += uncompressedSize; |
2632 | 758 } |
759 | |
760 bool IsZip64() const | |
761 { | |
762 return IsZip64Required(GetUncompressedSize(), GetInstancesCount()); | |
763 } | |
764 }; | |
765 | |
766 | |
767 | |
768 class ArchiveJob::ArchiveIndexVisitor : public IArchiveVisitor | |
769 { | |
770 private: | |
771 ZipCommands& commands_; | |
772 ServerContext& context_; | |
773 char instanceFormat_[24]; | |
774 unsigned int counter_; | |
775 | |
776 static std::string GetTag(const DicomMap& tags, | |
777 const DicomTag& tag) | |
778 { | |
779 const DicomValue* v = tags.TestAndGetValue(tag); | |
780 if (v != NULL && | |
781 !v->IsBinary() && | |
782 !v->IsNull()) | |
783 { | |
784 return v->GetContent(); | |
785 } | |
786 else | |
787 { | |
788 return ""; | |
789 } | |
790 } | |
791 | |
792 public: | |
793 ArchiveIndexVisitor(ZipCommands& commands, | |
794 ServerContext& context) : | |
795 commands_(commands), | |
796 context_(context), | |
797 counter_(0) | |
798 { | |
799 if (commands.GetSize() != 0) | |
800 { | |
801 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
802 } | |
803 | |
804 snprintf(instanceFormat_, sizeof(instanceFormat_) - 1, "%%08d.dcm"); | |
805 } | |
806 | |
807 virtual void Open(ResourceType level, | |
4205 | 808 const std::string& publicId) ORTHANC_OVERRIDE |
2632 | 809 { |
810 std::string path; | |
811 | |
812 DicomMap tags; | |
813 if (context_.GetIndex().GetMainDicomTags(tags, publicId, level, level)) | |
814 { | |
815 switch (level) | |
816 { | |
817 case ResourceType_Patient: | |
818 path = GetTag(tags, DICOM_TAG_PATIENT_ID) + " " + GetTag(tags, DICOM_TAG_PATIENT_NAME); | |
819 break; | |
820 | |
821 case ResourceType_Study: | |
822 path = GetTag(tags, DICOM_TAG_ACCESSION_NUMBER) + " " + GetTag(tags, DICOM_TAG_STUDY_DESCRIPTION); | |
823 break; | |
824 | |
825 case ResourceType_Series: | |
826 { | |
827 std::string modality = GetTag(tags, DICOM_TAG_MODALITY); | |
828 path = modality + " " + GetTag(tags, DICOM_TAG_SERIES_DESCRIPTION); | |
829 | |
830 if (modality.size() == 0) | |
831 { | |
832 snprintf(instanceFormat_, sizeof(instanceFormat_) - 1, "%%08d.dcm"); | |
833 } | |
834 else if (modality.size() == 1) | |
835 { | |
836 snprintf(instanceFormat_, sizeof(instanceFormat_) - 1, "%c%%07d.dcm", | |
837 toupper(modality[0])); | |
838 } | |
839 else if (modality.size() >= 2) | |
840 { | |
841 snprintf(instanceFormat_, sizeof(instanceFormat_) - 1, "%c%c%%06d.dcm", | |
842 toupper(modality[0]), toupper(modality[1])); | |
843 } | |
844 | |
845 counter_ = 0; | |
846 | |
847 break; | |
848 } | |
849 | |
850 default: | |
851 throw OrthancException(ErrorCode_InternalError); | |
852 } | |
853 } | |
854 | |
855 path = Toolbox::StripSpaces(Toolbox::ConvertToAscii(path)); | |
856 | |
857 if (path.empty()) | |
858 { | |
859 path = std::string("Unknown ") + EnumerationToString(level); | |
860 } | |
861 | |
862 commands_.AddOpenDirectory(path.c_str()); | |
863 } | |
864 | |
4205 | 865 virtual void Close() ORTHANC_OVERRIDE |
2632 | 866 { |
867 commands_.AddCloseDirectory(); | |
868 } | |
869 | |
870 virtual void AddInstance(const std::string& instanceId, | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
871 uint64_t uncompressedSize) ORTHANC_OVERRIDE |
2632 | 872 { |
873 char filename[24]; | |
874 snprintf(filename, sizeof(filename) - 1, instanceFormat_, counter_); | |
875 counter_ ++; | |
876 | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
877 commands_.AddWriteInstance(filename, instanceId, uncompressedSize); |
2632 | 878 } |
879 }; | |
880 | |
881 | |
882 class ArchiveJob::MediaIndexVisitor : public IArchiveVisitor | |
883 { | |
884 private: | |
885 ZipCommands& commands_; | |
886 unsigned int counter_; | |
887 | |
888 public: | |
4591
ff8170d17d90
moving all accesses to databases from IDatabaseWrapper to ITransaction
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4588
diff
changeset
|
889 explicit MediaIndexVisitor(ZipCommands& commands) : |
2632 | 890 commands_(commands), |
891 counter_(0) | |
892 { | |
893 } | |
894 | |
895 virtual void Open(ResourceType level, | |
4205 | 896 const std::string& publicId) ORTHANC_OVERRIDE |
2632 | 897 { |
898 } | |
899 | |
4205 | 900 virtual void Close() ORTHANC_OVERRIDE |
2632 | 901 { |
902 } | |
903 | |
904 virtual void AddInstance(const std::string& instanceId, | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
905 uint64_t uncompressedSize) ORTHANC_OVERRIDE |
2632 | 906 { |
907 // "DICOM restricts the filenames on DICOM media to 8 | |
908 // characters (some systems wrongly use 8.3, but this does not | |
909 // conform to the standard)." | |
910 std::string filename = "IM" + boost::lexical_cast<std::string>(counter_); | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
911 commands_.AddWriteInstance(filename, instanceId, uncompressedSize); |
2632 | 912 |
913 counter_ ++; | |
914 } | |
915 }; | |
916 | |
917 | |
918 class ArchiveJob::ZipWriterIterator : public boost::noncopyable | |
919 { | |
920 private: | |
3712
2a170a8f1faf
replacing std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
921 ServerContext& context_; |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
922 InstanceLoader& instanceLoader_; |
3712
2a170a8f1faf
replacing std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
923 ZipCommands commands_; |
2a170a8f1faf
replacing std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
924 std::unique_ptr<HierarchicalZipWriter> zip_; |
2a170a8f1faf
replacing std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
925 std::unique_ptr<DicomDirWriter> dicomDir_; |
2a170a8f1faf
replacing std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
926 bool isMedia_; |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
927 bool isStream_; |
2632 | 928 |
929 public: | |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
930 ZipWriterIterator(ServerContext& context, |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
931 InstanceLoader& instanceLoader, |
2632 | 932 ArchiveIndex& archive, |
933 bool isMedia, | |
934 bool enableExtendedSopClass) : | |
935 context_(context), | |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
936 instanceLoader_(instanceLoader), |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
937 commands_(instanceLoader), |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
938 isMedia_(isMedia), |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
939 isStream_(false) |
2632 | 940 { |
941 if (isMedia) | |
942 { | |
4588 | 943 MediaIndexVisitor visitor(commands_); |
2632 | 944 archive.Expand(context.GetIndex()); |
945 | |
946 commands_.AddOpenDirectory(MEDIA_IMAGES_FOLDER); | |
947 archive.Apply(visitor); | |
948 commands_.AddCloseDirectory(); | |
949 | |
950 dicomDir_.reset(new DicomDirWriter); | |
951 dicomDir_->EnableExtendedSopClass(enableExtendedSopClass); | |
952 } | |
953 else | |
954 { | |
955 ArchiveIndexVisitor visitor(commands_, context); | |
956 archive.Expand(context.GetIndex()); | |
957 archive.Apply(visitor); | |
958 } | |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
959 } |
2632 | 960 |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
961 void SetOutputFile(const std::string& path) |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
962 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
963 if (zip_.get() == NULL) |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
964 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
965 zip_.reset(new HierarchicalZipWriter(path.c_str())); |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
966 zip_->SetZip64(commands_.IsZip64()); |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
967 isStream_ = false; |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
968 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
969 else |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
970 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
971 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
972 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
973 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
974 |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
975 void AcquireOutputStream(ZipWriter::IOutputStream* output) |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
976 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
977 std::unique_ptr<ZipWriter::IOutputStream> protection(output); |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
978 |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
979 if (zip_.get() == NULL) |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
980 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
981 zip_.reset(new HierarchicalZipWriter(protection.release(), commands_.IsZip64())); |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
982 isStream_ = true; |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
983 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
984 else |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
985 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
986 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
987 } |
2632 | 988 } |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
989 |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
990 void CancelStream() |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
991 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
992 if (zip_.get() == NULL) |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
993 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
994 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
995 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
996 else if (isStream_) |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
997 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
998 zip_->CancelStream(); |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
999 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1000 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1001 |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1002 void Close() |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1003 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1004 if (zip_.get() == NULL) |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1005 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1006 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1007 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1008 else |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1009 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1010 zip_->Close(); |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1011 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1012 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1013 |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1014 uint64_t GetArchiveSize() const |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1015 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1016 if (zip_.get() == NULL) |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1017 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1018 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1019 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1020 else |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1021 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1022 return zip_->GetArchiveSize(); |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1023 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1024 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1025 |
2632 | 1026 size_t GetStepsCount() const |
1027 { | |
1028 return commands_.GetSize() + 1; | |
1029 } | |
1030 | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1031 void RunStep(size_t index, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1032 bool transcode, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1033 DicomTransferSyntax transferSyntax) |
2632 | 1034 { |
1035 if (index > commands_.GetSize()) | |
1036 { | |
1037 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
1038 } | |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1039 else if (zip_.get() == NULL) |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1040 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1041 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1042 } |
2632 | 1043 else if (index == commands_.GetSize()) |
1044 { | |
1045 // Last step: Add the DICOMDIR | |
1046 if (isMedia_) | |
1047 { | |
1048 assert(dicomDir_.get() != NULL); | |
1049 std::string s; | |
1050 dicomDir_->Encode(s); | |
1051 | |
1052 zip_->OpenFile("DICOMDIR"); | |
1053 zip_->Write(s); | |
1054 } | |
1055 } | |
1056 else | |
1057 { | |
1058 if (isMedia_) | |
1059 { | |
1060 assert(dicomDir_.get() != NULL); | |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1061 commands_.Apply(*zip_, context_, instanceLoader_, index, *dicomDir_, |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1062 MEDIA_IMAGES_FOLDER, transcode, transferSyntax); |
2632 | 1063 } |
1064 else | |
1065 { | |
1066 assert(dicomDir_.get() == NULL); | |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1067 commands_.Apply(*zip_, context_, instanceLoader_, index, transcode, transferSyntax); |
2632 | 1068 } |
1069 } | |
1070 } | |
1071 | |
1072 unsigned int GetInstancesCount() const | |
1073 { | |
1074 return commands_.GetInstancesCount(); | |
1075 } | |
1076 | |
1077 uint64_t GetUncompressedSize() const | |
1078 { | |
1079 return commands_.GetUncompressedSize(); | |
1080 } | |
1081 }; | |
1082 | |
1083 | |
2966 | 1084 ArchiveJob::ArchiveJob(ServerContext& context, |
2632 | 1085 bool isMedia, |
1086 bool enableExtendedSopClass) : | |
1087 context_(context), | |
1088 archive_(new ArchiveIndex(ResourceType_Patient)), // root | |
1089 isMedia_(isMedia), | |
1090 enableExtendedSopClass_(enableExtendedSopClass), | |
1091 currentStep_(0), | |
1092 instancesCount_(0), | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1093 uncompressedSize_(0), |
4341
977c2759eb0a
Archive/media jobs report the size of the created ZIP file in content field "ArchiveSizeMB"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4205
diff
changeset
|
1094 archiveSize_(0), |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1095 transcode_(false), |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1096 transferSyntax_(DicomTransferSyntax_LittleEndianImplicit), |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1097 loaderThreads_(0) |
2632 | 1098 { |
2966 | 1099 } |
1100 | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1101 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1102 ArchiveJob::~ArchiveJob() |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1103 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1104 if (!mediaArchiveId_.empty()) |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1105 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1106 context_.GetMediaArchive().Remove(mediaArchiveId_); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1107 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1108 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1109 |
2966 | 1110 |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1111 void ArchiveJob::AcquireSynchronousTarget(ZipWriter::IOutputStream* target) |
2966 | 1112 { |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1113 std::unique_ptr<ZipWriter::IOutputStream> protection(target); |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1114 |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1115 if (target == NULL) |
2632 | 1116 { |
1117 throw OrthancException(ErrorCode_NullPointer); | |
1118 } | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1119 else if (writer_.get() != NULL || // Already started |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1120 synchronousTarget_.get() != NULL || |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1121 asynchronousTarget_.get() != NULL) |
2966 | 1122 { |
1123 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1124 } | |
1125 else | |
1126 { | |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1127 synchronousTarget_.reset(protection.release()); |
2966 | 1128 } |
2632 | 1129 } |
1130 | |
1131 | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1132 void ArchiveJob::SetDescription(const std::string& description) |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1133 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1134 if (writer_.get() != NULL) // Already started |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1135 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1136 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1137 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1138 else |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1139 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1140 description_ = description; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1141 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1142 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1143 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1144 |
2632 | 1145 void ArchiveJob::AddResource(const std::string& publicId) |
1146 { | |
1147 if (writer_.get() != NULL) // Already started | |
1148 { | |
1149 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1150 } | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1151 else |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1152 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1153 ResourceIdentifiers resource(context_.GetIndex(), publicId); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1154 archive_->Add(context_.GetIndex(), resource); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1155 } |
2632 | 1156 } |
1157 | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1158 |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1159 void ArchiveJob::SetTranscode(DicomTransferSyntax transferSyntax) |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1160 { |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1161 if (writer_.get() != NULL) // Already started |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1162 { |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1163 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1164 } |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1165 else |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1166 { |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1167 transcode_ = true; |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1168 transferSyntax_ = transferSyntax; |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1169 } |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1170 } |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1171 |
2632 | 1172 |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1173 void ArchiveJob::SetLoaderThreads(unsigned int loaderThreads) |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1174 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1175 if (writer_.get() != NULL) // Already started |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1176 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1177 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1178 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1179 else |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1180 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1181 loaderThreads_ = loaderThreads; |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1182 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1183 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1184 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1185 |
2812
ea7aea6f6a95
improved naming of methods in IJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2730
diff
changeset
|
1186 void ArchiveJob::Reset() |
2632 | 1187 { |
2955 | 1188 throw OrthancException(ErrorCode_BadSequenceOfCalls, |
1189 "Cannot resubmit the creation of an archive"); | |
2632 | 1190 } |
1191 | |
1192 | |
1193 void ArchiveJob::Start() | |
1194 { | |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1195 if (loaderThreads_ == 0) |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1196 { |
4902
df86d2505df8
Orthanc 1.9.8 is now known as Orthanc 1.10.0
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4892
diff
changeset
|
1197 // default behaviour before loaderThreads was introducted in 1.10.0 |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1198 instanceLoader_.reset(new SynchronousInstanceLoader(context_)); |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1199 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1200 else |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1201 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1202 instanceLoader_.reset(new ThreadedInstanceLoader(context_, loaderThreads_)); |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1203 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1204 |
2632 | 1205 if (writer_.get() != NULL) |
1206 { | |
1207 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1208 } | |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1209 else |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1210 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1211 if (synchronousTarget_.get() == NULL) |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1212 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1213 if (asynchronousTarget_.get() != NULL) |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1214 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1215 // It is up to this method to create the asynchronous target |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1216 throw OrthancException(ErrorCode_InternalError); |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1217 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1218 else |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1219 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1220 OrthancConfiguration::ReaderLock lock; |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1221 asynchronousTarget_.reset(lock.GetConfiguration().CreateTemporaryFile()); |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1222 |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1223 assert(asynchronousTarget_.get() != NULL); |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1224 asynchronousTarget_->Touch(); // Make sure we can write to the temporary file |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1225 |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1226 writer_.reset(new ZipWriterIterator(context_, *instanceLoader_, *archive_, isMedia_, enableExtendedSopClass_)); |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1227 writer_->SetOutputFile(asynchronousTarget_->GetPath()); |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1228 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1229 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1230 else |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1231 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1232 assert(synchronousTarget_.get() != NULL); |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1233 |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1234 writer_.reset(new ZipWriterIterator(context_, *instanceLoader_, *archive_, isMedia_, enableExtendedSopClass_)); |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1235 writer_->AcquireOutputStream(synchronousTarget_.release()); |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1236 } |
2632 | 1237 |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1238 instancesCount_ = writer_->GetInstancesCount(); |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1239 uncompressedSize_ = writer_->GetUncompressedSize(); |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1240 } |
2632 | 1241 } |
1242 | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1243 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1244 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1245 namespace |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1246 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1247 class DynamicTemporaryFile : public IDynamicObject |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1248 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1249 private: |
3712
2a170a8f1faf
replacing std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
1250 std::unique_ptr<TemporaryFile> file_; |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1251 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1252 public: |
4205 | 1253 explicit DynamicTemporaryFile(TemporaryFile* f) : file_(f) |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1254 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1255 if (f == NULL) |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1256 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1257 throw OrthancException(ErrorCode_NullPointer); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1258 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1259 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1260 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1261 const TemporaryFile& GetFile() const |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1262 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1263 assert(file_.get() != NULL); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1264 return *file_; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1265 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1266 }; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1267 } |
2632 | 1268 |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1269 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1270 void ArchiveJob::FinalizeTarget() |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1271 { |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1272 if (writer_.get() != NULL) |
4641
b02dc8303cf6
Fixed the lifetime of temporary files associated with jobs that create ZIP archive/media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4627
diff
changeset
|
1273 { |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1274 writer_->Close(); // Flush all the results |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1275 archiveSize_ = writer_->GetArchiveSize(); |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1276 writer_.reset(); |
4641
b02dc8303cf6
Fixed the lifetime of temporary files associated with jobs that create ZIP archive/media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4627
diff
changeset
|
1277 } |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1278 |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1279 if (instanceLoader_.get() != NULL) |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1280 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1281 instanceLoader_->Clear(); |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1282 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1283 |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1284 if (asynchronousTarget_.get() != NULL) |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1285 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1286 // Asynchronous behavior: Move the resulting file into the media archive |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1287 mediaArchiveId_ = context_.GetMediaArchive().Add( |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1288 new DynamicTemporaryFile(asynchronousTarget_.release())); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1289 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1290 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1291 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1292 |
3658
2d90dd30858c
providing job ID to the IJob::Step() methods
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
1293 JobStepResult ArchiveJob::Step(const std::string& jobId) |
2632 | 1294 { |
1295 assert(writer_.get() != NULL); | |
1296 | |
1297 if (writer_->GetStepsCount() == 0) | |
1298 { | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1299 FinalizeTarget(); |
2632 | 1300 return JobStepResult::Success(); |
1301 } | |
1302 else | |
1303 { | |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1304 try |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1305 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1306 writer_->RunStep(currentStep_, transcode_, transferSyntax_); |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1307 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1308 catch (Orthanc::OrthancException& e) |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1309 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1310 LOG(ERROR) << "Error while creating an archive: " << e.What(); |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1311 writer_->CancelStream(); |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1312 throw; |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1313 } |
2632 | 1314 |
1315 currentStep_ ++; | |
1316 | |
1317 if (currentStep_ == writer_->GetStepsCount()) | |
1318 { | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1319 FinalizeTarget(); |
2632 | 1320 return JobStepResult::Success(); |
1321 } | |
1322 else | |
1323 { | |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1324 archiveSize_ = writer_->GetArchiveSize(); |
2632 | 1325 return JobStepResult::Continue(); |
1326 } | |
1327 } | |
1328 } | |
1329 | |
1330 | |
4641
b02dc8303cf6
Fixed the lifetime of temporary files associated with jobs that create ZIP archive/media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4627
diff
changeset
|
1331 void ArchiveJob::Stop(JobStopReason reason) |
b02dc8303cf6
Fixed the lifetime of temporary files associated with jobs that create ZIP archive/media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4627
diff
changeset
|
1332 { |
b02dc8303cf6
Fixed the lifetime of temporary files associated with jobs that create ZIP archive/media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4627
diff
changeset
|
1333 /** |
b02dc8303cf6
Fixed the lifetime of temporary files associated with jobs that create ZIP archive/media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4627
diff
changeset
|
1334 * New in Orthanc 1.9.3: Remove the temporary file associated with |
b02dc8303cf6
Fixed the lifetime of temporary files associated with jobs that create ZIP archive/media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4627
diff
changeset
|
1335 * the job as soon as its job gets canceled (especially visible in |
b02dc8303cf6
Fixed the lifetime of temporary files associated with jobs that create ZIP archive/media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4627
diff
changeset
|
1336 * asynchronous mode). |
b02dc8303cf6
Fixed the lifetime of temporary files associated with jobs that create ZIP archive/media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4627
diff
changeset
|
1337 **/ |
b02dc8303cf6
Fixed the lifetime of temporary files associated with jobs that create ZIP archive/media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4627
diff
changeset
|
1338 if (reason == JobStopReason_Canceled || |
b02dc8303cf6
Fixed the lifetime of temporary files associated with jobs that create ZIP archive/media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4627
diff
changeset
|
1339 reason == JobStopReason_Failure || |
b02dc8303cf6
Fixed the lifetime of temporary files associated with jobs that create ZIP archive/media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4627
diff
changeset
|
1340 reason == JobStopReason_Retry) |
b02dc8303cf6
Fixed the lifetime of temporary files associated with jobs that create ZIP archive/media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4627
diff
changeset
|
1341 { |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1342 writer_->CancelStream(); |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1343 |
4641
b02dc8303cf6
Fixed the lifetime of temporary files associated with jobs that create ZIP archive/media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4627
diff
changeset
|
1344 // First delete the writer, as it holds a reference to "(a)synchronousTarget_", cf. (*) |
b02dc8303cf6
Fixed the lifetime of temporary files associated with jobs that create ZIP archive/media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4627
diff
changeset
|
1345 writer_.reset(); |
b02dc8303cf6
Fixed the lifetime of temporary files associated with jobs that create ZIP archive/media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4627
diff
changeset
|
1346 |
b02dc8303cf6
Fixed the lifetime of temporary files associated with jobs that create ZIP archive/media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4627
diff
changeset
|
1347 synchronousTarget_.reset(); |
b02dc8303cf6
Fixed the lifetime of temporary files associated with jobs that create ZIP archive/media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4627
diff
changeset
|
1348 asynchronousTarget_.reset(); |
b02dc8303cf6
Fixed the lifetime of temporary files associated with jobs that create ZIP archive/media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4627
diff
changeset
|
1349 } |
b02dc8303cf6
Fixed the lifetime of temporary files associated with jobs that create ZIP archive/media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4627
diff
changeset
|
1350 } |
b02dc8303cf6
Fixed the lifetime of temporary files associated with jobs that create ZIP archive/media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4627
diff
changeset
|
1351 |
b02dc8303cf6
Fixed the lifetime of temporary files associated with jobs that create ZIP archive/media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4627
diff
changeset
|
1352 |
2632 | 1353 float ArchiveJob::GetProgress() |
1354 { | |
1355 if (writer_.get() == NULL || | |
1356 writer_->GetStepsCount() == 0) | |
1357 { | |
1358 return 1; | |
1359 } | |
1360 else | |
1361 { | |
1362 return (static_cast<float>(currentStep_) / | |
1363 static_cast<float>(writer_->GetStepsCount() - 1)); | |
1364 } | |
1365 } | |
1366 | |
1367 | |
1368 void ArchiveJob::GetJobType(std::string& target) | |
1369 { | |
1370 if (isMedia_) | |
1371 { | |
1372 target = "Media"; | |
1373 } | |
1374 else | |
1375 { | |
1376 target = "Archive"; | |
1377 } | |
1378 } | |
1379 | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1380 |
2632 | 1381 void ArchiveJob::GetPublicContent(Json::Value& value) |
1382 { | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1383 value = Json::objectValue; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1384 value[KEY_DESCRIPTION] = description_; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1385 value[KEY_INSTANCES_COUNT] = instancesCount_; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1386 value[KEY_UNCOMPRESSED_SIZE_MB] = |
2643 | 1387 static_cast<unsigned int>(uncompressedSize_ / MEGA_BYTES); |
4341
977c2759eb0a
Archive/media jobs report the size of the created ZIP file in content field "ArchiveSizeMB"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4205
diff
changeset
|
1388 value[KEY_ARCHIVE_SIZE_MB] = |
977c2759eb0a
Archive/media jobs report the size of the created ZIP file in content field "ArchiveSizeMB"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4205
diff
changeset
|
1389 static_cast<unsigned int>(archiveSize_ / MEGA_BYTES); |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1390 |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1391 // New in Orthanc 1.9.4 |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1392 value[KEY_ARCHIVE_SIZE] = boost::lexical_cast<std::string>(archiveSize_); |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1393 value[KEY_UNCOMPRESSED_SIZE] = boost::lexical_cast<std::string>(uncompressedSize_); |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1394 |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1395 if (transcode_) |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1396 { |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1397 value[KEY_TRANSCODE] = GetTransferSyntaxUid(transferSyntax_); |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1398 } |
2632 | 1399 } |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1400 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1401 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1402 bool ArchiveJob::GetOutput(std::string& output, |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1403 MimeType& mime, |
4805
0a38000b086d
Archive jobs response now contains a header Content-Disposition:filename='archive.zip'
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1404 std::string& filename, |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1405 const std::string& key) |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1406 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1407 if (key == "archive" && |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1408 !mediaArchiveId_.empty()) |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1409 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1410 SharedArchive::Accessor accessor(context_.GetMediaArchive(), mediaArchiveId_); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1411 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1412 if (accessor.IsValid()) |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1413 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1414 const DynamicTemporaryFile& f = dynamic_cast<DynamicTemporaryFile&>(accessor.GetItem()); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1415 f.GetFile().Read(output); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1416 mime = MimeType_Zip; |
4805
0a38000b086d
Archive jobs response now contains a header Content-Disposition:filename='archive.zip'
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1417 filename = "archive.zip"; |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1418 return true; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1419 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1420 else |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1421 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1422 return false; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1423 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1424 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1425 else |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1426 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1427 return false; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1428 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1429 } |
2632 | 1430 } |