From 3fb94d77e7ca2b52fe29e5fc07f24eedb450deeb Mon Sep 17 00:00:00 2001 From: Lexi Mayfield Date: Sun, 3 Mar 2024 15:21:22 -0500 Subject: [PATCH] Document all new "try" functions --- include/lexio/core.hpp | 11 ++- include/lexio/try.hpp | 174 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 182 insertions(+), 3 deletions(-) diff --git a/include/lexio/core.hpp b/include/lexio/core.hpp index d8010b6..4ed9969 100644 --- a/include/lexio/core.hpp +++ b/include/lexio/core.hpp @@ -63,7 +63,8 @@ * * The return value of `LexFillBuffer` is a pointer/length pair that offers a * view of the internal buffer after the fill operation. A `count` of 0 is - * expected to offer a view of the internal buffer without changing it. + * expected to offer a view of the internal buffer without changing it, and + * shall not throw an exception. * * `LexConsumeBuffer` removes `count` bytes from the front of the internal * buffer, shrinking it. A `count` of more than the current size of the internal @@ -949,6 +950,8 @@ inline size_t RawWrite(const WriterRef &writer, const uint8_t *src, size_t count * @brief Flushes data to underlying storage. Can be a no-op. * * @param writer Writer to operate on. + * @throws std::runtime_error if an error with the flush operation was + * encountered. */ inline void Flush(const WriterRef &writer) { @@ -1037,11 +1040,13 @@ LEXIO_FORCEINLINE size_t Read(BYTE (&outArray)[N], const ReaderRef &reader) /** * @brief Get the current contents of the buffer. + * + * @details LexIO::FillBuffer(0) should NEVER throw an exception. * * @param bufReader BufferedReader to operate on. - * @return Span view of the internal buffer. + * @return View of the internal buffer. */ -inline BufferView GetBuffer(const BufferedReaderRef &bufReader) +inline BufferView GetBuffer(const BufferedReaderRef &bufReader) noexcept { return bufReader.LexFillBuffer(0); } diff --git a/include/lexio/try.hpp b/include/lexio/try.hpp index cebfe0c..b86ce87 100644 --- a/include/lexio/try.hpp +++ b/include/lexio/try.hpp @@ -34,21 +34,46 @@ std::exception_ptr &LastError() noexcept } // namespace Detail +/** + * @brief Set the "most recent" error for this thread. Usually called from + * within a `catch` block of a LexIO function marked `noexcept`. + * + * @param ex Exception to set as most recent error. + */ inline void SetLastError(std::exception_ptr ex) noexcept { Detail::LastError() = ex; } +/** + * @brief Throw the most recent error for this thread. + */ [[noreturn]] inline void ThrowLastError() { std::rethrow_exception(Detail::LastError()); } +/** + * @brief Clear the most recently set error for this thread. + */ inline void ClearLastError() noexcept { Detail::LastError() = nullptr; } +/** + * @brief Attempt to read data from the current offset, inserting it into + * the passed buffer. + * + * @param outActual Actual number of bytes read, or 0 if EOF-like condition + * was encountered. + * @param outDest Pointer to starting byte of output buffer. + * @param reader Reader to operate on. + * @param count Number of bytes to attempt to read. + * @return True if successful, false if an error with the read operation was + * encountered. EOF is _not_ considered an error. To get specific + * error, call LexIO::ThrowLastError. + */ inline bool TryRawRead(size_t &outActual, uint8_t *outDest, const ReaderRef &reader, size_t count) noexcept { try @@ -63,6 +88,21 @@ inline bool TryRawRead(size_t &outActual, uint8_t *outDest, const ReaderRef &rea } } +/** + * @brief Fill the internal buffer of data to the requested size without + * advancing the offset. If EOF is encountered, the rest of the + * data up to the EOF is buffered. + * + * @param outBuffer Span view of the internal buffer after buffering data + * to the requested size. Must be a span with a size between + * 0 and the given size. A span of size 0 indicates EOF + * was reached. + * @param bufReader BufferedReader to operate on. + * @param size Amount of data to buffer in bytes. + * @return True if successful, false if an error with the read operation was + * encountered, or if too large of a buffer was requested. To get + * specific error, call LexIO::ThrowLastError. + */ inline bool TryFillBuffer(BufferView &outBuffer, const BufferedReaderRef &bufReader, size_t size) noexcept { try @@ -77,6 +117,17 @@ inline bool TryFillBuffer(BufferView &outBuffer, const BufferedReaderRef &bufRea } } +/** + * @brief Signal to the reader that the given number of bytes have been + * "consumed" and should no longer be returned by FillBuffer. + * + * @param bufReader BufferedReader to operate on. + * @param size Amount of data to consume in bytes. Must be less than or + * equal to the amount of data in the visible buffer. + * @return True if successful, false if a size greater than the amount of + * data in the visible buffer is passed to the function. To get + * specific error, call LexIO::ThrowLastError. + */ inline bool TryConsumeBuffer(const BufferedReaderRef &bufReader, size_t size) noexcept { try @@ -91,6 +142,18 @@ inline bool TryConsumeBuffer(const BufferedReaderRef &bufReader, size_t size) no } } +/** + * @brief Attempt to write a buffer of data at the current offset. + * + * @param outActual Actual number of bytes written, or 0 if EOF-like condition + * was encountered. + * @param writer Writer to operate on. + * @param src Pointer to starting byte of input buffer. + * @param count Size of input buffer in bytes. + * @throws True if successful, false if an error with the write operation + * was encountered. A partial write is _not_ considered an error. + * To get specific error, call LexIO::ThrowLastError. + */ inline bool TryRawWrite(size_t &outActual, const WriterRef &writer, const uint8_t *src, size_t count) noexcept { try @@ -105,6 +168,13 @@ inline bool TryRawWrite(size_t &outActual, const WriterRef &writer, const uint8_ } } +/** + * @brief Flushes data to underlying storage. Can be a no-op. + * + * @param writer Writer to operate on. + * @return True if successful, false if an error with the flush operation + * was encountered. To get specific error, call LexIO::ThrowLastError. + */ inline bool TryFlush(const WriterRef &writer) noexcept { try @@ -119,6 +189,16 @@ inline bool TryFlush(const WriterRef &writer) noexcept } } +/** + * @brief Seek to a position in the underlying Seekable. + * + * @param outOffset Absolute position in stream after seek. + * @param seekable Seekable to operate on. + * @param pos Seek position. + * @return True if successful, returns false if underlying seek operation + * goes past start of data, or has some other error condition. To + * get specific error, call LexIO::ThrowLastError. + */ inline bool TrySeek(size_t &outOffset, const SeekableRef &seekable, const SeekPos &pos) noexcept { try @@ -133,6 +213,17 @@ inline bool TrySeek(size_t &outOffset, const SeekableRef &seekable, const SeekPo } } +/** + * @brief Seek to a position in the underlying Seekable. + * + * @param outOffset Absolute position in stream after seek. + * @param seekable Seekable to operate on. + * @param offset Seek offset. + * @param whence Position to seek relative to. + * @return True if successful, returns false if underlying seek operation + * goes past start of data, or has some other error condition. To + * get specific error, call LexIO::ThrowLastError. + */ inline size_t TrySeek(size_t &outOffset, const SeekableRef &seekable, ptrdiff_t offset, Whence whence) noexcept { try @@ -147,6 +238,20 @@ inline size_t TrySeek(size_t &outOffset, const SeekableRef &seekable, ptrdiff_t } } +/** + * @brief Read data from the current offset, inserting it into the passed + * buffer. Calls LexIO::RawRead as many times as necessary to fill + * the output buffer until EOF is hit. + * + * @param outActual Actual number of bytes read, or 0 if EOF-like condition + * was encountered. + * @param outDest Pointer to starting byte of output buffer. + * @param reader Reader to operate on. + * @param count Number of bytes to attempt to read. + * @return True if successful, false if an error with the read operation was + * encountered. EOF is _not_ considered an error. To get specific + * error, call LexIO::ThrowLastError. + */ template > inline bool TryRead(size_t &outActual, BYTE *outDest, const ReaderRef &reader, size_t count) noexcept { @@ -177,12 +282,39 @@ inline bool TryRead(size_t &outActual, BYTE *outDest, const ReaderRef &reader, s } } +/** + * @brief Read data from the current offset, inserting it into the passed + * buffer. Calls LexIO::RawRead as many times as necessary to fill + * the output buffer until EOF is hit. + * + * @param outActual Actual number of bytes read, or 0 if EOF-like condition + * was encountered. + * @param outArray Output buffer array. + * @param reader Reader to operate on. + * @return True if successful, false if an error with the read operation was + * encountered. EOF is _not_ considered an error. To get specific + * error, call LexIO::ThrowLastError. + */ template && sizeof(BYTE) == 1>> LEXIO_FORCEINLINE bool TryRead(size_t &outActual, BYTE (&outArray)[N], const ReaderRef &reader) noexcept { return TryRead(outActual, outArray, reader, N); } +/** + * @brief Write a buffer of data at the current offset. Calls LexIO::RawWrite + * as many times as necessary to write the entire buffer unless EOF + * is hit. + * + * @param outActual Actual number of bytes written, or 0 if EOF-like condition + * was encountered. + * @param writer Writer to operate on. + * @param src Pointer to starting byte of input buffer. + * @param count Size of input buffer in bytes. + * @return True if successful, false if an error with the write operation + * was encountered. A partial write is _not_ considered an error. + * To get specific error, call LexIO::ThrowLastError. + */ template > inline bool TryWrite(size_t &outActual, const WriterRef &writer, const BYTE *src, size_t count) noexcept { @@ -213,12 +345,36 @@ inline bool TryWrite(size_t &outActual, const WriterRef &writer, const BYTE *src } } +/** + * @brief Write a buffer of data at the current offset. Calls LexIO::RawWrite + * as many times as necessary to write the entire buffer unless EOF + * is hit. + * + * @param outActual Actual number of bytes written, or 0 if EOF-like condition + * was encountered. + * @param writer Writer to operate on. + * @param array Input buffer array. + * @return Actual number of bytes written, or 0 if EOF-like condition was + * encountered. + * @return True if successful, false if an error with the write operation + * was encountered. A partial write is _not_ considered an error. + * To get specific error, call LexIO::ThrowLastError. + */ template > LEXIO_FORCEINLINE bool TryWrite(size_t &outActual, const WriterRef &writer, const BYTE (&array)[N]) noexcept { return TryWrite(outActual, writer, array, N); } +/** + * @brief Return the current offset position. + * + * @param outOffset Absolute position in stream. + * @param seekable Seekable to operate on. + * @return True if successful, false if Seek call throws, or some other error + * condition occurrs. To get specific error, call + * LexIO::ThrowLastError. + */ inline bool TryTell(size_t &outOffset, const SeekableRef &seekable) noexcept { try @@ -233,6 +389,15 @@ inline bool TryTell(size_t &outOffset, const SeekableRef &seekable) noexcept } } +/** + * @brief Rewind the seekable stream to the beginning. + * + * @param outOffset Resulting position in stream, should be 0 on success. + * @param seekable Seekable to operate on. + * @return True if successful, false if Seek call throws, or some other error + * condition occurrs. To get specific error, call + * LexIO::ThrowLastError. + */ inline bool TryRewind(size_t &outOffset, const SeekableRef &seekable) noexcept { try @@ -247,6 +412,15 @@ inline bool TryRewind(size_t &outOffset, const SeekableRef &seekable) noexcept } } +/** + * @brief Return length of underlying data. + * + * @param outLength Length of underlying data. + * @param seekable Seekable to operate on. + * @return True if successful, false if Seek call throws, or some other error + * condition occurrs. To get specific error, call + * LexIO::ThrowLastError. + */ inline bool TryLength(size_t &outLength, const SeekableRef &seekable) noexcept { try