0
|
1 /**
|
|
2 * Orthanc - A Lightweight, RESTful DICOM Store
|
|
3 * Copyright (C) 2012-2015 Sebastien Jodogne, Medical Physics
|
|
4 * Department, University Hospital of Liege, Belgium
|
|
5 *
|
|
6 * This program is free software: you can redistribute it and/or
|
|
7 * modify it under the terms of the GNU Affero General Public License
|
|
8 * as published by the Free Software Foundation, either version 3 of
|
|
9 * the License, or (at your option) any later version.
|
|
10 *
|
|
11 * This program is distributed in the hope that it will be useful, but
|
|
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
14 * Affero General Public License for more details.
|
|
15 *
|
|
16 * You should have received a copy of the GNU Affero General Public License
|
|
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
18 **/
|
|
19
|
|
20
|
|
21 #include "ViewerToolbox.h"
|
|
22
|
|
23 #include "../Orthanc/OrthancException.h"
|
|
24 #include "../Orthanc/Toolbox.h"
|
|
25
|
|
26 #include <json/reader.h>
|
|
27 #include <zlib.h>
|
|
28 #include <stdexcept>
|
|
29 #include <boost/lexical_cast.hpp>
|
|
30 #include <fstream>
|
|
31 #include <sys/stat.h>
|
|
32
|
|
33 namespace OrthancPlugins
|
|
34 {
|
|
35 bool GetStringFromOrthanc(std::string& content,
|
|
36 OrthancPluginContext* context,
|
|
37 const std::string& uri)
|
|
38 {
|
|
39 OrthancPluginMemoryBuffer answer;
|
|
40
|
|
41 if (OrthancPluginRestApiGet(context, &answer, uri.c_str()))
|
|
42 {
|
|
43 return false;
|
|
44 }
|
|
45
|
|
46 if (answer.size)
|
|
47 {
|
|
48 try
|
|
49 {
|
|
50 content.assign(reinterpret_cast<const char*>(answer.data), answer.size);
|
|
51 }
|
|
52 catch (std::bad_alloc&)
|
|
53 {
|
|
54 OrthancPluginFreeMemoryBuffer(context, &answer);
|
|
55 throw Orthanc::OrthancException("Not enough memory");
|
|
56 }
|
|
57 }
|
|
58
|
|
59 OrthancPluginFreeMemoryBuffer(context, &answer);
|
|
60 return true;
|
|
61 }
|
|
62
|
|
63
|
|
64 bool GetJsonFromOrthanc(Json::Value& json,
|
|
65 OrthancPluginContext* context,
|
|
66 const std::string& uri)
|
|
67 {
|
|
68 OrthancPluginMemoryBuffer answer;
|
|
69
|
|
70 if (OrthancPluginRestApiGet(context, &answer, uri.c_str()))
|
|
71 {
|
|
72 return false;
|
|
73 }
|
|
74
|
|
75 if (answer.size)
|
|
76 {
|
|
77 try
|
|
78 {
|
|
79 const char* data = reinterpret_cast<const char*>(answer.data);
|
|
80 Json::Reader reader;
|
|
81 if (!reader.parse(data, data + answer.size, json,
|
|
82 false /* don't collect comments */))
|
|
83 {
|
|
84 return false;
|
|
85 }
|
|
86 }
|
|
87 catch (std::runtime_error&)
|
|
88 {
|
|
89 OrthancPluginFreeMemoryBuffer(context, &answer);
|
|
90 return false;
|
|
91 }
|
|
92 }
|
|
93
|
|
94 OrthancPluginFreeMemoryBuffer(context, &answer);
|
|
95 return true;
|
|
96 }
|
|
97
|
|
98
|
|
99
|
|
100
|
|
101 bool TokenizeVector(std::vector<float>& result,
|
|
102 const std::string& value,
|
|
103 unsigned int expectedSize)
|
|
104 {
|
|
105 std::vector<std::string> tokens;
|
|
106 Orthanc::Toolbox::TokenizeString(tokens, value, '\\');
|
|
107
|
|
108 if (tokens.size() != expectedSize)
|
|
109 {
|
|
110 return false;
|
|
111 }
|
|
112
|
|
113 result.resize(tokens.size());
|
|
114
|
|
115 for (size_t i = 0; i < tokens.size(); i++)
|
|
116 {
|
|
117 try
|
|
118 {
|
|
119 result[i] = boost::lexical_cast<float>(tokens[i]);
|
|
120 }
|
|
121 catch (boost::bad_lexical_cast&)
|
|
122 {
|
|
123 return false;
|
|
124 }
|
|
125 }
|
|
126
|
|
127 return true;
|
|
128 }
|
|
129
|
|
130
|
|
131 bool CompressUsingDeflate(std::string& compressed,
|
|
132 const void* uncompressed,
|
|
133 size_t uncompressedSize,
|
|
134 uint8_t compressionLevel)
|
|
135 {
|
|
136 if (uncompressedSize == 0)
|
|
137 {
|
|
138 compressed.clear();
|
|
139 return true;
|
|
140 }
|
|
141
|
|
142 uLongf compressedSize = compressBound(uncompressedSize);
|
|
143 compressed.resize(compressedSize);
|
|
144
|
|
145 int error = compress2
|
|
146 (reinterpret_cast<uint8_t*>(&compressed[0]),
|
|
147 &compressedSize,
|
|
148 const_cast<Bytef *>(static_cast<const Bytef *>(uncompressed)),
|
|
149 uncompressedSize,
|
|
150 compressionLevel);
|
|
151
|
|
152 if (error == Z_OK)
|
|
153 {
|
|
154 compressed.resize(compressedSize);
|
|
155 return true;
|
|
156 }
|
|
157 else
|
|
158 {
|
|
159 compressed.clear();
|
|
160 return false;
|
|
161 }
|
|
162 }
|
|
163
|
|
164
|
|
165
|
|
166 const char* GetMimeType(const std::string& path)
|
|
167 {
|
|
168 size_t dot = path.find_last_of('.');
|
|
169
|
|
170 std::string extension = (dot == std::string::npos) ? "" : path.substr(dot);
|
|
171 std::transform(extension.begin(), extension.end(), extension.begin(), tolower);
|
|
172
|
|
173 if (extension == ".html")
|
|
174 {
|
|
175 return "text/html";
|
|
176 }
|
|
177 else if (extension == ".css")
|
|
178 {
|
|
179 return "text/css";
|
|
180 }
|
|
181 else if (extension == ".js")
|
|
182 {
|
|
183 return "application/javascript";
|
|
184 }
|
|
185 else if (extension == ".gif")
|
|
186 {
|
|
187 return "image/gif";
|
|
188 }
|
|
189 else if (extension == ".svg")
|
|
190 {
|
|
191 return "image/svg+xml";
|
|
192 }
|
|
193 else if (extension == ".json")
|
|
194 {
|
|
195 return "application/json";
|
|
196 }
|
|
197 else if (extension == ".xml")
|
|
198 {
|
|
199 return "application/xml";
|
|
200 }
|
|
201 else if (extension == ".png")
|
|
202 {
|
|
203 return "image/png";
|
|
204 }
|
|
205 else if (extension == ".jpg" || extension == ".jpeg")
|
|
206 {
|
|
207 return "image/jpeg";
|
|
208 }
|
|
209 else
|
|
210 {
|
|
211 return "application/octet-stream";
|
|
212 }
|
|
213 }
|
|
214
|
|
215
|
|
216 bool ReadConfiguration(Json::Value& configuration,
|
|
217 OrthancPluginContext* context)
|
|
218 {
|
|
219 std::string path;
|
|
220
|
|
221 {
|
|
222 char* pathTmp = OrthancPluginGetConfigurationPath(context);
|
|
223 if (pathTmp == NULL)
|
|
224 {
|
|
225 OrthancPluginLogError(context, "No configuration file is provided");
|
|
226 return false;
|
|
227 }
|
|
228
|
|
229 path = std::string(pathTmp);
|
|
230
|
|
231 OrthancPluginFreeString(context, pathTmp);
|
|
232 }
|
|
233
|
|
234 std::ifstream f(path.c_str());
|
|
235
|
|
236 Json::Reader reader;
|
|
237 if (!reader.parse(f, configuration) ||
|
|
238 configuration.type() != Json::objectValue)
|
|
239 {
|
|
240 std::string s = "Unable to parse the configuration file: " + std::string(path);
|
|
241 OrthancPluginLogError(context, s.c_str());
|
|
242 return false;
|
|
243 }
|
|
244
|
|
245 return true;
|
|
246 }
|
|
247
|
|
248
|
|
249 std::string GetStringValue(const Json::Value& configuration,
|
|
250 const std::string& key,
|
|
251 const std::string& defaultValue)
|
|
252 {
|
|
253 if (configuration.type() != Json::objectValue ||
|
|
254 !configuration.isMember(key) ||
|
|
255 configuration[key].type() != Json::stringValue)
|
|
256 {
|
|
257 return defaultValue;
|
|
258 }
|
|
259 else
|
|
260 {
|
|
261 return configuration[key].asString();
|
|
262 }
|
|
263 }
|
|
264
|
|
265
|
|
266 int GetIntegerValue(const Json::Value& configuration,
|
|
267 const std::string& key,
|
|
268 int defaultValue)
|
|
269 {
|
|
270 if (configuration.type() != Json::objectValue ||
|
|
271 !configuration.isMember(key) ||
|
|
272 configuration[key].type() != Json::intValue)
|
|
273 {
|
|
274 return defaultValue;
|
|
275 }
|
|
276 else
|
|
277 {
|
|
278 return configuration[key].asInt();
|
|
279 }
|
|
280 }
|
|
281
|
|
282
|
|
283 bool ReadFile(std::string& content,
|
|
284 const std::string& path)
|
|
285 {
|
|
286 struct stat s;
|
|
287 if (stat(path.c_str(), &s) != 0 ||
|
|
288 !(s.st_mode & S_IFREG))
|
|
289 {
|
|
290 // Either the path does not exist, or it is not a regular file
|
|
291 return false;
|
|
292 }
|
|
293
|
|
294 FILE* fp = fopen(path.c_str(), "rb");
|
|
295 if (fp == NULL)
|
|
296 {
|
|
297 return false;
|
|
298 }
|
|
299
|
|
300 long size;
|
|
301
|
|
302 if (fseek(fp, 0, SEEK_END) == -1 ||
|
|
303 (size = ftell(fp)) < 0)
|
|
304 {
|
|
305 fclose(fp);
|
|
306 return false;
|
|
307 }
|
|
308
|
|
309 content.resize(size);
|
|
310
|
|
311 if (fseek(fp, 0, SEEK_SET) == -1)
|
|
312 {
|
|
313 fclose(fp);
|
|
314 return false;
|
|
315 }
|
|
316
|
|
317 bool ok = true;
|
|
318
|
|
319 if (size > 0 &&
|
|
320 fread(&content[0], size, 1, fp) != 1)
|
|
321 {
|
|
322 ok = false;
|
|
323 }
|
|
324
|
|
325 fclose(fp);
|
|
326
|
|
327 return ok;
|
|
328 }
|
|
329 }
|