1 /*
2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <string>
17 #include "libpandabase/os/filesystem.h"
18 #include "libpandabase/os/file.h"
19 #include "libpandabase/utils/logger.h"
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #if defined(PANDA_TARGET_WINDOWS)
23 #include <fileapi.h>
24 #endif
25
26 namespace ark::os {
27
CreateDirectories(const std::string & folderName)28 void CreateDirectories(const std::string &folderName)
29 {
30 #ifdef PANDA_TARGET_MOBILE
31 constexpr auto DIR_PERMISSIONS = 0775;
32 mkdir(folderName.c_str(), DIR_PERMISSIONS);
33 #elif PANDA_TARGET_MACOS || PANDA_TARGET_OHOS
34 std::filesystem::create_directories(std::filesystem::path(folderName));
35 #elif PANDA_TARGET_WINDOWS
36 CreateDirectory(folderName.c_str(), NULL);
37 #else
38 constexpr auto DIR_PERMISSIONS = 0775;
39 auto status = mkdir(folderName.c_str(), DIR_PERMISSIONS);
40 if (status != 0) {
41 LOG(WARNING, COMMON) << "Failed to create directory \"" << folderName.c_str() << "\"\n";
42 LOG(WARNING, COMMON) << "Return status :" << status << "\n";
43 }
44 #endif
45 }
46
IsFileExists(const std::string & filepath)47 bool IsFileExists(const std::string &filepath)
48 {
49 std::ifstream openedFile(filepath);
50 return openedFile.good();
51 }
52
GetParentDir(const std::string & filepath)53 std::string GetParentDir(const std::string &filepath)
54 {
55 size_t found = filepath.find_last_of("/\\");
56 if (found == std::string::npos) {
57 return std::string("");
58 }
59 return filepath.substr(0, found);
60 }
61
IsDirExists(const std::string & dirpath)62 bool IsDirExists(const std::string &dirpath)
63 {
64 if (dirpath == std::string("")) {
65 return true;
66 }
67 struct stat info {};
68 return (stat(dirpath.c_str(), &info) == 0) && ((info.st_mode & static_cast<unsigned int>(S_IFDIR)) != 0U);
69 }
70
RemoveExtension(const std::string & filepath)71 std::string RemoveExtension(const std::string &filepath)
72 {
73 auto pos = filepath.find_last_of('.');
74 if (pos != std::string::npos) {
75 return filepath.substr(0, pos);
76 }
77 return filepath;
78 }
79
NormalizePath(const std::string & path)80 std::string NormalizePath(const std::string &path)
81 {
82 if (path.empty()) {
83 return path;
84 }
85
86 auto delim = file::File::GetPathDelim();
87 ASSERT(delim.length() == 1);
88 auto delimChar = delim[0];
89
90 std::vector<std::string_view> parts;
91 size_t begin = 0;
92 size_t length = 0;
93 size_t i = 0;
94 while (i < path.size()) {
95 if (path[i++] != delimChar) {
96 ++length;
97 continue;
98 }
99
100 std::string_view sv(&path[begin], length);
101
102 while (path[i] == delimChar) {
103 ++i;
104 }
105
106 begin = i;
107 length = 0;
108
109 if (sv == ".") {
110 continue;
111 }
112
113 if (sv == "..") {
114 if (parts.empty()) {
115 parts.emplace_back("");
116 continue;
117 }
118
119 if (!parts.back().empty()) {
120 parts.pop_back();
121 }
122 continue;
123 }
124
125 parts.push_back(sv);
126 }
127
128 std::string_view sv(&path[begin], length);
129 parts.push_back(sv);
130
131 std::stringstream ss;
132
133 ASSERT(!parts.empty());
134 i = 0;
135 ss << parts[i++];
136
137 while (i < parts.size()) {
138 ss << delim;
139 ss << parts[i++];
140 }
141
142 return ss.str();
143 }
144
GetCurrentWorkingDirectory()145 std::string GetCurrentWorkingDirectory()
146 {
147 #ifdef PANDA_TARGET_UNIX
148 std::array<char, PATH_MAX> cwd {};
149 if (getcwd(cwd.data(), sizeof(char) * cwd.size()) == nullptr) {
150 LOG(WARNING, COMMON) << "Failed to get current working directory";
151 return {};
152 }
153 return std::string {cwd.data()};
154 #else
155 UNREACHABLE();
156 #endif
157 }
158
ChangeCurrentWorkingDirectory(const std::string & path)159 void ChangeCurrentWorkingDirectory([[maybe_unused]] const std::string &path)
160 {
161 #ifdef PANDA_TARGET_UNIX
162 auto status = chdir(path.c_str());
163 if (status != 0) {
164 LOG(WARNING, COMMON) << "Failed to change current working directory\n";
165 }
166 #else
167 UNREACHABLE();
168 #endif
169 }
170
171 } // namespace ark::os
172