comparison Plugins/Engine/OrthancPlugins.cpp @ 1801:2c60c357ee3e worklists

sdk primitives to handle worklists
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 20 Nov 2015 14:33:41 +0100
parents 30e97a1f4093
children 138664eb59de
comparison
equal deleted inserted replaced
1800:30e97a1f4093 1801:2c60c357ee3e
45 #include "../../Core/Toolbox.h" 45 #include "../../Core/Toolbox.h"
46 #include "../../OrthancServer/FromDcmtkBridge.h" 46 #include "../../OrthancServer/FromDcmtkBridge.h"
47 #include "../../OrthancServer/OrthancInitialization.h" 47 #include "../../OrthancServer/OrthancInitialization.h"
48 #include "../../OrthancServer/ServerContext.h" 48 #include "../../OrthancServer/ServerContext.h"
49 #include "../../OrthancServer/ServerToolbox.h" 49 #include "../../OrthancServer/ServerToolbox.h"
50 #include "../../OrthancServer/Search/HierarchicalMatcher.h"
50 #include "../../Core/Compression/ZlibCompressor.h" 51 #include "../../Core/Compression/ZlibCompressor.h"
51 #include "../../Core/Compression/GzipCompressor.h" 52 #include "../../Core/Compression/GzipCompressor.h"
52 #include "../../Core/Images/Image.h" 53 #include "../../Core/Images/Image.h"
53 #include "../../Core/Images/PngReader.h" 54 #include "../../Core/Images/PngReader.h"
54 #include "../../Core/Images/PngWriter.h" 55 #include "../../Core/Images/PngWriter.h"
59 60
60 #include <boost/regex.hpp> 61 #include <boost/regex.hpp>
61 62
62 namespace Orthanc 63 namespace Orthanc
63 { 64 {
65 static void CopyToMemoryBuffer(OrthancPluginMemoryBuffer& target,
66 const void* data,
67 size_t size)
68 {
69 target.size = size;
70
71 if (size == 0)
72 {
73 target.data = NULL;
74 }
75 else
76 {
77 target.data = malloc(size);
78 if (target.data != NULL)
79 {
80 memcpy(target.data, data, size);
81 }
82 else
83 {
84 throw OrthancException(ErrorCode_NotEnoughMemory);
85 }
86 }
87 }
88
89
90 static void CopyToMemoryBuffer(OrthancPluginMemoryBuffer& target,
91 const std::string& str)
92 {
93 if (str.size() == 0)
94 {
95 target.size = 0;
96 target.data = NULL;
97 }
98 else
99 {
100 CopyToMemoryBuffer(target, str.c_str(), str.size());
101 }
102 }
103
104
64 namespace 105 namespace
65 { 106 {
66 class PluginStorageArea : public IStorageArea 107 class PluginStorageArea : public IStorageArea
67 { 108 {
68 private: 109 private:
264 argv_(NULL) 305 argv_(NULL)
265 { 306 {
266 } 307 }
267 }; 308 };
268 309
310
311
312 class OrthancPlugins::WorklistHandler : public IWorklistRequestHandler
313 {
314 private:
315 OrthancPlugins& that_;
316 std::auto_ptr<HierarchicalMatcher> matcher_;
317 ParsedDicomFile* currentQuery_;
318
319 void Reset()
320 {
321 matcher_.reset(NULL);
322 currentQuery_ = NULL;
323 }
324
325 public:
326 WorklistHandler(OrthancPlugins& that) : that_(that)
327 {
328 Reset();
329 }
330
331 virtual void Handle(DicomFindAnswers& answers,
332 ParsedDicomFile& query,
333 const std::string& remoteIp,
334 const std::string& remoteAet,
335 const std::string& calledAet)
336 {
337 bool caseSensitivePN = Configuration::GetGlobalBoolParameter("CaseSensitivePN", false);
338 matcher_.reset(new HierarchicalMatcher(query, caseSensitivePN));
339 currentQuery_ = &query;
340
341 {
342 boost::recursive_mutex::scoped_lock lock(that_.pimpl_->worklistCallbackMutex_);
343
344 for (PImpl::WorklistCallbacks::const_iterator
345 callback = that_.pimpl_->worklistCallbacks_.begin();
346 callback != that_.pimpl_->worklistCallbacks_.end(); ++callback)
347 {
348 OrthancPluginErrorCode error = (*callback)
349 (reinterpret_cast<OrthancPluginWorklistAnswers*>(&answers),
350 reinterpret_cast<const OrthancPluginWorklistQuery*>(this),
351 remoteAet.c_str(),
352 calledAet.c_str());
353
354 if (error != OrthancPluginErrorCode_Success)
355 {
356 Reset();
357 that_.GetErrorDictionary().LogError(error, true);
358 throw OrthancException(static_cast<ErrorCode>(error));
359 }
360 }
361 }
362
363 Reset();
364 }
365
366 bool IsMatch(const void* dicom,
367 size_t size) const
368 {
369 assert(matcher_.get() != NULL);
370 ParsedDicomFile f(dicom, size);
371 return matcher_->Match(f);
372 }
373
374 void GetQueryDicom(OrthancPluginMemoryBuffer& target) const
375 {
376 assert(currentQuery_ != NULL);
377 std::string dicom;
378 currentQuery_->SaveToMemoryBuffer(dicom);
379 CopyToMemoryBuffer(target, dicom.c_str(), dicom.size());
380 }
381 };
269 382
270 383
271 static char* CopyString(const std::string& str) 384 static char* CopyString(const std::string& str)
272 { 385 {
273 char *result = reinterpret_cast<char*>(malloc(str.size() + 1)); 386 char *result = reinterpret_cast<char*>(malloc(str.size() + 1));
547 change.GetPublicId().c_str()); 660 change.GetPublicId().c_str());
548 } 661 }
549 662
550 663
551 664
552 static void CopyToMemoryBuffer(OrthancPluginMemoryBuffer& target,
553 const void* data,
554 size_t size)
555 {
556 target.size = size;
557
558 if (size == 0)
559 {
560 target.data = NULL;
561 }
562 else
563 {
564 target.data = malloc(size);
565 if (target.data != NULL)
566 {
567 memcpy(target.data, data, size);
568 }
569 else
570 {
571 throw OrthancException(ErrorCode_NotEnoughMemory);
572 }
573 }
574 }
575
576
577 static void CopyToMemoryBuffer(OrthancPluginMemoryBuffer& target,
578 const std::string& str)
579 {
580 if (str.size() == 0)
581 {
582 target.size = 0;
583 target.data = NULL;
584 }
585 else
586 {
587 CopyToMemoryBuffer(target, str.c_str(), str.size());
588 }
589 }
590
591
592 void OrthancPlugins::RegisterRestCallback(const void* parameters, 665 void OrthancPlugins::RegisterRestCallback(const void* parameters,
593 bool lock) 666 bool lock)
594 { 667 {
595 const _OrthancPluginRestCallback& p = 668 const _OrthancPluginRestCallback& p =
596 *reinterpret_cast<const _OrthancPluginRestCallback*>(parameters); 669 *reinterpret_cast<const _OrthancPluginRestCallback*>(parameters);
1849 ApplyDicomToJson(service, parameters); 1922 ApplyDicomToJson(service, parameters);
1850 return true; 1923 return true;
1851 1924
1852 case _OrthancPluginService_AddWorklistAnswer: 1925 case _OrthancPluginService_AddWorklistAnswer:
1853 { 1926 {
1854 const _OrthancPluginAddWorklistAnswer& p = 1927 const _OrthancPluginWorklistAnswersOperation& p =
1855 *reinterpret_cast<const _OrthancPluginAddWorklistAnswer*>(parameters); 1928 *reinterpret_cast<const _OrthancPluginWorklistAnswersOperation*>(parameters);
1856 1929
1857 ParsedDicomFile answer(p.answerDicom, p.answerSize); 1930 ParsedDicomFile answer(p.dicom, p.size);
1858 reinterpret_cast<DicomFindAnswers*>(p.target)->Add(answer); 1931 reinterpret_cast<DicomFindAnswers*>(p.answers)->Add(answer);
1932 return true;
1933 }
1934
1935 case _OrthancPluginService_MarkWorklistAnswersIncomplete:
1936 {
1937 const _OrthancPluginWorklistAnswersOperation& p =
1938 *reinterpret_cast<const _OrthancPluginWorklistAnswersOperation*>(parameters);
1939
1940 reinterpret_cast<DicomFindAnswers*>(p.answers)->SetComplete(false);
1941 return true;
1942 }
1943
1944 case _OrthancPluginService_IsWorklistMatch:
1945 {
1946 const _OrthancPluginWorklistQueryOperation& p =
1947 *reinterpret_cast<const _OrthancPluginWorklistQueryOperation*>(parameters);
1948 *p.isMatch = reinterpret_cast<const WorklistHandler*>(p.query)->IsMatch(p.dicom, p.size);
1949 return true;
1950 }
1951
1952 case _OrthancPluginService_GetWorklistQueryDicom:
1953 {
1954 const _OrthancPluginWorklistQueryOperation& p =
1955 *reinterpret_cast<const _OrthancPluginWorklistQueryOperation*>(parameters);
1956 reinterpret_cast<const WorklistHandler*>(p.query)->GetQueryDicom(*p.target);
1859 return true; 1957 return true;
1860 } 1958 }
1861 1959
1862 default: 1960 default:
1863 { 1961 {
1976 { 2074 {
1977 return pimpl_->dictionary_; 2075 return pimpl_->dictionary_;
1978 } 2076 }
1979 2077
1980 2078
1981 void OrthancPlugins::HandleWorklist(DicomFindAnswers& answers,
1982 ParsedDicomFile& query,
1983 const std::string& remoteIp,
1984 const std::string& remoteAet,
1985 const std::string& calledAet)
1986 {
1987 boost::recursive_mutex::scoped_lock lock(pimpl_->worklistCallbackMutex_);
1988
1989 for (PImpl::WorklistCallbacks::const_iterator
1990 callback = pimpl_->worklistCallbacks_.begin();
1991 callback != pimpl_->worklistCallbacks_.end(); ++callback)
1992 {
1993 OrthancPluginErrorCode error = (*callback)
1994 (reinterpret_cast<OrthancPluginWorklistAnswers*>(&answers),
1995 reinterpret_cast<OrthancPluginWorklistQuery*>(&query),
1996 remoteAet.c_str(),
1997 calledAet.c_str());
1998
1999 if (error != OrthancPluginErrorCode_Success)
2000 {
2001 GetErrorDictionary().LogError(error, true);
2002 throw OrthancException(static_cast<ErrorCode>(error));
2003 }
2004 }
2005 }
2006
2007
2008 class OrthancPlugins::WorklistHandler : public IWorklistRequestHandler
2009 {
2010 private:
2011 OrthancPlugins& plugins_;
2012
2013 public:
2014 WorklistHandler(OrthancPlugins& plugins) : plugins_(plugins)
2015 {
2016 }
2017
2018 virtual void Handle(DicomFindAnswers& answers,
2019 ParsedDicomFile& query,
2020 const std::string& remoteIp,
2021 const std::string& remoteAet,
2022 const std::string& calledAet)
2023 {
2024 plugins_.HandleWorklist(answers, query, remoteIp, remoteAet, calledAet);
2025 }
2026 };
2027
2028
2029 IWorklistRequestHandler* OrthancPlugins::ConstructWorklistRequestHandler() 2079 IWorklistRequestHandler* OrthancPlugins::ConstructWorklistRequestHandler()
2030 { 2080 {
2031 bool hasHandler; 2081 bool hasHandler;
2032 2082
2033 { 2083 {