Line data Source code
1 : /**
2 : * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 :
11 : #include "path.h"
12 : #include <algorithm>
13 : #include "str_utils.h"
14 : #include "log/hdc_log.h"
15 :
16 : namespace Adx {
17 : namespace {
18 : constexpr char DIRECTORY_SEPARATOR = '/';
19 : constexpr char FILE_EXTENSION_CHAR = '.';
20 :
21 : constexpr mmMode_t DEFAULT_DIR_MODE = M_IRUSR | M_IWUSR | M_IXUSR;
22 : } // namespace
23 :
24 29 : Path &Path::operator = (const std::string &path)
25 : {
26 29 : path_ = path;
27 29 : return *this;
28 : }
29 :
30 0 : bool Path::operator == (const Path &other) const
31 : {
32 0 : return this->path_ == other.GetString();
33 : }
34 :
35 3 : Path &Path::operator += (const std::string &path)
36 : {
37 3 : return Append(path);
38 : }
39 :
40 3 : Path &Path::Assign(const std::string &path)
41 : {
42 3 : path_ = path;
43 3 : return *this;
44 : }
45 :
46 588 : Path &Path::Append(const std::string &path)
47 : {
48 588 : AddSeperator();
49 588 : AppendPath(path);
50 588 : AddSeperator();
51 588 : return *this;
52 : }
53 :
54 346 : Path &Path::Concat(const std::string &path)
55 : {
56 346 : AddSeperator();
57 346 : AppendPath(path);
58 346 : return *this;
59 : }
60 :
61 13 : Path &Path::AddExtension(const std::string &extension)
62 : {
63 13 : std::string ext = StrUtils::Trim(extension);
64 13 : if (path_.empty() || ext.empty() || GetExtension() == ext) {
65 3 : return *this;
66 : }
67 :
68 10 : if (ext.front() != FILE_EXTENSION_CHAR) {
69 3 : path_ += FILE_EXTENSION_CHAR;
70 : }
71 10 : path_.append(ext);
72 10 : return *this;
73 13 : }
74 :
75 25 : std::string Path::GetExtension() const
76 : {
77 25 : std::string file = GetFileName();
78 25 : const auto pos = file.rfind(FILE_EXTENSION_CHAR);
79 63 : return pos != std::string::npos ? file.substr(pos) : "";
80 25 : }
81 :
82 270 : std::string Path::GetFileName() const
83 : {
84 270 : const auto pos = path_.find_last_of(DIRECTORY_SEPARATOR);
85 270 : return pos != std::string::npos ? path_.substr(pos + 1) : path_;
86 : }
87 :
88 475 : bool Path::Empty() const
89 : {
90 475 : return path_.empty();
91 : }
92 :
93 57 : bool Path::Exist() const
94 : {
95 57 : return Asccess(F_OK);
96 : }
97 :
98 563 : bool Path::Asccess(mmMode_t mode) const
99 : {
100 563 : return !path_.empty() && mmAccess2(path_.c_str(), mode) == EN_OK;
101 : }
102 :
103 919 : bool Path::IsDirectory() const
104 : {
105 919 : return mmIsDir(path_.c_str()) == EN_OK;
106 : }
107 :
108 139838 : bool Path::RealPath()
109 : {
110 139838 : if (path_.empty()) {
111 3 : return false;
112 : }
113 :
114 139860 : char realPath[MMPA_MAX_PATH] = {0};
115 139860 : const int32_t ret = mmRealPath(path_.c_str(), realPath, MMPA_MAX_PATH);
116 139936 : if (ret != EN_OK) {
117 66 : return false;
118 : }
119 139870 : path_ = realPath;
120 139737 : return true;
121 : }
122 :
123 : /*
124 : * @brief: Get parent path
125 : * /path/to/file -> /path/to
126 : * / -> /
127 : * /file -> /
128 : * file -> ""
129 : */
130 462 : Path Path::ParentPath() const
131 : {
132 462 : if (path_.length() == 1 && path_[0] == DIRECTORY_SEPARATOR) {
133 3 : return Path(path_);
134 : }
135 :
136 459 : const size_t pos = path_.find_last_of(DIRECTORY_SEPARATOR);
137 459 : std::string parentPath = pos != std::string::npos ?
138 477 : (pos == 0 ? std::string(&DIRECTORY_SEPARATOR, 1) : path_.substr(0, pos)) : "";
139 459 : return Path(parentPath);
140 459 : }
141 :
142 392 : bool Path::CreateDirectory(bool recursion) const
143 : {
144 392 : if (path_.empty() || path_.length() > MMPA_MAX_PATH) {
145 3 : IDE_LOGW("Director path is empty or overlength, path: %s", path_.c_str());
146 3 : return false;
147 : }
148 :
149 389 : if (IsDirectory()) {
150 178 : return true;
151 : }
152 :
153 211 : if (recursion) {
154 205 : Path parentPath = ParentPath();
155 205 : if (!parentPath.Empty() && !parentPath.CreateDirectory(recursion)) {
156 0 : return false;
157 : }
158 205 : }
159 :
160 211 : const int32_t ret = mmMkdir(path_.c_str(), DEFAULT_DIR_MODE);
161 211 : if (ret != 0 && errno != EEXIST) {
162 3 : IDE_LOGW("Can not mkdir %s, mode: %d, errno: %s", path_.c_str(), DEFAULT_DIR_MODE, strerror(errno));
163 3 : return false;
164 : }
165 208 : return true;
166 : }
167 :
168 139910 : std::string Path::GetString() const
169 : {
170 139910 : return path_;
171 : }
172 :
173 290 : const char *Path::GetCString() const
174 : {
175 290 : return path_.c_str();
176 : }
177 :
178 934 : void Path::AppendPath(const std::string &path)
179 : {
180 934 : std::string newPath = StrUtils::Trim(path);
181 934 : (void)newPath.erase(newPath.begin(),
182 1080 : std::find_if(newPath.begin(), newPath.end(), [](uint8_t ch) { return ch != DIRECTORY_SEPARATOR; }));
183 934 : (void)newPath.erase(std::find_if(newPath.rbegin(), newPath.rend(),
184 1024 : [](uint8_t ch) {
185 1024 : return ch != DIRECTORY_SEPARATOR;
186 : }).base(),
187 : newPath.end());
188 934 : path_ += newPath;
189 934 : }
190 :
191 1522 : void Path::AddSeperator()
192 : {
193 1522 : if (!path_.empty() && path_.back() != DIRECTORY_SEPARATOR) {
194 1238 : path_ += DIRECTORY_SEPARATOR;
195 : }
196 1522 : }
197 : } // namespace Adx
|