Mana
Loading...
Searching...
No Matches
path.cpp
Go to the documentation of this file.
1/*
2 * The Mana Server
3 * Copyright (C) 2013 The Mana World Development Team
4 *
5 * This file is part of The Mana Server.
6 *
7 * The Mana Server is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * any later version.
11 *
12 * The Mana Server is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with The Mana Server. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include "utils/path.h"
22#include <vector>
23
24namespace utils
25{
29 std::string_view path(std::string_view fullFilePath)
30 {
31 // We'll reverse-search for '/' or'\' and extract the substring
32 // corresponding to path.
33 const auto slashPos = fullFilePath.find_last_of("/\\");
34 if (slashPos != std::string::npos)
35 return fullFilePath.substr(0, slashPos + 1);
36 else
37 return std::string_view();
38 }
39
55 std::string joinPaths(std::string_view path1, std::string_view path2)
56 {
57 std::string joined;
58
59 if (path2.empty())
60 {
61 joined.append(path1);
62 }
63 else if (path1.empty())
64 {
65 joined.append(path2);
66 }
67 else if (path2[0] == '/' || path2[0] == '\\')
68 {
69 // return only path2 if it is an absolute path
70 joined.append(path2);
71 }
72 else
73 {
74 joined.append(path1);
75 if (joined.back() != '/' && joined.back() != '\\')
76 joined.append("/");
77 joined.append(path2);
78 }
79
80 return joined;
81 }
82
86 std::string cleanPath(const std::string &path)
87 {
88 std::string part;
89 std::string result;
90 std::vector<std::string> pathStack;
91
92 size_t prev = 0;
93 while (true)
94 {
95 size_t cur = path.find_first_of("/\\", prev);
96 if (cur == std::string::npos)
97 {
98 // FIXME add everything from prev to the end
99 pathStack.push_back(path.substr(prev));
100 break;
101 }
102
103 part = path.substr(prev, cur - prev);
104 if (part == "..")
105 {
106 // go back one level
107 if (!pathStack.empty())
108 {
109 pathStack.pop_back();
110 }
111 }
112 else if (part == ".")
113 {
114 // do nothing
115 }
116 else if (part.empty())
117 {
118 if (pathStack.empty() && cur == 0)
119 {
120 // handle first empty match before the root slash
121 pathStack.emplace_back();
122 }
123 else
124 {
125 // empty match in the middle of the path should be ignored
126 }
127 }
128 else
129 {
130 // normal path element
131 pathStack.push_back(part);
132 }
133
134 cur++;
135 prev = cur;
136 }
137
138 // join the pathStack into a normal path
139 unsigned int i = 0;
140 for (i = 0; i < pathStack.size(); i++)
141 {
142 result += pathStack[i];
143 if (i < pathStack.size() - 1) {
144 result += "/";
145 }
146 }
147
148 return result;
149 }
150}
Definition path.cpp:25
std::string cleanPath(const std::string &path)
Removes relative elements from the path.
Definition path.cpp:86
std::string_view path(std::string_view fullFilePath)
Returns the path without the file name.
Definition path.cpp:29
std::string joinPaths(std::string_view path1, std::string_view path2)
Join two path elements into one.
Definition path.cpp:55