pathsplit.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. #pragma once
  2. #include <util/generic/vector.h>
  3. #include <util/generic/strbuf.h>
  4. #include <util/generic/string.h>
  5. #include <util/string/ascii.h>
  6. //do not own any data
  7. struct TPathSplitStore: public TVector<TStringBuf> {
  8. TStringBuf Drive;
  9. bool IsAbsolute = false;
  10. void AppendComponent(const TStringBuf comp);
  11. TStringBuf Extension() const;
  12. protected:
  13. TString DoReconstruct(const TStringBuf slash) const;
  14. inline void DoAppendHint(size_t hint) {
  15. reserve(size() + hint);
  16. }
  17. };
  18. struct TPathSplitTraitsUnix: public TPathSplitStore {
  19. static constexpr char MainPathSep = '/';
  20. inline TString Reconstruct() const {
  21. return DoReconstruct(TStringBuf("/"));
  22. }
  23. static constexpr bool IsPathSep(const char c) noexcept {
  24. return c == '/';
  25. }
  26. static inline bool IsAbsolutePath(const TStringBuf path) noexcept {
  27. return path && IsPathSep(path[0]);
  28. }
  29. void DoParseFirstPart(const TStringBuf part);
  30. void DoParsePart(const TStringBuf part);
  31. };
  32. struct TPathSplitTraitsWindows: public TPathSplitStore {
  33. static constexpr char MainPathSep = '\\';
  34. inline TString Reconstruct() const {
  35. return DoReconstruct(TStringBuf("\\"));
  36. }
  37. static constexpr bool IsPathSep(char c) noexcept {
  38. return c == '/' || c == '\\';
  39. }
  40. static inline bool IsAbsolutePath(const TStringBuf path) noexcept {
  41. return path && (IsPathSep(path[0]) || (path.size() > 1 && path[1] == ':' && IsAsciiAlpha(path[0]) && (path.size() == 2 || IsPathSep(path[2]))));
  42. }
  43. void DoParseFirstPart(const TStringBuf part);
  44. void DoParsePart(const TStringBuf part);
  45. };
  46. #if defined(_unix_)
  47. using TPathSplitTraitsLocal = TPathSplitTraitsUnix;
  48. #else
  49. using TPathSplitTraitsLocal = TPathSplitTraitsWindows;
  50. #endif
  51. template <class TTraits>
  52. class TPathSplitBase: public TTraits {
  53. public:
  54. inline TPathSplitBase() = default;
  55. inline TPathSplitBase(const TStringBuf part) {
  56. this->ParseFirstPart(part);
  57. }
  58. inline TPathSplitBase& AppendHint(size_t hint) {
  59. this->DoAppendHint(hint);
  60. return *this;
  61. }
  62. inline TPathSplitBase& ParseFirstPart(const TStringBuf part) {
  63. this->DoParseFirstPart(part);
  64. return *this;
  65. }
  66. inline TPathSplitBase& ParsePart(const TStringBuf part) {
  67. this->DoParsePart(part);
  68. return *this;
  69. }
  70. template <class It>
  71. inline TPathSplitBase& AppendMany(It b, It e) {
  72. this->AppendHint(e - b);
  73. while (b != e) {
  74. this->AppendComponent(*b++);
  75. }
  76. return *this;
  77. }
  78. };
  79. using TPathSplit = TPathSplitBase<TPathSplitTraitsLocal>;
  80. using TPathSplitUnix = TPathSplitBase<TPathSplitTraitsUnix>;
  81. using TPathSplitWindows = TPathSplitBase<TPathSplitTraitsWindows>;
  82. TString JoinPaths(const TPathSplit& p1, const TPathSplit& p2);
  83. TStringBuf CutExtension(const TStringBuf fileName);