Changeset 9
- Timestamp:
- Jan 12, 2006, 6:44:29 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtransmission/inout.c
r3 r9 353 353 * 354 354 **********************************************************************/ 355 typedef size_t (* iofunc) ( void *, size_t, size_t, FILE * ); 355 356 static int readOrWriteBytes( tr_io_t * io, uint64_t offset, int size, 356 357 uint8_t * buf, int write ) … … 359 360 tr_info_t * inf = &tor->info; 360 361 361 int piece = offset / inf->pieceSize; 362 int begin = offset % inf->pieceSize; 363 364 int i; 365 uint64_t foo; 366 uint64_t posInFile = 0; 367 int willRead; 368 char * path; 369 FILE * file; 370 371 /* We can't ever read or write more than a piece at a time */ 362 int piece = offset / inf->pieceSize; 363 int begin = offset % inf->pieceSize; 364 int i, cur; 365 char * path; 366 FILE * file; 367 iofunc readOrWrite = write ? (iofunc) fwrite : (iofunc) fread; 368 369 /* Release the torrent lock so the UI can still update itself if 370 this blocks for a while */ 371 tr_lockUnlock( tor->lock ); 372 373 /* We don't ever read or write more than a piece at a time */ 372 374 if( tr_pieceSize( piece ) < begin + size ) 373 375 { 374 return 1; 376 tr_err( "readOrWriteBytes: trying to write more than a piece" ); 377 goto fail; 375 378 } 376 379 377 380 /* Find which file we shall start reading/writing in */ 378 foo = 0;379 381 for( i = 0; i < inf->fileCount; i++ ) 380 382 { 381 if( offset < foo +inf->files[i].length )382 { 383 posInFile = offset - foo;383 if( offset < inf->files[i].length ) 384 { 385 /* This is the file */ 384 386 break; 385 387 } 386 foo += inf->files[i].length; 388 offset -= inf->files[i].length; 389 } 390 if( i >= inf->fileCount ) 391 { 392 /* Should not happen */ 393 tr_err( "readOrWriteBytes: offset out of range" ); 394 goto fail; 387 395 } 388 396 389 397 while( size > 0 ) 390 398 { 399 /* How much can we put or take with this file */ 400 if( inf->files[i].length < offset + size ) 401 { 402 cur = (int) ( inf->files[i].length - offset ); 403 } 404 else 405 { 406 cur = size; 407 } 408 409 /* Now let's get a stream on the file... */ 391 410 asprintf( &path, "%s/%s", tor->destination, inf->files[i].name ); 392 tr_lockUnlock( tor->lock );393 411 file = tr_fdFileOpen( tor->fdlimit, path ); 394 tr_lockLock( tor->lock ); 412 if( !file ) 413 { 414 tr_err( "readOrWriteBytes: could not open file '%s'", path ); 415 free( path ); 416 goto fail; 417 } 395 418 free( path ); 396 419 397 if( !file ) 398 { 399 return 1; 400 } 401 402 willRead = MIN( inf->files[i].length - posInFile, 403 (uint64_t) size ); 404 405 tr_lockUnlock( tor->lock ); 406 if( fseeko( file, posInFile, SEEK_SET ) ) 407 { 408 tr_lockLock( tor->lock ); 409 return 1; 410 } 411 if( write ) 412 { 413 if( fwrite( buf, willRead, 1, file ) != 1 ) 414 { 415 tr_lockLock( tor->lock ); 416 return 1; 417 } 418 } 419 else 420 { 421 if( fread( buf, willRead, 1, file ) != 1 ) 422 { 423 tr_lockLock( tor->lock ); 424 return 1; 425 } 426 } 427 tr_lockLock( tor->lock ); 420 /* seek to the right offset... */ 421 if( fseeko( file, offset, SEEK_SET ) ) 422 { 423 goto fail; 424 } 425 426 /* do what we are here to do... */ 427 if( readOrWrite( buf, cur, 1, file ) != 1 ) 428 { 429 goto fail; 430 } 431 432 /* and close the stream. */ 428 433 tr_fdFileRelease( tor->fdlimit, file ); 429 434 430 /* 'willRead' less bytes to do */ 431 size -= willRead; 432 buf += willRead; 433 434 /* Go to the beginning of the next file */ 435 i += 1; 436 posInFile = 0; 437 } 438 435 /* 'cur' bytes done, 'size - cur' bytes to go with the next file */ 436 i += 1; 437 offset = 0; 438 size -= cur; 439 buf += cur; 440 } 441 442 tr_lockLock( tor->lock ); 439 443 return 0; 444 445 fail: 446 tr_lockLock( tor->lock ); 447 return 1; 440 448 } 441 449
Note: See TracChangeset
for help on using the changeset viewer.