Mercurial > hg > orthanc
comparison OrthancServer/OrthancRestApi/OrthancRestArchive.cpp @ 2629:db895b36f4c5 jobs
reorganization
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 25 May 2018 15:13:45 +0200 |
parents | 7ba7d5806911 |
children | 00327e989458 |
comparison
equal
deleted
inserted
replaced
2628:7ba7d5806911 | 2629:db895b36f4c5 |
---|---|
347 } | 347 } |
348 }; | 348 }; |
349 | 349 |
350 | 350 |
351 | 351 |
352 class ArchiveCommands : public boost::noncopyable | 352 class ZipCommands : public boost::noncopyable |
353 { | 353 { |
354 private: | 354 private: |
355 enum Type | 355 enum Type |
356 { | 356 { |
357 Type_OpenDirectory, | 357 Type_OpenDirectory, |
459 | 459 |
460 commands_[index]->Apply(writer, context, dicomDir, dicomDirFolder); | 460 commands_[index]->Apply(writer, context, dicomDir, dicomDirFolder); |
461 } | 461 } |
462 | 462 |
463 public: | 463 public: |
464 ArchiveCommands() : | 464 ZipCommands() : |
465 uncompressedSize_(0), | 465 uncompressedSize_(0), |
466 instancesCount_(0) | 466 instancesCount_(0) |
467 { | 467 { |
468 } | 468 } |
469 | 469 |
470 ~ArchiveCommands() | 470 ~ZipCommands() |
471 { | 471 { |
472 for (std::deque<Command*>::iterator it = commands_.begin(); | 472 for (std::deque<Command*>::iterator it = commands_.begin(); |
473 it != commands_.end(); ++it) | 473 it != commands_.end(); ++it) |
474 { | 474 { |
475 assert(*it != NULL); | 475 assert(*it != NULL); |
536 | 536 |
537 | 537 |
538 class ArchiveIndexVisitor : public IArchiveVisitor | 538 class ArchiveIndexVisitor : public IArchiveVisitor |
539 { | 539 { |
540 private: | 540 private: |
541 ArchiveCommands& commands_; | 541 ZipCommands& commands_; |
542 ServerContext& context_; | 542 ServerContext& context_; |
543 char instanceFormat_[24]; | 543 char instanceFormat_[24]; |
544 unsigned int counter_; | 544 unsigned int counter_; |
545 | 545 |
546 static std::string GetTag(const DicomMap& tags, | 546 static std::string GetTag(const DicomMap& tags, |
547 const DicomTag& tag) | 547 const DicomTag& tag) |
548 { | 548 { |
549 const DicomValue* v = tags.TestAndGetValue(tag); | 549 const DicomValue* v = tags.TestAndGetValue(tag); |
558 return ""; | 558 return ""; |
559 } | 559 } |
560 } | 560 } |
561 | 561 |
562 public: | 562 public: |
563 ArchiveIndexVisitor(ArchiveCommands& commands, | 563 ArchiveIndexVisitor(ZipCommands& commands, |
564 ServerContext& context) : | 564 ServerContext& context) : |
565 commands_(commands), | 565 commands_(commands), |
566 context_(context), | 566 context_(context), |
567 counter_(0) | 567 counter_(0) |
568 { | 568 { |
650 | 650 |
651 | 651 |
652 class MediaIndexVisitor : public IArchiveVisitor | 652 class MediaIndexVisitor : public IArchiveVisitor |
653 { | 653 { |
654 private: | 654 private: |
655 ArchiveCommands& commands_; | 655 ZipCommands& commands_; |
656 ServerContext& context_; | 656 ServerContext& context_; |
657 unsigned int counter_; | 657 unsigned int counter_; |
658 | 658 |
659 public: | 659 public: |
660 MediaIndexVisitor(ArchiveCommands& commands, | 660 MediaIndexVisitor(ZipCommands& commands, |
661 ServerContext& context) : | 661 ServerContext& context) : |
662 commands_(commands), | 662 commands_(commands), |
663 context_(context), | 663 context_(context), |
664 counter_(0) | 664 counter_(0) |
665 { | 665 { |
686 counter_ ++; | 686 counter_ ++; |
687 } | 687 } |
688 }; | 688 }; |
689 | 689 |
690 | 690 |
691 static const char* IMAGES_FOLDER = "IMAGES"; | |
692 | |
693 | |
694 class ZipWriterIterator : public boost::noncopyable | |
695 { | |
696 private: | |
697 TemporaryFile& target_; | |
698 ServerContext& context_; | |
699 ZipCommands commands_; | |
700 std::auto_ptr<HierarchicalZipWriter> zip_; | |
701 std::auto_ptr<DicomDirWriter> dicomDir_; | |
702 bool isMedia_; | |
703 | |
704 public: | |
705 ZipWriterIterator(TemporaryFile& target, | |
706 ServerContext& context, | |
707 ArchiveIndex& archive, | |
708 bool isMedia, | |
709 bool enableExtendedSopClass) : | |
710 target_(target), | |
711 context_(context), | |
712 isMedia_(isMedia) | |
713 { | |
714 if (isMedia) | |
715 { | |
716 MediaIndexVisitor visitor(commands_, context); | |
717 archive.Expand(context.GetIndex()); | |
718 | |
719 commands_.AddOpenDirectory(IMAGES_FOLDER); | |
720 archive.Apply(visitor); | |
721 commands_.AddCloseDirectory(); | |
722 | |
723 dicomDir_.reset(new DicomDirWriter); | |
724 dicomDir_->EnableExtendedSopClass(enableExtendedSopClass); | |
725 } | |
726 else | |
727 { | |
728 ArchiveIndexVisitor visitor(commands_, context); | |
729 archive.Expand(context.GetIndex()); | |
730 archive.Apply(visitor); | |
731 } | |
732 | |
733 zip_.reset(new HierarchicalZipWriter(target.GetPath().c_str())); | |
734 zip_->SetZip64(commands_.IsZip64()); | |
735 } | |
736 | |
737 size_t GetStepsCount() const | |
738 { | |
739 return commands_.GetSize() + 1; | |
740 } | |
741 | |
742 void RunStep(size_t index) | |
743 { | |
744 if (index > commands_.GetSize()) | |
745 { | |
746 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
747 } | |
748 else if (index == commands_.GetSize()) | |
749 { | |
750 // Last step: Add the DICOMDIR | |
751 if (isMedia_) | |
752 { | |
753 assert(dicomDir_.get() != NULL); | |
754 std::string s; | |
755 dicomDir_->Encode(s); | |
756 | |
757 zip_->OpenFile("DICOMDIR"); | |
758 zip_->Write(s); | |
759 } | |
760 } | |
761 else | |
762 { | |
763 if (isMedia_) | |
764 { | |
765 assert(dicomDir_.get() != NULL); | |
766 commands_.Apply(*zip_, context_, index, *dicomDir_, IMAGES_FOLDER); | |
767 } | |
768 else | |
769 { | |
770 assert(dicomDir_.get() == NULL); | |
771 commands_.Apply(*zip_, context_, index); | |
772 } | |
773 } | |
774 } | |
775 | |
776 void RunAllSteps() | |
777 { | |
778 for (size_t i = 0; i < GetStepsCount(); i++) | |
779 { | |
780 RunStep(i); | |
781 } | |
782 } | |
783 }; | |
784 | |
785 | |
691 static void CreateArchive(TemporaryFile& tmp, | 786 static void CreateArchive(TemporaryFile& tmp, |
692 ServerContext& context, | 787 ServerContext& context, |
693 ArchiveIndex& archive) | 788 ArchiveIndex& archive) |
694 { | 789 { |
695 ArchiveCommands commands; | 790 ZipWriterIterator writer(tmp, context, archive, false, false); |
696 | 791 writer.RunAllSteps(); |
697 { | |
698 ArchiveIndexVisitor visitor(commands, context); | |
699 archive.Expand(context.GetIndex()); | |
700 archive.Apply(visitor); | |
701 } | |
702 | |
703 HierarchicalZipWriter writer(tmp.GetPath().c_str()); | |
704 writer.SetZip64(commands.IsZip64()); | |
705 | |
706 for (size_t i = 0; i < commands.GetSize(); i++) | |
707 { | |
708 commands.Apply(writer, context, i); | |
709 } | |
710 } | 792 } |
711 | 793 |
712 | 794 |
713 static void CreateMedia(TemporaryFile& tmp, | 795 static void CreateMedia(TemporaryFile& tmp, |
714 ServerContext& context, | 796 ServerContext& context, |
715 ArchiveIndex& archive, | 797 ArchiveIndex& archive, |
716 bool enableExtendedSopClass) | 798 bool enableExtendedSopClass) |
717 { | 799 { |
718 static const char* IMAGES_FOLDER = "IMAGES"; | 800 ZipWriterIterator writer(tmp, context, archive, true, enableExtendedSopClass); |
719 | 801 writer.RunAllSteps(); |
720 ArchiveCommands commands; | |
721 | |
722 { | |
723 MediaIndexVisitor visitor(commands, context); | |
724 archive.Expand(context.GetIndex()); | |
725 | |
726 commands.AddOpenDirectory(IMAGES_FOLDER); | |
727 archive.Apply(visitor); | |
728 commands.AddCloseDirectory(); | |
729 } | |
730 | |
731 DicomDirWriter dicomDir; | |
732 dicomDir.EnableExtendedSopClass(enableExtendedSopClass); | |
733 | |
734 HierarchicalZipWriter writer(tmp.GetPath().c_str()); | |
735 writer.SetZip64(commands.IsZip64()); | |
736 | |
737 for (size_t i = 0; i < commands.GetSize(); i++) | |
738 { | |
739 commands.Apply(writer, context, i, dicomDir, IMAGES_FOLDER); | |
740 } | |
741 | |
742 // Add the DICOMDIR | |
743 writer.OpenFile("DICOMDIR"); | |
744 std::string s; | |
745 dicomDir.Encode(s); | |
746 writer.Write(s); | |
747 } | 802 } |
748 | 803 |
749 | 804 |
750 static void SendTemporaryFile(RestApiOutput& output, | 805 static void SendTemporaryFile(RestApiOutput& output, |
751 TemporaryFile& tmp, | 806 TemporaryFile& tmp, |