99#include < aws/core/utils/HashingUtils.h>
1010#include < aws/core/utils/logging/LogMacros.h>
1111#include < aws/core/utils/memory/stl/AWSStringStream.h>
12+ #include < aws/core/utils/memory/stl/AWSVector.h>
1213#include < smithy/interceptor/Interceptor.h>
1314#include < aws/core/client/ClientConfiguration.h>
1415#include < aws/core/utils/Outcome.h>
@@ -29,8 +30,7 @@ class AwsChunkedStreamBuf : public std::streambuf {
2930 AwsChunkedStreamBuf (Aws::Http::HttpRequest* request,
3031 const std::shared_ptr<Aws::IOStream>& stream,
3132 size_t bufferSize = DataBufferSize)
32- : m_chunkingStream(Aws::MakeShared<Aws::StringStream>(ALLOCATION_TAG)),
33- m_request (request),
33+ : m_request(request),
3434 m_stream (stream),
3535 m_data(bufferSize)
3636 {
@@ -67,58 +67,53 @@ class AwsChunkedStreamBuf : public std::streambuf {
6767 }
6868 }
6969
70- // if the underlying stream is empty there is nothing to read
71- if ((m_chunkingStream-> peek () == EOF || m_chunkingStream-> eof ()) && !m_chunkingStream-> bad ()) {
70+ // if the chunking buffer is empty there is nothing to read
71+ if (m_chunkingBufferPos >= m_chunkingBuffer. size ()) {
7272 return traits_type::eof ();
7373 }
7474
75- // Read from chunking stream to internal buffer
76- m_chunkingStream->read (m_buffer.GetUnderlyingData (), m_buffer.GetLength ());
77- size_t bytesRead = static_cast <size_t >(m_chunkingStream->gcount ());
78- if (bytesRead == 0 ) {
79- return traits_type::eof ();
80- }
81-
82- setg (m_buffer.GetUnderlyingData (), m_buffer.GetUnderlyingData (), m_buffer.GetUnderlyingData () + bytesRead);
75+ // Set up buffer pointers to read from chunking buffer
76+ size_t remainingBytes = m_chunkingBuffer.size () - m_chunkingBufferPos;
77+ size_t bytesToRead = std::min (remainingBytes, DataBufferSize);
78+
79+ setg (m_chunkingBuffer.data () + m_chunkingBufferPos,
80+ m_chunkingBuffer.data () + m_chunkingBufferPos,
81+ m_chunkingBuffer.data () + m_chunkingBufferPos + bytesToRead);
82+
83+ m_chunkingBufferPos += bytesToRead;
8384 return traits_type::to_int_type (*gptr ());
8485 }
8586
8687private:
8788 void writeTrailerToUnderlyingStream () {
88- Aws::StringStream chunkedTrailerStream;
89- chunkedTrailerStream << " 0\r\n " ;
89+ Aws::String trailer = " 0\r\n " ;
9090 if (m_request->GetRequestHash ().second != nullptr ) {
91- chunkedTrailerStream << " x-amz-checksum-" << m_request->GetRequestHash ().first << " :"
92- << Aws::Utils::HashingUtils::Base64Encode (m_request->GetRequestHash ().second ->GetHash ().GetResult ()) << " \r\n " ;
93- }
94- chunkedTrailerStream << " \r\n " ;
95- const auto chunkedTrailer = chunkedTrailerStream.str ();
96- if (m_chunkingStream->eof ()) {
97- m_chunkingStream->clear ();
91+ trailer += " x-amz-checksum-" + m_request->GetRequestHash ().first + " :"
92+ + Aws::Utils::HashingUtils::Base64Encode (m_request->GetRequestHash ().second ->GetHash ().GetResult ()) + " \r\n " ;
9893 }
99- *m_chunkingStream << chunkedTrailer;
94+ trailer += " \r\n " ;
95+ m_chunkingBuffer.insert (m_chunkingBuffer.end (), trailer.begin (), trailer.end ());
10096 }
10197
10298 void writeChunk (size_t bytesRead) {
10399 if (m_request->GetRequestHash ().second != nullptr ) {
104100 m_request->GetRequestHash ().second ->Update (reinterpret_cast <unsigned char *>(m_data.GetUnderlyingData ()), bytesRead);
105101 }
106102
107- if (bytesRead > 0 && m_chunkingStream && !m_chunkingStream->bad ()) {
108- if (m_chunkingStream->eof ()) {
109- m_chunkingStream->clear ();
110- }
111- *m_chunkingStream << Aws::Utils::StringUtils::ToHexString (bytesRead) << " \r\n " ;
112- m_chunkingStream->write (m_data.GetUnderlyingData (), bytesRead);
113- *m_chunkingStream << " \r\n " ;
103+ if (bytesRead > 0 ) {
104+ Aws::String chunkHeader = Aws::Utils::StringUtils::ToHexString (bytesRead) + " \r\n " ;
105+ m_chunkingBuffer.insert (m_chunkingBuffer.end (), chunkHeader.begin (), chunkHeader.end ());
106+ m_chunkingBuffer.insert (m_chunkingBuffer.end (), m_data.GetUnderlyingData (), m_data.GetUnderlyingData () + bytesRead);
107+ Aws::String chunkFooter = " \r\n " ;
108+ m_chunkingBuffer.insert (m_chunkingBuffer.end (), chunkFooter.begin (), chunkFooter.end ());
114109 }
115110 }
116111
117- std::shared_ptr<Aws::IOStream> m_chunkingStream;
112+ Aws::Vector<char > m_chunkingBuffer;
113+ size_t m_chunkingBufferPos{0 };
118114 Aws::Http::HttpRequest* m_request{nullptr };
119115 std::shared_ptr<Aws::IOStream> m_stream;
120116 Aws::Utils::Array<char > m_data;
121- Aws::Utils::Array<char > m_buffer{DataBufferSize};
122117};
123118
124119class AwsChunkedIOStream : public Aws ::IOStream {
0 commit comments