comparison Plugins/Engine/OrthancPlugins.cpp @ 3786:3801435e34a1 SylvainRouquette/fix-issue169-95b752c

integration Orthanc-1.6.0->SylvainRouquette
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 19 Mar 2020 11:48:30 +0100
parents 56f2397f027a
children e7003b2203a7
comparison
equal deleted inserted replaced
3785:763533d6dd67 3786:3801435e34a1
1 /** 1 /**
2 * Orthanc - A Lightweight, RESTful DICOM Store 2 * Orthanc - A Lightweight, RESTful DICOM Store
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics 3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
4 * Department, University Hospital of Liege, Belgium 4 * Department, University Hospital of Liege, Belgium
5 * Copyright (C) 2017-2019 Osimis S.A., Belgium 5 * Copyright (C) 2017-2020 Osimis S.A., Belgium
6 * 6 *
7 * This program is free software: you can redistribute it and/or 7 * This program is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as 8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation, either version 3 of the 9 * published by the Free Software Foundation, either version 3 of the
10 * License, or (at your option) any later version. 10 * License, or (at your option) any later version.
365 } 365 }
366 } 366 }
367 367
368 public: 368 public:
369 DicomWebBinaryFormatter(const _OrthancPluginEncodeDicomWeb& parameters) : 369 DicomWebBinaryFormatter(const _OrthancPluginEncodeDicomWeb& parameters) :
370 callback_(parameters.callback) 370 callback_(parameters.callback)
371 { 371 {
372 } 372 }
373 373
374 virtual DicomWebJsonVisitor::BinaryMode Format(std::string& bulkDataUri, 374 virtual DicomWebJsonVisitor::BinaryMode Format(std::string& bulkDataUri,
375 const std::vector<DicomTag>& parentTags, 375 const std::vector<DicomTag>& parentTags,
433 MultipartState_SecondPart, 433 MultipartState_SecondPart,
434 MultipartState_NextParts 434 MultipartState_NextParts
435 }; 435 };
436 436
437 HttpOutput& output_; 437 HttpOutput& output_;
438 std::auto_ptr<std::string> errorDetails_; 438 std::unique_ptr<std::string> errorDetails_;
439 bool logDetails_; 439 bool logDetails_;
440 MultipartState multipartState_; 440 MultipartState multipartState_;
441 std::string multipartSubType_; 441 std::string multipartSubType_;
442 std::string multipartContentType_; 442 std::string multipartContentType_;
443 std::string multipartFirstPart_; 443 std::string multipartFirstPart_;
663 _OrthancPluginChunkedRestCallback parameters_; 663 _OrthancPluginChunkedRestCallback parameters_;
664 boost::regex regex_; 664 boost::regex regex_;
665 665
666 public: 666 public:
667 ChunkedRestCallback(_OrthancPluginChunkedRestCallback parameters) : 667 ChunkedRestCallback(_OrthancPluginChunkedRestCallback parameters) :
668 parameters_(parameters), 668 parameters_(parameters),
669 regex_(parameters.pathRegularExpression) 669 regex_(parameters.pathRegularExpression)
670 { 670 {
671 } 671 }
672 672
673 const boost::regex& GetRegularExpression() const 673 const boost::regex& GetRegularExpression() const
674 { 674 {
676 } 676 }
677 677
678 const _OrthancPluginChunkedRestCallback& GetParameters() const 678 const _OrthancPluginChunkedRestCallback& GetParameters() const
679 { 679 {
680 return parameters_; 680 return parameters_;
681 }
682 };
683
684
685
686 class StorageCommitmentScp : public IStorageCommitmentFactory
687 {
688 private:
689 class Handler : public IStorageCommitmentFactory::ILookupHandler
690 {
691 private:
692 _OrthancPluginRegisterStorageCommitmentScpCallback parameters_;
693 void* handler_;
694
695 public:
696 Handler(_OrthancPluginRegisterStorageCommitmentScpCallback parameters,
697 void* handler) :
698 parameters_(parameters),
699 handler_(handler)
700 {
701 if (handler == NULL)
702 {
703 throw OrthancException(ErrorCode_NullPointer);
704 }
705 }
706
707 virtual ~Handler()
708 {
709 assert(handler_ != NULL);
710 parameters_.destructor(handler_);
711 handler_ = NULL;
712 }
713
714 virtual StorageCommitmentFailureReason Lookup(const std::string& sopClassUid,
715 const std::string& sopInstanceUid)
716 {
717 assert(handler_ != NULL);
718 OrthancPluginStorageCommitmentFailureReason reason =
719 OrthancPluginStorageCommitmentFailureReason_Success;
720 OrthancPluginErrorCode error = parameters_.lookup(
721 &reason, handler_, sopClassUid.c_str(), sopInstanceUid.c_str());
722 if (error == OrthancPluginErrorCode_Success)
723 {
724 return Plugins::Convert(reason);
725 }
726 else
727 {
728 throw OrthancException(static_cast<ErrorCode>(error));
729 }
730 }
731 };
732
733 _OrthancPluginRegisterStorageCommitmentScpCallback parameters_;
734
735 public:
736 StorageCommitmentScp(_OrthancPluginRegisterStorageCommitmentScpCallback parameters) :
737 parameters_(parameters)
738 {
739 }
740
741 virtual ILookupHandler* CreateStorageCommitment(
742 const std::string& jobId,
743 const std::string& transactionUid,
744 const std::vector<std::string>& sopClassUids,
745 const std::vector<std::string>& sopInstanceUids,
746 const std::string& remoteAet,
747 const std::string& calledAet) ORTHANC_OVERRIDE
748 {
749 const size_t n = sopClassUids.size();
750
751 if (sopInstanceUids.size() != n)
752 {
753 throw OrthancException(ErrorCode_ParameterOutOfRange);
754 }
755
756 std::vector<const char*> a, b;
757 a.resize(n);
758 b.resize(n);
759
760 for (size_t i = 0; i < n; i++)
761 {
762 a[i] = sopClassUids[i].c_str();
763 b[i] = sopInstanceUids[i].c_str();
764 }
765
766 void* handler = NULL;
767 OrthancPluginErrorCode error = parameters_.factory(
768 &handler, jobId.c_str(), transactionUid.c_str(),
769 a.empty() ? NULL : &a[0], b.empty() ? NULL : &b[0], static_cast<uint32_t>(n),
770 remoteAet.c_str(), calledAet.c_str());
771
772 if (error != OrthancPluginErrorCode_Success)
773 {
774 throw OrthancException(static_cast<ErrorCode>(error));
775 }
776 else if (handler == NULL)
777 {
778 // This plugin won't handle this storage commitment request
779 return NULL;
780 }
781 else
782 {
783 return new Handler(parameters_, handler);
784 }
681 } 785 }
682 }; 786 };
683 787
684 788
685 class ServerContextLock 789 class ServerContextLock
688 boost::mutex::scoped_lock lock_; 792 boost::mutex::scoped_lock lock_;
689 ServerContext* context_; 793 ServerContext* context_;
690 794
691 public: 795 public:
692 ServerContextLock(PImpl& that) : 796 ServerContextLock(PImpl& that) :
693 lock_(that.contextMutex_), 797 lock_(that.contextMutex_),
694 context_(that.context_) 798 context_(that.context_)
695 { 799 {
696 if (context_ == NULL) 800 if (context_ == NULL)
697 { 801 {
698 throw OrthancException(ErrorCode_DatabaseNotInitialized); 802 throw OrthancException(ErrorCode_DatabaseNotInitialized);
699 } 803 }
722 typedef std::list<OrthancPluginIncomingHttpRequestFilter> IncomingHttpRequestFilters; 826 typedef std::list<OrthancPluginIncomingHttpRequestFilter> IncomingHttpRequestFilters;
723 typedef std::list<OrthancPluginIncomingHttpRequestFilter2> IncomingHttpRequestFilters2; 827 typedef std::list<OrthancPluginIncomingHttpRequestFilter2> IncomingHttpRequestFilters2;
724 typedef std::list<OrthancPluginDecodeImageCallback> DecodeImageCallbacks; 828 typedef std::list<OrthancPluginDecodeImageCallback> DecodeImageCallbacks;
725 typedef std::list<OrthancPluginJobsUnserializer> JobsUnserializers; 829 typedef std::list<OrthancPluginJobsUnserializer> JobsUnserializers;
726 typedef std::list<OrthancPluginRefreshMetricsCallback> RefreshMetricsCallbacks; 830 typedef std::list<OrthancPluginRefreshMetricsCallback> RefreshMetricsCallbacks;
831 typedef std::list<StorageCommitmentScp*> StorageCommitmentScpCallbacks;
727 typedef std::map<Property, std::string> Properties; 832 typedef std::map<Property, std::string> Properties;
728 833
729 PluginsManager manager_; 834 PluginsManager manager_;
730 835
731 RestCallbacks restCallbacks_; 836 RestCallbacks restCallbacks_;
738 JobsUnserializers jobsUnserializers_; 843 JobsUnserializers jobsUnserializers_;
739 _OrthancPluginMoveCallback moveCallbacks_; 844 _OrthancPluginMoveCallback moveCallbacks_;
740 IncomingHttpRequestFilters incomingHttpRequestFilters_; 845 IncomingHttpRequestFilters incomingHttpRequestFilters_;
741 IncomingHttpRequestFilters2 incomingHttpRequestFilters2_; 846 IncomingHttpRequestFilters2 incomingHttpRequestFilters2_;
742 RefreshMetricsCallbacks refreshMetricsCallbacks_; 847 RefreshMetricsCallbacks refreshMetricsCallbacks_;
743 std::auto_ptr<StorageAreaFactory> storageArea_; 848 StorageCommitmentScpCallbacks storageCommitmentScpCallbacks_;
849 std::unique_ptr<StorageAreaFactory> storageArea_;
744 850
745 boost::recursive_mutex restCallbackMutex_; 851 boost::recursive_mutex restCallbackMutex_;
746 boost::recursive_mutex storedCallbackMutex_; 852 boost::recursive_mutex storedCallbackMutex_;
747 boost::recursive_mutex changeCallbackMutex_; 853 boost::recursive_mutex changeCallbackMutex_;
748 boost::mutex findCallbackMutex_; 854 boost::mutex findCallbackMutex_;
749 boost::mutex worklistCallbackMutex_; 855 boost::mutex worklistCallbackMutex_;
750 boost::mutex decodeImageCallbackMutex_; 856 boost::mutex decodeImageCallbackMutex_;
751 boost::mutex jobsUnserializersMutex_; 857 boost::mutex jobsUnserializersMutex_;
752 boost::mutex refreshMetricsMutex_; 858 boost::mutex refreshMetricsMutex_;
859 boost::mutex storageCommitmentScpMutex_;
753 boost::recursive_mutex invokeServiceMutex_; 860 boost::recursive_mutex invokeServiceMutex_;
754 861
755 Properties properties_; 862 Properties properties_;
756 int argc_; 863 int argc_;
757 char** argv_; 864 char** argv_;
758 std::auto_ptr<OrthancPluginDatabase> database_; 865 std::unique_ptr<OrthancPluginDatabase> database_;
759 PluginsErrorDictionary dictionary_; 866 PluginsErrorDictionary dictionary_;
760 867
761 PImpl() : 868 PImpl() :
762 context_(NULL), 869 context_(NULL),
763 findCallback_(NULL), 870 findCallback_(NULL),
773 880
774 class OrthancPlugins::WorklistHandler : public IWorklistRequestHandler 881 class OrthancPlugins::WorklistHandler : public IWorklistRequestHandler
775 { 882 {
776 private: 883 private:
777 OrthancPlugins& that_; 884 OrthancPlugins& that_;
778 std::auto_ptr<HierarchicalMatcher> matcher_; 885 std::unique_ptr<HierarchicalMatcher> matcher_;
779 std::auto_ptr<ParsedDicomFile> filtered_; 886 std::unique_ptr<ParsedDicomFile> filtered_;
780 ParsedDicomFile* currentQuery_; 887 ParsedDicomFile* currentQuery_;
781 888
782 void Reset() 889 void Reset()
783 { 890 {
784 matcher_.reset(); 891 matcher_.reset();
822 call.PushJson(origin); 929 call.PushJson(origin);
823 930
824 Json::Value target; 931 Json::Value target;
825 call.ExecuteToJson(target, true); 932 call.ExecuteToJson(target, true);
826 933
827 filtered_.reset(ParsedDicomFile::CreateFromJson(target, DicomFromJsonFlags_None)); 934 filtered_.reset(ParsedDicomFile::CreateFromJson(target, DicomFromJsonFlags_None,
935 "" /* no private creator */));
828 currentQuery_ = filtered_.get(); 936 currentQuery_ = filtered_.get();
829 } 937 }
830 } 938 }
831 939
832 matcher_.reset(new HierarchicalMatcher(*currentQuery_)); 940 matcher_.reset(new HierarchicalMatcher(*currentQuery_));
886 { 994 {
887 throw OrthancException(ErrorCode_Plugin); 995 throw OrthancException(ErrorCode_Plugin);
888 } 996 }
889 997
890 ParsedDicomFile f(dicom, size); 998 ParsedDicomFile f(dicom, size);
891 std::auto_ptr<ParsedDicomFile> summary(matcher_->Extract(f)); 999 std::unique_ptr<ParsedDicomFile> summary(matcher_->Extract(f));
892 reinterpret_cast<DicomFindAnswers*>(answers)->Add(*summary); 1000 reinterpret_cast<DicomFindAnswers*>(answers)->Add(*summary);
893 } 1001 }
894 }; 1002 };
895 1003
896 1004
897 class OrthancPlugins::FindHandler : public IFindRequestHandler 1005 class OrthancPlugins::FindHandler : public IFindRequestHandler
898 { 1006 {
899 private: 1007 private:
900 OrthancPlugins& that_; 1008 OrthancPlugins& that_;
901 std::auto_ptr<DicomArray> currentQuery_; 1009 std::unique_ptr<DicomArray> currentQuery_;
902 1010
903 void Reset() 1011 void Reset()
904 { 1012 {
905 currentQuery_.reset(NULL); 1013 currentQuery_.reset(NULL);
906 } 1014 }
1258 sizeof(int32_t) != sizeof(OrthancPluginInstanceOrigin) || 1366 sizeof(int32_t) != sizeof(OrthancPluginInstanceOrigin) ||
1259 sizeof(int32_t) != sizeof(OrthancPluginJobStepStatus) || 1367 sizeof(int32_t) != sizeof(OrthancPluginJobStepStatus) ||
1260 sizeof(int32_t) != sizeof(OrthancPluginConstraintType) || 1368 sizeof(int32_t) != sizeof(OrthancPluginConstraintType) ||
1261 sizeof(int32_t) != sizeof(OrthancPluginMetricsType) || 1369 sizeof(int32_t) != sizeof(OrthancPluginMetricsType) ||
1262 sizeof(int32_t) != sizeof(OrthancPluginDicomWebBinaryMode) || 1370 sizeof(int32_t) != sizeof(OrthancPluginDicomWebBinaryMode) ||
1371 sizeof(int32_t) != sizeof(OrthancPluginStorageCommitmentFailureReason) ||
1263 static_cast<int>(OrthancPluginDicomToJsonFlags_IncludeBinary) != static_cast<int>(DicomToJsonFlags_IncludeBinary) || 1372 static_cast<int>(OrthancPluginDicomToJsonFlags_IncludeBinary) != static_cast<int>(DicomToJsonFlags_IncludeBinary) ||
1264 static_cast<int>(OrthancPluginDicomToJsonFlags_IncludePrivateTags) != static_cast<int>(DicomToJsonFlags_IncludePrivateTags) || 1373 static_cast<int>(OrthancPluginDicomToJsonFlags_IncludePrivateTags) != static_cast<int>(DicomToJsonFlags_IncludePrivateTags) ||
1265 static_cast<int>(OrthancPluginDicomToJsonFlags_IncludeUnknownTags) != static_cast<int>(DicomToJsonFlags_IncludeUnknownTags) || 1374 static_cast<int>(OrthancPluginDicomToJsonFlags_IncludeUnknownTags) != static_cast<int>(DicomToJsonFlags_IncludeUnknownTags) ||
1266 static_cast<int>(OrthancPluginDicomToJsonFlags_IncludePixelData) != static_cast<int>(DicomToJsonFlags_IncludePixelData) || 1375 static_cast<int>(OrthancPluginDicomToJsonFlags_IncludePixelData) != static_cast<int>(DicomToJsonFlags_IncludePixelData) ||
1267 static_cast<int>(OrthancPluginDicomToJsonFlags_ConvertBinaryToNull) != static_cast<int>(DicomToJsonFlags_ConvertBinaryToNull) || 1376 static_cast<int>(OrthancPluginDicomToJsonFlags_ConvertBinaryToNull) != static_cast<int>(DicomToJsonFlags_ConvertBinaryToNull) ||
1301 for (PImpl::ChunkedRestCallbacks::iterator it = pimpl_->chunkedRestCallbacks_.begin(); 1410 for (PImpl::ChunkedRestCallbacks::iterator it = pimpl_->chunkedRestCallbacks_.begin();
1302 it != pimpl_->chunkedRestCallbacks_.end(); ++it) 1411 it != pimpl_->chunkedRestCallbacks_.end(); ++it)
1303 { 1412 {
1304 delete *it; 1413 delete *it;
1305 } 1414 }
1415
1416 for (PImpl::StorageCommitmentScpCallbacks::iterator
1417 it = pimpl_->storageCommitmentScpCallbacks_.begin();
1418 it != pimpl_->storageCommitmentScpCallbacks_.end(); ++it)
1419 {
1420 delete *it;
1421 }
1306 } 1422 }
1307 1423
1308 1424
1309 static void ArgumentsToPlugin(std::vector<const char*>& keys, 1425 static void ArgumentsToPlugin(std::vector<const char*>& keys,
1310 std::vector<const char*>& values, 1426 std::vector<const char*>& values,
1348 std::vector<std::string> groups_; 1464 std::vector<std::string> groups_;
1349 std::vector<const char*> cgroups_; 1465 std::vector<const char*> cgroups_;
1350 1466
1351 public: 1467 public:
1352 RestCallbackMatcher(const UriComponents& uri) : 1468 RestCallbackMatcher(const UriComponents& uri) :
1353 flatUri_(Toolbox::FlattenUri(uri)) 1469 flatUri_(Toolbox::FlattenUri(uri))
1354 { 1470 {
1355 } 1471 }
1356 1472
1357 bool IsMatch(const boost::regex& re) 1473 bool IsMatch(const boost::regex& re)
1358 { 1474 {
1861 LOG(INFO) << "Plugin has registered a callback to refresh its metrics"; 1977 LOG(INFO) << "Plugin has registered a callback to refresh its metrics";
1862 pimpl_->refreshMetricsCallbacks_.push_back(p.callback); 1978 pimpl_->refreshMetricsCallbacks_.push_back(p.callback);
1863 } 1979 }
1864 1980
1865 1981
1982 void OrthancPlugins::RegisterStorageCommitmentScpCallback(const void* parameters)
1983 {
1984 const _OrthancPluginRegisterStorageCommitmentScpCallback& p =
1985 *reinterpret_cast<const _OrthancPluginRegisterStorageCommitmentScpCallback*>(parameters);
1986
1987 boost::mutex::scoped_lock lock(pimpl_->storageCommitmentScpMutex_);
1988 LOG(INFO) << "Plugin has registered a storage commitment callback";
1989
1990 pimpl_->storageCommitmentScpCallbacks_.push_back(new PImpl::StorageCommitmentScp(p));
1991 }
1992
1993
1866 void OrthancPlugins::AnswerBuffer(const void* parameters) 1994 void OrthancPlugins::AnswerBuffer(const void* parameters)
1867 { 1995 {
1868 const _OrthancPluginAnswerBuffer& p = 1996 const _OrthancPluginAnswerBuffer& p =
1869 *reinterpret_cast<const _OrthancPluginAnswerBuffer*>(parameters); 1997 *reinterpret_cast<const _OrthancPluginAnswerBuffer*>(parameters);
1870 1998
2353 *reinterpret_cast<const _OrthancPluginBufferCompression*>(parameters); 2481 *reinterpret_cast<const _OrthancPluginBufferCompression*>(parameters);
2354 2482
2355 std::string result; 2483 std::string result;
2356 2484
2357 { 2485 {
2358 std::auto_ptr<DeflateBaseCompressor> compressor; 2486 std::unique_ptr<DeflateBaseCompressor> compressor;
2359 2487
2360 switch (p.compression) 2488 switch (p.compression)
2361 { 2489 {
2362 case OrthancPluginCompressionType_Zlib: 2490 case OrthancPluginCompressionType_Zlib:
2363 { 2491 {
2403 2531
2404 CopyToMemoryBuffer(*p.target, result); 2532 CopyToMemoryBuffer(*p.target, result);
2405 } 2533 }
2406 2534
2407 2535
2408 static OrthancPluginImage* ReturnImage(std::auto_ptr<ImageAccessor>& image) 2536 static OrthancPluginImage* ReturnImage(std::unique_ptr<ImageAccessor>& image)
2409 { 2537 {
2410 // Images returned to plugins are assumed to be writeable. If the 2538 // Images returned to plugins are assumed to be writeable. If the
2411 // input image is read-only, we return a copy so that it can be modified. 2539 // input image is read-only, we return a copy so that it can be modified.
2412 2540
2413 if (image->IsReadOnly()) 2541 if (image->IsReadOnly())
2414 { 2542 {
2415 std::auto_ptr<Image> copy(new Image(image->GetFormat(), image->GetWidth(), image->GetHeight(), false)); 2543 std::unique_ptr<Image> copy(new Image(image->GetFormat(), image->GetWidth(), image->GetHeight(), false));
2416 ImageProcessing::Copy(*copy, *image); 2544 ImageProcessing::Copy(*copy, *image);
2417 image.reset(NULL); 2545 image.reset(NULL);
2418 return reinterpret_cast<OrthancPluginImage*>(copy.release()); 2546 return reinterpret_cast<OrthancPluginImage*>(copy.release());
2419 } 2547 }
2420 else 2548 else
2426 2554
2427 void OrthancPlugins::UncompressImage(const void* parameters) 2555 void OrthancPlugins::UncompressImage(const void* parameters)
2428 { 2556 {
2429 const _OrthancPluginUncompressImage& p = *reinterpret_cast<const _OrthancPluginUncompressImage*>(parameters); 2557 const _OrthancPluginUncompressImage& p = *reinterpret_cast<const _OrthancPluginUncompressImage*>(parameters);
2430 2558
2431 std::auto_ptr<ImageAccessor> image; 2559 std::unique_ptr<ImageAccessor> image;
2432 2560
2433 switch (p.format) 2561 switch (p.format)
2434 { 2562 {
2435 case OrthancPluginImageFormat_Png: 2563 case OrthancPluginImageFormat_Png:
2436 { 2564 {
2810 void OrthancPlugins::ConvertPixelFormat(const void* parameters) 2938 void OrthancPlugins::ConvertPixelFormat(const void* parameters)
2811 { 2939 {
2812 const _OrthancPluginConvertPixelFormat& p = *reinterpret_cast<const _OrthancPluginConvertPixelFormat*>(parameters); 2940 const _OrthancPluginConvertPixelFormat& p = *reinterpret_cast<const _OrthancPluginConvertPixelFormat*>(parameters);
2813 const ImageAccessor& source = *reinterpret_cast<const ImageAccessor*>(p.source); 2941 const ImageAccessor& source = *reinterpret_cast<const ImageAccessor*>(p.source);
2814 2942
2815 std::auto_ptr<ImageAccessor> target(new Image(Plugins::Convert(p.targetFormat), source.GetWidth(), source.GetHeight(), false)); 2943 std::unique_ptr<ImageAccessor> target(new Image(Plugins::Convert(p.targetFormat), source.GetWidth(), source.GetHeight(), false));
2816 ImageProcessing::Convert(*target, source); 2944 ImageProcessing::Convert(*target, source);
2817 2945
2818 *(p.target) = ReturnImage(target); 2946 *(p.target) = ReturnImage(target);
2819 } 2947 }
2820 2948
2863 const void* parameters) 2991 const void* parameters)
2864 { 2992 {
2865 const _OrthancPluginDicomToJson& p = 2993 const _OrthancPluginDicomToJson& p =
2866 *reinterpret_cast<const _OrthancPluginDicomToJson*>(parameters); 2994 *reinterpret_cast<const _OrthancPluginDicomToJson*>(parameters);
2867 2995
2868 std::auto_ptr<ParsedDicomFile> dicom; 2996 std::unique_ptr<ParsedDicomFile> dicom;
2869 2997
2870 if (service == _OrthancPluginService_DicomBufferToJson) 2998 if (service == _OrthancPluginService_DicomBufferToJson)
2871 { 2999 {
2872 dicom.reset(new ParsedDicomFile(p.buffer, p.size)); 3000 dicom.reset(new ParsedDicomFile(p.buffer, p.size));
2873 } 3001 }
2919 } 3047 }
2920 3048
2921 std::string dicom; 3049 std::string dicom;
2922 3050
2923 { 3051 {
2924 std::auto_ptr<ParsedDicomFile> file 3052 // Fix issue 168 (Plugins can't read private tags from the
2925 (ParsedDicomFile::CreateFromJson(json, static_cast<DicomFromJsonFlags>(p.flags))); 3053 // configuration file)
3054 // https://bitbucket.org/sjodogne/orthanc/issues/168/
3055 std::string privateCreator;
3056 {
3057 OrthancConfiguration::ReaderLock lock;
3058 privateCreator = lock.GetConfiguration().GetDefaultPrivateCreator();
3059 }
3060
3061 std::unique_ptr<ParsedDicomFile> file
3062 (ParsedDicomFile::CreateFromJson(json, static_cast<DicomFromJsonFlags>(p.flags),
3063 privateCreator));
2926 3064
2927 if (p.pixelData) 3065 if (p.pixelData)
2928 { 3066 {
2929 file->EmbedImage(*reinterpret_cast<const ImageAccessor*>(p.pixelData)); 3067 file->EmbedImage(*reinterpret_cast<const ImageAccessor*>(p.pixelData));
2930 } 3068 }
2982 const void* parameters) 3120 const void* parameters)
2983 { 3121 {
2984 const _OrthancPluginCreateImage& p = 3122 const _OrthancPluginCreateImage& p =
2985 *reinterpret_cast<const _OrthancPluginCreateImage*>(parameters); 3123 *reinterpret_cast<const _OrthancPluginCreateImage*>(parameters);
2986 3124
2987 std::auto_ptr<ImageAccessor> result; 3125 std::unique_ptr<ImageAccessor> result;
2988 3126
2989 switch (service) 3127 switch (service)
2990 { 3128 {
2991 case _OrthancPluginService_CreateImage: 3129 case _OrthancPluginService_CreateImage:
2992 result.reset(new Image(Plugins::Convert(p.format), p.width, p.height, false)); 3130 result.reset(new Image(Plugins::Convert(p.format), p.width, p.height, false));
3093 3231
3094 DicomTag tag(FromDcmtkBridge::ParseTag(p.name)); 3232 DicomTag tag(FromDcmtkBridge::ParseTag(p.name));
3095 DcmTagKey tag2(tag.GetGroup(), tag.GetElement()); 3233 DcmTagKey tag2(tag.GetGroup(), tag.GetElement());
3096 3234
3097 DictionaryReadLocker locker; 3235 DictionaryReadLocker locker;
3098 const DcmDictEntry* entry = locker->findEntry(tag2, NULL); 3236 const DcmDictEntry* entry = NULL;
3237
3238 if (tag.IsPrivate())
3239 {
3240 // Fix issue 168 (Plugins can't read private tags from the
3241 // configuration file)
3242 // https://bitbucket.org/sjodogne/orthanc/issues/168/
3243 std::string privateCreator;
3244 {
3245 OrthancConfiguration::ReaderLock lock;
3246 privateCreator = lock.GetConfiguration().GetDefaultPrivateCreator();
3247 }
3248
3249 entry = locker->findEntry(tag2, privateCreator.c_str());
3250 }
3251 else
3252 {
3253 entry = locker->findEntry(tag2, NULL);
3254 }
3099 3255
3100 if (entry == NULL) 3256 if (entry == NULL)
3101 { 3257 {
3102 throw OrthancException(ErrorCode_UnknownDicomTag); 3258 throw OrthancException(ErrorCode_UnknownDicomTag);
3103 } 3259 }
3880 4036
3881 case _OrthancPluginService_RegisterRefreshMetricsCallback: 4037 case _OrthancPluginService_RegisterRefreshMetricsCallback:
3882 RegisterRefreshMetricsCallback(parameters); 4038 RegisterRefreshMetricsCallback(parameters);
3883 return true; 4039 return true;
3884 4040
4041 case _OrthancPluginService_RegisterStorageCommitmentScpCallback:
4042 RegisterStorageCommitmentScpCallback(parameters);
4043 return true;
4044
3885 case _OrthancPluginService_RegisterStorageArea: 4045 case _OrthancPluginService_RegisterStorageArea:
3886 { 4046 {
3887 LOG(INFO) << "Plugin has registered a custom storage area"; 4047 LOG(INFO) << "Plugin has registered a custom storage area";
3888 const _OrthancPluginRegisterStorageArea& p = 4048 const _OrthancPluginRegisterStorageArea& p =
3889 *reinterpret_cast<const _OrthancPluginRegisterStorageArea*>(parameters); 4049 *reinterpret_cast<const _OrthancPluginRegisterStorageArea*>(parameters);
4450 pluginOutput.Close(error, errorDictionary_); 4610 pluginOutput.Close(error, errorDictionary_);
4451 } 4611 }
4452 }; 4612 };
4453 4613
4454 4614
4455 bool OrthancPlugins::CreateChunkedRequestReader(std::auto_ptr<IChunkedRequestReader>& target, 4615 bool OrthancPlugins::CreateChunkedRequestReader(std::unique_ptr<IChunkedRequestReader>& target,
4456 RequestOrigin origin, 4616 RequestOrigin origin,
4457 const char* remoteIp, 4617 const char* remoteIp,
4458 const char* username, 4618 const char* username,
4459 HttpMethod method, 4619 HttpMethod method,
4460 const UriComponents& uri, 4620 const UriComponents& uri,
4537 return true; 4697 return true;
4538 } 4698 }
4539 } 4699 }
4540 } 4700 }
4541 } 4701 }
4702
4703
4704 IStorageCommitmentFactory::ILookupHandler* OrthancPlugins::CreateStorageCommitment(
4705 const std::string& jobId,
4706 const std::string& transactionUid,
4707 const std::vector<std::string>& sopClassUids,
4708 const std::vector<std::string>& sopInstanceUids,
4709 const std::string& remoteAet,
4710 const std::string& calledAet)
4711 {
4712 boost::mutex::scoped_lock lock(pimpl_->storageCommitmentScpMutex_);
4713
4714 for (PImpl::StorageCommitmentScpCallbacks::iterator
4715 it = pimpl_->storageCommitmentScpCallbacks_.begin();
4716 it != pimpl_->storageCommitmentScpCallbacks_.end(); ++it)
4717 {
4718 assert(*it != NULL);
4719 IStorageCommitmentFactory::ILookupHandler* handler = (*it)->CreateStorageCommitment
4720 (jobId, transactionUid, sopClassUids, sopInstanceUids, remoteAet, calledAet);
4721
4722 if (handler != NULL)
4723 {
4724 return handler;
4725 }
4726 }
4727
4728 return NULL;
4729 }
4542 } 4730 }