Mercurial > hg > orthanc
annotate OrthancServer/Sources/ServerJobs/ArchiveJob.cpp @ 5448:2d23c92c359a
Zip of studies whose PatientName and PatientID did not contain any ASCII character are now valid
author | Alain Mazy <am@osimis.io> |
---|---|
date | Mon, 27 Nov 2023 09:05:05 +0100 |
parents | b83192e7ad10 |
children | 9ffd6d18daf3 |
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 | |
5185
0ea402b4d901
upgrade to year 2023
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5169
diff
changeset
|
5 * Copyright (C) 2017-2023 Osimis S.A., Belgium |
0ea402b4d901
upgrade to year 2023
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5169
diff
changeset
|
6 * Copyright (C) 2021-2023 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 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
226 while (true) |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
227 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
228 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
|
229 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
|
230 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
231 return; |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
232 } |
5302
ad3cd5ec2074
Reduced the memory usage when downloading archives when "ZipLoaderThreads" > 0
Alain Mazy <am@osimis.io>
parents:
5185
diff
changeset
|
233 |
ad3cd5ec2074
Reduced the memory usage when downloading archives when "ZipLoaderThreads" > 0
Alain Mazy <am@osimis.io>
parents:
5185
diff
changeset
|
234 // 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
|
235 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
|
236 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
237 try |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
238 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
239 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
|
240 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
|
241 |
a386dfb5b386
Optimization: now using multiple threads to transcode files for asynchronous download of studies archive
Alain Mazy <am@osimis.io>
parents:
4902
diff
changeset
|
242 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
|
243 { |
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 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
|
245 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
|
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 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
|
248 } |
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 |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
251 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
252 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
|
253 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
|
254 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
255 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
256 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
|
257 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
258 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
|
259 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
260 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
|
261 // 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
|
262 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
|
263 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
|
264 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
265 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
266 } |
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 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
|
269 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
270 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
|
271 } |
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 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
|
274 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
275 while (true) |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
276 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
277 // 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
|
278 availableInstancesSemaphore_.Acquire(); |
5302
ad3cd5ec2074
Reduced the memory usage when downloading archives when "ZipLoaderThreads" > 0
Alain Mazy <am@osimis.io>
parents:
5185
diff
changeset
|
279 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
|
280 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
281 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
|
282 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
283 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
|
284 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
285 // 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
|
286 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
|
287 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
|
288 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
289 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
|
290 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
291 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
|
292 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
293 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
|
294 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
295 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
|
296 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
297 // 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
|
298 // 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
|
299 availableInstancesSemaphore_.Release(); |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
300 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
301 return; |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
302 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
303 // 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
|
304 // 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
|
305 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
306 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
307 } |
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 |
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
|
310 // 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
|
311 // 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
|
312 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
|
313 { |
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 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
|
315 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
|
316 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
|
317 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
|
318 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
|
319 }; |
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 |
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 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
|
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 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
|
324 { |
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 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
|
326 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
|
327 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
|
328 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
|
329 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
|
330 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
|
331 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
|
332 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
|
333 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
|
334 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
|
335 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
|
336 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
|
337 } |
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 } |
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 |
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 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
|
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 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
|
343 { |
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 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
|
345 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
|
346 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
|
347 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
|
348 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
|
349 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
|
350 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
|
351 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
|
352 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
|
353 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
|
354 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
|
355 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
|
356 } |
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 } |
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 |
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 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
|
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 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
|
362 { |
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 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
|
364 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
|
365 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
|
366 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
|
367 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
|
368 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
|
369 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
|
370 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
|
371 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
|
372 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
|
373 } |
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 } |
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 |
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 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
|
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 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
|
379 { |
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 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
|
381 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
|
382 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
|
383 |
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_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
|
385 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
|
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_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
|
388 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
|
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 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
|
391 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
|
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 } |
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 |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
395 |
2632 | 396 class ArchiveJob::ResourceIdentifiers : public boost::noncopyable |
397 { | |
398 private: | |
399 ResourceType level_; | |
400 std::string patient_; | |
401 std::string study_; | |
402 std::string series_; | |
403 std::string instance_; | |
404 | |
405 static void GoToParent(ServerIndex& index, | |
406 std::string& current) | |
407 { | |
408 std::string tmp; | |
409 | |
410 if (index.LookupParent(tmp, current)) | |
411 { | |
412 current = tmp; | |
413 } | |
414 else | |
415 { | |
416 throw OrthancException(ErrorCode_UnknownResource); | |
417 } | |
418 } | |
419 | |
420 | |
421 public: | |
422 ResourceIdentifiers(ServerIndex& index, | |
423 const std::string& publicId) | |
424 { | |
425 if (!index.LookupResourceType(level_, publicId)) | |
426 { | |
427 throw OrthancException(ErrorCode_UnknownResource); | |
428 } | |
429 | |
430 std::string current = publicId;; | |
431 switch (level_) // Do not add "break" below! | |
432 { | |
433 case ResourceType_Instance: | |
434 instance_ = current; | |
435 GoToParent(index, current); | |
436 | |
437 case ResourceType_Series: | |
438 series_ = current; | |
439 GoToParent(index, current); | |
440 | |
441 case ResourceType_Study: | |
442 study_ = current; | |
443 GoToParent(index, current); | |
444 | |
445 case ResourceType_Patient: | |
446 patient_ = current; | |
447 break; | |
448 | |
449 default: | |
450 throw OrthancException(ErrorCode_InternalError); | |
451 } | |
452 } | |
453 | |
454 ResourceType GetLevel() const | |
455 { | |
456 return level_; | |
457 } | |
458 | |
459 const std::string& GetIdentifier(ResourceType level) const | |
460 { | |
461 // Some sanity check to ensure enumerations are not altered | |
462 assert(ResourceType_Patient < ResourceType_Study); | |
463 assert(ResourceType_Study < ResourceType_Series); | |
464 assert(ResourceType_Series < ResourceType_Instance); | |
465 | |
466 if (level > level_) | |
467 { | |
468 throw OrthancException(ErrorCode_InternalError); | |
469 } | |
470 | |
471 switch (level) | |
472 { | |
473 case ResourceType_Patient: | |
474 return patient_; | |
475 | |
476 case ResourceType_Study: | |
477 return study_; | |
478 | |
479 case ResourceType_Series: | |
480 return series_; | |
481 | |
482 case ResourceType_Instance: | |
483 return instance_; | |
484 | |
485 default: | |
486 throw OrthancException(ErrorCode_InternalError); | |
487 } | |
488 } | |
489 }; | |
490 | |
491 | |
492 class ArchiveJob::IArchiveVisitor : public boost::noncopyable | |
493 { | |
494 public: | |
495 virtual ~IArchiveVisitor() | |
496 { | |
497 } | |
498 | |
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
|
499 virtual void Open(ArchiveResourceType level, |
2632 | 500 const std::string& publicId) = 0; |
501 | |
502 virtual void Close() = 0; | |
503 | |
504 virtual void AddInstance(const std::string& instanceId, | |
4510
a3635a01a945
fix signature of virtual method
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4509
diff
changeset
|
505 uint64_t uncompressedSize) = 0; |
2632 | 506 }; |
507 | |
508 | |
509 class ArchiveJob::ArchiveIndex : public boost::noncopyable | |
510 { | |
511 private: | |
512 struct Instance | |
513 { | |
514 std::string id_; | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
515 uint64_t uncompressedSize_; |
2632 | 516 |
517 Instance(const std::string& id, | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
518 uint64_t uncompressedSize) : |
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
519 id_(id), |
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
520 uncompressedSize_(uncompressedSize) |
2632 | 521 { |
522 } | |
523 }; | |
524 | |
525 // A "NULL" value for ArchiveIndex indicates a non-expanded node | |
526 typedef std::map<std::string, ArchiveIndex*> Resources; | |
527 | |
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
|
528 ArchiveResourceType level_; |
2632 | 529 Resources resources_; // Only at patient/study/series level |
530 std::list<Instance> instances_; // Only at instance level | |
531 | |
532 | |
533 void AddResourceToExpand(ServerIndex& index, | |
534 const std::string& id) | |
535 { | |
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
|
536 if (level_ == ArchiveResourceType_Instance) |
2632 | 537 { |
538 FileInfo tmp; | |
4627
f7d5372b59b3
handling revisions of attachments
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4591
diff
changeset
|
539 int64_t revision; // ignored |
f7d5372b59b3
handling revisions of attachments
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4591
diff
changeset
|
540 if (index.LookupAttachment(tmp, revision, id, FileContentType_Dicom)) |
2632 | 541 { |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
542 instances_.push_back(Instance(id, tmp.GetUncompressedSize())); |
2632 | 543 } |
544 } | |
545 else | |
546 { | |
547 resources_[id] = NULL; | |
548 } | |
549 } | |
550 | |
551 | |
552 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
|
553 explicit ArchiveIndex(ArchiveResourceType level) : |
2632 | 554 level_(level) |
555 { | |
556 } | |
557 | |
558 ~ArchiveIndex() | |
559 { | |
560 for (Resources::iterator it = resources_.begin(); | |
561 it != resources_.end(); ++it) | |
562 { | |
563 delete it->second; | |
564 } | |
565 } | |
566 | |
567 | |
568 void Add(ServerIndex& index, | |
569 const ResourceIdentifiers& resource) | |
570 { | |
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
|
571 const std::string& id = resource.GetIdentifier(GetResourceIdType(level_)); |
2632 | 572 Resources::iterator previous = resources_.find(id); |
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 if (level_ == ArchiveResourceType_Instance) |
2632 | 575 { |
576 AddResourceToExpand(index, id); | |
577 } | |
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
|
578 else if (resource.GetLevel() == GetResourceLevel(level_)) |
2632 | 579 { |
580 // Mark this resource for further expansion | |
581 if (previous != resources_.end()) | |
582 { | |
583 delete previous->second; | |
584 } | |
585 | |
586 resources_[id] = NULL; | |
587 } | |
588 else if (previous == resources_.end()) | |
589 { | |
590 // 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
|
591 std::unique_ptr<ArchiveIndex> child(new ArchiveIndex(GetChildResourceType(level_))); |
2632 | 592 child->Add(index, resource); |
593 resources_[id] = child.release(); | |
594 } | |
595 else if (previous->second != NULL) | |
596 { | |
597 previous->second->Add(index, resource); | |
598 } | |
599 else | |
600 { | |
601 // Nothing to do: This item is marked for further expansion | |
602 } | |
603 } | |
604 | |
605 | |
606 void Expand(ServerIndex& index) | |
607 { | |
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
|
608 if (level_ == ArchiveResourceType_Instance) |
2632 | 609 { |
610 // Expanding an instance node makes no sense | |
611 return; | |
612 } | |
613 | |
614 for (Resources::iterator it = resources_.begin(); | |
615 it != resources_.end(); ++it) | |
616 { | |
617 if (it->second == NULL) | |
618 { | |
619 // This is resource is marked for expansion | |
620 std::list<std::string> children; | |
621 index.GetChildren(children, it->first); | |
622 | |
3712
2a170a8f1faf
replacing std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
623 std::unique_ptr<ArchiveIndex> child(new ArchiveIndex(GetChildResourceType(level_))); |
2632 | 624 |
625 for (std::list<std::string>::const_iterator | |
626 it2 = children.begin(); it2 != children.end(); ++it2) | |
627 { | |
628 child->AddResourceToExpand(index, *it2); | |
629 } | |
630 | |
631 it->second = child.release(); | |
632 } | |
633 | |
634 assert(it->second != NULL); | |
635 it->second->Expand(index); | |
636 } | |
637 } | |
638 | |
639 | |
640 void Apply(IArchiveVisitor& visitor) const | |
641 { | |
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
|
642 if (level_ == ArchiveResourceType_Instance) |
2632 | 643 { |
644 for (std::list<Instance>::const_iterator | |
645 it = instances_.begin(); it != instances_.end(); ++it) | |
646 { | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
647 visitor.AddInstance(it->id_, it->uncompressedSize_); |
2632 | 648 } |
649 } | |
650 else | |
651 { | |
652 for (Resources::const_iterator it = resources_.begin(); | |
653 it != resources_.end(); ++it) | |
654 { | |
655 assert(it->second != NULL); // There must have been a call to "Expand()" | |
656 visitor.Open(level_, it->first); | |
657 it->second->Apply(visitor); | |
658 visitor.Close(); | |
659 } | |
660 } | |
661 } | |
662 }; | |
663 | |
664 | |
665 | |
666 class ArchiveJob::ZipCommands : public boost::noncopyable | |
667 { | |
668 private: | |
669 enum Type | |
670 { | |
671 Type_OpenDirectory, | |
672 Type_CloseDirectory, | |
673 Type_WriteInstance | |
674 }; | |
675 | |
676 class Command : public boost::noncopyable | |
677 { | |
678 private: | |
679 Type type_; | |
680 std::string filename_; | |
681 std::string instanceId_; | |
682 | |
683 public: | |
684 explicit Command(Type type) : | |
685 type_(type) | |
686 { | |
687 assert(type_ == Type_CloseDirectory); | |
688 } | |
689 | |
690 Command(Type type, | |
691 const std::string& filename) : | |
692 type_(type), | |
693 filename_(filename) | |
694 { | |
695 assert(type_ == Type_OpenDirectory); | |
696 } | |
697 | |
698 Command(Type type, | |
699 const std::string& filename, | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
700 const std::string& instanceId) : |
2632 | 701 type_(type), |
702 filename_(filename), | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
703 instanceId_(instanceId) |
2632 | 704 { |
705 assert(type_ == Type_WriteInstance); | |
706 } | |
707 | |
708 void Apply(HierarchicalZipWriter& writer, | |
709 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
|
710 InstanceLoader& instanceLoader, |
2632 | 711 DicomDirWriter* dicomDir, |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
712 const std::string& dicomDirFolder, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
713 bool transcode, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
714 DicomTransferSyntax transferSyntax) const |
2632 | 715 { |
716 switch (type_) | |
717 { | |
718 case Type_OpenDirectory: | |
719 writer.OpenDirectory(filename_.c_str()); | |
720 break; | |
721 | |
722 case Type_CloseDirectory: | |
723 writer.CloseDirectory(); | |
724 break; | |
725 | |
726 case Type_WriteInstance: | |
727 { | |
728 std::string content; | |
729 | |
730 try | |
731 { | |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
732 instanceLoader.GetDicom(content, instanceId_); |
2632 | 733 } |
734 catch (OrthancException& e) | |
735 { | |
736 LOG(WARNING) << "An instance was removed after the job was issued: " << instanceId_; | |
737 return; | |
738 } | |
2636 | 739 |
2632 | 740 writer.OpenFile(filename_.c_str()); |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
741 |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
742 std::unique_ptr<ParsedDicomFile> parsed; |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
743 |
5109 | 744 writer.Write(content); |
745 | |
746 if (dicomDir != NULL) | |
2632 | 747 { |
5109 | 748 if (parsed.get() == NULL) |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
749 { |
5109 | 750 parsed.reset(new ParsedDicomFile(content)); |
751 } | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
752 |
5109 | 753 dicomDir->Add(dicomDirFolder, filename_, *parsed); |
2632 | 754 } |
755 | |
756 break; | |
757 } | |
758 | |
759 default: | |
760 throw OrthancException(ErrorCode_InternalError); | |
761 } | |
762 } | |
763 }; | |
764 | |
765 std::deque<Command*> commands_; | |
766 uint64_t uncompressedSize_; | |
767 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
|
768 InstanceLoader& instanceLoader_; |
2632 | 769 |
770 | |
771 void ApplyInternal(HierarchicalZipWriter& writer, | |
772 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
|
773 InstanceLoader& instanceLoader, |
2632 | 774 size_t index, |
775 DicomDirWriter* dicomDir, | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
776 const std::string& dicomDirFolder, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
777 bool transcode, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
778 DicomTransferSyntax transferSyntax) const |
2632 | 779 { |
780 if (index >= commands_.size()) | |
781 { | |
782 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
783 } | |
784 | |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
785 commands_[index]->Apply(writer, context, instanceLoader, dicomDir, dicomDirFolder, transcode, transferSyntax); |
2632 | 786 } |
787 | |
788 public: | |
4815 | 789 explicit ZipCommands(InstanceLoader& instanceLoader) : |
2632 | 790 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
|
791 instancesCount_(0), |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
792 instanceLoader_(instanceLoader) |
2632 | 793 { |
794 } | |
795 | |
796 ~ZipCommands() | |
797 { | |
798 for (std::deque<Command*>::iterator it = commands_.begin(); | |
799 it != commands_.end(); ++it) | |
800 { | |
801 assert(*it != NULL); | |
802 delete *it; | |
803 } | |
804 } | |
805 | |
806 size_t GetSize() const | |
807 { | |
808 return commands_.size(); | |
809 } | |
810 | |
811 unsigned int GetInstancesCount() const | |
812 { | |
813 return instancesCount_; | |
814 } | |
815 | |
816 uint64_t GetUncompressedSize() const | |
817 { | |
818 return uncompressedSize_; | |
819 } | |
820 | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
821 // "media" flavor (with DICOMDIR) |
2632 | 822 void Apply(HierarchicalZipWriter& writer, |
823 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
|
824 InstanceLoader& instanceLoader, |
2632 | 825 size_t index, |
826 DicomDirWriter& dicomDir, | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
827 const std::string& dicomDirFolder, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
828 bool transcode, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
829 DicomTransferSyntax transferSyntax) const |
2632 | 830 { |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
831 ApplyInternal(writer, context, instanceLoader, index, &dicomDir, dicomDirFolder, transcode, transferSyntax); |
2632 | 832 } |
833 | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
834 // "archive" flavor (without DICOMDIR) |
2632 | 835 void Apply(HierarchicalZipWriter& writer, |
836 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
|
837 InstanceLoader& instanceLoader, |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
838 size_t index, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
839 bool transcode, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
840 DicomTransferSyntax transferSyntax) const |
2632 | 841 { |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
842 ApplyInternal(writer, context, instanceLoader, index, NULL, "", transcode, transferSyntax); |
2632 | 843 } |
844 | |
845 void AddOpenDirectory(const std::string& filename) | |
846 { | |
847 commands_.push_back(new Command(Type_OpenDirectory, filename)); | |
848 } | |
849 | |
850 void AddCloseDirectory() | |
851 { | |
852 commands_.push_back(new Command(Type_CloseDirectory)); | |
853 } | |
854 | |
855 void AddWriteInstance(const std::string& filename, | |
856 const std::string& instanceId, | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
857 uint64_t uncompressedSize) |
2632 | 858 { |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
859 instanceLoader_.PrepareDicom(instanceId); |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
860 commands_.push_back(new Command(Type_WriteInstance, filename, instanceId)); |
2632 | 861 instancesCount_ ++; |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
862 uncompressedSize_ += uncompressedSize; |
2632 | 863 } |
864 | |
865 bool IsZip64() const | |
866 { | |
867 return IsZip64Required(GetUncompressedSize(), GetInstancesCount()); | |
868 } | |
869 }; | |
870 | |
871 | |
872 | |
873 class ArchiveJob::ArchiveIndexVisitor : public IArchiveVisitor | |
874 { | |
875 private: | |
876 ZipCommands& commands_; | |
877 ServerContext& context_; | |
878 char instanceFormat_[24]; | |
879 unsigned int counter_; | |
880 | |
881 static std::string GetTag(const DicomMap& tags, | |
882 const DicomTag& tag) | |
883 { | |
884 const DicomValue* v = tags.TestAndGetValue(tag); | |
885 if (v != NULL && | |
886 !v->IsBinary() && | |
887 !v->IsNull()) | |
888 { | |
889 return v->GetContent(); | |
890 } | |
891 else | |
892 { | |
893 return ""; | |
894 } | |
895 } | |
896 | |
897 public: | |
898 ArchiveIndexVisitor(ZipCommands& commands, | |
899 ServerContext& context) : | |
900 commands_(commands), | |
901 context_(context), | |
902 counter_(0) | |
903 { | |
904 if (commands.GetSize() != 0) | |
905 { | |
906 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
907 } | |
908 | |
909 snprintf(instanceFormat_, sizeof(instanceFormat_) - 1, "%%08d.dcm"); | |
910 } | |
911 | |
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
|
912 virtual void Open(ArchiveResourceType level, |
4205 | 913 const std::string& publicId) ORTHANC_OVERRIDE |
2632 | 914 { |
915 std::string path; | |
916 | |
917 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
|
918 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
|
919 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
|
920 |
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 if (context_.GetIndex().GetMainDicomTags(tags, publicId, resourceIdLevel, interestLevel)) |
2632 | 922 { |
923 switch (level) | |
924 { | |
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
|
925 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
|
926 case ArchiveResourceType_PatientInfoFromStudy: |
2632 | 927 path = GetTag(tags, DICOM_TAG_PATIENT_ID) + " " + GetTag(tags, DICOM_TAG_PATIENT_NAME); |
928 break; | |
929 | |
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
|
930 case ArchiveResourceType_Study: |
2632 | 931 path = GetTag(tags, DICOM_TAG_ACCESSION_NUMBER) + " " + GetTag(tags, DICOM_TAG_STUDY_DESCRIPTION); |
932 break; | |
933 | |
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
|
934 case ArchiveResourceType_Series: |
2632 | 935 { |
936 std::string modality = GetTag(tags, DICOM_TAG_MODALITY); | |
937 path = modality + " " + GetTag(tags, DICOM_TAG_SERIES_DESCRIPTION); | |
938 | |
939 if (modality.size() == 0) | |
940 { | |
941 snprintf(instanceFormat_, sizeof(instanceFormat_) - 1, "%%08d.dcm"); | |
942 } | |
943 else if (modality.size() == 1) | |
944 { | |
945 snprintf(instanceFormat_, sizeof(instanceFormat_) - 1, "%c%%07d.dcm", | |
946 toupper(modality[0])); | |
947 } | |
948 else if (modality.size() >= 2) | |
949 { | |
950 snprintf(instanceFormat_, sizeof(instanceFormat_) - 1, "%c%c%%06d.dcm", | |
951 toupper(modality[0]), toupper(modality[1])); | |
952 } | |
953 | |
954 counter_ = 0; | |
955 | |
956 break; | |
957 } | |
958 | |
959 default: | |
960 throw OrthancException(ErrorCode_InternalError); | |
961 } | |
962 } | |
963 | |
964 path = Toolbox::StripSpaces(Toolbox::ConvertToAscii(path)); | |
965 | |
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
|
966 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
|
967 || (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 | 968 { |
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
|
969 path = std::string("Unknown ") + EnumerationToString(GetResourceLevel(level)); |
2632 | 970 } |
971 | |
972 commands_.AddOpenDirectory(path.c_str()); | |
973 } | |
974 | |
4205 | 975 virtual void Close() ORTHANC_OVERRIDE |
2632 | 976 { |
977 commands_.AddCloseDirectory(); | |
978 } | |
979 | |
980 virtual void AddInstance(const std::string& instanceId, | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
981 uint64_t uncompressedSize) ORTHANC_OVERRIDE |
2632 | 982 { |
983 char filename[24]; | |
984 snprintf(filename, sizeof(filename) - 1, instanceFormat_, counter_); | |
985 counter_ ++; | |
986 | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
987 commands_.AddWriteInstance(filename, instanceId, uncompressedSize); |
2632 | 988 } |
989 }; | |
990 | |
991 | |
992 class ArchiveJob::MediaIndexVisitor : public IArchiveVisitor | |
993 { | |
994 private: | |
995 ZipCommands& commands_; | |
996 unsigned int counter_; | |
997 | |
998 public: | |
4591
ff8170d17d90
moving all accesses to databases from IDatabaseWrapper to ITransaction
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4588
diff
changeset
|
999 explicit MediaIndexVisitor(ZipCommands& commands) : |
2632 | 1000 commands_(commands), |
1001 counter_(0) | |
1002 { | |
1003 } | |
1004 | |
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
|
1005 virtual void Open(ArchiveResourceType level, |
4205 | 1006 const std::string& publicId) ORTHANC_OVERRIDE |
2632 | 1007 { |
1008 } | |
1009 | |
4205 | 1010 virtual void Close() ORTHANC_OVERRIDE |
2632 | 1011 { |
1012 } | |
1013 | |
1014 virtual void AddInstance(const std::string& instanceId, | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
1015 uint64_t uncompressedSize) ORTHANC_OVERRIDE |
2632 | 1016 { |
1017 // "DICOM restricts the filenames on DICOM media to 8 | |
1018 // characters (some systems wrongly use 8.3, but this does not | |
1019 // conform to the standard)." | |
1020 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
|
1021 commands_.AddWriteInstance(filename, instanceId, uncompressedSize); |
2632 | 1022 |
1023 counter_ ++; | |
1024 } | |
1025 }; | |
1026 | |
1027 | |
1028 class ArchiveJob::ZipWriterIterator : public boost::noncopyable | |
1029 { | |
1030 private: | |
3712
2a170a8f1faf
replacing std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
1031 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
|
1032 InstanceLoader& instanceLoader_; |
3712
2a170a8f1faf
replacing std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
1033 ZipCommands commands_; |
2a170a8f1faf
replacing std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
1034 std::unique_ptr<HierarchicalZipWriter> zip_; |
2a170a8f1faf
replacing std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
1035 std::unique_ptr<DicomDirWriter> dicomDir_; |
2a170a8f1faf
replacing std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
1036 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
|
1037 bool isStream_; |
2632 | 1038 |
1039 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
|
1040 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
|
1041 InstanceLoader& instanceLoader, |
2632 | 1042 ArchiveIndex& archive, |
1043 bool isMedia, | |
1044 bool enableExtendedSopClass) : | |
1045 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
|
1046 instanceLoader_(instanceLoader), |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1047 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
|
1048 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
|
1049 isStream_(false) |
2632 | 1050 { |
1051 if (isMedia) | |
1052 { | |
4588 | 1053 MediaIndexVisitor visitor(commands_); |
2632 | 1054 archive.Expand(context.GetIndex()); |
1055 | |
1056 commands_.AddOpenDirectory(MEDIA_IMAGES_FOLDER); | |
1057 archive.Apply(visitor); | |
1058 commands_.AddCloseDirectory(); | |
1059 | |
1060 dicomDir_.reset(new DicomDirWriter); | |
1061 dicomDir_->EnableExtendedSopClass(enableExtendedSopClass); | |
1062 } | |
1063 else | |
1064 { | |
1065 ArchiveIndexVisitor visitor(commands_, context); | |
1066 archive.Expand(context.GetIndex()); | |
1067 archive.Apply(visitor); | |
1068 } | |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1069 } |
2632 | 1070 |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1071 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
|
1072 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1073 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
|
1074 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1075 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
|
1076 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
|
1077 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
|
1078 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1079 else |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1080 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1081 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
|
1082 } |
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 |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1085 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
|
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 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
|
1088 |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1089 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
|
1090 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1091 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
|
1092 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
|
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 else |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1095 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1096 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
|
1097 } |
2632 | 1098 } |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1099 |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1100 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
|
1101 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1102 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
|
1103 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1104 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
|
1105 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1106 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
|
1107 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1108 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
|
1109 } |
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 |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1112 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
|
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 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
|
1115 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1116 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
|
1117 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1118 else |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1119 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1120 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
|
1121 } |
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 |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1124 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
|
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 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
|
1127 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1128 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
|
1129 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1130 else |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1131 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1132 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
|
1133 } |
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 |
2632 | 1136 size_t GetStepsCount() const |
1137 { | |
1138 return commands_.GetSize() + 1; | |
1139 } | |
1140 | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1141 void RunStep(size_t index, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1142 bool transcode, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1143 DicomTransferSyntax transferSyntax) |
2632 | 1144 { |
1145 if (index > commands_.GetSize()) | |
1146 { | |
1147 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
1148 } | |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1149 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
|
1150 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1151 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
|
1152 } |
2632 | 1153 else if (index == commands_.GetSize()) |
1154 { | |
1155 // Last step: Add the DICOMDIR | |
1156 if (isMedia_) | |
1157 { | |
1158 assert(dicomDir_.get() != NULL); | |
1159 std::string s; | |
1160 dicomDir_->Encode(s); | |
1161 | |
1162 zip_->OpenFile("DICOMDIR"); | |
1163 zip_->Write(s); | |
1164 } | |
1165 } | |
1166 else | |
1167 { | |
1168 if (isMedia_) | |
1169 { | |
1170 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
|
1171 commands_.Apply(*zip_, context_, instanceLoader_, index, *dicomDir_, |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1172 MEDIA_IMAGES_FOLDER, transcode, transferSyntax); |
2632 | 1173 } |
1174 else | |
1175 { | |
1176 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
|
1177 commands_.Apply(*zip_, context_, instanceLoader_, index, transcode, transferSyntax); |
2632 | 1178 } |
1179 } | |
1180 } | |
1181 | |
1182 unsigned int GetInstancesCount() const | |
1183 { | |
1184 return commands_.GetInstancesCount(); | |
1185 } | |
1186 | |
1187 uint64_t GetUncompressedSize() const | |
1188 { | |
1189 return commands_.GetUncompressedSize(); | |
1190 } | |
1191 }; | |
1192 | |
1193 | |
2966 | 1194 ArchiveJob::ArchiveJob(ServerContext& context, |
2632 | 1195 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
|
1196 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
|
1197 ResourceType jobLevel) : |
2632 | 1198 context_(context), |
5403
05cb668c5f3f
fix to keep backward behaviour when exporting a series archive
Alain Mazy <am@osimis.io>
parents:
5401
diff
changeset
|
1199 archive_(new ArchiveIndex(GetArchiveResourceType(jobLevel))), // get patient Info from this level |
2632 | 1200 isMedia_(isMedia), |
1201 enableExtendedSopClass_(enableExtendedSopClass), | |
1202 currentStep_(0), | |
1203 instancesCount_(0), | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1204 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
|
1205 archiveSize_(0), |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1206 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
|
1207 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
|
1208 loaderThreads_(0) |
2632 | 1209 { |
2966 | 1210 } |
1211 | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1212 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1213 ArchiveJob::~ArchiveJob() |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1214 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1215 if (!mediaArchiveId_.empty()) |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1216 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1217 context_.GetMediaArchive().Remove(mediaArchiveId_); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1218 } |
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 |
2966 | 1221 |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1222 void ArchiveJob::AcquireSynchronousTarget(ZipWriter::IOutputStream* target) |
2966 | 1223 { |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1224 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
|
1225 |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1226 if (target == NULL) |
2632 | 1227 { |
1228 throw OrthancException(ErrorCode_NullPointer); | |
1229 } | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1230 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
|
1231 synchronousTarget_.get() != NULL || |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1232 asynchronousTarget_.get() != NULL) |
2966 | 1233 { |
1234 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1235 } | |
1236 else | |
1237 { | |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1238 synchronousTarget_.reset(protection.release()); |
2966 | 1239 } |
2632 | 1240 } |
1241 | |
1242 | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1243 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
|
1244 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1245 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
|
1246 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1247 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1248 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1249 else |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1250 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1251 description_ = description; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1252 } |
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 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1255 |
5169
8b74aa4f3515
enforce the existence of the patient/study/instance while creating its archive
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5109
diff
changeset
|
1256 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
|
1257 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
|
1258 ResourceType expectedType) |
2632 | 1259 { |
1260 if (writer_.get() != NULL) // Already started | |
1261 { | |
1262 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1263 } | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1264 else |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1265 { |
5169
8b74aa4f3515
enforce the existence of the patient/study/instance while creating its archive
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5109
diff
changeset
|
1266 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
|
1267 { |
8b74aa4f3515
enforce the existence of the patient/study/instance while creating its archive
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5109
diff
changeset
|
1268 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
|
1269 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
|
1270 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
|
1271 { |
8b74aa4f3515
enforce the existence of the patient/study/instance while creating its archive
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5109
diff
changeset
|
1272 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
|
1273 "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
|
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 } |
8b74aa4f3515
enforce the existence of the patient/study/instance while creating its archive
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5109
diff
changeset
|
1276 |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1277 ResourceIdentifiers resource(context_.GetIndex(), publicId); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1278 archive_->Add(context_.GetIndex(), resource); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1279 } |
2632 | 1280 } |
1281 | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1282 |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1283 void ArchiveJob::SetTranscode(DicomTransferSyntax transferSyntax) |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1284 { |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1285 if (writer_.get() != NULL) // Already started |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1286 { |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1287 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1288 } |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1289 else |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1290 { |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1291 transcode_ = true; |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1292 transferSyntax_ = transferSyntax; |
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 } |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1295 |
2632 | 1296 |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1297 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
|
1298 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1299 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
|
1300 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1301 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
|
1302 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1303 else |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1304 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1305 loaderThreads_ = loaderThreads; |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1306 } |
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 |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1309 |
2812
ea7aea6f6a95
improved naming of methods in IJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2730
diff
changeset
|
1310 void ArchiveJob::Reset() |
2632 | 1311 { |
2955 | 1312 throw OrthancException(ErrorCode_BadSequenceOfCalls, |
1313 "Cannot resubmit the creation of an archive"); | |
2632 | 1314 } |
1315 | |
1316 | |
1317 void ArchiveJob::Start() | |
1318 { | |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1319 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
|
1320 { |
4902
df86d2505df8
Orthanc 1.9.8 is now known as Orthanc 1.10.0
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4892
diff
changeset
|
1321 // 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
|
1322 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
|
1323 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1324 else |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1325 { |
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
|
1326 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
|
1327 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1328 |
2632 | 1329 if (writer_.get() != NULL) |
1330 { | |
1331 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1332 } | |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1333 else |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1334 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1335 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
|
1336 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1337 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
|
1338 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1339 // 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
|
1340 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
|
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 else |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1343 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1344 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
|
1345 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
|
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 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
|
1348 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
|
1349 |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1350 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
|
1351 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
|
1352 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1353 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1354 else |
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 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
|
1357 |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1358 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
|
1359 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
|
1360 } |
2632 | 1361 |
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 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
|
1363 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
|
1364 } |
2632 | 1365 } |
1366 | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1367 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1368 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1369 namespace |
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 class DynamicTemporaryFile : public IDynamicObject |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1372 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1373 private: |
3712
2a170a8f1faf
replacing std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
1374 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
|
1375 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1376 public: |
4205 | 1377 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
|
1378 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1379 if (f == NULL) |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1380 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1381 throw OrthancException(ErrorCode_NullPointer); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1382 } |
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 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1385 const TemporaryFile& GetFile() const |
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 assert(file_.get() != NULL); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1388 return *file_; |
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 }; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1391 } |
2632 | 1392 |
2976
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 void ArchiveJob::FinalizeTarget() |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1395 { |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1396 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
|
1397 { |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1398 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
|
1399 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
|
1400 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
|
1401 } |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1402 |
4797
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1403 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
|
1404 { |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1405 instanceLoader_->Clear(); |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1406 } |
4e765c18ace7
enable using multiple threads to load instances when generating zip archive/media
Alain Mazy <am@osimis.io>
parents:
4674
diff
changeset
|
1407 |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1408 if (asynchronousTarget_.get() != NULL) |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1409 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1410 // 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
|
1411 mediaArchiveId_ = context_.GetMediaArchive().Add( |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1412 new DynamicTemporaryFile(asynchronousTarget_.release())); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1413 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1414 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1415 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1416 |
3658
2d90dd30858c
providing job ID to the IJob::Step() methods
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
1417 JobStepResult ArchiveJob::Step(const std::string& jobId) |
2632 | 1418 { |
1419 assert(writer_.get() != NULL); | |
1420 | |
1421 if (writer_->GetStepsCount() == 0) | |
1422 { | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1423 FinalizeTarget(); |
2632 | 1424 return JobStepResult::Success(); |
1425 } | |
1426 else | |
1427 { | |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1428 try |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1429 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1430 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
|
1431 } |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1432 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
|
1433 { |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1434 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
|
1435 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
|
1436 throw; |
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1437 } |
2632 | 1438 |
1439 currentStep_ ++; | |
1440 | |
1441 if (currentStep_ == writer_->GetStepsCount()) | |
1442 { | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1443 FinalizeTarget(); |
2632 | 1444 return JobStepResult::Success(); |
1445 } | |
1446 else | |
1447 { | |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1448 archiveSize_ = writer_->GetArchiveSize(); |
2632 | 1449 return JobStepResult::Continue(); |
1450 } | |
1451 } | |
1452 } | |
1453 | |
1454 | |
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
|
1455 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
|
1456 { |
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
|
1457 /** |
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 * 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
|
1459 * 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
|
1460 * 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
|
1461 **/ |
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 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
|
1463 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
|
1464 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
|
1465 { |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1466 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
|
1467 |
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
|
1468 // 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
|
1469 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
|
1470 |
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 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
|
1472 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
|
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 } |
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 |
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 |
2632 | 1477 float ArchiveJob::GetProgress() |
1478 { | |
1479 if (writer_.get() == NULL || | |
1480 writer_->GetStepsCount() == 0) | |
1481 { | |
1482 return 1; | |
1483 } | |
1484 else | |
1485 { | |
1486 return (static_cast<float>(currentStep_) / | |
1487 static_cast<float>(writer_->GetStepsCount() - 1)); | |
1488 } | |
1489 } | |
1490 | |
1491 | |
1492 void ArchiveJob::GetJobType(std::string& target) | |
1493 { | |
1494 if (isMedia_) | |
1495 { | |
1496 target = "Media"; | |
1497 } | |
1498 else | |
1499 { | |
1500 target = "Archive"; | |
1501 } | |
1502 } | |
1503 | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1504 |
2632 | 1505 void ArchiveJob::GetPublicContent(Json::Value& value) |
1506 { | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1507 value = Json::objectValue; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1508 value[KEY_DESCRIPTION] = description_; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1509 value[KEY_INSTANCES_COUNT] = instancesCount_; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1510 value[KEY_UNCOMPRESSED_SIZE_MB] = |
2643 | 1511 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
|
1512 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
|
1513 static_cast<unsigned int>(archiveSize_ / MEGA_BYTES); |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1514 |
4674
cdab941fe17d
ZIP archive/media generated in synchronous mode are now streamed by default
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4641
diff
changeset
|
1515 // 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
|
1516 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
|
1517 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
|
1518 |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1519 if (transcode_) |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1520 { |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1521 value[KEY_TRANSCODE] = GetTransferSyntaxUid(transferSyntax_); |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1522 } |
2632 | 1523 } |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1524 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1525 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1526 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
|
1527 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
|
1528 std::string& filename, |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1529 const std::string& key) |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1530 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1531 if (key == "archive" && |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1532 !mediaArchiveId_.empty()) |
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 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
|
1535 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1536 if (accessor.IsValid()) |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1537 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1538 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
|
1539 f.GetFile().Read(output); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1540 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
|
1541 filename = "archive.zip"; |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1542 return true; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1543 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1544 else |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1545 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1546 return false; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1547 } |
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 else |
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 return false; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1552 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1553 } |
5310
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1554 |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1555 bool ArchiveJob::DeleteOutput(const std::string& key) |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1556 { |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1557 if (key == "archive" && |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1558 !mediaArchiveId_.empty()) |
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 SharedArchive::Accessor accessor(context_.GetMediaArchive(), mediaArchiveId_); |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1561 |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1562 if (accessor.IsValid()) |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1563 { |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1564 context_.GetMediaArchive().Remove(mediaArchiveId_); |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1565 return true; |
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 else |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1568 { |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1569 return false; |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1570 } |
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 else |
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 return false; |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1575 } |
b5c502bcaf99
added a route to DELETE /jobs/../archive
Alain Mazy <am@osimis.io>
parents:
5302
diff
changeset
|
1576 } |
5364
b5f2122a1334
Added a route to delete completed jobs from history: DELETE /jobs/{id}
Alain Mazy <am@osimis.io>
parents:
5310
diff
changeset
|
1577 |
b5f2122a1334
Added a route to delete completed jobs from history: DELETE /jobs/{id}
Alain Mazy <am@osimis.io>
parents:
5310
diff
changeset
|
1578 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
|
1579 { |
b5f2122a1334
Added a route to delete completed jobs from history: DELETE /jobs/{id}
Alain Mazy <am@osimis.io>
parents:
5310
diff
changeset
|
1580 DeleteOutput("archive"); |
b5f2122a1334
Added a route to delete completed jobs from history: DELETE /jobs/{id}
Alain Mazy <am@osimis.io>
parents:
5310
diff
changeset
|
1581 } |
2632 | 1582 } |