Fennel: FileDevice Class Reference (original) (raw)

Executes a synchronous transfer request for a single random access binding.

This is an all-or-nothing request, so unless the result size is equal to the requested transfer size, the request is considered a failure. However, no exception is thrown when failure occurs; instead, the binding notification method is called.

Parameters:

request transfer specification; must have exactly one binding

Reimplemented in RandomAccessFileDevice.

Definition at line 217 of file FileDevice.cpp.

References RandomAccessRequest::bindingList, RandomAccessRequest::cbOffset, RandomAccessRequest::cbTransfer, handle, RandomAccessRequest::READ, and RandomAccessRequest::type.

Referenced by RandomAccessFileDevice::transfer().

00218 { 00219 FileSize cbActual; 00220 assert(request.bindingList.size() == 1); 00221 #ifdef MSVC 00222 LARGE_INTEGER largeInt; 00223 RandomAccessRequestBinding &binding = request.bindingList.front(); 00224 largeInt.QuadPart = request.cbOffset; 00225 binding.Offset = largeInt.LowPart; 00226 binding.OffsetHigh = largeInt.HighPart; 00227 00228 DWORD dwActual = 0; 00229 BOOL bCompleted; 00230 if (request.type == RandomAccessRequest::READ) { 00231 bCompleted = ReadFile( 00232 HANDLE(handle), 00233 request.bindingList.front().getBuffer(), 00234 request.cbTransfer, 00235 &dwActual, 00236 &binding); 00237 } else { 00238 bCompleted = WriteFile( 00239 HANDLE(handle), 00240 request.bindingList.front().getBuffer(), 00241 request.cbTransfer, 00242 &dwActual, 00243 &binding); 00244 } 00245 if (!bCompleted) { 00246 if (GetLastError() == ERROR_IO_PENDING) { 00247 if (!GetOverlappedResult( 00248 HANDLE(handle), 00249 &binding, 00250 &dwActual, 00251 TRUE)) 00252 { 00253 dwActual = 0; 00254 } 00255 } else { 00256 dwActual = 0; 00257 } 00258 } 00259 cbActual = dwActual; 00260 #else 00261 if (request.type == RandomAccessRequest::READ) { 00262 cbActual = ::pread( 00263 handle, 00264 request.bindingList.front().getBuffer(), 00265 request.cbTransfer, 00266 request.cbOffset); 00267 } else { 00268 cbActual = ::pwrite( 00269 handle, 00270 request.bindingList.front().getBuffer(), 00271 request.cbTransfer, 00272 request.cbOffset); 00273 } 00274 #endif 00275 request.bindingList.front().notifyTransferCompletion( 00276 cbActual == request.cbTransfer); 00277 }