• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "file_entry.h"
17 #include<fstream>
18 #include<iostream>
19 #include "dirent.h"
20 #include "sys/stat.h"
21 #include "unistd.h"
22 
23 namespace OHOS {
24 namespace Global {
25 namespace Restool {
26 #ifdef _WIN32
27 const std::string FileEntry::SEPARATE = "\\";
28 #else
29 const std::string FileEntry::SEPARATE = "/";
30 #endif
31 
32 using namespace std;
FileEntry(const string & path)33 FileEntry::FileEntry(const string &path)
34     : filePath_(path), isFile_(false)
35 {
36 }
37 
~FileEntry()38 FileEntry::~FileEntry()
39 {
40 }
41 
Init()42 bool FileEntry::Init()
43 {
44     string filePath = filePath_.GetPath();
45     if (!Exist(filePath)) {
46         cerr << "Error: '" << filePath << "' not exists." << endl;
47         return false;
48     }
49 
50     isFile_ = !IsDirectory(filePath);
51     return true;
52 }
53 
GetChilds() const54 const vector<unique_ptr<FileEntry>> FileEntry::GetChilds() const
55 {
56     vector<unique_ptr<FileEntry>> children;
57     struct dirent *entry;
58     string filePath = filePath_.GetPath();
59     DIR *handle = opendir(filePath.c_str());
60     while ((entry = readdir(handle)) != nullptr) {
61         string filename(entry->d_name);
62         if (IsIgnore(filename)) {
63             continue;
64         }
65 
66         filePath = filePath_.GetPath() + SEPARATE + filename;
67         unique_ptr<FileEntry> f = make_unique<FileEntry>(filePath);
68         f->Init();
69         children.push_back(move(f));
70     }
71     closedir(handle);
72     return children;
73 }
74 
IsFile() const75 bool FileEntry::IsFile() const
76 {
77     return isFile_;
78 }
79 
GetFilePath() const80 const FileEntry::FilePath &FileEntry::GetFilePath() const
81 {
82     return filePath_;
83 }
84 
Exist(const string & path)85 bool FileEntry::Exist(const string &path)
86 {
87     struct stat s;
88     if (stat(path.c_str(), &s) != 0) {
89         return false;
90     }
91     return true;
92 }
93 
RemoveAllDir(const string & path)94 bool FileEntry::RemoveAllDir(const string &path)
95 {
96     FileEntry f(path);
97     if (!f.Init()) {
98         return false;
99     }
100 
101     if (f.IsFile()) {
102         cerr << "Error: RemoveAllDir '" << path << "' not directory." << endl;
103         return false;
104     }
105     return RemoveAllDirInner(f);
106 }
107 
CreateDirs(const string & path)108 bool FileEntry::CreateDirs(const string &path)
109 {
110     return CreateDirsInner(path, 0);
111 }
112 
CopyFile(const string & src,const string & dst)113 bool FileEntry::CopyFile(const string &src, const string &dst)
114 {
115     ifstream in(src, ios::binary);
116     ofstream out(dst, ios::binary);
117     if (!in || !out) {
118         cerr << "Error: CopyFile '" << src << "' or '" << dst << "' open fail." << endl;
119         return false;
120     }
121     out << in.rdbuf();
122     return true;
123 }
124 
IsDirectory(const string & path)125 bool FileEntry::IsDirectory(const string &path)
126 {
127     struct stat s;
128     stat(path.c_str(), &s);
129     return S_ISDIR(s.st_mode);
130 }
131 
FilePath(const string & path)132 FileEntry::FilePath::FilePath(const string &path) : filePath_(path)
133 {
134     Format();
135     Init();
136 }
137 
~FilePath()138 FileEntry::FilePath::~FilePath()
139 {
140 }
141 
Append(const string & path)142 FileEntry::FilePath FileEntry::FilePath::Append(const string &path)
143 {
144     Format();
145     string filePath = filePath_ + SEPARATE + path;
146     return FilePath(filePath);
147 }
148 
ReplaceExtension(const string & extension)149 FileEntry::FilePath FileEntry::FilePath::ReplaceExtension(const string &extension)
150 {
151     string filePath;
152     if (!parent_.empty()) {
153         filePath += parent_ + SEPARATE;
154     }
155 
156     filePath += filename_.substr(0, filename_.length() - extension_.length()) + extension;
157     return FilePath(filePath);
158 }
159 
GetParent()160 FileEntry::FilePath FileEntry::FilePath::GetParent()
161 {
162     return FilePath(parent_);
163 }
164 
GetPath() const165 const string &FileEntry::FilePath::GetPath() const
166 {
167     return filePath_;
168 }
169 
GetFilename() const170 const string &FileEntry::FilePath::GetFilename() const
171 {
172     return filename_;
173 }
174 
GetExtension() const175 const string &FileEntry::FilePath::GetExtension() const
176 {
177     return extension_;
178 }
179 
GetSegments() const180 const vector<string> FileEntry::FilePath::GetSegments() const
181 {
182     vector<string> segments;
183     string::size_type offset = 0;
184     string::size_type pos = filePath_.find_first_of(SEPARATE.front(), offset);
185     while (pos != string::npos) {
186         segments.push_back(filePath_.substr(offset, pos - offset));
187         offset = pos + 1;
188         pos = filePath_.find_first_of(SEPARATE.front(), offset);
189     }
190 
191     if (offset < filePath_.length()) {
192         segments.push_back(filePath_.substr(offset));
193     }
194     return segments;
195 }
196 
197 // below private
IsIgnore(const string & filename) const198 bool FileEntry::IsIgnore(const string &filename) const
199 {
200     if (filename == "." || filename == "..") {
201         return true;
202     }
203     return false;
204 }
205 
RemoveAllDirInner(const FileEntry & entry)206 bool FileEntry::RemoveAllDirInner(const FileEntry &entry)
207 {
208     if (entry.IsFile()) {
209         return remove(entry.GetFilePath().GetPath().c_str()) == 0;
210     }
211 
212     for (const auto &iter : entry.GetChilds()) {
213         if (!RemoveAllDirInner(*iter)) {
214             return false;
215         }
216     }
217     return rmdir(entry.GetFilePath().GetPath().c_str()) == 0;
218 }
219 
CreateDirsInner(const string & path,string::size_type offset)220 bool FileEntry::CreateDirsInner(const string &path, string::size_type offset)
221 {
222     string::size_type pos = path.find_first_of(SEPARATE.front(), offset);
223     if (pos == string::npos) {
224 #if _WIN32
225         return mkdir(path.c_str()) == 0;
226 #else
227         return mkdir(path.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == 0;
228 #endif
229     }
230 
231     string subPath = path.substr(0, pos + 1);
232     if (!Exist(subPath)) {
233 #if _WIN32
234         if (mkdir(subPath.c_str()) != 0) {
235 #else
236         if (mkdir(subPath.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) != 0) {
237 #endif
238             return false;
239         }
240     }
241     return CreateDirsInner(path, pos + 1);
242 }
243 
244 void FileEntry::FilePath::Format()
245 {
246     if (filePath_.back() != SEPARATE.front()) {
247         return;
248     }
249     filePath_.pop_back();
250 }
251 
252 void FileEntry::FilePath::Init()
253 {
254     filename_ = filePath_;
255     string::size_type pos = filePath_.find_last_of(SEPARATE.front());
256     if (pos != string::npos) {
257         parent_ = filePath_.substr(0, pos);
258         if (pos + 1 < filePath_.length()) {
259             filename_ = filePath_.substr(pos + 1);
260         }
261     }
262 
263     pos = filename_.find_last_of('.');
264     if (pos != string::npos && pos + 1 < filename_.length()) {
265         extension_ = filename_.substr(pos);
266     }
267 }
268 }
269 }
270 }
271