Changeset 19926 in vbox for trunk/src/VBox/Runtime/r3
- Timestamp:
- May 22, 2009 11:37:39 PM (16 years ago)
- svn:sync-xref-src-repo-rev:
- 47628
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/path.cpp
r19924 r19926 448 448 * such as: 449 449 * <ul> 450 * <li>On DOS-like platforms, both |\| and |/| separator charsare considered450 * <li>On DOS-like platforms, both separator chars (|\| and |/|) are considered 451 451 * to be equal. 452 452 * <li>On platforms with case-insensitive file systems, mismatching characters … … 454 454 * </ul> 455 455 * 456 * @remark457 *458 * File system details are currently ignored. This means that you won't get459 * case-insentive compares on unix systems when a path goes into a case-insensitive460 * filesystem like FAT, HPFS, HFS, NTFS, JFS, or similar. For NT, OS/2 and similar461 * you'll won't get case-sensitve compares on a case-sensitive file system.462 *463 * @param pszPath1 Path to compare (must be an absolute path).464 * @param pszPath2 Path to compare (must be an absolute path).465 *466 456 * @returns @< 0 if the first path less than the second path. 467 457 * @returns 0 if the first path identical to the second path. 468 458 * @returns @> 0 if the first path greater than the second path. 459 * 460 * @param pszPath1 Path to compare (must be an absolute path). 461 * @param pszPath2 Path to compare (must be an absolute path). 462 * 463 * @remarks File system details are currently ignored. This means that you won't 464 * get case-insentive compares on unix systems when a path goes into a 465 * case-insensitive filesystem like FAT, HPFS, HFS, NTFS, JFS, or 466 * similar. For NT, OS/2 and similar you'll won't get case-sensitve 467 * compares on a case-sensitive file system. 469 468 */ 470 469 RTDECL(int) RTPathCompare(const char *pszPath1, const char *pszPath2) … … 477 476 * Checks if a path starts with the given parent path. 478 477 * 479 * This means that either the path and the parent path matches completely, or that480 * th e path is to some file or directory residing in the tree given by the parent481 * directory.478 * This means that either the path and the parent path matches completely, or 479 * that the path is to some file or directory residing in the tree given by the 480 * parent directory. 482 481 * 483 482 * The path comparison takes platform-dependent details into account, 484 483 * see RTPathCompare() for details. 484 * 485 * @returns |true| when \a pszPath starts with \a pszParentPath (or when they 486 * are identical), or |false| otherwise. 485 487 * 486 488 * @param pszPath Path to check, must be an absolute path. … … 488 490 * No trailing directory slash! 489 491 * 490 * @returns |true| when \a pszPath starts with \a pszParentPath (or when they 491 * are identical), or |false| otherwise. 492 * 493 * @remark This API doesn't currently handle root directory compares in a manner 494 * consistant with the other APIs. RTPathStartsWith(pszSomePath, "/") will 495 * not work if pszSomePath isn't "/". 492 * @remarks This API doesn't currently handle root directory compares in a 493 * manner consistant with the other APIs. RTPathStartsWith(pszSomePath, 494 * "/") will not work if pszSomePath isn't "/". 496 495 */ 497 496 RTDECL(bool) RTPathStartsWith(const char *pszPath, const char *pszParentPath) … … 542 541 return RTStrDup(szPath); 543 542 return NULL; 543 } 544 545 546 /** 547 * Figures the length of the root part of the path. 548 * 549 * @returns length of the root specifier. 550 * @retval 0 if none. 551 * 552 * @param pszPath The path to investigate. 553 * 554 * @remarks Unnecessary root slashes will not be counted. The caller will have 555 * to deal with it where it matters. 556 */ 557 static size_t rtPathRootSpecLen(const char *pszPath) 558 { 559 /* fend of wildlife. */ 560 if (!pszPath) 561 return 0; 562 563 /* Root slash? */ 564 if (RTPATH_IS_SLASH(pszPath[0])) 565 { 566 #if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS) 567 /* UNC? */ 568 if ( RTPATH_IS_SLASH(pszPath[1]) 569 && pszPath[2] != '\0' 570 && !RTPATH_IS_SLASH(pszPath[2])) 571 { 572 /* Find the end of the server name. */ 573 const char *pszEnd = pszPath + 2; 574 pszEnd += 2; 575 while ( *pszEnd != '\0' 576 && !RTPATH_IS_SLASH(*pszEnd)) 577 pszEnd++; 578 if (RTPATH_IS_SLASH(*pszEnd)) 579 { 580 pszEnd++; 581 while (RTPATH_IS_SLASH(*pszEnd)) 582 pszEnd++; 583 584 /* Find the end of the share name */ 585 while ( *pszEnd != '\0' 586 && !RTPATH_IS_SLASH(*pszEnd)) 587 pszEnd++; 588 if (RTPATH_IS_SLASH(*pszEnd)) 589 pszEnd++; 590 return pszPath - pszEnd; 591 } 592 } 593 #endif 594 return 1; 595 } 596 597 #if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS) 598 /* Drive specifier? */ 599 if ( pszPath[0] != '\0' 600 && pszPath[1] == ':' 601 && RT_C_IS_ALPHA(pszPath[0])) 602 { 603 if (RTPATH_IS_SLASH(pszPath[2])) 604 return 3; 605 return 2; 606 } 607 #endif 608 return 0; 544 609 } 545 610 … … 664 729 665 730 731 RTDECL(int) RTPathAppend(char *pszPath, size_t cchPath, const char *pszAppend) 732 { 733 char *pszPathEnd = (char *)memchr(pszPath, '\0', cchPath); 734 AssertReturn(pszPathEnd, VERR_INVALID_PARAMETER); 735 736 /* 737 * Special cases. 738 */ 739 if (!pszAppend) 740 return VINF_SUCCESS; 741 size_t cchAppend = strlen(pszAppend); 742 if (!cchAppend) 743 return VINF_SUCCESS; 744 if (pszPathEnd == pszPath) 745 { 746 if (cchAppend >= cchPath) 747 return VERR_BUFFER_OVERFLOW; 748 memcpy(pszPath, pszAppend, cchAppend + 1); 749 return VINF_SUCCESS; 750 } 751 752 /* 753 * Balance slashes and check for buffer overflow. 754 */ 755 bool fAddSlash = false; 756 if (!RTPATH_IS_SLASH(pszPathEnd[-1])) 757 { 758 if (!RTPATH_IS_SLASH(pszAppend[0])) 759 { 760 #if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS) 761 if ( pszPath[1] == ':' 762 && RT_C_IS_ALPHA(pszPath[0])) 763 { 764 if ((size_t)(pszPathEnd - pszPath) + cchAppend >= cchPath) 765 return VERR_BUFFER_OVERFLOW; 766 } 767 else 768 #endif 769 { 770 if ((size_t)(pszPathEnd - pszPath) + 1 + cchAppend >= cchPath) 771 return VERR_BUFFER_OVERFLOW; 772 *pszPathEnd++ = '/'; 773 } 774 } 775 else 776 { 777 /* One slash is sufficient at this point. */ 778 while (RTPATH_IS_SLASH(pszAppend[1])) 779 pszAppend++, cchAppend--; 780 781 if ((size_t)(pszPathEnd - pszPath) + cchAppend >= cchPath) 782 return VERR_BUFFER_OVERFLOW; 783 } 784 } 785 else 786 { 787 /* No slashes needed in the appended bit. */ 788 while (RTPATH_IS_SLASH(*pszAppend)) 789 pszAppend++, cchAppend--; 790 791 /* In the leading path we can skip unnecessary trailing slashes, but 792 be sure to leave one. */ 793 size_t const cchRoot = rtPathRootSpecLen(pszPath); 794 while ( (size_t)(pszPathEnd - pszPath) > RT_MAX(1, cchRoot) 795 && RTPATH_IS_SLASH(pszPathEnd[-2])) 796 pszPathEnd--; 797 798 if ((size_t)(pszPathEnd - pszPath) + cchAppend >= cchPath) 799 return VERR_BUFFER_OVERFLOW; 800 } 801 802 /* 803 * What remains now is the just the copying. 804 */ 805 memcpy(pszPathEnd, pszAppend, cchAppend + 1); 806 return VINF_SUCCESS; 807 } 808 809 666 810 #ifndef RT_MINI 667 811
Note:
See TracChangeset
for help on using the changeset viewer.