diff OrthancServer/ParsedDicomFile.cpp @ 1519:8bd0d897763f

refactoring: IHttpStreamAnswer
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 11 Aug 2015 13:15:16 +0200
parents f967bdf8534e
children 4a503a8c7749
line wrap: on
line diff
--- a/OrthancServer/ParsedDicomFile.cpp	Tue Aug 11 10:36:05 2015 +0200
+++ b/OrthancServer/ParsedDicomFile.cpp	Tue Aug 11 13:15:16 2015 +0200
@@ -255,46 +255,93 @@
   }
 
 
-  static void AnswerDicomField(RestApiOutput& output,
-                               DcmElement& element,
-                               E_TransferSyntax transferSyntax)
+  namespace
   {
-    // This element is nor a sequence, neither a pixel-data
-    std::string buffer;
-    buffer.resize(65536);
-    Uint32 length = element.getLength(transferSyntax);
-    Uint32 offset = 0;
+    class DicomFieldStream : public IHttpStreamAnswer
+    {
+    private:
+      DcmElement&  element_;
+      uint32_t     length_;
+      uint32_t     offset_;
+      std::string  chunk_;
+      size_t       chunkSize_;
+      
+    public:
+      DicomFieldStream(DcmElement& element,
+                       E_TransferSyntax transferSyntax) :
+        element_(element),
+        length_(element.getLength(transferSyntax)),
+        offset_(0)
+      {
+        static const size_t CHUNK_SIZE = 64 * 1024;  // Use a 64KB chunk
+        chunk_.resize(CHUNK_SIZE);
+      }
 
-    output.GetLowLevelOutput().SetContentType(CONTENT_TYPE_OCTET_STREAM);
-    output.GetLowLevelOutput().SetContentLength(length);
+      virtual HttpCompression GetHttpCompression(bool /*gzipAllowed*/,
+                                                 bool /*deflateAllowed*/)
+      {
+        // No support for compression
+        return HttpCompression_None;
+      }
 
-    while (offset < length)
-    {
-      Uint32 nbytes;
-      if (length - offset < buffer.size())
+      virtual bool HasContentFilename(std::string& filename)
       {
-        nbytes = length - offset;
+        return false;
       }
-      else
+
+      virtual std::string GetContentType()
       {
-        nbytes = buffer.size();
+        return "";
       }
 
-      OFCondition cond = element.getPartialValue(&buffer[0], offset, nbytes);
-
-      if (cond.good())
+      virtual uint64_t  GetContentLength()
       {
-        output.GetLowLevelOutput().SendBody(&buffer[0], nbytes);
-        offset += nbytes;
+        return length_;
       }
-      else
+ 
+      virtual bool ReadNextChunk()
       {
-        LOG(ERROR) << "Error while sending a DICOM field: " << cond.text();
-        return;
+        assert(offset_ < length_);
+
+        if (offset_ == length_)
+        {
+          return false;
+        }
+        else
+        {
+          if (length_ - offset_ < chunk_.size())
+          {
+            chunkSize_ = length_ - offset_;
+          }
+          else
+          {
+            chunkSize_ = chunk_.size();
+          }
+
+          OFCondition cond = element_.getPartialValue(&chunk_[0], offset_, chunkSize_);
+
+          offset_ += chunkSize_;
+
+          if (!cond.good())
+          {
+            LOG(ERROR) << "Error while sending a DICOM field: " << cond.text();
+            throw OrthancException(ErrorCode_InternalError);
+          }
+
+          return true;
+        }
       }
-    }
-
-    output.MarkLowLevelOutputDone();
+ 
+      virtual const char *GetChunkContent()
+      {
+        return chunk_.c_str();
+      }
+ 
+      virtual size_t GetChunkSize()
+      {
+        return chunkSize_;
+      }
+    };
   }
 
 
@@ -365,7 +412,8 @@
         {
           // This is the case for raw, uncompressed image buffers
           assert(*blockUri == "0");
-          AnswerDicomField(output, *element, transferSyntax);
+          DicomFieldStream stream(*element, transferSyntax);
+          output.AnswerStream(stream);
         }
       }
     }
@@ -406,7 +454,8 @@
         //element->getVR() != EVR_UNKNOWN &&  // This would forbid private tags
         element->getVR() != EVR_SQ)
     {
-      AnswerDicomField(output, *element, transferSyntax);
+      DicomFieldStream stream(*element, transferSyntax);
+      output.AnswerStream(stream);
     }
   }