diff --git a/docs/user/support/DataIO.dox b/docs/user/support/DataIO.dox index fe9fb58df8..7885975cba 100644 --- a/docs/user/support/DataIO.dox +++ b/docs/user/support/DataIO.dox @@ -89,6 +89,51 @@ */ +/*! + \fn virtual status_t BDataIO::ReadExactly(void* buffer, size_t size, size_t* _bytesRead) + \brief Reads an exact amount of data from the object into a buffer. + + This is a convenience wrapper method for Read() for code that expects the + exact number of bytes requested to be read. This method calls Read() in a + loop to read the data. It fails when Read() returns an error or fails to + read any more data (i.e. returns 0). + + \param buffer Pointer to pre-allocated storage of at least \a size bytes + into which the data shall be read. Won't be dereferenced, when \a size + is 0. + \param size The number of bytes to be read. + \param _bytesRead Optional pointer to a pre-allocated size_t into which the + number of bytes actually read will be written. When the method returns + \c B_OK this will always be \a size. Can be \c NULL. + \return An error code indicated whether the method succeeded. + \retval B_OK All data have been read. + \retval B_PARTIAL_READ Read() didn't fail, but couldn't provide as many + bytes as requested. +*/ + + +/*! + \fn virtual status_t BDataIO::WriteExactly(const void* buffer, size_t size, size_t* _bytesWritten) + \brief Writes an exact amount of data from a buffer to the object. + + This is a convenience wrapper method for Write() for code that expects the + exact number of bytes given to be written. This method calls Write() in a + loop to write the data. It fails when Write() returns an error or fails to + write any more data (i.e. returns 0). + + \param buffer Pointer to a buffer of at least \a size bytes containing the + data to be written. Won't be dereferenced, when \a size is 0. + \param size The number of bytes to be written. + \param _bytesWritten Optional pointer to a pre-allocated size_t into which + the number of bytes actually written will be written. When the method + returns \c B_OK this will always be \a size. Can be \c NULL. + \return An error code indicated whether the method succeeded. + \retval B_OK All data have been written. + \retval B_PARTIAL_READ Write() didn't fail, but couldn't write as many + bytes as provided. +*/ + + //////////// BPositionIO diff --git a/headers/os/support/DataIO.h b/headers/os/support/DataIO.h index 539b65d1a6..1e5dc6a520 100644 --- a/headers/os/support/DataIO.h +++ b/headers/os/support/DataIO.h @@ -17,6 +17,11 @@ public: virtual ssize_t Read(void* buffer, size_t size); virtual ssize_t Write(const void* buffer, size_t size); + status_t ReadExactly(void* buffer, size_t size, + size_t* _bytesRead = NULL); + status_t WriteExactly(const void* buffer, size_t size, + size_t* _bytesWritten = NULL); + private: BDataIO(const BDataIO&); BDataIO& operator=(const BDataIO&); diff --git a/src/kits/support/DataIO.cpp b/src/kits/support/DataIO.cpp index 71f81f91c9..dd0da79423 100644 --- a/src/kits/support/DataIO.cpp +++ b/src/kits/support/DataIO.cpp @@ -38,6 +38,66 @@ BDataIO::Write(const void* buffer, size_t size) } +status_t +BDataIO::ReadExactly(void* buffer, size_t size, size_t* _bytesRead) +{ + uint8* out = (uint8*)buffer; + size_t bytesRemaining = size; + status_t error = B_OK; + + while (bytesRemaining > 0) { + ssize_t bytesRead = Read(out, bytesRemaining); + if (bytesRead < 0) { + error = bytesRead; + break; + } + + if (bytesRead == 0) { + error = B_PARTIAL_READ; + break; + } + + out += bytesRead; + bytesRemaining -= bytesRead; + } + + if (_bytesRead != NULL) + *_bytesRead = size - bytesRemaining; + + return error; +} + + +status_t +BDataIO::WriteExactly(const void* buffer, size_t size, size_t* _bytesWritten) +{ + const uint8* in = (const uint8*)buffer; + size_t bytesRemaining = size; + status_t error = B_OK; + + while (bytesRemaining > 0) { + ssize_t bytesWritten = Write(in, bytesRemaining); + if (bytesWritten < 0) { + error = bytesWritten; + break; + } + + if (bytesWritten == 0) { + error = B_PARTIAL_WRITE; + break; + } + + in += bytesWritten; + bytesRemaining -= bytesWritten; + } + + if (_bytesWritten != NULL) + *_bytesWritten = size - bytesRemaining; + + return error; +} + + // Private or Reserved BDataIO::BDataIO(const BDataIO &)