1/* 2 * Copyright 2009-2011, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6#include <io_requests.h> 7 8#include "IORequest.h" 9 10 11// #pragma mark - static helpers 12 13 14static status_t 15transfer_io_request_data(io_request* request, void* buffer, size_t size, 16 bool writeToRequest) 17{ 18 if (writeToRequest == request->IsWrite() 19 || request->RemainingBytes() < size) { 20 return B_BAD_VALUE; 21 } 22 23 // lock the request buffer memory, if it is user memory 24 IOBuffer* ioBuffer = request->Buffer(); 25 if (ioBuffer->IsUser() && !ioBuffer->IsMemoryLocked()) { 26 status_t error = ioBuffer->LockMemory(request->TeamID(), 27 !writeToRequest); 28 if (error != B_OK) 29 return error; 30 } 31 32 // read/write 33 off_t offset = request->Offset() + request->TransferredBytes(); 34 status_t error = writeToRequest 35 ? request->CopyData(buffer, offset, size) 36 : request->CopyData(offset, buffer, size); 37 if (error != B_OK) 38 return error; 39 40 request->Advance(size); 41 return B_OK; 42} 43 44 45// #pragma mark - public API 46 47 48/*! Returns whether the given I/O request is a write request. */ 49bool 50io_request_is_write(const io_request* request) 51{ 52 return request->IsWrite(); 53} 54 55 56/*! Returns whether the I/O request has VIP status. */ 57bool 58io_request_is_vip(const io_request* request) 59{ 60 return (request->Flags() & B_VIP_IO_REQUEST) != 0; 61} 62 63 64/*! Returns the read/write offset of the given I/O request. 65 This is the immutable offset the request was created with; 66 read_from_io_request() and write_to_io_request() don't change it. 67*/ 68off_t 69io_request_offset(const io_request* request) 70{ 71 return request->Offset(); 72} 73 74 75/*! Returns the read/write length of the given I/O request. 76 This is the immutable length the request was created with; 77 read_from_io_request() and write_to_io_request() don't change it. 78*/ 79off_t 80io_request_length(const io_request* request) 81{ 82 return request->Length(); 83} 84 85 86/*! Reads data from the given I/O request into the given buffer and advances 87 the request's transferred data pointer. 88 Multiple calls to read_from_io_request() are allowed, but the total size 89 must not exceed io_request_length(request). 90*/ 91status_t 92read_from_io_request(io_request* request, void* buffer, size_t size) 93{ 94 return transfer_io_request_data(request, buffer, size, false); 95} 96 97 98/*! Writes data from the given buffer to the given I/O request and advances 99 the request's transferred data pointer. 100 Multiple calls to write_to_io_request() are allowed, but the total size 101 must not exceed io_request_length(request). 102*/ 103status_t 104write_to_io_request(io_request* request, const void* buffer, size_t size) 105{ 106 return transfer_io_request_data(request, (void*)buffer, size, true); 107} 108 109 110/*! Sets the given I/O request's status and notifies listeners that the request 111 is finished. 112*/ 113void 114notify_io_request(io_request* request, status_t status) 115{ 116 request->SetStatusAndNotify(status); 117} 118