changeset 4148:732ad6c618ba

removing ChunkedBuffer::AddChunkDestructive()
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 18 Aug 2020 16:56:33 +0200
parents ecc11c232326
children 72047b61570f
files OrthancFramework/Sources/ChunkedBuffer.cpp OrthancFramework/Sources/ChunkedBuffer.h OrthancFramework/Sources/HttpServer/MultipartStreamReader.cpp OrthancFramework/UnitTestsSources/RestApiTests.cpp
diffstat 4 files changed, 154 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancFramework/Sources/ChunkedBuffer.cpp	Tue Aug 18 16:11:03 2020 +0200
+++ b/OrthancFramework/Sources/ChunkedBuffer.cpp	Tue Aug 18 16:56:33 2020 +0200
@@ -66,18 +66,17 @@
   }
 
 
-  void ChunkedBuffer::AddChunkDestructive(std::string& chunk)
+  void ChunkedBuffer::AddChunk(const std::string::const_iterator& begin,
+                               const std::string::const_iterator& end)
   {
-    size_t chunkSize = chunk.size();
-    
-    if (chunkSize > 0)
+    const size_t s = end - begin;
+
+    if (s > 0)
     {
-      chunks_.push_back(new std::string);
-      chunks_.back()->swap(chunk);
-      numBytes_ += chunkSize;
+      AddChunk(&begin[0], s);
     }
   }
-
+  
 
   void ChunkedBuffer::Flatten(std::string& result)
   {
--- a/OrthancFramework/Sources/ChunkedBuffer.h	Tue Aug 18 16:11:03 2020 +0200
+++ b/OrthancFramework/Sources/ChunkedBuffer.h	Tue Aug 18 16:56:33 2020 +0200
@@ -59,8 +59,8 @@
 
     void AddChunk(const std::string& chunk);
 
-    // The source content will be emptied
-    void AddChunkDestructive(std::string& chunk);
+    void AddChunk(const std::string::const_iterator& begin,
+                  const std::string::const_iterator& end);
 
     void Flatten(std::string& result);
   };
--- a/OrthancFramework/Sources/HttpServer/MultipartStreamReader.cpp	Tue Aug 18 16:11:03 2020 +0200
+++ b/OrthancFramework/Sources/HttpServer/MultipartStreamReader.cpp	Tue Aug 18 16:56:33 2020 +0200
@@ -126,8 +126,7 @@
       else
       {
         // We have not seen the end of the unused area yet
-        std::string reminder(current, corpusEnd);
-        buffer_.AddChunkDestructive(reminder);
+        buffer_.AddChunk(current, corpusEnd);
         return;
       }          
     } 
@@ -206,8 +205,7 @@
 
     if (current != corpusEnd)
     {
-      std::string reminder(current, corpusEnd);
-      buffer_.AddChunkDestructive(reminder);
+      buffer_.AddChunk(current, corpusEnd);
     }
   }
 
--- a/OrthancFramework/UnitTestsSources/RestApiTests.cpp	Tue Aug 18 16:11:03 2020 +0200
+++ b/OrthancFramework/UnitTestsSources/RestApiTests.cpp	Tue Aug 18 16:56:33 2020 +0200
@@ -146,6 +146,8 @@
 TEST(RestApi, ChunkedBuffer)
 {
   ChunkedBuffer b;
+  //b.SetTrailingBufferSize(0);   // TODO
+  
   ASSERT_EQ(0u, b.GetNumBytes());
 
   b.AddChunk("hello", 5);
@@ -159,6 +161,7 @@
   ASSERT_EQ("helloworld", s);
 }
 
+
 TEST(RestApi, ParseCookies)
 {
   IHttpHandler::Arguments headers;
@@ -878,3 +881,143 @@
   w.SetUrl("coucou");
   w.SetUrl("/coucou");
 }
+
+
+
+
+namespace
+{
+  class TotoBody : public HttpClient::IRequestBody
+  {
+  private:
+    size_t size_;
+    size_t chunkSize_;
+    size_t pos_;
+      
+  public:
+    TotoBody(size_t size,
+             size_t chunkSize) :
+      size_(size),
+      chunkSize_(chunkSize),
+      pos_(0)
+    {
+    }
+      
+    virtual bool ReadNextChunk(std::string& chunk)
+    {
+      if (pos_ == size_)
+      {
+        return false;
+      }
+
+      chunk.clear();
+      chunk.resize(chunkSize_);
+
+      size_t i = 0;
+      while (pos_ < size_ &&
+             i < chunkSize_)
+      {
+        chunk[i] = '0' + (pos_ % 7);
+        pos_++;
+        i++;
+      }
+
+      if (i < chunk.size())
+      {
+        chunk.erase(i, chunk.size());
+      }
+      
+      return true;
+    }
+  };
+
+  class TotoServer : public IHttpHandler
+  {
+  public:
+    virtual bool CreateChunkedRequestReader(std::unique_ptr<IChunkedRequestReader>& target,
+                                            RequestOrigin origin,
+                                            const char* remoteIp,
+                                            const char* username,
+                                            HttpMethod method,
+                                            const UriComponents& uri,
+                                            const Arguments& headers)
+    {
+      return false;
+    }
+
+    virtual bool Handle(HttpOutput& output,
+                        RequestOrigin origin,
+                        const char* remoteIp,
+                        const char* username,
+                        HttpMethod method,
+                        const UriComponents& uri,
+                        const Arguments& headers,
+                        const GetArguments& getArguments,
+                        const void* bodyData,
+                        size_t bodySize)
+    {
+      printf("received %llu\n", bodySize);
+
+      const uint8_t* b = reinterpret_cast<const uint8_t*>(bodyData);
+      
+      for (size_t i = 0; i < bodySize; i++)
+      {
+        if (b[i] != ('0' + i % 7))
+        {
+          throw;
+        }
+      }
+      
+      output.Answer("ok");
+      return true;
+    }
+  };
+}
+
+
+#include "../Sources/HttpServer/HttpServer.h"
+
+TEST(Toto, DISABLED_Toto)
+{
+  TotoServer handler;
+  HttpServer server;
+  server.SetPortNumber(5000);
+  server.Register(handler);
+  server.Start();
+  
+  WebServiceParameters w;
+  w.SetUrl("http://localhost:5000");
+
+  TotoBody body(600 * 1024 * 1024, 6 * 1024 * 1024 - 17);
+  //TotoBody body(600 * 1024 * 1024, 1);
+  
+  HttpClient c(w, "toto");
+  c.SetMethod(HttpMethod_Post);
+  c.AddHeader("Expect", "");
+  c.AddHeader("Transfer-Encoding", "chunked");
+  c.SetBody(body);
+
+  std::string s;
+  ASSERT_TRUE(c.Apply(s));
+
+  printf(">> [%s]\n", s.c_str());
+
+  server.Stop();
+}
+
+
+
+TEST(Toto, DISABLED_Tata)
+{
+  boost::posix_time::ptime start = boost::posix_time::microsec_clock::local_time();
+  
+  ChunkedBuffer b;
+  for (unsigned int i = 0; i < 600 * 1024 * 1024; i++)
+  {
+    b.AddChunk("a", 1);
+  }
+
+  boost::posix_time::ptime end = boost::posix_time::microsec_clock::local_time();
+
+  printf("time: %d\n", (end-start).total_microseconds());
+}