Mercurial > hg > orthanc
comparison Plugins/Engine/OrthancPlugins.cpp @ 1132:f739d3f6cfcf
rename
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 09 Sep 2014 10:43:23 +0200 |
parents | Plugins/Engine/PluginsHttpHandler.cpp@da56a7916e8a |
children | 382e162c074c |
comparison
equal
deleted
inserted
replaced
1131:ac6bd50a8c83 | 1132:f739d3f6cfcf |
---|---|
1 /** | |
2 * Orthanc - A Lightweight, RESTful DICOM Store | |
3 * Copyright (C) 2012-2014 Medical Physics Department, CHU of Liege, | |
4 * Belgium | |
5 * | |
6 * This program is free software: you can redistribute it and/or | |
7 * modify it under the terms of the GNU General Public License as | |
8 * published by the Free Software Foundation, either version 3 of the | |
9 * License, or (at your option) any later version. | |
10 * | |
11 * In addition, as a special exception, the copyright holders of this | |
12 * program give permission to link the code of its release with the | |
13 * OpenSSL project's "OpenSSL" library (or with modified versions of it | |
14 * that use the same license as the "OpenSSL" library), and distribute | |
15 * the linked executables. You must obey the GNU General Public License | |
16 * in all respects for all of the code used other than "OpenSSL". If you | |
17 * modify file(s) with this exception, you may extend this exception to | |
18 * your version of the file(s), but you are not obligated to do so. If | |
19 * you do not wish to do so, delete this exception statement from your | |
20 * version. If you delete this exception statement from all source files | |
21 * in the program, then also delete it here. | |
22 * | |
23 * This program is distributed in the hope that it will be useful, but | |
24 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
26 * General Public License for more details. | |
27 * | |
28 * You should have received a copy of the GNU General Public License | |
29 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
30 **/ | |
31 | |
32 | |
33 #include "PluginsHttpHandler.h" | |
34 | |
35 #include "../../Core/ChunkedBuffer.h" | |
36 #include "../../Core/OrthancException.h" | |
37 #include "../../Core/Toolbox.h" | |
38 #include "../../Core/HttpServer/HttpOutput.h" | |
39 #include "../../Core/ImageFormats/PngWriter.h" | |
40 #include "../../OrthancServer/ServerToolbox.h" | |
41 | |
42 #include <boost/regex.hpp> | |
43 #include <glog/logging.h> | |
44 | |
45 namespace Orthanc | |
46 { | |
47 namespace | |
48 { | |
49 // Anonymous namespace to avoid clashes between compilation modules | |
50 class StringHttpOutput : public IHttpOutputStream | |
51 { | |
52 private: | |
53 ChunkedBuffer buffer_; | |
54 | |
55 public: | |
56 void GetOutput(std::string& output) | |
57 { | |
58 buffer_.Flatten(output); | |
59 } | |
60 | |
61 virtual void OnHttpStatusReceived(HttpStatus status) | |
62 { | |
63 if (status != HttpStatus_200_Ok) | |
64 { | |
65 throw OrthancException(ErrorCode_BadRequest); | |
66 } | |
67 } | |
68 | |
69 virtual void Send(bool isHeader, const void* buffer, size_t length) | |
70 { | |
71 if (!isHeader) | |
72 { | |
73 buffer_.AddChunk(reinterpret_cast<const char*>(buffer), length); | |
74 } | |
75 } | |
76 }; | |
77 } | |
78 | |
79 | |
80 | |
81 struct PluginsHttpHandler::PImpl | |
82 { | |
83 typedef std::pair<boost::regex*, OrthancPluginRestCallback> RestCallback; | |
84 typedef std::list<RestCallback> RestCallbacks; | |
85 typedef std::list<OrthancPluginOnStoredInstanceCallback> OnStoredCallbacks; | |
86 | |
87 ServerContext& context_; | |
88 RestCallbacks restCallbacks_; | |
89 OrthancRestApi* restApi_; | |
90 OnStoredCallbacks onStoredCallbacks_; | |
91 | |
92 PImpl(ServerContext& context) : context_(context), restApi_(NULL) | |
93 { | |
94 } | |
95 }; | |
96 | |
97 | |
98 static char* CopyString(const std::string& str) | |
99 { | |
100 char *result = reinterpret_cast<char*>(malloc(str.size() + 1)); | |
101 if (result == NULL) | |
102 { | |
103 throw OrthancException(ErrorCode_NotEnoughMemory); | |
104 } | |
105 | |
106 if (str.size() == 0) | |
107 { | |
108 result[0] = '\0'; | |
109 } | |
110 else | |
111 { | |
112 memcpy(result, &str[0], str.size() + 1); | |
113 } | |
114 | |
115 return result; | |
116 } | |
117 | |
118 | |
119 PluginsHttpHandler::PluginsHttpHandler(ServerContext& context) | |
120 { | |
121 pimpl_.reset(new PImpl(context)); | |
122 } | |
123 | |
124 | |
125 PluginsHttpHandler::~PluginsHttpHandler() | |
126 { | |
127 for (PImpl::RestCallbacks::iterator it = pimpl_->restCallbacks_.begin(); | |
128 it != pimpl_->restCallbacks_.end(); ++it) | |
129 { | |
130 // Delete the regular expression associated with this callback | |
131 delete it->first; | |
132 } | |
133 } | |
134 | |
135 | |
136 static void ArgumentsToPlugin(std::vector<const char*>& keys, | |
137 std::vector<const char*>& values, | |
138 const HttpHandler::Arguments& arguments) | |
139 { | |
140 keys.resize(arguments.size()); | |
141 values.resize(arguments.size()); | |
142 | |
143 size_t pos = 0; | |
144 for (HttpHandler::Arguments::const_iterator | |
145 it = arguments.begin(); it != arguments.end(); ++it) | |
146 { | |
147 keys[pos] = it->first.c_str(); | |
148 values[pos] = it->second.c_str(); | |
149 pos++; | |
150 } | |
151 } | |
152 | |
153 | |
154 bool PluginsHttpHandler::Handle(HttpOutput& output, | |
155 HttpMethod method, | |
156 const UriComponents& uri, | |
157 const Arguments& headers, | |
158 const Arguments& getArguments, | |
159 const std::string& postData) | |
160 { | |
161 std::string flatUri = Toolbox::FlattenUri(uri); | |
162 OrthancPluginRestCallback callback = NULL; | |
163 | |
164 std::vector<std::string> groups; | |
165 std::vector<const char*> cgroups; | |
166 | |
167 // Loop over the callbacks registered by the plugins | |
168 bool found = false; | |
169 for (PImpl::RestCallbacks::const_iterator it = pimpl_->restCallbacks_.begin(); | |
170 it != pimpl_->restCallbacks_.end() && !found; ++it) | |
171 { | |
172 // Check whether the regular expression associated to this | |
173 // callback matches the URI | |
174 boost::cmatch what; | |
175 if (boost::regex_match(flatUri.c_str(), what, *(it->first))) | |
176 { | |
177 callback = it->second; | |
178 | |
179 // Extract the value of the free parameters of the regular expression | |
180 if (what.size() > 1) | |
181 { | |
182 groups.resize(what.size() - 1); | |
183 cgroups.resize(what.size() - 1); | |
184 for (size_t i = 1; i < what.size(); i++) | |
185 { | |
186 groups[i - 1] = what[i]; | |
187 cgroups[i - 1] = groups[i - 1].c_str(); | |
188 } | |
189 } | |
190 | |
191 found = true; | |
192 } | |
193 } | |
194 | |
195 if (!found) | |
196 { | |
197 return false; | |
198 } | |
199 | |
200 LOG(INFO) << "Delegating HTTP request to plugin for URI: " << flatUri; | |
201 | |
202 std::vector<const char*> getKeys, getValues, headersKeys, headersValues; | |
203 | |
204 OrthancPluginHttpRequest request; | |
205 memset(&request, 0, sizeof(OrthancPluginHttpRequest)); | |
206 | |
207 ArgumentsToPlugin(headersKeys, headersValues, headers); | |
208 | |
209 switch (method) | |
210 { | |
211 case HttpMethod_Get: | |
212 request.method = OrthancPluginHttpMethod_Get; | |
213 ArgumentsToPlugin(getKeys, getValues, getArguments); | |
214 break; | |
215 | |
216 case HttpMethod_Post: | |
217 request.method = OrthancPluginHttpMethod_Post; | |
218 break; | |
219 | |
220 case HttpMethod_Delete: | |
221 request.method = OrthancPluginHttpMethod_Delete; | |
222 break; | |
223 | |
224 case HttpMethod_Put: | |
225 request.method = OrthancPluginHttpMethod_Put; | |
226 break; | |
227 | |
228 default: | |
229 throw OrthancException(ErrorCode_InternalError); | |
230 } | |
231 | |
232 | |
233 request.groups = (cgroups.size() ? &cgroups[0] : NULL); | |
234 request.groupsCount = cgroups.size(); | |
235 request.getCount = getArguments.size(); | |
236 request.body = (postData.size() ? &postData[0] : NULL); | |
237 request.bodySize = postData.size(); | |
238 request.headersCount = headers.size(); | |
239 | |
240 if (getArguments.size() > 0) | |
241 { | |
242 request.getKeys = &getKeys[0]; | |
243 request.getValues = &getValues[0]; | |
244 } | |
245 | |
246 if (headers.size() > 0) | |
247 { | |
248 request.headersKeys = &headersKeys[0]; | |
249 request.headersValues = &headersValues[0]; | |
250 } | |
251 | |
252 assert(callback != NULL); | |
253 int32_t error = callback(reinterpret_cast<OrthancPluginRestOutput*>(&output), | |
254 flatUri.c_str(), | |
255 &request); | |
256 | |
257 if (error < 0) | |
258 { | |
259 LOG(ERROR) << "Plugin callback failed with error code " << error; | |
260 return false; | |
261 } | |
262 else | |
263 { | |
264 if (error > 0) | |
265 { | |
266 LOG(WARNING) << "Plugin callback finished with warning code " << error; | |
267 } | |
268 | |
269 return true; | |
270 } | |
271 } | |
272 | |
273 | |
274 void PluginsHttpHandler::SignalStoredInstance(DicomInstanceToStore& instance, | |
275 const std::string& instanceId) | |
276 { | |
277 for (PImpl::OnStoredCallbacks::const_iterator | |
278 callback = pimpl_->onStoredCallbacks_.begin(); | |
279 callback != pimpl_->onStoredCallbacks_.end(); ++callback) | |
280 { | |
281 (*callback) (reinterpret_cast<OrthancPluginDicomInstance*>(&instance), | |
282 instanceId.c_str()); | |
283 } | |
284 } | |
285 | |
286 | |
287 | |
288 static void CopyToMemoryBuffer(OrthancPluginMemoryBuffer& target, | |
289 const void* data, | |
290 size_t size) | |
291 { | |
292 target.size = size; | |
293 | |
294 if (size == 0) | |
295 { | |
296 target.data = NULL; | |
297 } | |
298 else | |
299 { | |
300 target.data = malloc(size); | |
301 if (target.data != NULL) | |
302 { | |
303 memcpy(target.data, data, size); | |
304 } | |
305 else | |
306 { | |
307 throw OrthancException(ErrorCode_NotEnoughMemory); | |
308 } | |
309 } | |
310 } | |
311 | |
312 | |
313 static void CopyToMemoryBuffer(OrthancPluginMemoryBuffer& target, | |
314 const std::string& str) | |
315 { | |
316 if (str.size() == 0) | |
317 { | |
318 target.size = 0; | |
319 target.data = NULL; | |
320 } | |
321 else | |
322 { | |
323 CopyToMemoryBuffer(target, str.c_str(), str.size()); | |
324 } | |
325 } | |
326 | |
327 | |
328 void PluginsHttpHandler::RegisterRestCallback(const void* parameters) | |
329 { | |
330 const _OrthancPluginRestCallback& p = | |
331 *reinterpret_cast<const _OrthancPluginRestCallback*>(parameters); | |
332 | |
333 LOG(INFO) << "Plugin has registered a REST callback on: " << p.pathRegularExpression; | |
334 pimpl_->restCallbacks_.push_back(std::make_pair(new boost::regex(p.pathRegularExpression), p.callback)); | |
335 } | |
336 | |
337 | |
338 | |
339 void PluginsHttpHandler::RegisterOnStoredInstanceCallback(const void* parameters) | |
340 { | |
341 const _OrthancPluginOnStoredInstanceCallback& p = | |
342 *reinterpret_cast<const _OrthancPluginOnStoredInstanceCallback*>(parameters); | |
343 | |
344 LOG(INFO) << "Plugin has registered an OnStoredInstance callback"; | |
345 pimpl_->onStoredCallbacks_.push_back(p.callback); | |
346 } | |
347 | |
348 | |
349 | |
350 void PluginsHttpHandler::AnswerBuffer(const void* parameters) | |
351 { | |
352 const _OrthancPluginAnswerBuffer& p = | |
353 *reinterpret_cast<const _OrthancPluginAnswerBuffer*>(parameters); | |
354 | |
355 HttpOutput* translatedOutput = reinterpret_cast<HttpOutput*>(p.output); | |
356 translatedOutput->SetContentType(p.mimeType); | |
357 translatedOutput->SendBody(p.answer, p.answerSize); | |
358 } | |
359 | |
360 | |
361 void PluginsHttpHandler::Redirect(const void* parameters) | |
362 { | |
363 const _OrthancPluginOutputPlusArgument& p = | |
364 *reinterpret_cast<const _OrthancPluginOutputPlusArgument*>(parameters); | |
365 | |
366 HttpOutput* translatedOutput = reinterpret_cast<HttpOutput*>(p.output); | |
367 translatedOutput->Redirect(p.argument); | |
368 } | |
369 | |
370 | |
371 void PluginsHttpHandler::SendHttpStatusCode(const void* parameters) | |
372 { | |
373 const _OrthancPluginSendHttpStatusCode& p = | |
374 *reinterpret_cast<const _OrthancPluginSendHttpStatusCode*>(parameters); | |
375 | |
376 HttpOutput* translatedOutput = reinterpret_cast<HttpOutput*>(p.output); | |
377 translatedOutput->SendStatus(static_cast<HttpStatus>(p.status)); | |
378 } | |
379 | |
380 | |
381 void PluginsHttpHandler::SendUnauthorized(const void* parameters) | |
382 { | |
383 const _OrthancPluginOutputPlusArgument& p = | |
384 *reinterpret_cast<const _OrthancPluginOutputPlusArgument*>(parameters); | |
385 | |
386 HttpOutput* translatedOutput = reinterpret_cast<HttpOutput*>(p.output); | |
387 translatedOutput->SendUnauthorized(p.argument); | |
388 } | |
389 | |
390 | |
391 void PluginsHttpHandler::SendMethodNotAllowed(const void* parameters) | |
392 { | |
393 const _OrthancPluginOutputPlusArgument& p = | |
394 *reinterpret_cast<const _OrthancPluginOutputPlusArgument*>(parameters); | |
395 | |
396 HttpOutput* translatedOutput = reinterpret_cast<HttpOutput*>(p.output); | |
397 translatedOutput->SendMethodNotAllowed(p.argument); | |
398 } | |
399 | |
400 | |
401 void PluginsHttpHandler::SetCookie(const void* parameters) | |
402 { | |
403 const _OrthancPluginSetCookie& p = | |
404 *reinterpret_cast<const _OrthancPluginSetCookie*>(parameters); | |
405 | |
406 HttpOutput* translatedOutput = reinterpret_cast<HttpOutput*>(p.output); | |
407 translatedOutput->SetCookie(p.cookie, p.value); | |
408 } | |
409 | |
410 | |
411 void PluginsHttpHandler::CompressAndAnswerPngImage(const void* parameters) | |
412 { | |
413 const _OrthancPluginCompressAndAnswerPngImage& p = | |
414 *reinterpret_cast<const _OrthancPluginCompressAndAnswerPngImage*>(parameters); | |
415 | |
416 HttpOutput* translatedOutput = reinterpret_cast<HttpOutput*>(p.output); | |
417 | |
418 PixelFormat format; | |
419 switch (p.format) | |
420 { | |
421 case OrthancPluginPixelFormat_Grayscale8: | |
422 format = PixelFormat_Grayscale8; | |
423 break; | |
424 | |
425 case OrthancPluginPixelFormat_Grayscale16: | |
426 format = PixelFormat_Grayscale16; | |
427 break; | |
428 | |
429 case OrthancPluginPixelFormat_SignedGrayscale16: | |
430 format = PixelFormat_SignedGrayscale16; | |
431 break; | |
432 | |
433 case OrthancPluginPixelFormat_RGB24: | |
434 format = PixelFormat_RGB24; | |
435 break; | |
436 | |
437 case OrthancPluginPixelFormat_RGBA32: | |
438 format = PixelFormat_RGBA32; | |
439 break; | |
440 | |
441 default: | |
442 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
443 } | |
444 | |
445 ImageAccessor accessor; | |
446 accessor.AssignReadOnly(format, p.width, p.height, p.pitch, p.buffer); | |
447 | |
448 PngWriter writer; | |
449 std::string png; | |
450 writer.WriteToMemory(png, accessor); | |
451 | |
452 translatedOutput->SetContentType("image/png"); | |
453 translatedOutput->SendBody(png); | |
454 } | |
455 | |
456 | |
457 void PluginsHttpHandler::GetDicomForInstance(const void* parameters) | |
458 { | |
459 const _OrthancPluginGetDicomForInstance& p = | |
460 *reinterpret_cast<const _OrthancPluginGetDicomForInstance*>(parameters); | |
461 | |
462 std::string dicom; | |
463 pimpl_->context_.ReadFile(dicom, p.instanceId, FileContentType_Dicom); | |
464 CopyToMemoryBuffer(*p.target, dicom); | |
465 } | |
466 | |
467 | |
468 void PluginsHttpHandler::RestApiGet(const void* parameters) | |
469 { | |
470 const _OrthancPluginRestApiGet& p = | |
471 *reinterpret_cast<const _OrthancPluginRestApiGet*>(parameters); | |
472 | |
473 HttpHandler::Arguments headers; // No HTTP header | |
474 std::string body; // No body for a GET request | |
475 | |
476 UriComponents uri; | |
477 HttpHandler::Arguments getArguments; | |
478 HttpHandler::ParseGetQuery(uri, getArguments, p.uri); | |
479 | |
480 StringHttpOutput stream; | |
481 HttpOutput http(stream, false /* no keep alive */); | |
482 | |
483 LOG(INFO) << "Plugin making REST GET call on URI " << p.uri; | |
484 | |
485 if (pimpl_->restApi_ != NULL && | |
486 pimpl_->restApi_->Handle(http, HttpMethod_Get, uri, headers, getArguments, body)) | |
487 { | |
488 std::string result; | |
489 stream.GetOutput(result); | |
490 CopyToMemoryBuffer(*p.target, result); | |
491 } | |
492 else | |
493 { | |
494 throw OrthancException(ErrorCode_BadRequest); | |
495 } | |
496 } | |
497 | |
498 | |
499 void PluginsHttpHandler::RestApiPostPut(bool isPost, const void* parameters) | |
500 { | |
501 const _OrthancPluginRestApiPostPut& p = | |
502 *reinterpret_cast<const _OrthancPluginRestApiPostPut*>(parameters); | |
503 | |
504 HttpHandler::Arguments headers; // No HTTP header | |
505 HttpHandler::Arguments getArguments; // No GET argument for POST/PUT | |
506 | |
507 UriComponents uri; | |
508 Toolbox::SplitUriComponents(uri, p.uri); | |
509 | |
510 // TODO Avoid unecessary memcpy | |
511 std::string body(p.body, p.bodySize); | |
512 | |
513 StringHttpOutput stream; | |
514 HttpOutput http(stream, false /* no keep alive */); | |
515 | |
516 HttpMethod method = (isPost ? HttpMethod_Post : HttpMethod_Put); | |
517 LOG(INFO) << "Plugin making REST " << EnumerationToString(method) << " call on URI " << p.uri; | |
518 | |
519 if (pimpl_->restApi_ != NULL && | |
520 pimpl_->restApi_->Handle(http, method, uri, headers, getArguments, body)) | |
521 { | |
522 std::string result; | |
523 stream.GetOutput(result); | |
524 CopyToMemoryBuffer(*p.target, result); | |
525 } | |
526 else | |
527 { | |
528 throw OrthancException(ErrorCode_BadRequest); | |
529 } | |
530 } | |
531 | |
532 | |
533 void PluginsHttpHandler::RestApiDelete(const void* parameters) | |
534 { | |
535 // The "parameters" point to the URI | |
536 UriComponents uri; | |
537 Toolbox::SplitUriComponents(uri, reinterpret_cast<const char*>(parameters)); | |
538 | |
539 HttpHandler::Arguments headers; // No HTTP header | |
540 HttpHandler::Arguments getArguments; // No GET argument for POST/PUT | |
541 std::string body; // No body for DELETE | |
542 | |
543 StringHttpOutput stream; | |
544 HttpOutput http(stream, false /* no keep alive */); | |
545 | |
546 LOG(INFO) << "Plugin making REST DELETE call on URI " | |
547 << reinterpret_cast<const char*>(parameters); | |
548 | |
549 if (pimpl_->restApi_ == NULL || | |
550 !pimpl_->restApi_->Handle(http, HttpMethod_Delete, uri, headers, getArguments, body)) | |
551 { | |
552 throw OrthancException(ErrorCode_BadRequest); | |
553 } | |
554 } | |
555 | |
556 | |
557 void PluginsHttpHandler::LookupResource(_OrthancPluginService service, | |
558 const void* parameters) | |
559 { | |
560 const _OrthancPluginLookupResource& p = | |
561 *reinterpret_cast<const _OrthancPluginLookupResource*>(parameters); | |
562 | |
563 /** | |
564 * The enumeration below only uses the tags that are indexed in | |
565 * the Orthanc database. It reflects the | |
566 * "CandidateResources::ApplyFilter()" method of the | |
567 * "OrthancFindRequestHandler" class. | |
568 **/ | |
569 | |
570 DicomTag tag(0, 0); | |
571 ResourceType level; | |
572 switch (service) | |
573 { | |
574 case _OrthancPluginService_LookupPatient: | |
575 tag = DICOM_TAG_PATIENT_ID; | |
576 level = ResourceType_Patient; | |
577 break; | |
578 | |
579 case _OrthancPluginService_LookupStudy: | |
580 tag = DICOM_TAG_STUDY_INSTANCE_UID; | |
581 level = ResourceType_Study; | |
582 break; | |
583 | |
584 case _OrthancPluginService_LookupStudyWithAccessionNumber: | |
585 tag = DICOM_TAG_ACCESSION_NUMBER; | |
586 level = ResourceType_Study; | |
587 break; | |
588 | |
589 case _OrthancPluginService_LookupSeries: | |
590 tag = DICOM_TAG_SERIES_INSTANCE_UID; | |
591 level = ResourceType_Series; | |
592 break; | |
593 | |
594 case _OrthancPluginService_LookupInstance: | |
595 tag = DICOM_TAG_SOP_INSTANCE_UID; | |
596 level = ResourceType_Instance; | |
597 break; | |
598 | |
599 default: | |
600 throw OrthancException(ErrorCode_InternalError); | |
601 } | |
602 | |
603 std::list<std::string> result; | |
604 pimpl_->context_.GetIndex().LookupTagValue(result, tag, p.identifier, level); | |
605 | |
606 if (result.size() == 1) | |
607 { | |
608 *p.result = CopyString(result.front()); | |
609 } | |
610 else | |
611 { | |
612 throw OrthancException(ErrorCode_UnknownResource); | |
613 } | |
614 } | |
615 | |
616 | |
617 static void AccessInstanceMetadataInternal(bool checkExistence, | |
618 const _OrthancPluginAccessDicomInstance& params, | |
619 const DicomInstanceToStore& instance) | |
620 { | |
621 MetadataType metadata; | |
622 | |
623 try | |
624 { | |
625 metadata = StringToMetadata(params.key); | |
626 } | |
627 catch (OrthancException&) | |
628 { | |
629 // Unknown metadata | |
630 if (checkExistence) | |
631 { | |
632 *params.resultInt64 = -1; | |
633 } | |
634 else | |
635 { | |
636 *params.resultString = NULL; | |
637 } | |
638 | |
639 return; | |
640 } | |
641 | |
642 ServerIndex::MetadataMap::const_iterator it = | |
643 instance.GetMetadata().find(std::make_pair(ResourceType_Instance, metadata)); | |
644 | |
645 if (checkExistence) | |
646 { | |
647 if (it != instance.GetMetadata().end()) | |
648 { | |
649 *params.resultInt64 = 1; | |
650 } | |
651 else | |
652 { | |
653 *params.resultInt64 = 0; | |
654 } | |
655 } | |
656 else | |
657 { | |
658 if (it != instance.GetMetadata().end()) | |
659 { | |
660 *params.resultString = it->second.c_str(); | |
661 } | |
662 else | |
663 { | |
664 // Error: Missing metadata | |
665 *params.resultString = NULL; | |
666 } | |
667 } | |
668 } | |
669 | |
670 | |
671 static void AccessDicomInstance(_OrthancPluginService service, | |
672 const void* parameters) | |
673 { | |
674 const _OrthancPluginAccessDicomInstance& p = | |
675 *reinterpret_cast<const _OrthancPluginAccessDicomInstance*>(parameters); | |
676 | |
677 DicomInstanceToStore& instance = | |
678 *reinterpret_cast<DicomInstanceToStore*>(p.instance); | |
679 | |
680 switch (service) | |
681 { | |
682 case _OrthancPluginService_GetInstanceRemoteAet: | |
683 *p.resultString = instance.GetRemoteAet().c_str(); | |
684 return; | |
685 | |
686 case _OrthancPluginService_GetInstanceSize: | |
687 *p.resultInt64 = instance.GetBufferSize(); | |
688 return; | |
689 | |
690 case _OrthancPluginService_GetInstanceData: | |
691 *p.resultString = instance.GetBufferData(); | |
692 return; | |
693 | |
694 case _OrthancPluginService_HasInstanceMetadata: | |
695 AccessInstanceMetadataInternal(true, p, instance); | |
696 return; | |
697 | |
698 case _OrthancPluginService_GetInstanceMetadata: | |
699 AccessInstanceMetadataInternal(false, p, instance); | |
700 return; | |
701 | |
702 case _OrthancPluginService_GetInstanceJson: | |
703 case _OrthancPluginService_GetInstanceSimplifiedJson: | |
704 { | |
705 Json::StyledWriter writer; | |
706 std::string s; | |
707 | |
708 if (service == _OrthancPluginService_GetInstanceJson) | |
709 { | |
710 s = writer.write(instance.GetJson()); | |
711 } | |
712 else | |
713 { | |
714 Json::Value simplified; | |
715 SimplifyTags(simplified, instance.GetJson()); | |
716 s = writer.write(simplified); | |
717 } | |
718 | |
719 *p.resultStringToFree = CopyString(s); | |
720 return; | |
721 } | |
722 | |
723 default: | |
724 throw OrthancException(ErrorCode_InternalError); | |
725 } | |
726 } | |
727 | |
728 | |
729 bool PluginsHttpHandler::InvokeService(_OrthancPluginService service, | |
730 const void* parameters) | |
731 { | |
732 switch (service) | |
733 { | |
734 case _OrthancPluginService_RegisterRestCallback: | |
735 RegisterRestCallback(parameters); | |
736 return true; | |
737 | |
738 case _OrthancPluginService_RegisterOnStoredInstanceCallback: | |
739 RegisterOnStoredInstanceCallback(parameters); | |
740 return true; | |
741 | |
742 case _OrthancPluginService_AnswerBuffer: | |
743 AnswerBuffer(parameters); | |
744 return true; | |
745 | |
746 case _OrthancPluginService_CompressAndAnswerPngImage: | |
747 CompressAndAnswerPngImage(parameters); | |
748 return true; | |
749 | |
750 case _OrthancPluginService_GetDicomForInstance: | |
751 GetDicomForInstance(parameters); | |
752 return true; | |
753 | |
754 case _OrthancPluginService_RestApiGet: | |
755 RestApiGet(parameters); | |
756 return true; | |
757 | |
758 case _OrthancPluginService_RestApiPost: | |
759 RestApiPostPut(true, parameters); | |
760 return true; | |
761 | |
762 case _OrthancPluginService_RestApiDelete: | |
763 RestApiDelete(parameters); | |
764 return true; | |
765 | |
766 case _OrthancPluginService_RestApiPut: | |
767 RestApiPostPut(false, parameters); | |
768 return true; | |
769 | |
770 case _OrthancPluginService_Redirect: | |
771 Redirect(parameters); | |
772 return true; | |
773 | |
774 case _OrthancPluginService_SendUnauthorized: | |
775 SendUnauthorized(parameters); | |
776 return true; | |
777 | |
778 case _OrthancPluginService_SendMethodNotAllowed: | |
779 SendMethodNotAllowed(parameters); | |
780 return true; | |
781 | |
782 case _OrthancPluginService_SendHttpStatusCode: | |
783 SendHttpStatusCode(parameters); | |
784 return true; | |
785 | |
786 case _OrthancPluginService_SetCookie: | |
787 SetCookie(parameters); | |
788 return true; | |
789 | |
790 case _OrthancPluginService_LookupPatient: | |
791 case _OrthancPluginService_LookupStudy: | |
792 case _OrthancPluginService_LookupStudyWithAccessionNumber: | |
793 case _OrthancPluginService_LookupSeries: | |
794 case _OrthancPluginService_LookupInstance: | |
795 LookupResource(service, parameters); | |
796 return true; | |
797 | |
798 case _OrthancPluginService_GetInstanceRemoteAet: | |
799 case _OrthancPluginService_GetInstanceSize: | |
800 case _OrthancPluginService_GetInstanceData: | |
801 case _OrthancPluginService_GetInstanceJson: | |
802 case _OrthancPluginService_GetInstanceSimplifiedJson: | |
803 case _OrthancPluginService_HasInstanceMetadata: | |
804 case _OrthancPluginService_GetInstanceMetadata: | |
805 AccessDicomInstance(service, parameters); | |
806 return true; | |
807 | |
808 default: | |
809 return false; | |
810 } | |
811 } | |
812 | |
813 | |
814 void PluginsHttpHandler::SetOrthancRestApi(OrthancRestApi& restApi) | |
815 { | |
816 pimpl_->restApi_ = &restApi; | |
817 } | |
818 | |
819 } |