MCPcopy Create free account
hub / github.com/deathkiller/jazz2-native / GetPathRootLength

Function GetPathRootLength

Sources/Shared/IO/FileSystem.cpp:109–185  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

107 namespace
108 {
109 static std::size_t GetPathRootLength(StringView path)
110 {
111 if (path.empty()) return 0;
112
113#if defined(DEATH_TARGET_WINDOWS)
114 constexpr StringView ExtendedPathPrefix = "\\\\?\\"_s;
115 constexpr StringView UncExtendedPathPrefix = "\\\\?\\UNC\\"_s;
116
117 std::size_t i = 0;
118 std::size_t pathLength = path.size();
119 std::size_t volumeSeparatorLength = 2; // Length to the colon "C:"
120 std::size_t uncRootLength = 2; // Length to the start of the server name "\\"
121
122 bool extendedSyntax = path.hasPrefix(ExtendedPathPrefix);
123 bool extendedUncSyntax = path.hasPrefix(UncExtendedPathPrefix);
124 if (extendedSyntax) {
125 // Shift the position we look for the root from to account for the extended prefix
126 if (extendedUncSyntax) {
127 // "\\" -> "\\?\UNC\"
128 uncRootLength = UncExtendedPathPrefix.size();
129 } else {
130 // "C:" -> "\\?\C:"
131 volumeSeparatorLength += ExtendedPathPrefix.size();
132 }
133 }
134
135 if ((!extendedSyntax || extendedUncSyntax) && (path[0] == '/' || path[0] == '\\')) {
136 // UNC or simple rooted path (e.g., "\foo", NOT "\\?\C:\foo")
137 i = 1;
138 if (extendedUncSyntax || (pathLength > 1 && (path[1] == '/' || path[1] == '\\'))) {
139 // UNC ("\\?\UNC\" or "\\"), scan past the next two directory separators at most (e.g., "\\?\UNC\Server\Share" or "\\Server\Share\")
140 i = uncRootLength;
141 std::int32_t n = 2; // Maximum separators to skip
142 while (i < pathLength && ((path[i] != '/' && path[i] != '\\') || --n > 0)) {
143 i++;
144 }
145 // Keep the last path separator as part of root prefix
146 if (i < pathLength && (path[i] == '/' || path[i] == '\\')) {
147 i++;
148 }
149 }
150 } else if (pathLength >= volumeSeparatorLength && path[volumeSeparatorLength - 1] == ':') {
151 // Path is at least longer than where we expect a colon and has a colon ("\\?\A:", "A:")
152 // If the colon is followed by a directory separator, move past it
153 i = volumeSeparatorLength;
154 if (pathLength >= volumeSeparatorLength + 1 && (path[volumeSeparatorLength] == '/' || path[volumeSeparatorLength] == '\\')) {
155 i++;
156 }
157 }
158
159 return i;
160#else
161# if defined(DEATH_TARGET_ANDROID)
162 if (path.hasPrefix(AndroidAssetStream::Prefix)) {
163 return AndroidAssetStream::Prefix.size();
164 }
165# elif defined(DEATH_TARGET_SWITCH) || defined(DEATH_TARGET_VITA)
166 // Switch mount points: romfs:, sdmc:, etc.

Callers 5

CombinePathMethod · 0.85
GetDirectoryNameMethod · 0.85
GetFileNameMethod · 0.85
GetAbsolutePathMethod · 0.85
IsAbsolutePathMethod · 0.85

Calls 4

emptyMethod · 0.45
sizeMethod · 0.45
hasPrefixMethod · 0.45
dataMethod · 0.45

Tested by

no test coverage detected