@@ -25,22 +25,29 @@ static const size_t DATA_BUFFER_SIZE = 65536;
2525
2626} // anonymous namespace
2727
28- class AwsChunkedStreamBuf : public std ::streambuf {
28+ class AwsChunkedStreamWrapper {
2929public:
30- AwsChunkedStreamBuf (Aws::Http::HttpRequest* request, const std::shared_ptr<Aws::IOStream>& originalBody, size_t bufferSize = DATA_BUFFER_SIZE)
31- : m_request(request), m_stream(originalBody), m_data(bufferSize), m_bufferSize(bufferSize),
32- m_chunkingStream (Aws::MakeShared<Aws::StringStream>(ALLOCATION_TAG)) {
33- setg (nullptr , nullptr , nullptr );
34- }
30+ AwsChunkedStreamWrapper (Aws::Http::HttpRequest* request, const std::shared_ptr<Aws::IOStream>& originalBody, size_t bufferSize = DATA_BUFFER_SIZE)
31+ : m_streambuf(request, originalBody, bufferSize), m_iostream(&m_streambuf) {}
32+
33+ Aws::IOStream* GetIOStream () { return &m_iostream; }
3534
36- protected:
37- int_type underflow () override {
38- if (gptr () < egptr ()) {
39- return traits_type::to_int_type (*gptr ());
35+ private:
36+ class AwsChunkedStreamBuf : public std ::streambuf {
37+ public:
38+ AwsChunkedStreamBuf (Aws::Http::HttpRequest* request, const std::shared_ptr<Aws::IOStream>& originalBody, size_t bufferSize)
39+ : m_request(request), m_stream(originalBody), m_data(bufferSize), m_bufferSize(bufferSize),
40+ m_chunkingStream (Aws::MakeShared<Aws::StringStream>(ALLOCATION_TAG)) {
41+ setg (nullptr , nullptr , nullptr );
4042 }
41-
42- // Only read from source stream if chunking stream is empty
43- if ((m_chunkingStream->peek () == EOF || m_chunkingStream->eof ()) && !m_chunkingStream->bad ()) {
43+
44+ protected:
45+ int_type underflow () override {
46+ if (gptr () < egptr ()) {
47+ return traits_type::to_int_type (*gptr ());
48+ }
49+
50+ // BufferedRead logic inlined per Sam's guidance
4451 if (m_stream->good ()) {
4552 m_stream->read (m_data.GetUnderlyingData (), m_bufferSize);
4653 size_t bytesRead = static_cast <size_t >(m_stream->gcount ());
@@ -49,23 +56,24 @@ class AwsChunkedStreamBuf : public std::streambuf {
4956 if ((m_stream->peek () == EOF || m_stream->eof ()) && !m_stream->bad ()) {
5057 writeTrailerToUnderlyingStream ();
5158 }
52- } else {
59+ }
60+
61+ if ((m_chunkingStream->peek () == EOF || m_chunkingStream->eof ()) && !m_chunkingStream->bad ()) {
5362 return traits_type::eof ();
5463 }
64+
65+ m_chunkingStream->read (m_buffer, sizeof (m_buffer));
66+ size_t bytesRead = static_cast <size_t >(m_chunkingStream->gcount ());
67+ if (bytesRead == 0 ) {
68+ return traits_type::eof ();
69+ }
70+
71+ setg (m_buffer, m_buffer, m_buffer + bytesRead);
72+ return traits_type::to_int_type (*gptr ());
5573 }
56-
57- m_chunkingStream->read (m_buffer, sizeof (m_buffer));
58- size_t bytesRead = static_cast <size_t >(m_chunkingStream->gcount ());
59- if (bytesRead == 0 ) {
60- return traits_type::eof ();
61- }
62-
63- setg (m_buffer, m_buffer, m_buffer + bytesRead);
64- return traits_type::to_int_type (*gptr ());
65- }
6674
67- private:
68- void writeTrailerToUnderlyingStream () {
75+ private:
76+ void writeTrailerToUnderlyingStream () {
6977 Aws::StringStream chunkedTrailerStream;
7078 chunkedTrailerStream << " 0\r\n " ;
7179 if (m_request->GetRequestHash ().second != nullptr ) {
@@ -95,12 +103,16 @@ class AwsChunkedStreamBuf : public std::streambuf {
95103 }
96104 }
97105
98- Aws::Http::HttpRequest* m_request;
99- std::shared_ptr<Aws::IOStream> m_stream;
100- Aws::Utils::Array<char > m_data;
101- size_t m_bufferSize;
102- std::shared_ptr<Aws::IOStream> m_chunkingStream;
103- char m_buffer[8192 ];
106+ Aws::Http::HttpRequest* m_request;
107+ std::shared_ptr<Aws::IOStream> m_stream;
108+ Aws::Utils::Array<char > m_data;
109+ size_t m_bufferSize;
110+ std::shared_ptr<Aws::IOStream> m_chunkingStream;
111+ char m_buffer[8192 ];
112+ };
113+
114+ AwsChunkedStreamBuf m_streambuf;
115+ Aws::IOStream m_iostream;
104116};
105117
106118/* *
@@ -148,11 +160,11 @@ class ChunkingInterceptor : public smithy::interceptor::Interceptor {
148160 }
149161 }
150162
151- auto chunkedBuf = Aws::MakeUnique<AwsChunkedStreamBuf >(
163+ auto wrapper = Aws::MakeShared<AwsChunkedStreamWrapper >(
152164 ALLOCATION_TAG, request.get (), originalBody);
153165 auto chunkedBody = std::shared_ptr<Aws::IOStream>(
154- new Aws::IOStream (chunkedBuf. release () ));
155-
166+ wrapper, wrapper-> GetIOStream ( ));
167+
156168 request->AddContentBody (chunkedBody);
157169 return request;
158170 }
0 commit comments