Changeset 49033 in vbox
- Timestamp:
- Oct 10, 2013 4:43:04 PM (11 years ago)
- svn:sync-xref-src-repo-rev:
- 89809
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/file.h
r48820 r49033 512 512 * Copies a file. 513 513 * 514 * @returns VERR_ALREADY_EXISTS if the destination file exists.515 * @ret urns VBox Status code.514 * @returns IPRT status code 515 * @retval VERR_ALREADY_EXISTS if the destination file exists. 516 516 * 517 517 * @param pszSrc The path to the source file. … … 524 524 * Copies a file given the handles to both files. 525 525 * 526 * @returns VBox Status code.526 * @returns IPRT status code 527 527 * 528 528 * @param FileSrc The source file. The file position is unaltered. … … 548 548 * Copies a file. 549 549 * 550 * @returns VERR_ALREADY_EXISTS if the destination file exists.551 * @ret urns VBox Status code.550 * @returns IPRT status code 551 * @retval VERR_ALREADY_EXISTS if the destination file exists. 552 552 * 553 553 * @param pszSrc The path to the source file. … … 574 574 */ 575 575 RTDECL(int) RTFileCopyByHandlesEx(RTFILE FileSrc, RTFILE FileDst, PFNRTPROGRESS pfnProgress, void *pvUser); 576 577 578 /** 579 * Compares two file given the paths to both files. 580 * 581 * @returns IPRT status code. 582 * @retval VINF_SUCCESS if equal. 583 * @retval VERR_NOT_EQUAL if not equal. 584 * 585 * @param pszFile1 The path to the first file. 586 * @param pszFile2 The path to the second file. 587 */ 588 RTDECL(int) RTFileCompare(const char *pszFile1, const char *pszFile2); 589 590 /** 591 * Compares two file given the handles to both files. 592 * 593 * @returns IPRT status code. 594 * @retval VINF_SUCCESS if equal. 595 * @retval VERR_NOT_EQUAL if not equal. 596 * 597 * @param hFile1 The first file. Undefined return position. 598 * @param hFile2 The second file. Undefined return position. 599 */ 600 RTDECL(int) RTFileCompareByHandles(RTFILE hFile1, RTFILE hFile2); 601 602 /** Flags for RTFileCompareEx(). 603 * @{ */ 604 /** Do not use RTFILE_O_DENY_WRITE on the first file. */ 605 #define RTFILECOMP_FLAGS_NO_DENY_WRITE_FILE1 RT_BIT(0) 606 /** Do not use RTFILE_O_DENY_WRITE on the second file. */ 607 #define RTFILECOMP_FLAGS_NO_DENY_WRITE_FILE2 RT_BIT(1) 608 /** Do not use RTFILE_O_DENY_WRITE on either of the two files. */ 609 #define RTFILECOMP_FLAGS_NO_DENY_WRITE ( RTFILECOMP_FLAGS_NO_DENY_WRITE_FILE1 | RTFILECOMP_FLAGS_NO_DENY_WRITE_FILE2 ) 610 /** */ 611 #define RTFILECOMP_FLAGS_MASK UINT32_C(0x00000003) 612 /** @} */ 613 614 /** 615 * Compares two files, extended version with progress callback. 616 * 617 * @returns IPRT status code. 618 * @retval VINF_SUCCESS if equal. 619 * @retval VERR_NOT_EQUAL if not equal. 620 * 621 * @param pszFile1 The path to the source file. 622 * @param pszFile2 The path to the destination file. This file will be 623 * created. 624 * @param fFlags Flags, any of the RTFILECOMP_FLAGS_ \#defines. 625 * @param pfnProgress Pointer to callback function for reporting progress. 626 * @param pvUser User argument to pass to pfnProgress along with the completion percentage. 627 */ 628 RTDECL(int) RTFileCompareEx(const char *pszFile1, const char *pszFile2, uint32_t fFlags, PFNRTPROGRESS pfnProgress, void *pvUser); 629 630 /** 631 * Compares two files given their handles, extended version with progress 632 * callback. 633 * 634 * @returns IPRT status code. 635 * @retval VINF_SUCCESS if equal. 636 * @retval VERR_NOT_EQUAL if not equal. 637 * 638 * @param hFile1 The first file. Undefined return position. 639 * @param hFile2 The second file. Undefined return position. 640 * 641 * @param fFlags Flags, any of the RTFILECOMP_FLAGS_ \#defines, flags 642 * related to opening of the files will be ignored. 643 * @param pfnProgress Pointer to callback function for reporting progress. 644 * @param pvUser User argument to pass to pfnProgress along with the completion percentage. 645 */ 646 RTDECL(int) RTFileCompareByHandlesEx(RTFILE hFile1, RTFILE hFile2, uint32_t fFlags, PFNRTPROGRESS pfnProgress, void *pvUser); 576 647 577 648 /** -
trunk/src/VBox/Runtime/r3/fileio.cpp
r48935 r49033 28 28 * Header Files * 29 29 *******************************************************************************/ 30 #include "internal/iprt.h" 30 31 #include <iprt/file.h> 31 #include <iprt/alloc.h> 32 33 #include <iprt/mem.h> 32 34 #include <iprt/assert.h> 33 35 #include <iprt/alloca.h> 36 #include <iprt/string.h> 34 37 #include <iprt/err.h> 35 38 #include "internal/file.h" … … 352 355 353 356 354 /**355 * Copies a file given the handles to both files.356 *357 * @returns VBox Status code.358 *359 * @param FileSrc The source file. The file position is unaltered.360 * @param FileDst The destination file.361 * On successful returns the file position is at the end of the file.362 * On failures the file position and size is undefined.363 */364 357 RTDECL(int) RTFileCopyByHandles(RTFILE FileSrc, RTFILE FileDst) 365 358 { … … 368 361 369 362 370 /**371 * Copies a file.372 *373 * @returns VERR_ALREADY_EXISTS if the destination file exists.374 * @returns VBox Status code.375 *376 * @param pszSrc The path to the source file.377 * @param pszDst The path to the destination file.378 * This file will be created.379 * @param fFlags Flags, any of the RTFILECOPY_FLAGS_ \#defines.380 * @param pfnProgress Pointer to callback function for reporting progress.381 * @param pvUser User argument to pass to pfnProgress along with the completion percentage.382 */383 363 RTDECL(int) RTFileCopyEx(const char *pszSrc, const char *pszDst, uint32_t fFlags, PFNRTPROGRESS pfnProgress, void *pvUser) 384 364 { … … 432 412 433 413 434 /**435 * Copies a file given the handles to both files and436 * provide progress callbacks.437 *438 * @returns VBox Status code.439 *440 * @param FileSrc The source file. The file position is unaltered.441 * @param FileDst The destination file.442 * On successful returns the file position is at the end of the file.443 * On failures the file position and size is undefined.444 * @param pfnProgress Pointer to callback function for reporting progress.445 * @param pvUser User argument to pass to pfnProgress along with the completion percentage.446 */447 414 RTDECL(int) RTFileCopyByHandlesEx(RTFILE FileSrc, RTFILE FileDst, PFNRTPROGRESS pfnProgress, void *pvUser) 448 415 { … … 561 528 } 562 529 530 531 RTDECL(int) RTFileCompare(const char *pszFile1, const char *pszFile2) 532 { 533 return RTFileCompareEx(pszFile1, pszFile2, 0 /*fFlags*/, NULL, NULL); 534 } 535 536 537 RTDECL(int) RTFileCompareByHandles(RTFILE hFile1, RTFILE hFile2) 538 { 539 return RTFileCompareByHandlesEx(hFile1, hFile2, 0 /*fFlags*/, NULL, NULL); 540 } 541 542 543 RTDECL(int) RTFileCompareEx(const char *pszFile1, const char *pszFile2, uint32_t fFlags, PFNRTPROGRESS pfnProgress, void *pvUser) 544 { 545 /* 546 * Validate input. 547 */ 548 AssertPtrReturn(pszFile1, VERR_INVALID_POINTER); 549 AssertReturn(*pszFile1, VERR_INVALID_PARAMETER); 550 AssertPtrReturn(pszFile2, VERR_INVALID_POINTER); 551 AssertReturn(*pszFile2, VERR_INVALID_PARAMETER); 552 AssertMsgReturn(!pfnProgress || VALID_PTR(pfnProgress), ("pfnProgress=%p\n", pfnProgress), VERR_INVALID_PARAMETER); 553 AssertMsgReturn(!(fFlags & ~RTFILECOMP_FLAGS_MASK), ("%#x\n", fFlags), VERR_INVALID_PARAMETER); 554 555 /* 556 * Open the files. 557 */ 558 RTFILE hFile1; 559 int rc = RTFileOpen(&hFile1, pszFile1, 560 RTFILE_O_READ | RTFILE_O_OPEN 561 | (fFlags & RTFILECOMP_FLAGS_NO_DENY_WRITE_FILE1 ? RTFILE_O_DENY_NONE : RTFILE_O_DENY_WRITE)); 562 if (RT_SUCCESS(rc)) 563 { 564 RTFILE hFile2; 565 rc = RTFileOpen(&hFile2, pszFile2, 566 RTFILE_O_WRITE | RTFILE_O_CREATE 567 | (fFlags & RTFILECOMP_FLAGS_NO_DENY_WRITE_FILE2 ? RTFILE_O_DENY_NONE : RTFILE_O_DENY_WRITE)); 568 if (RT_SUCCESS(rc)) 569 { 570 /* 571 * Call the ByHandles version and let it do the job. 572 */ 573 rc = RTFileCompareByHandlesEx(hFile1, hFile2, fFlags, pfnProgress, pvUser); 574 575 /* Clean up */ 576 int rc2 = RTFileClose(hFile2); 577 AssertRC(rc2); 578 if (RT_FAILURE(rc2) && RT_SUCCESS(rc)) 579 rc = rc2; 580 } 581 582 int rc2 = RTFileClose(hFile2); 583 AssertRC(rc2); 584 if (RT_FAILURE(rc2) && RT_SUCCESS(rc)) 585 rc = rc2; 586 } 587 return rc; 588 } 589 590 591 RTDECL(int) RTFileCompareByHandlesEx(RTFILE hFile1, RTFILE hFile2, uint32_t fFlags, PFNRTPROGRESS pfnProgress, void *pvUser) 592 { 593 /* 594 * Validate input. 595 */ 596 AssertReturn(RTFileIsValid(hFile1), VERR_INVALID_HANDLE); 597 AssertReturn(RTFileIsValid(hFile1), VERR_INVALID_HANDLE); 598 AssertMsgReturn(!pfnProgress || VALID_PTR(pfnProgress), ("pfnProgress=%p\n", pfnProgress), VERR_INVALID_PARAMETER); 599 AssertMsgReturn(!(fFlags & ~RTFILECOMP_FLAGS_MASK), ("%#x\n", fFlags), VERR_INVALID_PARAMETER); 600 601 /* 602 * Compare the file sizes first. 603 */ 604 uint64_t cbFile1; 605 int rc = RTFileGetSize(hFile1, &cbFile1); 606 if (RT_FAILURE(rc)) 607 return rc; 608 609 uint64_t cbFile2; 610 rc = RTFileGetSize(hFile1, &cbFile2); 611 if (RT_FAILURE(rc)) 612 return rc; 613 614 if (cbFile1 != cbFile2) 615 return VERR_NOT_EQUAL; 616 617 618 /* 619 * Allocate buffer. 620 */ 621 size_t cbBuf; 622 uint8_t *pbBuf1Free = NULL; 623 uint8_t *pbBuf1; 624 uint8_t *pbBuf2Free = NULL; 625 uint8_t *pbBuf2; 626 if (cbFile1 < _512K) 627 { 628 cbBuf = 8*_1K; 629 pbBuf1 = (uint8_t *)alloca(cbBuf); 630 pbBuf2 = (uint8_t *)alloca(cbBuf); 631 } 632 else 633 { 634 cbBuf = _128K; 635 pbBuf1 = pbBuf1Free = (uint8_t *)RTMemTmpAlloc(cbBuf); 636 pbBuf2 = pbBuf2Free = (uint8_t *)RTMemTmpAlloc(cbBuf); 637 } 638 if (pbBuf1 && pbBuf2) 639 { 640 /* 641 * Seek to the start of each file 642 * and set the size of the destination file. 643 */ 644 rc = RTFileSeek(hFile1, 0, RTFILE_SEEK_BEGIN, NULL); 645 if (RT_SUCCESS(rc)) 646 { 647 rc = RTFileSeek(hFile2, 0, RTFILE_SEEK_BEGIN, NULL); 648 if (RT_SUCCESS(rc) && pfnProgress) 649 rc = pfnProgress(0, pvUser); 650 if (RT_SUCCESS(rc)) 651 { 652 /* 653 * Compare loop. 654 */ 655 unsigned uPercentage = 0; 656 RTFOFF off = 0; 657 RTFOFF cbPercent = cbFile1 / 100; 658 RTFOFF offNextPercent = cbPercent; 659 while (off < (RTFOFF)cbFile1) 660 { 661 /* read the blocks */ 662 RTFOFF cbLeft = cbFile1 - off; 663 size_t cbBlock = cbLeft >= (RTFOFF)cbBuf ? cbBuf : (size_t)cbLeft; 664 rc = RTFileRead(hFile1, pbBuf1, cbBlock, NULL); 665 if (RT_FAILURE(rc)) 666 break; 667 rc = RTFileRead(hFile2, pbBuf2, cbBlock, NULL); 668 if (RT_FAILURE(rc)) 669 break; 670 671 /* compare */ 672 if (memcmp(pbBuf1, pbBuf2, cbBlock)) 673 { 674 rc = VERR_NOT_EQUAL; 675 break; 676 } 677 678 /* advance */ 679 off += cbBlock; 680 if (pfnProgress && offNextPercent < off) 681 { 682 while (offNextPercent < off) 683 { 684 uPercentage++; 685 offNextPercent += cbPercent; 686 } 687 rc = pfnProgress(uPercentage, pvUser); 688 if (RT_FAILURE(rc)) 689 break; 690 } 691 } 692 693 #if 0 694 /* 695 * Compare OS specific data (EAs and stuff). 696 */ 697 if (RT_SUCCESS(rc)) 698 rc = rtFileCompareOSStuff(hFile1, hFile2); 699 #endif 700 701 /* 100% */ 702 if (pfnProgress && uPercentage < 100 && RT_SUCCESS(rc)) 703 rc = pfnProgress(100, pvUser); 704 } 705 } 706 } 707 else 708 rc = VERR_NO_MEMORY; 709 RTMemTmpFree(pbBuf2Free); 710 RTMemTmpFree(pbBuf1Free); 711 712 return rc; 713 } 714
Note:
See TracChangeset
for help on using the changeset viewer.