Mercurial > hg > orthanc
comparison OrthancServer/OrthancRestApi.cpp @ 646:fb49bf72ac2d
fix issue #7
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 30 Oct 2013 08:58:45 +0100 |
parents | 60d90e48e809 |
children | bcf5c9a767a9 |
comparison
equal
deleted
inserted
replaced
645:75af92b18e23 | 646:fb49bf72ac2d |
---|---|
44 #include <dcmtk/dcmdata/dcistrmb.h> | 44 #include <dcmtk/dcmdata/dcistrmb.h> |
45 #include <dcmtk/dcmdata/dcfilefo.h> | 45 #include <dcmtk/dcmdata/dcfilefo.h> |
46 #include <boost/lexical_cast.hpp> | 46 #include <boost/lexical_cast.hpp> |
47 #include <glog/logging.h> | 47 #include <glog/logging.h> |
48 | 48 |
49 static const uint64_t MEGA_BYTES = 1024 * 1024; | |
50 static const uint64_t GIGA_BYTES = 1024 * 1024 * 1024; | |
51 | |
49 | 52 |
50 #define RETRIEVE_CONTEXT(call) \ | 53 #define RETRIEVE_CONTEXT(call) \ |
51 OrthancRestApi& contextApi = \ | 54 OrthancRestApi& contextApi = \ |
52 dynamic_cast<OrthancRestApi&>(call.GetContext()); \ | 55 dynamic_cast<OrthancRestApi&>(call.GetContext()); \ |
53 ServerContext& context = contextApi.GetContext() | 56 ServerContext& context = contextApi.GetContext() |
549 static bool ArchiveInternal(HierarchicalZipWriter& writer, | 552 static bool ArchiveInternal(HierarchicalZipWriter& writer, |
550 ServerContext& context, | 553 ServerContext& context, |
551 const std::string& publicId, | 554 const std::string& publicId, |
552 ResourceType resourceType, | 555 ResourceType resourceType, |
553 bool isFirstLevel) | 556 bool isFirstLevel) |
554 { | 557 { |
555 Json::Value resource; | 558 Json::Value resource; |
556 if (!context.GetIndex().LookupResource(resource, publicId, resourceType)) | 559 if (!context.GetIndex().LookupResource(resource, publicId, resourceType)) |
557 { | 560 { |
558 return false; | 561 return false; |
559 } | 562 } |
560 | 563 |
561 if (isFirstLevel && | 564 if (isFirstLevel && |
562 !CreateRootDirectoryInArchive(writer, context, resource, resourceType)) | 565 !CreateRootDirectoryInArchive(writer, context, resource, resourceType)) |
563 { | 566 { |
564 return false; | 567 return false; |
610 | 613 |
611 template <enum ResourceType resourceType> | 614 template <enum ResourceType resourceType> |
612 static void GetArchive(RestApi::GetCall& call) | 615 static void GetArchive(RestApi::GetCall& call) |
613 { | 616 { |
614 RETRIEVE_CONTEXT(call); | 617 RETRIEVE_CONTEXT(call); |
618 std::string id = call.GetUriComponent("id", ""); | |
619 | |
620 /** | |
621 * Determine whether ZIP64 is required. Original ZIP format can | |
622 * store up to 2GB of data (some implementation supporting up to | |
623 * 4GB of data), and up to 65535 files. | |
624 * https://en.wikipedia.org/wiki/Zip_(file_format)#ZIP64 | |
625 **/ | |
626 | |
627 uint64_t uncompressedSize; | |
628 uint64_t compressedSize; | |
629 unsigned int countStudies; | |
630 unsigned int countSeries; | |
631 unsigned int countInstances; | |
632 context.GetIndex().GetStatistics(compressedSize, uncompressedSize, | |
633 countStudies, countSeries, countInstances, id); | |
634 const bool isZip64 = (uncompressedSize >= 2 * GIGA_BYTES || | |
635 countInstances >= 65535); | |
636 | |
637 LOG(INFO) << "Creating a ZIP file with " << countInstances << " files of size " | |
638 << (uncompressedSize / MEGA_BYTES) << "MB using the " | |
639 << (isZip64 ? "ZIP64" : "ZIP32") << " file format"; | |
615 | 640 |
616 // Create a RAII for the temporary file to manage the ZIP file | 641 // Create a RAII for the temporary file to manage the ZIP file |
617 Toolbox::TemporaryFile tmp; | 642 Toolbox::TemporaryFile tmp; |
618 std::string id = call.GetUriComponent("id", ""); | |
619 | 643 |
620 { | 644 { |
621 // Create a ZIP writer | 645 // Create a ZIP writer |
622 HierarchicalZipWriter writer(tmp.GetPath().c_str()); | 646 HierarchicalZipWriter writer(tmp.GetPath().c_str()); |
647 writer.SetZip64(isZip64); | |
623 | 648 |
624 // Store the requested resource into the ZIP | 649 // Store the requested resource into the ZIP |
625 if (!ArchiveInternal(writer, context, id, resourceType, true)) | 650 if (!ArchiveInternal(writer, context, id, resourceType, true)) |
626 { | 651 { |
627 return; | 652 return; |