1 /*
2 * Copyright (c) 2021-2022 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 "os/filesystem.h"
17 #include "os/file.h"
18 #include "utils/logger.h"
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #if defined(PANDA_TARGET_WINDOWS)
22 #include <fileapi.h>
23 #endif
24
25 namespace panda::os {
26
CreateDirectories(const std::string & folderName)27 void CreateDirectories(const std::string &folderName)
28 {
29 #ifdef PANDA_TARGET_MOBILE
30 constexpr auto DIR_PERMISSIONS = 0775;
31 mkdir(folderName.c_str(), DIR_PERMISSIONS);
32 #elif PANDA_TARGET_MACOS || PANDA_TARGET_OHOS
33 std::filesystem::create_directories(std::filesystem::path(folderName));
34 #elif PANDA_TARGET_WINDOWS
35 CreateDirectory(folderName.c_str(), NULL);
36 #else
37 constexpr auto DIR_PERMISSIONS = 0775;
38 auto status = mkdir(folderName.c_str(), DIR_PERMISSIONS);
39 if (status != 0) {
40 LOG(WARNING, COMMON) << "Failed to create directory \"" << folderName.c_str() << "\"\n";
41 LOG(WARNING, COMMON) << "Return status :" << status << "\n";
42 }
43 #endif
44 }
45
IsFileExists(const std::string & filepath)46 bool IsFileExists(const std::string &filepath)
47 {
48 std::ifstream openedFile(filepath);
49 return openedFile.good();
50 }
51
GetParentDir(const std::string & filepath)52 std::string GetParentDir(const std::string &filepath)
53 {
54 size_t found = filepath.find_last_of("/\\");
55 if (found == std::string::npos) {
56 return std::string("");
57 }
58 return filepath.substr(0, found);
59 }
60
IsDirExists(const std::string & dirpath)61 bool IsDirExists(const std::string &dirpath)
62 {
63 if (dirpath == std::string("")) {
64 return true;
65 }
66 struct stat info {};
67 return (stat(dirpath.c_str(), &info) == 0) && ((info.st_mode & (unsigned int)S_IFDIR) != 0U);
68 }
69
RemoveExtension(const std::string & filepath)70 std::string RemoveExtension(const std::string &filepath)
71 {
72 auto pos = filepath.find_last_of('.');
73 if (pos != std::string::npos) {
74 return filepath.substr(0, pos);
75 }
76 return filepath;
77 }
78
NormalizePath(const std::string & path)79 std::string NormalizePath(const std::string &path)
80 {
81 if (path.empty()) {
82 return path;
83 }
84
85 auto delim = file::File::GetPathDelim();
86 ASSERT(delim.length() == 1);
87 auto delimChar = delim[0];
88
89 std::vector<std::string_view> parts;
90 size_t begin = 0;
91 size_t length = 0;
92 size_t i = 0;
93 while (i < path.size()) {
94 if (path[i++] != delimChar) {
95 ++length;
96 continue;
97 }
98
99 std::string_view sv(&path[begin], length);
100
101 while (path[i] == delimChar) {
102 ++i;
103 }
104
105 begin = i;
106 length = 0;
107
108 if (sv == ".") {
109 continue;
110 }
111
112 if (sv == "..") {
113 if (parts.empty()) {
114 parts.emplace_back("");
115 continue;
116 }
117
118 if (!parts.back().empty()) {
119 parts.pop_back();
120 }
121 continue;
122 }
123
124 parts.push_back(sv);
125 }
126
127 std::string_view sv(&path[begin], length);
128 parts.push_back(sv);
129
130 std::stringstream ss;
131
132 ASSERT(!parts.empty());
133 i = 0;
134 ss << parts[i++];
135
136 while (i < parts.size()) {
137 ss << delim;
138 ss << parts[i++];
139 }
140
141 return ss.str();
142 }
143
144 } // namespace panda::os
145