Mercurial > hg > orthanc
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 { |