1 /*
2  * Copyright (C) 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 #define MLOG_TAG "RingtoneScannerUtils"
16 
17 #include "ringtone_scanner_utils.h"
18 
19 #include "ringtone_log.h"
20 
21 namespace OHOS {
22 namespace Media {
23 using namespace std;
24 
25 // Check if file exists or not
IsExists(const string & path)26 bool RingtoneScannerUtils::IsExists(const string &path)
27 {
28     struct stat statInfo {};
29 
30     if (path.empty()) {
31         RINGTONE_ERR_LOG("Given path name is empty");
32         return false;
33     }
34 
35     return ((stat(path.c_str(), &statInfo)) == ERR_SUCCESS);
36 }
37 
38 // Get the file name from file URI
GetFileNameFromUri(const string & path)39 string RingtoneScannerUtils::GetFileNameFromUri(const string &path)
40 {
41     if (!path.empty()) {
42         size_t lastSlashPosition = path.rfind("/");
43         if (lastSlashPosition != string::npos) {
44             if (path.size() > lastSlashPosition) {
45                 return path.substr(lastSlashPosition + 1);
46             }
47         }
48     }
49 
50     RINGTONE_ERR_LOG("Failed to obtain file name because given pathname is empty");
51     return "";
52 }
53 
54 // Get file extension from the given filepath uri
GetFileExtension(const string & path)55 string RingtoneScannerUtils::GetFileExtension(const string &path)
56 {
57     if (!path.empty()) {
58         size_t dotIndex = path.rfind(".");
59         if (dotIndex != string::npos) {
60             return path.substr(dotIndex + 1);
61         }
62     }
63 
64     RINGTONE_ERR_LOG("Failed to obtain file extension because given pathname is empty");
65     return "";
66 }
67 
68 // Check if the given path is a directory path
IsDirectory(const string & path)69 bool RingtoneScannerUtils::IsDirectory(const string &path)
70 {
71     struct stat s;
72 
73     if (!path.empty()) {
74         if (stat(path.c_str(), &s) == 0) {
75             if (s.st_mode & S_IFDIR) {
76                 return true;
77             }
78         }
79     }
80 
81     RINGTONE_ERR_LOG("Either path is empty or it is not a directory");
82     return false;
83 }
84 
IsRegularFile(const string & path)85 bool RingtoneScannerUtils::IsRegularFile(const string &path)
86 {
87     struct stat s;
88     if (!path.empty()) {
89         if (stat(path.c_str(), &s) == 0) {
90             if (s.st_mode & S_IFREG) {
91                 return true;
92             }
93         }
94     }
95 
96     return false;
97 }
98 
99 // Check if the given file starts with '.' , i.e. if it is hidden
IsFileHidden(const string & path)100 bool RingtoneScannerUtils::IsFileHidden(const string &path)
101 {
102     if (!path.empty()) {
103         string fileName = GetFileNameFromUri(path);
104         if (!fileName.empty() && fileName.at(0) == '.') {
105             return true;
106         }
107     }
108 
109     return false;
110 }
111 
112 // Get the parent path
GetParentPath(const string & path)113 string RingtoneScannerUtils::GetParentPath(const string &path)
114 {
115     if (!path.empty()) {
116         size_t lastSlashPosition = path.rfind("/");
117         if (lastSlashPosition != string::npos && path.size() > lastSlashPosition) {
118             return path.substr(0, lastSlashPosition);
119         }
120     }
121 
122     RINGTONE_ERR_LOG("Failed to obtain the parent path");
123     return "";
124 }
125 
GetFileTitle(const string & displayName)126 string RingtoneScannerUtils::GetFileTitle(const string &displayName)
127 {
128     string::size_type pos = displayName.find_last_of('.');
129     return (pos == string::npos) ? displayName : displayName.substr(0, pos);
130 }
131 
IsDirHidden(const string & path)132 bool RingtoneScannerUtils::IsDirHidden(const string &path)
133 {
134     bool dirHid = false;
135 
136     if (!path.empty()) {
137         string dirName = RingtoneScannerUtils::GetFileNameFromUri(path);
138         if (!dirName.empty() && dirName.at(0) == '.') {
139             RINGTONE_DEBUG_LOG("hidden Directory, name:%{private}s path:%{private}s", dirName.c_str(), path.c_str());
140             return true;
141         }
142 
143         string curPath = path;
144         string excludePath = curPath.append("/.nomedia");
145         // Check is the folder consist of .nomedia file
146         if (RingtoneScannerUtils::IsExists(excludePath)) {
147             return true;
148         }
149     }
150 
151     return dirHid;
152 }
153 
IsDirHiddenRecursive(const string & path)154 bool RingtoneScannerUtils::IsDirHiddenRecursive(const string &path)
155 {
156     bool dirHid = true;
157     string curPath = path;
158 
159     while (!IsDirHidden(curPath)) {
160         curPath = RingtoneScannerUtils::GetParentPath(curPath);
161         if (curPath.empty()) {
162             dirHid = false;
163             break;
164         }
165     }
166 
167     return dirHid;
168 }
169 } // namespace Media
170 } // namespace OHOS
171