@@ -40,50 +40,54 @@ const Path Path::REGISTRY = Path::DATA + "registry.db";
40
40
41
41
Path Path::s_root;
42
42
43
- static std::vector<std::string> Split (const std::string &input, bool *absolute )
43
+ static std::vector<std::string> Split (const std::string &input, int *attributes )
44
44
{
45
45
std::vector<std::string> list;
46
+ *attributes = 0 ;
46
47
47
- const auto append = [&list, absolute] (const std::string &part) {
48
- if (part.empty () || part == DOT)
49
- return ;
48
+ size_t last = 0 ;
50
49
51
- #ifdef _WIN32
52
- if (list.empty () && part.size () == 2 && isalpha (part[0 ]) && part[1 ] == ' :' )
53
- *absolute = true ;
54
- #else
55
- (void )absolute;
56
- #endif
57
-
58
- list.push_back (part);
59
- };
60
-
61
- size_t last = 0 , size = input.size ();
62
-
63
- while (last < size) {
50
+ while (last < input.size ()) {
64
51
const size_t pos = input.find_first_of (" \\ /" , last);
65
52
66
- if (pos == std::string::npos) {
67
- append (input.substr (last));
68
- break ;
69
- }
70
- else if (last + pos == 0 ) {
53
+ if (last + pos == 0 ) {
71
54
#ifndef _WIN32
72
- *absolute = true ;
55
+ *attributes |= Path::Absolute ;
73
56
#endif
74
57
last++;
75
58
continue ;
76
59
}
60
+ else if (last == pos) {
61
+ #ifdef _WIN32
62
+ if (pos == 1 )
63
+ *attributes |= Path::UNC | Path::Absolute;
64
+ #endif
65
+ last++;
66
+ continue ;
67
+ }
68
+
69
+ std::string part;
77
70
78
- append (input.substr (last, pos - last));
71
+ if (pos == std::string::npos)
72
+ part = input.substr (last);
73
+ else
74
+ part = input.substr (last, pos - last);
75
+
76
+ #ifdef _WIN32
77
+ if (list.empty () && part.size () == 2 && part[1 ] == ' :' && isalpha (part[0 ]))
78
+ *attributes |= Path::Absolute;
79
+ #endif
79
80
80
- last = pos + 1 ;
81
+ if (part != DOT)
82
+ list.push_back (part);
83
+
84
+ last += part.size () + 1 ;
81
85
}
82
86
83
87
return list;
84
88
}
85
89
86
- Path::Path (const std::string &path) : m_absolute( false )
90
+ Path::Path (const std::string &path) : m_attributes{}
87
91
{
88
92
append (path);
89
93
}
@@ -93,11 +97,11 @@ void Path::append(const std::string &input, const bool traversal)
93
97
if (input.empty ())
94
98
return ;
95
99
96
- bool absolute = false ;
97
- const auto &parts = Split (input, &absolute );
100
+ int attributes ;
101
+ const auto &parts = Split (input, &attributes );
98
102
99
- if (m_parts.empty () && absolute )
100
- m_absolute = true ;
103
+ if (m_parts.empty () && attributes )
104
+ m_attributes = attributes ;
101
105
102
106
for (const std::string &part : parts) {
103
107
if (part == DOTDOT) {
@@ -111,8 +115,8 @@ void Path::append(const std::string &input, const bool traversal)
111
115
112
116
void Path::append (const Path &o)
113
117
{
114
- if (m_parts.empty () && o. absolute () )
115
- m_absolute = true ;
118
+ if (m_parts.empty ())
119
+ m_attributes = o. attributes () ;
116
120
117
121
m_parts.insert (m_parts.end (), o.m_parts .begin (), o.m_parts .end ());
118
122
}
@@ -137,8 +141,8 @@ void Path::remove(const size_t pos, size_t count)
137
141
138
142
m_parts.erase (begin, end);
139
143
140
- if (!pos && m_absolute )
141
- m_absolute = false ;
144
+ if (!pos)
145
+ m_attributes = 0 ;
142
146
}
143
147
144
148
void Path::removeLast ()
@@ -177,35 +181,41 @@ std::string Path::join(const bool nativeSeparator) const
177
181
{
178
182
const char sep = nativeSeparator ? NATIVE_SEPARATOR : UNIX_SEPARATOR;
179
183
180
- #ifdef _WIN32
181
- constexpr bool absoluteSlash = false ;
182
- #else
183
- const bool absoluteSlash = m_absolute;
184
- #endif
185
-
186
184
std::string path;
187
185
186
+ #ifndef _WIN32
187
+ if (test (Absolute))
188
+ path += sep;
189
+ #endif
190
+
188
191
for (const std::string &part : m_parts) {
189
- if (!path.empty () || absoluteSlash)
192
+ #ifdef _WIN32
193
+ if (!path.empty ())
194
+ #else
195
+ if (path.size () > test (Absolute))
196
+ #endif
190
197
path += sep;
191
198
192
199
path += part;
193
200
}
194
201
195
- if (m_parts.empty () && absoluteSlash)
196
- path += sep;
197
-
198
202
#ifdef _WIN32
199
- if (m_absolute && path.size () > MAX_PATH)
203
+ if (test (Absolute) && path.size () > MAX_PATH) {
200
204
path.insert (0 , " \\\\ ?\\ " );
205
+
206
+ if (test (UNC))
207
+ path.insert (4 , " UNC\\ " );
208
+ }
209
+ else if (test (UNC))
210
+ path.insert (0 , " \\\\ " );
201
211
#endif
202
212
203
213
return path;
204
214
}
205
215
206
216
bool Path::startsWith (const Path &o) const
207
217
{
208
- if (size () < o.size () || absolute () != o.absolute ())
218
+ if (m_parts. size () < o.size () || m_attributes != o.attributes ())
209
219
return false ;
210
220
211
221
for (size_t i = 0 ; i < o.size (); i++) {
@@ -218,7 +228,7 @@ bool Path::startsWith(const Path &o) const
218
228
219
229
Path Path::prependRoot () const
220
230
{
221
- return m_absolute ? *this : s_root + *this ;
231
+ return m_attributes & Absolute ? *this : s_root + *this ;
222
232
}
223
233
224
234
Path Path::removeRoot () const
@@ -233,7 +243,7 @@ Path Path::removeRoot() const
233
243
234
244
bool Path::operator ==(const Path &o) const
235
245
{
236
- return m_absolute == o.absolute () && m_parts == o.m_parts ;
246
+ return m_attributes == o.attributes () && m_parts == o.m_parts ;
237
247
}
238
248
239
249
bool Path::operator !=(const Path &o) const
0 commit comments