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,