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 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->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. */ 49 bool 50 io_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. */ 57 bool 58 io_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 */ 68 off_t 69 io_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 */ 79 off_t 80 io_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 */ 91 status_t 92 read_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 */ 103 status_t 104 write_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 */ 113 void 114 notify_io_request(io_request* request, status_t status) 115 { 116 request->SetStatusAndNotify(status); 117 } 118