1 /**
2  * Copyright (c) 2023-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 <cstdio>
17 #include <string>
18 #include "os/filesystem.h"
19 #include "path.h"
20 
21 namespace ark::es2panda::util {
22 
23 Path::Path() = default;
24 
Path(const util::StringView &absolutePath, ArenaAllocator *allocator)25 Path::Path(const util::StringView &absolutePath, ArenaAllocator *allocator)
26 {
27     Initializer(absolutePath.Mutf8(), allocator);
28 }
29 
Initializer(const std::string &path, ArenaAllocator *allocator)30 void Path::Initializer(const std::string &path, ArenaAllocator *allocator)
31 {
32     isRelative_ = false;
33     allocator_ = allocator;
34     path_ = util::UString(path, allocator).View();
35     if (*(path_.Bytes()) == '.') {
36         isRelative_ = true;
37     }
38 
39     absolutePath_ = util::UString(os::GetAbsolutePath(path_.Utf8()), allocator_).View();
40 
41     InitializeFileExtension();
42     InitializeFileName();
43     InitializeParentFolder();
44     InitializeAbsoluteParentFolder();
45 }
46 
InitializeFileName()47 void Path::InitializeFileName()
48 {
49     if (path_.Empty()) {
50         return;
51     }
52 
53     int position = path_.Mutf8().find_last_of(PATH_DELIMITER);
54 
55     util::StringView fileName = path_.Substr(position + 1, path_.Length());
56     if (GetExtension().Empty()) {
57         fileName_ = fileName;
58     } else {
59         int extensionPosition = fileName.Mutf8().find_last_of('.');
60         fileName_ = fileName.Substr(0, extensionPosition);
61     }
62 }
63 
InitializeFileExtension()64 void Path::InitializeFileExtension()
65 {
66     if (path_.Empty()) {
67         return;
68     }
69 
70     size_t position = path_.Mutf8().find_last_of('.');
71     if (position != std::string::npos && position + 1 <= path_.Length()) {
72         fileExtension_ = path_.Substr(position + 1, path_.Length());
73     }
74 }
75 
InitializeAbsoluteParentFolder()76 void Path::InitializeAbsoluteParentFolder()
77 {
78     if (path_.Empty()) {
79         return;
80     }
81 
82     int position = absolutePath_.Mutf8().find_last_of(PATH_DELIMITER);
83 
84     if (!absolutePath_.Empty() && isRelative_) {
85         absoluteParentFolder_ = absolutePath_.Substr(0, position);
86     }
87 }
88 
InitializeParentFolder()89 void Path::InitializeParentFolder()
90 {
91     if (path_.Empty()) {
92         return;
93     }
94 
95     int position = path_.Mutf8().find_last_of(PATH_DELIMITER);
96 
97     parentFolder_ = path_.Substr(0, position);
98 }
99 
InitializeBasePath(std::string basePath)100 void Path::InitializeBasePath(std::string basePath)
101 {
102     if (!basePath.empty() && basePath.back() == PATH_DELIMITER) {
103         basePath_ = util::UString(basePath.substr(0, basePath.length() - 1), allocator_).View();
104     } else {
105         basePath_ = util::UString(basePath, allocator_).View();
106     }
107 
108     isRelative_ = true;
109 }
110 
Path(const util::StringView &relativePath, const util::StringView &basePath, ArenaAllocator *allocator)111 Path::Path(const util::StringView &relativePath, const util::StringView &basePath, ArenaAllocator *allocator)
112 {
113     Initializer(relativePath.Mutf8(), allocator);
114     InitializeBasePath(basePath.Mutf8());
115 }
116 
Path(const std::string &absolutePath, ArenaAllocator *allocator)117 Path::Path(const std::string &absolutePath, ArenaAllocator *allocator)
118 {
119     Initializer(absolutePath, allocator);
120 }
121 
Path(const std::string &relativePath, const std::string &basePath, ArenaAllocator *allocator)122 Path::Path(const std::string &relativePath, const std::string &basePath, ArenaAllocator *allocator)
123 {
124     Initializer(relativePath, allocator);
125     InitializeBasePath(basePath);
126 }
127 
IsRelative()128 bool Path::IsRelative()
129 {
130     return isRelative_;
131 }
132 
IsAbsolute()133 bool Path::IsAbsolute()
134 {
135     return !isRelative_;
136 }
137 
GetPath() const138 const util::StringView &Path::GetPath() const
139 {
140     return path_;
141 }
142 
GetAbsolutePath() const143 const util::StringView &Path::GetAbsolutePath() const
144 {
145     return absolutePath_;
146 }
147 
GetExtension() const148 const util::StringView &Path::GetExtension() const
149 {
150     return fileExtension_;
151 }
152 
GetFileName() const153 const util::StringView &Path::GetFileName() const
154 {
155     return fileName_;
156 }
157 
GetParentFolder() const158 const util::StringView &Path::GetParentFolder() const
159 {
160     return parentFolder_;
161 }
162 
GetAbsoluteParentFolder() const163 const util::StringView &Path::GetAbsoluteParentFolder() const
164 {
165     return absoluteParentFolder_;
166 }
167 
168 }  // namespace ark::es2panda::util
169