@@ -66,23 +66,29 @@ class AwsChunkedStreamBuf : public std::streambuf {
6666 }
6767
6868 // if the chunking buffer is empty there is nothing to read
69- if (m_chunkingBufferPos >= m_chunkingBuffer. size () ) {
69+ if (m_chunkingBufferPos >= m_chunkingBufferSize ) {
7070 return traits_type::eof ();
7171 }
7272
7373 // Set up buffer pointers to read from chunking buffer
74- size_t remainingBytes = m_chunkingBuffer. size () - m_chunkingBufferPos;
74+ size_t remainingBytes = m_chunkingBufferSize - m_chunkingBufferPos;
7575 size_t bytesToRead = std::min (remainingBytes, DataBufferSize);
7676
77- setg (m_chunkingBuffer.data () + m_chunkingBufferPos,
78- m_chunkingBuffer.data () + m_chunkingBufferPos,
79- m_chunkingBuffer.data () + m_chunkingBufferPos + bytesToRead);
77+ setg (m_chunkingBuffer.GetUnderlyingData () + m_chunkingBufferPos,
78+ m_chunkingBuffer.GetUnderlyingData () + m_chunkingBufferPos,
79+ m_chunkingBuffer.GetUnderlyingData () + m_chunkingBufferPos + bytesToRead);
8080
8181 m_chunkingBufferPos += bytesToRead;
8282
83- // Remove consumed data to prevent unbounded growth
84- if (m_chunkingBufferPos > DataBufferSize) {
85- m_chunkingBuffer.erase (m_chunkingBuffer.begin (), m_chunkingBuffer.begin () + m_chunkingBufferPos);
83+ // Compact buffer when consumed data exceeds half buffer size
84+ if (m_chunkingBufferPos > m_chunkingBuffer.GetLength () / 2 ) {
85+ size_t remaining = m_chunkingBufferSize - m_chunkingBufferPos;
86+ if (remaining > 0 ) {
87+ std::memmove (m_chunkingBuffer.GetUnderlyingData (),
88+ m_chunkingBuffer.GetUnderlyingData () + m_chunkingBufferPos,
89+ remaining);
90+ }
91+ m_chunkingBufferSize = remaining;
8692 m_chunkingBufferPos = 0 ;
8793 }
8894
@@ -97,7 +103,10 @@ class AwsChunkedStreamBuf : public std::streambuf {
97103 + Aws::Utils::HashingUtils::Base64Encode (m_request->GetRequestHash ().second ->GetHash ().GetResult ()) + " \r\n " ;
98104 }
99105 trailer += " \r\n " ;
100- m_chunkingBuffer.insert (m_chunkingBuffer.end (), trailer.begin (), trailer.end ());
106+ if (m_chunkingBufferSize + trailer.length () <= m_chunkingBuffer.GetLength ()) {
107+ std::memcpy (m_chunkingBuffer.GetUnderlyingData () + m_chunkingBufferSize, trailer.c_str (), trailer.length ());
108+ m_chunkingBufferSize += trailer.length ();
109+ }
101110 }
102111
103112 void writeChunk (size_t bytesRead) {
@@ -107,14 +116,17 @@ class AwsChunkedStreamBuf : public std::streambuf {
107116
108117 if (bytesRead > 0 ) {
109118 Aws::String chunkHeader = Aws::Utils::StringUtils::ToHexString (bytesRead) + " \r\n " ;
110- m_chunkingBuffer.insert (m_chunkingBuffer.end (), chunkHeader.begin (), chunkHeader.end ());
111- m_chunkingBuffer.insert (m_chunkingBuffer.end (), m_data.GetUnderlyingData (), m_data.GetUnderlyingData () + bytesRead);
112- Aws::String chunkFooter = " \r\n " ;
113- m_chunkingBuffer.insert (m_chunkingBuffer.end (), chunkFooter.begin (), chunkFooter.end ());
119+ std::memcpy (m_chunkingBuffer.GetUnderlyingData () + m_chunkingBufferSize, chunkHeader.c_str (), chunkHeader.length ());
120+ m_chunkingBufferSize += chunkHeader.length ();
121+ std::memcpy (m_chunkingBuffer.GetUnderlyingData () + m_chunkingBufferSize, m_data.GetUnderlyingData (), bytesRead);
122+ m_chunkingBufferSize += bytesRead;
123+ std::memcpy (m_chunkingBuffer.GetUnderlyingData () + m_chunkingBufferSize, " \r\n " , 2 );
124+ m_chunkingBufferSize += 2 ;
114125 }
115126 }
116127
117- Aws::Vector<char > m_chunkingBuffer;
128+ Aws::Utils::Array<char > m_chunkingBuffer{DataBufferSize * 4 };
129+ size_t m_chunkingBufferSize{0 };
118130 size_t m_chunkingBufferPos{0 };
119131 Aws::Http::HttpRequest* m_request{nullptr };
120132 std::shared_ptr<Aws::IOStream> m_stream;
0 commit comments