Extended the public I/O request C API.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34121 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2009-11-19 07:38:33 +00:00
parent e337e55fdd
commit 1ca0b78f54
2 changed files with 92 additions and 3 deletions

View File

@ -19,8 +19,14 @@ typedef struct IORequest io_request;
extern "C" {
#endif
bool io_request_is_write(const io_request* request);
void notify_io_request(io_request* request, status_t status);
bool io_request_is_write(const io_request* request);
off_t io_request_offset(const io_request* request);
off_t io_request_length(const io_request* request);
status_t read_from_io_request(io_request* request, void* buffer,
size_t size);
status_t write_to_io_request(io_request* request, const void* buffer,
size_t size);
void notify_io_request(io_request* request, status_t status);
#ifdef __cplusplus
}

View File

@ -8,6 +8,41 @@
#include "IORequest.h"
// #pragma mark - static helpers
status_t
transfer_io_request_data(io_request* request, void* buffer, size_t size,
bool isWrite)
{
if (isWrite != request->IsWrite() || request->RemainingBytes() < size)
return B_BAD_VALUE;
// lock the request buffer memory, if it is user memory
IOBuffer* ioBuffer = request->Buffer();
if (ioBuffer->IsUser() && !ioBuffer->IsMemoryLocked()) {
status_t error = ioBuffer->LockMemory(request->Team(), isWrite);
if (error != B_OK)
return error;
}
// read/write
off_t offset = request->Offset() + request->TransferredBytes();
status_t error = isWrite
? request->CopyData(buffer, offset, size)
: request->CopyData(offset, buffer, size);
if (error != B_OK)
return error;
request->Advance(size);
return B_OK;
}
// #pragma mark - public API
/*! Returns whether the given I/O request is a write request. */
bool
io_request_is_write(const io_request* request)
{
@ -15,9 +50,57 @@ io_request_is_write(const io_request* request)
}
/*! Returns the read/write offset of the given I/O request.
This is the immutable offset the request was created with;
read_from_io_request() and write_to_io_request() don't change it.
*/
off_t
io_request_offset(const io_request* request)
{
return request->Offset();
}
/*! Returns the read/write length of the given I/O request.
This is the immutable length the request was created with;
read_from_io_request() and write_to_io_request() don't change it.
*/
off_t
io_request_length(const io_request* request)
{
return request->Length();
}
/*! Reads data from the given I/O request into the given buffer and advances
the request's transferred data pointer.
Multiple calls to read_from_io_request() are allowed, but the total size
must not exceed io_request_length(request).
*/
status_t
read_from_io_request(io_request* request, void* buffer, size_t size)
{
return transfer_io_request_data(request, buffer, size, false);
}
/*! Writes data from the given buffer to the given I/O request and advances
the request's transferred data pointer.
Multiple calls to write_to_io_request() are allowed, but the total size
must not exceed io_request_length(request).
*/
status_t
write_to_io_request(io_request* request, const void* buffer, size_t size)
{
return transfer_io_request_data(request, (void*)buffer, size, true);
}
/*! Sets the given I/O request's status and notifies listeners that the request
is finished.
*/
void
notify_io_request(io_request* request, status_t status)
{
request->SetStatusAndNotify(status);
}