Mercurial > hg > orthanc
annotate OrthancServer/Sources/ServerJobs/ArchiveJob.cpp @ 5622:335e2079de1f tls-ignore-unexpected-tls
testing OpenSSL ignore_unexpected_eof option
author | Alain Mazy <am@orthanc.team> |
---|---|
date | Mon, 13 May 2024 12:13:50 +0200 |
parents | 48b8dae6dc77 |
children | f7adfb22e20e |
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 | |
5485
48b8dae6dc77
upgrade to year 2024
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5450
diff
changeset
|
5 * Copyright (C) 2017-2024 Osimis S.A., Belgium |
48b8dae6dc77
upgrade to year 2024
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5450
diff
changeset
|
6 * Copyright (C) 2021-2024 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> | |
5448
2d23c92c359a
Zip of studies whose PatientName and PatientID did not contain any ASCII character are now valid
Alain Mazy <am@osimis.io>
parents:
5430
diff
changeset
|
37 #include <boost/range/algorithm/count.hpp> |
2632 | 38 |
39 #if defined(_MSC_VER) | |
40 #define snprintf _snprintf | |
41 #endif | |
42 | |
43 static const uint64_t MEGA_BYTES = 1024 * 1024; | |
44 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
|
45 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
46 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
|
47 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
|
48 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
|
49 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
|
50 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
|
51 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
|
52 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
|
53 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
|
54 |
2632 | 55 |
56 namespace Orthanc | |
57 { | |
58 static bool IsZip64Required(uint64_t uncompressedSize, | |
59 unsigned int countInstances) | |
60 { | |
61 static const uint64_t SAFETY_MARGIN = 64 * MEGA_BYTES; // Should be large enough to hold DICOMDIR | |
62 static const unsigned int FILES_MARGIN = 10; | |
63 | |
64 /** | |
65 * Determine whether ZIP64 is required. Original ZIP format can | |
66 * store up to 2GB of data (some implementation supporting up to | |
67 * 4GB of data), and up to 65535 files. | |
68 * https://en.wikipedia.org/wiki/Zip_(file_format)#ZIP64 | |
69 **/ | |
70 | |
71 const bool isZip64 = (uncompressedSize >= 2 * GIGA_BYTES - SAFETY_MARGIN || | |
72 countInstances >= 65535 - FILES_MARGIN); | |
73 | |
74 LOG(INFO) << "Creating a ZIP file with " << countInstances << " files of size " | |
5430
b83192e7ad10
Now displaying timings when reading from/writing to disk in the verbose logs
Alain Mazy <am@osimis.io>
parents:
5403
diff
changeset
|
75 << Toolbox::GetHumanFileSize(uncompressedSize) << " using the " |
2632 | 76 << (isZip64 ? "ZIP64" : "ZIP32") << " file format"; |
77 | |
78 return isZip64; | |
79 } | |
80 | |
81 | |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
82 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
|
83 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
84 protected: |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
85 ServerContext& context_; |
5108
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
86 bool transcode_; |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
87 DicomTransferSyntax transferSyntax_; |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
88 public: |
5108
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
89 explicit InstanceLoader(ServerContext& context, bool transcode, DicomTransferSyntax transferSyntax) |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
90 : context_(context), |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
91 transcode_(transcode), |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
92 transferSyntax_(transferSyntax) |
4797
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 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
96 virtual ~InstanceLoader() |
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 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
|
101 { |
5108
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
102 } |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
103 |
5108
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
104 bool TranscodeDicom(std::string& transcodedBuffer, const std::string& sourceBuffer, const std::string& instanceId) |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
105 { |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
106 if (transcode_) |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
107 { |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
108 std::set<DicomTransferSyntax> syntaxes; |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
109 syntaxes.insert(transferSyntax_); |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
110 |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
111 IDicomTranscoder::DicomImage source, transcoded; |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
112 source.SetExternalBuffer(sourceBuffer); |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
113 |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
114 if (context_.Transcode(transcoded, source, syntaxes, true /* allow new SOP instance UID */)) |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
115 { |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
116 transcodedBuffer.assign(reinterpret_cast<const char*>(transcoded.GetBufferData()), transcoded.GetBufferSize()); |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
117 return true; |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
118 } |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
119 else |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
120 { |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
121 LOG(INFO) << "Cannot transcode instance " << instanceId |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
122 << " to transfer syntax: " << GetTransferSyntaxUid(transferSyntax_); |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
123 } |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
124 } |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
125 |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
126 return false; |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
127 } |
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 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
|
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 void Clear() |
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 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
136 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
|
137 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
138 public: |
5108
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
139 explicit SynchronousInstanceLoader(ServerContext& context, bool transcode, DicomTransferSyntax transferSyntax) |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
140 : InstanceLoader(context, transcode, transferSyntax) |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
141 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
142 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
143 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
144 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
|
145 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
146 context_.ReadDicom(dicom, instanceId); |
5108
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
147 |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
148 if (transcode_) |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
149 { |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
150 std::string transcoded; |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
151 if (TranscodeDicom(transcoded, dicom, instanceId)) |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
152 { |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
153 dicom.swap(transcoded); |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
154 } |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
155 } |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
156 |
4797
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 }; |
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 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
|
161 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
162 private: |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
163 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
|
164 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
165 public: |
4815 | 166 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
|
167 { |
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 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
|
171 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
172 } |
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 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
|
175 }; |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
176 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
177 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
|
178 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
179 Semaphore availableInstancesSemaphore_; |
5302
ad3cd5ec2074
Reduced the memory usage when downloading archives when "ZipLoaderThreads" > 0
Alain Mazy <am@osimis.io>
parents:
5185
diff
changeset
|
180 Semaphore bufferedInstancesSemaphore_; |
4814
46bfa3a4fd63
fix compatibility with LSB compiler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4810
diff
changeset
|
181 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
|
182 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
|
183 SharedMessageQueue instancesToPreload_; |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
184 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
|
185 |
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 public: |
5108
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
188 ThreadedInstanceLoader(ServerContext& context, size_t threadCount, bool transcode, DicomTransferSyntax transferSyntax) |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
189 : InstanceLoader(context, transcode, transferSyntax), |
5302
ad3cd5ec2074
Reduced the memory usage when downloading archives when "ZipLoaderThreads" > 0
Alain Mazy <am@osimis.io>
parents:
5185
diff
changeset
|
190 availableInstancesSemaphore_(0), |
ad3cd5ec2074
Reduced the memory usage when downloading archives when "ZipLoaderThreads" > 0
Alain Mazy <am@osimis.io>
parents:
5185
diff
changeset
|
191 bufferedInstancesSemaphore_(3*threadCount) |
4797
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 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
|
194 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
195 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
|
196 } |
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 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
199 virtual ~ThreadedInstanceLoader() |
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 Clear(); |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
202 } |
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 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
|
205 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
206 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
|
207 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
208 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
|
209 } |
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 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
|
212 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
213 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
|
214 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
215 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
|
216 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
217 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
|
218 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
219 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
220 threads_.clear(); |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
221 availableInstances_.clear(); |
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 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
224 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
|
225 { |
5450
9ffd6d18daf3
log lines now contain the thread name
Alain Mazy <am@osimis.io>
parents:
5448
diff
changeset
|
226 static uint16_t threadCounter = 0; |
9ffd6d18daf3
log lines now contain the thread name
Alain Mazy <am@osimis.io>
parents:
5448
diff
changeset
|
227 Logging::SetCurrentThreadName(std::string("ARCH-LOAD-") + boost::lexical_cast<std::string>(threadCounter++)); |
9ffd6d18daf3
log lines now contain the thread name
Alain Mazy <am@osimis.io>
parents:
5448
diff
changeset
|
228 |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
229 while (true) |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
230 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
231 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
|
232 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
|
233 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
234 return; |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
235 } |
5302
ad3cd5ec2074
Reduced the memory usage when downloading archives when "ZipLoaderThreads" > 0
Alain Mazy <am@osimis.io>
parents:
5185
diff
changeset
|
236 |
ad3cd5ec2074
Reduced the memory usage when downloading archives when "ZipLoaderThreads" > 0
Alain Mazy <am@osimis.io>
parents:
5185
diff
changeset
|
237 // wait for the consumers (zip writer), no need to accumulate instances in memory if loaders are faster than writers |
ad3cd5ec2074
Reduced the memory usage when downloading archives when "ZipLoaderThreads" > 0
Alain Mazy <am@osimis.io>
parents:
5185
diff
changeset
|
238 that->bufferedInstancesSemaphore_.Acquire(); |
4797
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 try |
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 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
|
243 that->context_.ReadDicom(*dicomContent, instanceId->GetId()); |
5108
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
244 |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
245 if (that->transcode_) |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
246 { |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
247 boost::shared_ptr<std::string> transcodedDicom(new std::string()); |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
248 if (that->TranscodeDicom(*transcodedDicom, *dicomContent, instanceId->GetId())) |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
249 { |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
250 dicomContent = transcodedDicom; |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
251 } |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
252 } |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
253 |
4797
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 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
|
256 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
|
257 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
258 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
259 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
|
260 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
261 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
|
262 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
263 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
|
264 // 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
|
265 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
|
266 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
|
267 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
268 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
269 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
270 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
271 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
|
272 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
273 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
|
274 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
275 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
276 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
|
277 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
278 while (true) |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
279 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
280 // 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
|
281 availableInstancesSemaphore_.Acquire(); |
5302
ad3cd5ec2074
Reduced the memory usage when downloading archives when "ZipLoaderThreads" > 0
Alain Mazy <am@osimis.io>
parents:
5185
diff
changeset
|
282 bufferedInstancesSemaphore_.Release(); // unlock the "flow" of loaders |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
283 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
284 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
|
285 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
286 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
|
287 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
288 // 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
|
289 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
|
290 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
|
291 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
292 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
|
293 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
294 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
|
295 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
296 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
|
297 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
298 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
|
299 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
300 // 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
|
301 // 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
|
302 availableInstancesSemaphore_.Release(); |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
303 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
304 return; |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
305 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
306 // 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
|
307 // 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
|
308 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
309 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
310 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
311 }; |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
312 |
5401
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
313 // This enum defines specific resource types to be used when exporting the archive. |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
314 // It defines if we should use the PatientInfo from the Patient or from the Study. |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
315 enum ArchiveResourceType |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
316 { |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
317 ArchiveResourceType_Patient = 0, |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
318 ArchiveResourceType_PatientInfoFromStudy = 1, |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
319 ArchiveResourceType_Study = 2, |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
320 ArchiveResourceType_Series = 3, |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
321 ArchiveResourceType_Instance = 4 |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
322 }; |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
323 |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
324 ResourceType GetResourceIdType(ArchiveResourceType type) |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
325 { |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
326 switch (type) |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
327 { |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
328 case ArchiveResourceType_Patient: |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
329 return ResourceType_Patient; |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
330 case ArchiveResourceType_PatientInfoFromStudy: // get the Patient tags from the Study id |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
331 return ResourceType_Study; |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
332 case ArchiveResourceType_Study: |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
333 return ResourceType_Study; |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
334 case ArchiveResourceType_Series: |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
335 return ResourceType_Series; |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
336 case ArchiveResourceType_Instance: |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
337 return ResourceType_Instance; |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
338 default: |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
339 throw OrthancException(ErrorCode_ParameterOutOfRange); |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
340 } |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
341 } |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
342 |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
343 ResourceType GetResourceLevel(ArchiveResourceType type) |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
344 { |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
345 switch (type) |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
346 { |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
347 case ArchiveResourceType_Patient: |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
348 return ResourceType_Patient; |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
349 case ArchiveResourceType_PatientInfoFromStudy: // this is actually the same level as the Patient |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
350 return ResourceType_Patient; |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
351 case ArchiveResourceType_Study: |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
352 return ResourceType_Study; |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
353 case ArchiveResourceType_Series: |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
354 return ResourceType_Series; |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
355 case ArchiveResourceType_Instance: |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
356 return ResourceType_Instance; |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
357 default: |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
358 throw OrthancException(ErrorCode_ParameterOutOfRange); |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
359 } |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
360 } |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
361 |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
362 ArchiveResourceType GetArchiveResourceType(ResourceType type) |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
363 { |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
364 switch (type) |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
365 { |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
366 case ResourceType_Patient: |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
367 return ArchiveResourceType_Patient; |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
368 case ArchiveResourceType_Study: |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
369 return ArchiveResourceType_PatientInfoFromStudy; |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
370 case ResourceType_Series: |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
371 return ArchiveResourceType_Series; |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
372 case ResourceType_Instance: |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
373 return ArchiveResourceType_Instance; |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
374 default: |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
375 throw OrthancException(ErrorCode_ParameterOutOfRange); |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
376 } |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
377 } |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
378 |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
379 ArchiveResourceType GetChildResourceType(ArchiveResourceType type) |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
380 { |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
381 switch (type) |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
382 { |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
383 case ArchiveResourceType_Patient: |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
384 case ArchiveResourceType_PatientInfoFromStudy: |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
385 return ArchiveResourceType_Study; |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
386 |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
387 case ArchiveResourceType_Study: |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
388 return ArchiveResourceType_Series; |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
389 |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
390 case ArchiveResourceType_Series: |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
391 return ArchiveResourceType_Instance; |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
392 |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
393 default: |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
394 throw OrthancException(ErrorCode_ParameterOutOfRange); |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
395 } |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
396 } |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
397 |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
398 |
2632 | 399 class ArchiveJob::ResourceIdentifiers : public boost::noncopyable |
400 { | |
401 private: | |
402 ResourceType level_; | |
403 std::string patient_; | |
404 std::string study_; | |
405 std::string series_; | |
406 std::string instance_; | |
407 | |
408 static void GoToParent(ServerIndex& index, | |
409 std::string& current) | |
410 { | |
411 std::string tmp; | |
412 | |
413 if (index.LookupParent(tmp, current)) | |
414 { | |
415 current = tmp; | |
416 } | |
417 else | |
418 { | |
419 throw OrthancException(ErrorCode_UnknownResource); | |
420 } | |
421 } | |
422 | |
423 | |
424 public: | |
425 ResourceIdentifiers(ServerIndex& index, | |
426 const std::string& publicId) | |
427 { | |
428 if (!index.LookupResourceType(level_, publicId)) | |
429 { | |
430 throw OrthancException(ErrorCode_UnknownResource); | |
431 } | |
432 | |
433 std::string current = publicId;; | |
434 switch (level_) // Do not add "break" below! | |
435 { | |
436 case ResourceType_Instance: | |
437 instance_ = current; | |
438 GoToParent(index, current); | |
439 | |
440 case ResourceType_Series: | |
441 series_ = current; | |
442 GoToParent(index, current); | |
443 | |
444 case ResourceType_Study: | |
445 study_ = current; | |
446 GoToParent(index, current); | |
447 | |
448 case ResourceType_Patient: | |
449 patient_ = current; | |
450 break; | |
451 | |
452 default: | |
453 throw OrthancException(ErrorCode_InternalError); | |
454 } | |
455 } | |
456 | |
457 ResourceType GetLevel() const | |
458 { | |
459 return level_; | |
460 } | |
461 | |
462 const std::string& GetIdentifier(ResourceType level) const | |
463 { | |
464 // Some sanity check to ensure enumerations are not altered | |
465 assert(ResourceType_Patient < ResourceType_Study); | |
466 assert(ResourceType_Study < ResourceType_Series); | |
467 assert(ResourceType_Series < ResourceType_Instance); | |
468 | |
469 if (level > level_) | |
470 { | |
471 throw OrthancException(ErrorCode_InternalError); | |
472 } | |
473 | |
474 switch (level) | |
475 { | |
476 case ResourceType_Patient: | |
477 return patient_; | |
478 | |
479 case ResourceType_Study: | |
480 return study_; | |
481 | |
482 case ResourceType_Series: | |
483 return series_; | |
484 | |
485 case ResourceType_Instance: | |
486 return instance_; | |
487 | |
488 default: | |
489 throw OrthancException(ErrorCode_InternalError); | |
490 } | |
491 } | |
492 }; | |
493 | |
494 | |
495 class ArchiveJob::IArchiveVisitor : public boost::noncopyable | |
496 { | |
497 public: | |
498 virtual ~IArchiveVisitor() | |
499 { | |
500 } | |
501 | |
5401
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
502 virtual void Open(ArchiveResourceType level, |
2632 | 503 const std::string& publicId) = 0; |
504 | |
505 virtual void Close() = 0; | |
506 | |
507 virtual void AddInstance(const std::string& instanceId, | |
4510
a3635a01a945
fix signature of virtual method
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4509
diff
changeset
|
508 uint64_t uncompressedSize) = 0; |
2632 | 509 }; |
510 | |
511 | |
512 class ArchiveJob::ArchiveIndex : public boost::noncopyable | |
513 { | |
514 private: | |
515 struct Instance | |
516 { | |
517 std::string id_; | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
518 uint64_t uncompressedSize_; |
2632 | 519 |
520 Instance(const std::string& id, | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
521 uint64_t uncompressedSize) : |
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
522 id_(id), |
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
523 uncompressedSize_(uncompressedSize) |
2632 | 524 { |
525 } | |
526 }; | |
527 | |
528 // A "NULL" value for ArchiveIndex indicates a non-expanded node | |
529 typedef std::map<std::string, ArchiveIndex*> Resources; | |
530 | |
5401
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
531 ArchiveResourceType level_; |
2632 | 532 Resources resources_; // Only at patient/study/series level |
533 std::list<Instance> instances_; // Only at instance level | |
534 | |
535 | |
536 void AddResourceToExpand(ServerIndex& index, | |
537 const std::string& id) | |
538 { | |
5401
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
539 if (level_ == ArchiveResourceType_Instance) |
2632 | 540 { |
541 FileInfo tmp; | |
4627
f7d5372b59b3
handling revisions of attachments
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4591
diff
changeset
|
542 int64_t revision; // ignored |
f7d5372b59b3
handling revisions of attachments
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4591
diff
changeset
|
543 if (index.LookupAttachment(tmp, revision, id, FileContentType_Dicom)) |
2632 | 544 { |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
545 instances_.push_back(Instance(id, tmp.GetUncompressedSize())); |
2632 | 546 } |
547 } | |
548 else | |
549 { | |
550 resources_[id] = NULL; | |
551 } | |
552 } | |
553 | |
554 | |
555 public: | |
5401
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
556 explicit ArchiveIndex(ArchiveResourceType level) : |
2632 | 557 level_(level) |
558 { | |
559 } | |
560 | |
561 ~ArchiveIndex() | |
562 { | |
563 for (Resources::iterator it = resources_.begin(); | |
564 it != resources_.end(); ++it) | |
565 { | |
566 delete it->second; | |
567 } | |
568 } | |
569 | |
570 | |
571 void Add(ServerIndex& index, | |
572 const ResourceIdentifiers& resource) | |
573 { | |
5401
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
574 const std::string& id = resource.GetIdentifier(GetResourceIdType(level_)); |
2632 | 575 Resources::iterator previous = resources_.find(id); |
576 | |
5401
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
577 if (level_ == ArchiveResourceType_Instance) |
2632 | 578 { |
579 AddResourceToExpand(index, id); | |
580 } | |
5401
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
581 else if (resource.GetLevel() == GetResourceLevel(level_)) |
2632 | 582 { |
583 // Mark this resource for further expansion | |
584 if (previous != resources_.end()) | |
585 { | |
586 delete previous->second; | |
587 } | |
588 | |
589 resources_[id] = NULL; | |
590 } | |
591 else if (previous == resources_.end()) | |
592 { | |
593 // 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
|
594 std::unique_ptr<ArchiveIndex> child(new ArchiveIndex(GetChildResourceType(level_))); |
2632 | 595 child->Add(index, resource); |
596 resources_[id] = child.release(); | |
597 } | |
598 else if (previous->second != NULL) | |
599 { | |
600 previous->second->Add(index, resource); | |
601 } | |
602 else | |
603 { | |
604 // Nothing to do: This item is marked for further expansion | |
605 } | |
606 } | |
607 | |
608 | |
609 void Expand(ServerIndex& index) | |
610 { | |
5401
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
611 if (level_ == ArchiveResourceType_Instance) |
2632 | 612 { |
613 // Expanding an instance node makes no sense | |
614 return; | |
615 } | |
616 | |
617 for (Resources::iterator it = resources_.begin(); | |
618 it != resources_.end(); ++it) | |
619 { | |
620 if (it->second == NULL) | |
621 { | |
622 // This is resource is marked for expansion | |
623 std::list<std::string> children; | |
624 index.GetChildren(children, it->first); | |
625 | |
3712
2a170a8f1faf
replacing std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
626 std::unique_ptr<ArchiveIndex> child(new ArchiveIndex(GetChildResourceType(level_))); |
2632 | 627 |
628 for (std::list<std::string>::const_iterator | |
629 it2 = children.begin(); it2 != children.end(); ++it2) | |
630 { | |
631 child->AddResourceToExpand(index, *it2); | |
632 } | |
633 | |
634 it->second = child.release(); | |
635 } | |
636 | |
637 assert(it->second != NULL); | |
638 it->second->Expand(index); | |
639 } | |
640 } | |
641 | |
642 | |
643 void Apply(IArchiveVisitor& visitor) const | |
644 { | |
5401
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
645 if (level_ == ArchiveResourceType_Instance) |
2632 | 646 { |
647 for (std::list<Instance>::const_iterator | |
648 it = instances_.begin(); it != instances_.end(); ++it) | |
649 { | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
650 visitor.AddInstance(it->id_, it->uncompressedSize_); |
2632 | 651 } |
652 } | |
653 else | |
654 { | |
655 for (Resources::const_iterator it = resources_.begin(); | |
656 it != resources_.end(); ++it) | |
657 { | |
658 assert(it->second != NULL); // There must have been a call to "Expand()" | |
659 visitor.Open(level_, it->first); | |
660 it->second->Apply(visitor); | |
661 visitor.Close(); | |
662 } | |
663 } | |
664 } | |
665 }; | |
666 | |
667 | |
668 | |
669 class ArchiveJob::ZipCommands : public boost::noncopyable | |
670 { | |
671 private: | |
672 enum Type | |
673 { | |
674 Type_OpenDirectory, | |
675 Type_CloseDirectory, | |
676 Type_WriteInstance | |
677 }; | |
678 | |
679 class Command : public boost::noncopyable | |
680 { | |
681 private: | |
682 Type type_; | |
683 std::string filename_; | |
684 std::string instanceId_; | |
685 | |
686 public: | |
687 explicit Command(Type type) : | |
688 type_(type) | |
689 { | |
690 assert(type_ == Type_CloseDirectory); | |
691 } | |
692 | |
693 Command(Type type, | |
694 const std::string& filename) : | |
695 type_(type), | |
696 filename_(filename) | |
697 { | |
698 assert(type_ == Type_OpenDirectory); | |
699 } | |
700 | |
701 Command(Type type, | |
702 const std::string& filename, | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
703 const std::string& instanceId) : |
2632 | 704 type_(type), |
705 filename_(filename), | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
706 instanceId_(instanceId) |
2632 | 707 { |
708 assert(type_ == Type_WriteInstance); | |
709 } | |
710 | |
711 void Apply(HierarchicalZipWriter& writer, | |
712 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
|
713 InstanceLoader& instanceLoader, |
2632 | 714 DicomDirWriter* dicomDir, |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
715 const std::string& dicomDirFolder, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
716 bool transcode, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
717 DicomTransferSyntax transferSyntax) const |
2632 | 718 { |
719 switch (type_) | |
720 { | |
721 case Type_OpenDirectory: | |
722 writer.OpenDirectory(filename_.c_str()); | |
723 break; | |
724 | |
725 case Type_CloseDirectory: | |
726 writer.CloseDirectory(); | |
727 break; | |
728 | |
729 case Type_WriteInstance: | |
730 { | |
731 std::string content; | |
732 | |
733 try | |
734 { | |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
735 instanceLoader.GetDicom(content, instanceId_); |
2632 | 736 } |
737 catch (OrthancException& e) | |
738 { | |
739 LOG(WARNING) << "An instance was removed after the job was issued: " << instanceId_; | |
740 return; | |
741 } | |
2636 | 742 |
2632 | 743 writer.OpenFile(filename_.c_str()); |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
744 |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
745 std::unique_ptr<ParsedDicomFile> parsed; |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
746 |
5109 | 747 writer.Write(content); |
748 | |
749 if (dicomDir != NULL) | |
2632 | 750 { |
5109 | 751 if (parsed.get() == NULL) |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
752 { |
5109 | 753 parsed.reset(new ParsedDicomFile(content)); |
754 } | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
755 |
5109 | 756 dicomDir->Add(dicomDirFolder, filename_, *parsed); |
2632 | 757 } |
758 | |
759 break; | |
760 } | |
761 | |
762 default: | |
763 throw OrthancException(ErrorCode_InternalError); | |
764 } | |
765 } | |
766 }; | |
767 | |
768 std::deque<Command*> commands_; | |
769 uint64_t uncompressedSize_; | |
770 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
|
771 InstanceLoader& instanceLoader_; |
2632 | 772 |
773 | |
774 void ApplyInternal(HierarchicalZipWriter& writer, | |
775 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
|
776 InstanceLoader& instanceLoader, |
2632 | 777 size_t index, |
778 DicomDirWriter* dicomDir, | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
779 const std::string& dicomDirFolder, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
780 bool transcode, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
781 DicomTransferSyntax transferSyntax) const |
2632 | 782 { |
783 if (index >= commands_.size()) | |
784 { | |
785 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
786 } | |
787 | |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
788 commands_[index]->Apply(writer, context, instanceLoader, dicomDir, dicomDirFolder, transcode, transferSyntax); |
2632 | 789 } |
790 | |
791 public: | |
4815 | 792 explicit ZipCommands(InstanceLoader& instanceLoader) : |
2632 | 793 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
|
794 instancesCount_(0), |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
795 instanceLoader_(instanceLoader) |
2632 | 796 { |
797 } | |
798 | |
799 ~ZipCommands() | |
800 { | |
801 for (std::deque<Command*>::iterator it = commands_.begin(); | |
802 it != commands_.end(); ++it) | |
803 { | |
804 assert(*it != NULL); | |
805 delete *it; | |
806 } | |
807 } | |
808 | |
809 size_t GetSize() const | |
810 { | |
811 return commands_.size(); | |
812 } | |
813 | |
814 unsigned int GetInstancesCount() const | |
815 { | |
816 return instancesCount_; | |
817 } | |
818 | |
819 uint64_t GetUncompressedSize() const | |
820 { | |
821 return uncompressedSize_; | |
822 } | |
823 | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
824 // "media" flavor (with DICOMDIR) |
2632 | 825 void Apply(HierarchicalZipWriter& writer, |
826 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
|
827 InstanceLoader& instanceLoader, |
2632 | 828 size_t index, |
829 DicomDirWriter& dicomDir, | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
830 const std::string& dicomDirFolder, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
831 bool transcode, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
832 DicomTransferSyntax transferSyntax) const |
2632 | 833 { |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
834 ApplyInternal(writer, context, instanceLoader, index, &dicomDir, dicomDirFolder, transcode, transferSyntax); |
2632 | 835 } |
836 | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
837 // "archive" flavor (without DICOMDIR) |
2632 | 838 void Apply(HierarchicalZipWriter& writer, |
839 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
|
840 InstanceLoader& instanceLoader, |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
841 size_t index, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
842 bool transcode, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
843 DicomTransferSyntax transferSyntax) const |
2632 | 844 { |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
845 ApplyInternal(writer, context, instanceLoader, index, NULL, "", transcode, transferSyntax); |
2632 | 846 } |
847 | |
848 void AddOpenDirectory(const std::string& filename) | |
849 { | |
850 commands_.push_back(new Command(Type_OpenDirectory, filename)); | |
851 } | |
852 | |
853 void AddCloseDirectory() | |
854 { | |
855 commands_.push_back(new Command(Type_CloseDirectory)); | |
856 } | |
857 | |
858 void AddWriteInstance(const std::string& filename, | |
859 const std::string& instanceId, | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
860 uint64_t uncompressedSize) |
2632 | 861 { |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
862 instanceLoader_.PrepareDicom(instanceId); |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
863 commands_.push_back(new Command(Type_WriteInstance, filename, instanceId)); |
2632 | 864 instancesCount_ ++; |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
865 uncompressedSize_ += uncompressedSize; |
2632 | 866 } |
867 | |
868 bool IsZip64() const | |
869 { | |
870 return IsZip64Required(GetUncompressedSize(), GetInstancesCount()); | |
871 } | |
872 }; | |
873 | |
874 | |
875 | |
876 class ArchiveJob::ArchiveIndexVisitor : public IArchiveVisitor | |
877 { | |
878 private: | |
879 ZipCommands& commands_; | |
880 ServerContext& context_; | |
881 char instanceFormat_[24]; | |
882 unsigned int counter_; | |
883 | |
884 static std::string GetTag(const DicomMap& tags, | |
885 const DicomTag& tag) | |
886 { | |
887 const DicomValue* v = tags.TestAndGetValue(tag); | |
888 if (v != NULL && | |
889 !v->IsBinary() && | |
890 !v->IsNull()) | |
891 { | |
892 return v->GetContent(); | |
893 } | |
894 else | |
895 { | |
896 return ""; | |
897 } | |
898 } | |
899 | |
900 public: | |
901 ArchiveIndexVisitor(ZipCommands& commands, | |
902 ServerContext& context) : | |
903 commands_(commands), | |
904 context_(context), | |
905 counter_(0) | |
906 { | |
907 if (commands.GetSize() != 0) | |
908 { | |
909 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
910 } | |
911 | |
912 snprintf(instanceFormat_, sizeof(instanceFormat_) - 1, "%%08d.dcm"); | |
913 } | |
914 | |
5401
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
915 virtual void Open(ArchiveResourceType level, |
4205 | 916 const std::string& publicId) ORTHANC_OVERRIDE |
2632 | 917 { |
918 std::string path; | |
919 | |
920 DicomMap tags; | |
5401
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
921 ResourceType resourceIdLevel = GetResourceIdType(level); |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
922 ResourceType interestLevel = (level == ArchiveResourceType_PatientInfoFromStudy ? ResourceType_Patient : resourceIdLevel); |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
923 |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
924 if (context_.GetIndex().GetMainDicomTags(tags, publicId, resourceIdLevel, interestLevel)) |
2632 | 925 { |
926 switch (level) | |
927 { | |
5401
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
928 case ArchiveResourceType_Patient: |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
929 case ArchiveResourceType_PatientInfoFromStudy: |
2632 | 930 path = GetTag(tags, DICOM_TAG_PATIENT_ID) + " " + GetTag(tags, DICOM_TAG_PATIENT_NAME); |
931 break; | |
932 | |
5401
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
933 case ArchiveResourceType_Study: |
2632 | 934 path = GetTag(tags, DICOM_TAG_ACCESSION_NUMBER) + " " + GetTag(tags, DICOM_TAG_STUDY_DESCRIPTION); |
935 break; | |
936 | |
5401
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
937 case ArchiveResourceType_Series: |
2632 | 938 { |
939 std::string modality = GetTag(tags, DICOM_TAG_MODALITY); | |
940 path = modality + " " + GetTag(tags, DICOM_TAG_SERIES_DESCRIPTION); | |
941 | |
942 if (modality.size() == 0) | |
943 { | |
944 snprintf(instanceFormat_, sizeof(instanceFormat_) - 1, "%%08d.dcm"); | |
945 } | |
946 else if (modality.size() == 1) | |
947 { | |
948 snprintf(instanceFormat_, sizeof(instanceFormat_) - 1, "%c%%07d.dcm", | |
949 toupper(modality[0])); | |
950 } | |
951 else if (modality.size() >= 2) | |
952 { | |
953 snprintf(instanceFormat_, sizeof(instanceFormat_) - 1, "%c%c%%06d.dcm", | |
954 toupper(modality[0]), toupper(modality[1])); | |
955 } | |
956 | |
957 counter_ = 0; | |
958 | |
959 break; | |
960 } | |
961 | |
962 default: | |
963 throw OrthancException(ErrorCode_InternalError); | |
964 } | |
965 } | |
966 | |
967 path = Toolbox::StripSpaces(Toolbox::ConvertToAscii(path)); | |
968 | |
5448
2d23c92c359a
Zip of studies whose PatientName and PatientID did not contain any ASCII character are now valid
Alain Mazy <am@osimis.io>
parents:
5430
diff
changeset
|
969 if (path.empty() |
2d23c92c359a
Zip of studies whose PatientName and PatientID did not contain any ASCII character are now valid
Alain Mazy <am@osimis.io>
parents:
5430
diff
changeset
|
970 || (static_cast<size_t>(boost::count(path, '^')) == path.size())) // this happens with non ASCII patient names: only the '^' remains and this is not a valid zip folder name |
2632 | 971 { |
5401
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
972 path = std::string("Unknown ") + EnumerationToString(GetResourceLevel(level)); |
2632 | 973 } |
974 | |
975 commands_.AddOpenDirectory(path.c_str()); | |
976 } | |
977 | |
4205 | 978 virtual void Close() ORTHANC_OVERRIDE |
2632 | 979 { |
980 commands_.AddCloseDirectory(); | |
981 } | |
982 | |
983 virtual void AddInstance(const std::string& instanceId, | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
984 uint64_t uncompressedSize) ORTHANC_OVERRIDE |
2632 | 985 { |
986 char filename[24]; | |
987 snprintf(filename, sizeof(filename) - 1, instanceFormat_, counter_); | |
988 counter_ ++; | |
989 | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
990 commands_.AddWriteInstance(filename, instanceId, uncompressedSize); |
2632 | 991 } |
992 }; | |
993 | |
994 | |
995 class ArchiveJob::MediaIndexVisitor : public IArchiveVisitor | |
996 { | |
997 private: | |
998 ZipCommands& commands_; | |
999 unsigned int counter_; | |
1000 | |
1001 public: | |
4591
ff8170d17d90
moving all accesses to databases from IDatabaseWrapper to ITransaction
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4588
diff
changeset
|
1002 explicit MediaIndexVisitor(ZipCommands& commands) : |
2632 | 1003 commands_(commands), |
1004 counter_(0) | |
1005 { | |
1006 } | |
1007 | |
5401
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
1008 virtual void Open(ArchiveResourceType level, |
4205 | 1009 const std::string& publicId) ORTHANC_OVERRIDE |
2632 | 1010 { |
1011 } | |
1012 | |
4205 | 1013 virtual void Close() ORTHANC_OVERRIDE |
2632 | 1014 { |
1015 } | |
1016 | |
1017 virtual void AddInstance(const std::string& instanceId, | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
1018 uint64_t uncompressedSize) ORTHANC_OVERRIDE |
2632 | 1019 { |
1020 // "DICOM restricts the filenames on DICOM media to 8 | |
1021 // characters (some systems wrongly use 8.3, but this does not | |
1022 // conform to the standard)." | |
1023 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
|
1024 commands_.AddWriteInstance(filename, instanceId, uncompressedSize); |
2632 | 1025 |
1026 counter_ ++; | |
1027 } | |
1028 }; | |
1029 | |
1030 | |
1031 class ArchiveJob::ZipWriterIterator : public boost::noncopyable | |
1032 { | |
1033 private: | |
3712
2a170a8f1faf
replacing std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
1034 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
|
1035 InstanceLoader& instanceLoader_; |
3712
2a170a8f1faf
replacing std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
1036 ZipCommands commands_; |
2a170a8f1faf
replacing std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
1037 std::unique_ptr<HierarchicalZipWriter> zip_; |
2a170a8f1faf
replacing std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
1038 std::unique_ptr<DicomDirWriter> dicomDir_; |
2a170a8f1faf
replacing std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
1039 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
|
1040 bool isStream_; |
2632 | 1041 |
1042 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
|
1043 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
|
1044 InstanceLoader& instanceLoader, |
2632 | 1045 ArchiveIndex& archive, |
1046 bool isMedia, | |
1047 bool enableExtendedSopClass) : | |
1048 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
|
1049 instanceLoader_(instanceLoader), |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1050 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
|
1051 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
|
1052 isStream_(false) |
2632 | 1053 { |
1054 if (isMedia) | |
1055 { | |
4588 | 1056 MediaIndexVisitor visitor(commands_); |
2632 | 1057 archive.Expand(context.GetIndex()); |
1058 | |
1059 commands_.AddOpenDirectory(MEDIA_IMAGES_FOLDER); | |
1060 archive.Apply(visitor); | |
1061 commands_.AddCloseDirectory(); | |
1062 | |
1063 dicomDir_.reset(new DicomDirWriter); | |
1064 dicomDir_->EnableExtendedSopClass(enableExtendedSopClass); | |
1065 } | |
1066 else | |
1067 { | |
1068 ArchiveIndexVisitor visitor(commands_, context); | |
1069 archive.Expand(context.GetIndex()); | |
1070 archive.Apply(visitor); | |
1071 } | |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1072 } |
2632 | 1073 |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1074 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
|
1075 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1076 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
|
1077 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1078 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
|
1079 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
|
1080 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
|
1081 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1082 else |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1083 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1084 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
|
1085 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1086 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1087 |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1088 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
|
1089 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1090 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
|
1091 |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1092 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
|
1093 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1094 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
|
1095 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
|
1096 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1097 else |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1098 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1099 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
|
1100 } |
2632 | 1101 } |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1102 |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1103 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
|
1104 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1105 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
|
1106 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1107 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
|
1108 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1109 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
|
1110 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1111 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
|
1112 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1113 } |
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 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
|
1116 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1117 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
|
1118 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1119 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
|
1120 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1121 else |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1122 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1123 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
|
1124 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1125 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1126 |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1127 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
|
1128 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1129 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
|
1130 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1131 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
|
1132 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1133 else |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1134 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1135 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
|
1136 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1137 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1138 |
2632 | 1139 size_t GetStepsCount() const |
1140 { | |
1141 return commands_.GetSize() + 1; | |
1142 } | |
1143 | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1144 void RunStep(size_t index, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1145 bool transcode, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1146 DicomTransferSyntax transferSyntax) |
2632 | 1147 { |
1148 if (index > commands_.GetSize()) | |
1149 { | |
1150 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
1151 } | |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1152 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
|
1153 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1154 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
|
1155 } |
2632 | 1156 else if (index == commands_.GetSize()) |
1157 { | |
1158 // Last step: Add the DICOMDIR | |
1159 if (isMedia_) | |
1160 { | |
1161 assert(dicomDir_.get() != NULL); | |
1162 std::string s; | |
1163 dicomDir_->Encode(s); | |
1164 | |
1165 zip_->OpenFile("DICOMDIR"); | |
1166 zip_->Write(s); | |
1167 } | |
1168 } | |
1169 else | |
1170 { | |
1171 if (isMedia_) | |
1172 { | |
1173 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
|
1174 commands_.Apply(*zip_, context_, instanceLoader_, index, *dicomDir_, |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1175 MEDIA_IMAGES_FOLDER, transcode, transferSyntax); |
2632 | 1176 } |
1177 else | |
1178 { | |
1179 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
|
1180 commands_.Apply(*zip_, context_, instanceLoader_, index, transcode, transferSyntax); |
2632 | 1181 } |
1182 } | |
1183 } | |
1184 | |
1185 unsigned int GetInstancesCount() const | |
1186 { | |
1187 return commands_.GetInstancesCount(); | |
1188 } | |
1189 | |
1190 uint64_t GetUncompressedSize() const | |
1191 { | |
1192 return commands_.GetUncompressedSize(); | |
1193 } | |
1194 }; | |
1195 | |
1196 | |
2966 | 1197 ArchiveJob::ArchiveJob(ServerContext& context, |
2632 | 1198 bool isMedia, |
5401
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
1199 bool enableExtendedSopClass, |
fc604681e6be
When exporting a study archive, make sure to use the PatientName from the study and not from the patient in case of PatientID collision
Alain Mazy <am@osimis.io>
parents:
5364
diff
changeset
|
1200 ResourceType jobLevel) : |
2632 | 1201 context_(context), |
5403
05cb668c5f3f
fix to keep backward behaviour when exporting a series archive
Alain Mazy <am@osimis.io>
parents:
5401
diff
changeset
|
1202 archive_(new ArchiveIndex(GetArchiveResourceType(jobLevel))), // get patient Info from this level |
2632 | 1203 isMedia_(isMedia), |
1204 enableExtendedSopClass_(enableExtendedSopClass), | |
1205 currentStep_(0), | |
1206 instancesCount_(0), | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1207 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
|
1208 archiveSize_(0), |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1209 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
|
1210 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
|
1211 loaderThreads_(0) |
2632 | 1212 { |
2966 | 1213 } |
1214 | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1215 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1216 ArchiveJob::~ArchiveJob() |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1217 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1218 if (!mediaArchiveId_.empty()) |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1219 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1220 context_.GetMediaArchive().Remove(mediaArchiveId_); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1221 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1222 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1223 |
2966 | 1224 |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1225 void ArchiveJob::AcquireSynchronousTarget(ZipWriter::IOutputStream* target) |
2966 | 1226 { |
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 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
|
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 if (target == NULL) |
2632 | 1230 { |
1231 throw OrthancException(ErrorCode_NullPointer); | |
1232 } | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1233 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
|
1234 synchronousTarget_.get() != NULL || |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1235 asynchronousTarget_.get() != NULL) |
2966 | 1236 { |
1237 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1238 } | |
1239 else | |
1240 { | |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1241 synchronousTarget_.reset(protection.release()); |
2966 | 1242 } |
2632 | 1243 } |
1244 | |
1245 | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1246 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
|
1247 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1248 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
|
1249 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1250 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
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 else |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1253 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1254 description_ = description; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1255 } |
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 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1258 |
5169
8b74aa4f3515
enforce the existence of the patient/study/instance while creating its archive
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5109
diff
changeset
|
1259 void ArchiveJob::AddResource(const std::string& publicId, |
8b74aa4f3515
enforce the existence of the patient/study/instance while creating its archive
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5109
diff
changeset
|
1260 bool mustExist, |
8b74aa4f3515
enforce the existence of the patient/study/instance while creating its archive
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5109
diff
changeset
|
1261 ResourceType expectedType) |
2632 | 1262 { |
1263 if (writer_.get() != NULL) // Already started | |
1264 { | |
1265 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1266 } | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1267 else |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1268 { |
5169
8b74aa4f3515
enforce the existence of the patient/study/instance while creating its archive
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5109
diff
changeset
|
1269 if (mustExist) |
8b74aa4f3515
enforce the existence of the patient/study/instance while creating its archive
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5109
diff
changeset
|
1270 { |
8b74aa4f3515
enforce the existence of the patient/study/instance while creating its archive
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5109
diff
changeset
|
1271 ResourceType type; |
8b74aa4f3515
enforce the existence of the patient/study/instance while creating its archive
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5109
diff
changeset
|
1272 if (!context_.GetIndex().LookupResourceType(type, publicId) || |
8b74aa4f3515
enforce the existence of the patient/study/instance while creating its archive
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5109
diff
changeset
|
1273 type != expectedType) |
8b74aa4f3515
enforce the existence of the patient/study/instance while creating its archive
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5109
diff
changeset
|
1274 { |
8b74aa4f3515
enforce the existence of the patient/study/instance while creating its archive
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5109
diff
changeset
|
1275 throw OrthancException(ErrorCode_InexistentItem, |
8b74aa4f3515
enforce the existence of the patient/study/instance while creating its archive
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5109
diff
changeset
|
1276 "Missing resource while creating an archive: " + publicId); |
8b74aa4f3515
enforce the existence of the patient/study/instance while creating its archive
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5109
diff
changeset
|
1277 } |
8b74aa4f3515
enforce the existence of the patient/study/instance while creating its archive
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5109
diff
changeset
|
1278 } |
8b74aa4f3515
enforce the existence of the patient/study/instance while creating its archive
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5109
diff
changeset
|
1279 |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1280 ResourceIdentifiers resource(context_.GetIndex(), publicId); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1281 archive_->Add(context_.GetIndex(), resource); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1282 } |
2632 | 1283 } |
1284 | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1285 |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1286 void ArchiveJob::SetTranscode(DicomTransferSyntax transferSyntax) |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1287 { |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1288 if (writer_.get() != NULL) // Already started |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1289 { |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1290 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1291 } |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1292 else |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1293 { |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1294 transcode_ = true; |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1295 transferSyntax_ = transferSyntax; |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1296 } |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1297 } |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1298 |
2632 | 1299 |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1300 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
|
1301 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1302 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
|
1303 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1304 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
|
1305 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1306 else |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1307 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1308 loaderThreads_ = loaderThreads; |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1309 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1310 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1311 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1312 |
2812
ea7aea6f6a95
improved naming of methods in IJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2730
diff
changeset
|
1313 void ArchiveJob::Reset() |
2632 | 1314 { |
2955 | 1315 throw OrthancException(ErrorCode_BadSequenceOfCalls, |
1316 "Cannot resubmit the creation of an archive"); | |
2632 | 1317 } |
1318 | |
1319 | |
1320 void ArchiveJob::Start() | |
1321 { | |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1322 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
|
1323 { |
4902
df86d2505df8
Orthanc 1.9.8 is now known as Orthanc 1.10.0
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4892
diff
changeset
|
1324 // default behaviour before loaderThreads was introducted in 1.10.0 |
5108
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
1325 instanceLoader_.reset(new SynchronousInstanceLoader(context_, transcode_, transferSyntax_)); |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1326 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1327 else |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1328 { |
5108
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
1329 instanceLoader_.reset(new ThreadedInstanceLoader(context_, loaderThreads_, transcode_, transferSyntax_)); |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1330 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1331 |
2632 | 1332 if (writer_.get() != NULL) |
1333 { | |
1334 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1335 } | |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1336 else |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1337 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1338 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
|
1339 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1340 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
|
1341 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1342 // 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
|
1343 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
|
1344 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1345 else |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1346 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1347 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
|
1348 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
|
1349 |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1350 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
|
1351 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
|
1352 |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1353 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
|
1354 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
|
1355 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1356 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1357 else |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1358 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1359 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
|
1360 |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1361 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
|
1362 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
|
1363 } |
2632 | 1364 |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1365 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
|
1366 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
|
1367 } |
2632 | 1368 } |
1369 | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1370 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1371 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1372 namespace |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1373 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1374 class DynamicTemporaryFile : public IDynamicObject |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1375 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1376 private: |
3712
2a170a8f1faf
replacing std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
1377 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
|
1378 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1379 public: |
4205 | 1380 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
|
1381 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1382 if (f == NULL) |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1383 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1384 throw OrthancException(ErrorCode_NullPointer); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1385 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1386 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1387 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1388 const TemporaryFile& GetFile() const |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1389 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1390 assert(file_.get() != NULL); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1391 return *file_; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1392 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1393 }; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1394 } |
2632 | 1395 |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1396 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1397 void ArchiveJob::FinalizeTarget() |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1398 { |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1399 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
|
1400 { |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1401 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
|
1402 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
|
1403 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
|
1404 } |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1405 |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1406 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
|
1407 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1408 instanceLoader_->Clear(); |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1409 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1410 |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1411 if (asynchronousTarget_.get() != NULL) |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1412 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1413 // 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
|
1414 mediaArchiveId_ = context_.GetMediaArchive().Add( |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1415 new DynamicTemporaryFile(asynchronousTarget_.release())); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1416 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1417 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1418 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1419 |
3658
2d90dd30858c
providing job ID to the IJob::Step() methods
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
1420 JobStepResult ArchiveJob::Step(const std::string& jobId) |
2632 | 1421 { |
1422 assert(writer_.get() != NULL); | |
1423 | |
1424 if (writer_->GetStepsCount() == 0) | |
1425 { | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1426 FinalizeTarget(); |
2632 | 1427 return JobStepResult::Success(); |
1428 } | |
1429 else | |
1430 { | |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1431 try |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1432 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1433 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
|
1434 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1435 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
|
1436 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1437 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
|
1438 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
|
1439 throw; |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1440 } |
2632 | 1441 |
1442 currentStep_ ++; | |
1443 | |
1444 if (currentStep_ == writer_->GetStepsCount()) | |
1445 { | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1446 FinalizeTarget(); |
2632 | 1447 return JobStepResult::Success(); |
1448 } | |
1449 else | |
1450 { | |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1451 archiveSize_ = writer_->GetArchiveSize(); |
2632 | 1452 return JobStepResult::Continue(); |
1453 } | |
1454 } | |
1455 } | |
1456 | |
1457 | |
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
|
1458 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
|
1459 { |
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
|
1460 /** |
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
|
1461 * 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
|
1462 * 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
|
1463 * 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
|
1464 **/ |
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
|
1465 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
|
1466 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
|
1467 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
|
1468 { |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1469 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
|
1470 |
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
|
1471 // 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
|
1472 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
|
1473 |
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
|
1474 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
|
1475 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
|
1476 } |
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
|
1477 } |
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
|
1478 |
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
|
1479 |
2632 | 1480 float ArchiveJob::GetProgress() |
1481 { | |
1482 if (writer_.get() == NULL || | |
1483 writer_->GetStepsCount() == 0) | |
1484 { | |
1485 return 1; | |
1486 } | |
1487 else | |
1488 { | |
1489 return (static_cast<float>(currentStep_) / | |
1490 static_cast<float>(writer_->GetStepsCount() - 1)); | |
1491 } | |
1492 } | |
1493 | |
1494 | |
1495 void ArchiveJob::GetJobType(std::string& target) | |
1496 { | |
1497 if (isMedia_) | |
1498 { | |
1499 target = "Media"; | |
1500 } | |
1501 else | |
1502 { | |
1503 target = "Archive"; | |
1504 } | |
1505 } | |
1506 | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1507 |
2632 | 1508 void ArchiveJob::GetPublicContent(Json::Value& value) |
1509 { | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1510 value = Json::objectValue; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1511 value[KEY_DESCRIPTION] = description_; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1512 value[KEY_INSTANCES_COUNT] = instancesCount_; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1513 value[KEY_UNCOMPRESSED_SIZE_MB] = |
2643 | 1514 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
|
1515 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
|
1516 static_cast<unsigned int>(archiveSize_ / MEGA_BYTES); |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1517 |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1518 // 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
|
1519 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
|
1520 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
|
1521 |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1522 if (transcode_) |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1523 { |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1524 value[KEY_TRANSCODE] = GetTransferSyntaxUid(transferSyntax_); |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1525 } |
2632 | 1526 } |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1527 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1528 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1529 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
|
1530 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
|
1531 std::string& filename, |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1532 const std::string& key) |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1533 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1534 if (key == "archive" && |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1535 !mediaArchiveId_.empty()) |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1536 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1537 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
|
1538 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1539 if (accessor.IsValid()) |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1540 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1541 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
|
1542 f.GetFile().Read(output); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1543 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
|
1544 filename = "archive.zip"; |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1545 return true; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1546 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1547 else |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1548 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1549 return false; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1550 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1551 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1552 else |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1553 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1554 return false; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1555 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1556 } |
5310
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1557 |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1558 bool ArchiveJob::DeleteOutput(const std::string& key) |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1559 { |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1560 if (key == "archive" && |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1561 !mediaArchiveId_.empty()) |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1562 { |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1563 SharedArchive::Accessor accessor(context_.GetMediaArchive(), mediaArchiveId_); |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1564 |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1565 if (accessor.IsValid()) |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1566 { |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1567 context_.GetMediaArchive().Remove(mediaArchiveId_); |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1568 return true; |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1569 } |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1570 else |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1571 { |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1572 return false; |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1573 } |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1574 } |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1575 else |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1576 { |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1577 return false; |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1578 } |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1579 } |
5364
b5f2122a1334
Added a route to delete completed jobs from history: DELETE /jobs/{id}
Alain Mazy <am@osimis.io>
parents:
5310
diff
changeset
|
1580 |
b5f2122a1334
Added a route to delete completed jobs from history: DELETE /jobs/{id}
Alain Mazy <am@osimis.io>
parents:
5310
diff
changeset
|
1581 void ArchiveJob::DeleteAllOutputs() |
b5f2122a1334
Added a route to delete completed jobs from history: DELETE /jobs/{id}
Alain Mazy <am@osimis.io>
parents:
5310
diff
changeset
|
1582 { |
b5f2122a1334
Added a route to delete completed jobs from history: DELETE /jobs/{id}
Alain Mazy <am@osimis.io>
parents:
5310
diff
changeset
|
1583 DeleteOutput("archive"); |
b5f2122a1334
Added a route to delete completed jobs from history: DELETE /jobs/{id}
Alain Mazy <am@osimis.io>
parents:
5310
diff
changeset
|
1584 } |
2632 | 1585 } |