diff --git a/include/aws/crt/io/Stream.h b/include/aws/crt/io/Stream.h index 91c8c36f2..929ecba9c 100644 --- a/include/aws/crt/io/Stream.h +++ b/include/aws/crt/io/Stream.h @@ -114,6 +114,19 @@ namespace Aws */ virtual bool ReadImpl(ByteBuf &buffer) noexcept = 0; + /*** + * Read up-to buffer::capacity - buffer::len immediately available bytes into buffer::buffer + * Increment buffer::len by the amount you read in. + * + * @return true if nothing went wrong. + * Return true even if you read 0 bytes because the end-of-file has been reached. + * Return true even if you read 0 bytes because data is not currently available. + * + * Return false if an actual failure condition occurs, + * you SHOULD also raise an error via aws_raise_error(). + */ + virtual bool ReadSomeImpl(ByteBuf &buffer) noexcept = 0; + /** * @return the current status of the stream. */ @@ -136,6 +149,15 @@ namespace Aws */ virtual bool SeekImpl(int64_t offset, StreamSeekBasis seekBasis) noexcept = 0; + /** + * Peeks the stream + * + * Essentially calls peek on the underlying istream + * + * @return return value of the underlying istream::peek + */ + virtual uint8_t PeekImpl() const noexcept = 0; + private: static int s_Seek(aws_input_stream *stream, int64_t offset, enum aws_stream_seek_basis basis); static int s_Read(aws_input_stream *stream, aws_byte_buf *dest); @@ -161,9 +183,11 @@ namespace Aws protected: bool ReadImpl(ByteBuf &buffer) noexcept override; + bool ReadSomeImpl(ByteBuf &buffer) noexcept override; StreamStatus GetStatusImpl() const noexcept override; int64_t GetLengthImpl() const noexcept override; bool SeekImpl(OffsetType offsetType, StreamSeekBasis seekBasis) noexcept override; + uint8_t PeekImpl() const noexcept override; private: std::shared_ptr m_stream; diff --git a/source/io/Stream.cpp b/source/io/Stream.cpp index 975d1c516..9bf8384d6 100644 --- a/source/io/Stream.cpp +++ b/source/io/Stream.cpp @@ -5,6 +5,7 @@ #include #include +#include #include @@ -150,6 +151,27 @@ namespace Aws return status.is_valid && !status.is_end_of_stream; } + bool StdIOStreamInputStream::ReadSomeImpl(ByteBuf &buffer) noexcept + { + // I have no idea why "readsome() doesn't work at all" for the original dev. It works well for me + // Jokes aside, read will always block and try to read till eof + // readsome will return available bytes without waiting for eof and without closing the stream. + auto actuallyRead = 0; + actuallyRead = m_stream->readsome( + reinterpret_cast(buffer.buffer + buffer.len), buffer.capacity - buffer.len); + + buffer.len += static_cast(actuallyRead); + + if (actuallyRead > 0 || (actuallyRead == 0 && m_stream->eof())) + { + return true; + } + + auto status = GetStatusImpl(); + + return status.is_valid && !status.is_end_of_stream; + } + StreamStatus StdIOStreamInputStream::GetStatusImpl() const noexcept { StreamStatus status; @@ -206,6 +228,11 @@ namespace Aws return true; } + + uint8_t StdIOStreamInputStream::PeekImpl() const noexcept + { + return m_stream->peek(); + } } // namespace Io } // namespace Crt } // namespace Aws