1 /**
2 * Copyright (c) 2023-2025 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 <cstdio>
17 #include <string>
18 #include "os/filesystem.h"
19 #include "path.h"
20
21 namespace ark::es2panda::util {
22
23 constexpr size_t ALLOWED_EXTENSIONS_SIZE = 8;
24 inline constexpr std::array<std::string_view, ALLOWED_EXTENSIONS_SIZE> SUPPORTED_EXTENSIONS = {
25 ".d.ets", ".ets", ".d.sts", ".sts", ".d.ts", ".ts", ".js", ".abc"};
26
27 Path::Path() = default;
28
Path(const util::StringView & absolutePath,ArenaAllocator * allocator)29 Path::Path(const util::StringView &absolutePath, ArenaAllocator *allocator)
30 {
31 Initializer(absolutePath.Mutf8(), allocator);
32 }
33
EndsWith(std::string_view str,std::string_view suffix)34 static bool EndsWith(std::string_view str, std::string_view suffix)
35 {
36 if (str.length() < suffix.length()) {
37 return false;
38 }
39 return str.compare(str.length() - suffix.length(), suffix.length(), suffix) == 0;
40 }
41
Initializer(const std::string & path,ArenaAllocator * allocator)42 void Path::Initializer(const std::string &path, ArenaAllocator *allocator)
43 {
44 isRelative_ = false;
45 allocator_ = allocator;
46 path_ = util::UString(path, allocator).View();
47 if (*(path_.Bytes()) == '.') {
48 isRelative_ = true;
49 }
50
51 absolutePath_ = util::UString(os::GetAbsolutePath(path_.Utf8()), allocator_).View();
52
53 InitializeFileNameWithExtension();
54 InitializeFileExtension();
55 InitializeFileName();
56 InitializeParentFolder();
57 InitializeAbsoluteParentFolder();
58 }
59
InitializeFileName()60 void Path::InitializeFileName()
61 {
62 if (path_.Empty()) {
63 return;
64 }
65
66 if (GetExtension().Empty()) {
67 fileName_ = fileNameWithExtension_;
68 return;
69 }
70
71 for (auto extension : SUPPORTED_EXTENSIONS) {
72 if (EndsWith(fileNameWithExtension_.Utf8(), extension)) {
73 fileName_ = fileNameWithExtension_.Substr(0, fileNameWithExtension_.Length() - extension.length());
74 return;
75 }
76 }
77
78 size_t extensionPosition = fileNameWithExtension_.Mutf8().find_last_of('.');
79 fileName_ = extensionPosition == std::string::npos ? fileNameWithExtension_
80 : fileNameWithExtension_.Substr(0, extensionPosition);
81 }
82
InitializeFileNameWithExtension()83 void Path::InitializeFileNameWithExtension()
84 {
85 if (path_.Empty()) {
86 return;
87 }
88
89 size_t position = path_.Mutf8().find_last_of(PATH_DELIMITER);
90 fileNameWithExtension_ = path_.Substr(position + 1, path_.Length());
91 }
92
InitializeFileExtension()93 void Path::InitializeFileExtension()
94 {
95 if (path_.Empty()) {
96 return;
97 }
98
99 for (auto extension : SUPPORTED_EXTENSIONS) {
100 if (EndsWith(path_.Utf8(), extension)) {
101 fileExtension_ = util::UString(extension, allocator_).View();
102 return;
103 }
104 }
105
106 size_t position = path_.Mutf8().find_last_of('.');
107 if (position != std::string::npos && position + 1 <= path_.Length()) {
108 fileExtension_ = path_.Substr(position + 1, path_.Length());
109 }
110 }
111
InitializeAbsoluteParentFolder()112 void Path::InitializeAbsoluteParentFolder()
113 {
114 if (path_.Empty()) {
115 return;
116 }
117
118 size_t position = absolutePath_.Mutf8().find_last_of(PATH_DELIMITER);
119
120 absoluteParentFolder_ = absolutePath_.Substr(0, position);
121 }
122
InitializeParentFolder()123 void Path::InitializeParentFolder()
124 {
125 if (path_.Empty()) {
126 return;
127 }
128
129 size_t position = path_.Mutf8().find_last_of(PATH_DELIMITER);
130
131 parentFolder_ = path_.Substr(0, position);
132 }
133
InitializeBasePath(std::string basePath)134 void Path::InitializeBasePath(std::string basePath)
135 {
136 if (!basePath.empty() && basePath.back() == PATH_DELIMITER) {
137 basePath_ = util::UString(basePath.substr(0, basePath.length() - 1), allocator_).View();
138 } else {
139 basePath_ = util::UString(basePath, allocator_).View();
140 }
141
142 isRelative_ = true;
143 }
144
Path(const util::StringView & relativePath,const util::StringView & basePath,ArenaAllocator * allocator)145 Path::Path(const util::StringView &relativePath, const util::StringView &basePath, ArenaAllocator *allocator)
146 {
147 Initializer(relativePath.Mutf8(), allocator);
148 InitializeBasePath(basePath.Mutf8());
149 }
150
Path(const std::string & absolutePath,ArenaAllocator * allocator)151 Path::Path(const std::string &absolutePath, ArenaAllocator *allocator)
152 {
153 Initializer(absolutePath, allocator);
154 }
155
Path(const std::string & relativePath,const std::string & basePath,ArenaAllocator * allocator)156 Path::Path(const std::string &relativePath, const std::string &basePath, ArenaAllocator *allocator)
157 {
158 Initializer(relativePath, allocator);
159 InitializeBasePath(basePath);
160 }
161
IsRelative()162 bool Path::IsRelative()
163 {
164 return isRelative_;
165 }
166
IsAbsolute()167 bool Path::IsAbsolute()
168 {
169 return !isRelative_;
170 }
171
GetPath() const172 const util::StringView &Path::GetPath() const
173 {
174 return path_;
175 }
176
GetAbsolutePath() const177 const util::StringView &Path::GetAbsolutePath() const
178 {
179 return absolutePath_;
180 }
181
GetExtension() const182 const util::StringView &Path::GetExtension() const
183 {
184 return fileExtension_;
185 }
186
GetFileName() const187 const util::StringView &Path::GetFileName() const
188 {
189 return fileName_;
190 }
191
GetFileNameWithExtension() const192 const util::StringView &Path::GetFileNameWithExtension() const
193 {
194 return fileNameWithExtension_;
195 }
196
GetParentFolder() const197 const util::StringView &Path::GetParentFolder() const
198 {
199 return parentFolder_;
200 }
201
GetAbsoluteParentFolder() const202 const util::StringView &Path::GetAbsoluteParentFolder() const
203 {
204 return absoluteParentFolder_;
205 }
206
207 } // namespace ark::es2panda::util
208