1 /* 2 * Copyright 2009, 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 14 static status_t 15 transfer_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->Team(), !writeToRequest); 27 if (error != B_OK) 28 return error; 29 } 30 31 // read/write 32 off_t offset = request->Offset() + request->TransferredBytes(); 33 status_t error = writeToRequest 34 ? request->CopyData(buffer, offset, size) 35 : request->CopyData(offset, buffer, size); 36 if (error != B_OK) 37 return error; 38 39 request->Advance(size); 40 return B_OK; 41 } 42 43 44 // #pragma mark - public API 45 46 47 /*! Returns whether the given I/O request is a write request. */ 48 bool 49 io_request_is_write(const io_request* request) 50 { 51 return request->IsWrite(); 52 } 53 54 55 /*! Returns whether the I/O request has VIP status. */ 56 bool 57 io_request_is_vip(const io_request* request) 58 { 59 return (request->Flags() & B_VIP_IO_REQUEST) != 0; 60 } 61 62 63 /*! Returns the read/write offset of the given I/O request. 64 This is the immutable offset the request was created with; 65 read_from_io_request() and write_to_io_request() don't change it. 66 */ 67 off_t 68 io_request_offset(const io_request* request) 69 { 70 return request->Offset(); 71 } 72 73 74 /*! Returns the read/write length of the given I/O request. 75 This is the immutable length the request was created with; 76 read_from_io_request() and write_to_io_request() don't change it. 77 */ 78 off_t 79 io_request_length(const io_request* request) 80 { 81 return request->Length(); 82 } 83 84 85 /*! Reads data from the given I/O request into the given buffer and advances 86 the request's transferred data pointer. 87 Multiple calls to read_from_io_request() are allowed, but the total size 88 must not exceed io_request_length(request). 89 */ 90 status_t 91 read_from_io_request(io_request* request, void* buffer, size_t size) 92 { 93 return transfer_io_request_data(request, buffer, size, false); 94 } 95 96 97 /*! Writes data from the given buffer to the given I/O request and advances 98 the request's transferred data pointer. 99 Multiple calls to write_to_io_request() are allowed, but the total size 100 must not exceed io_request_length(request). 101 */ 102 status_t 103 write_to_io_request(io_request* request, const void* buffer, size_t size) 104 { 105 return transfer_io_request_data(request, (void*)buffer, size, true); 106 } 107 108 109 /*! Sets the given I/O request's status and notifies listeners that the request 110 is finished. 111 */ 112 void 113 notify_io_request(io_request* request, status_t status) 114 { 115 request->SetStatusAndNotify(status); 116 } 117