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
21namespace ark::es2panda::util {
22
23Path::Path() = default;
24
25Path::Path(const util::StringView &absolutePath, ArenaAllocator *allocator)
26{
27    Initializer(absolutePath.Mutf8(), allocator);
28}
29
30void 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
47void 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
64void 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
76void 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
89void 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
100void 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
111Path::Path(const util::StringView &relativePath, const util::StringView &basePath, ArenaAllocator *allocator)
112{
113    Initializer(relativePath.Mutf8(), allocator);
114    InitializeBasePath(basePath.Mutf8());
115}
116
117Path::Path(const std::string &absolutePath, ArenaAllocator *allocator)
118{
119    Initializer(absolutePath, allocator);
120}
121
122Path::Path(const std::string &relativePath, const std::string &basePath, ArenaAllocator *allocator)
123{
124    Initializer(relativePath, allocator);
125    InitializeBasePath(basePath);
126}
127
128bool Path::IsRelative()
129{
130    return isRelative_;
131}
132
133bool Path::IsAbsolute()
134{
135    return !isRelative_;
136}
137
138const util::StringView &Path::GetPath() const
139{
140    return path_;
141}
142
143const util::StringView &Path::GetAbsolutePath() const
144{
145    return absolutePath_;
146}
147
148const util::StringView &Path::GetExtension() const
149{
150    return fileExtension_;
151}
152
153const util::StringView &Path::GetFileName() const
154{
155    return fileName_;
156}
157
158const util::StringView &Path::GetParentFolder() const
159{
160    return parentFolder_;
161}
162
163const util::StringView &Path::GetAbsoluteParentFolder() const
164{
165    return absoluteParentFolder_;
166}
167
168}  // namespace ark::es2panda::util
169