1 /*
2  * Copyright 2009-2017 Alibaba Cloud All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <string>
18 #include <map>
19 #include <ctime>
20 #include <fstream>
21 #include <memory>
22 #include <alibabacloud/oss/Types.h>
23 #include "FileSystemUtils.h"
24 #include <alibabacloud/oss/Const.h>
25 
26 #ifdef _WIN32
27 #include <direct.h>
28 #include <io.h>
29 #include <sys/stat.h>
30 #define  oss_access(a)  ::_access((a), 0)
31 #define  oss_mkdir(a)   ::_mkdir(a)
32 #define  oss_rmdir(a)   ::_rmdir(a)
33 #define  oss_stat       ::_stat64
34 #define  oss_waccess(a)  ::_waccess((a), 0)
35 #define  oss_wmkdir(a)   ::_wmkdir(a)
36 #define  oss_wrmdir(a)   ::_wrmdir(a)
37 #define  oss_wstat       ::_wstat64
38 #define  oss_wremove     ::_wremove
39 #define  oss_wrename     ::_wrename
40 #else
41 #include <unistd.h>
42 #include <fcntl.h>
43 #include <sys/stat.h>
44 #define  oss_access(a)  ::access(a, 0)
45 #define  oss_mkdir(a)   ::mkdir((a), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)
46 #define  oss_rmdir(a)   ::rmdir(a)
47 #define  oss_stat       stat
48 #endif
49 using namespace AlibabaCloud::OSS;
50 
CreateDirectory(const std::string & folder)51 bool AlibabaCloud::OSS::CreateDirectory(const std::string &folder)
52 {
53     std::string folder_builder;
54     std::string sub;
55     sub.reserve(folder.size());
56     for (auto it = folder.begin(); it != folder.end(); ++it) {
57         const char c = *it;
58         sub.push_back(c);
59         if (c == PATH_DELIMITER || it == folder.end() - 1) {
60             folder_builder.append(sub);
61             if (oss_access(folder_builder.c_str()) != 0) {
62                 if (oss_mkdir(folder_builder.c_str()) != 0) {
63                     return false;
64                 }
65             }
66             sub.clear();
67         }
68     }
69     return true;
70 }
71 
IsDirectoryExist(std::string folder)72 bool AlibabaCloud::OSS::IsDirectoryExist(std::string folder) {
73     if (folder[folder.length() - 1] != PATH_DELIMITER && folder[folder.length() - 1] != '/') {
74         folder += PATH_DELIMITER;
75     }
76     return !oss_access(folder.c_str());
77 }
78 
RemoveDirectory(const std::string & folder)79 bool AlibabaCloud::OSS::RemoveDirectory(const std::string &folder)
80 {
81     return !oss_rmdir(folder.c_str());
82 }
83 
RemoveFile(const std::string & filepath)84 bool AlibabaCloud::OSS::RemoveFile(const std::string &filepath)
85 {
86     int ret = ::remove(filepath.c_str());
87     return !ret;
88 }
89 
RenameFile(const std::string & from,const std::string & to)90 bool AlibabaCloud::OSS::RenameFile(const std::string &from, const std::string &to)
91 {
92     return !::rename(from.c_str(), to.c_str());
93 }
94 
GetPathLastModifyTime(const std::string & path,time_t & t)95 bool AlibabaCloud::OSS::GetPathLastModifyTime(const std::string& path, time_t& t)
96 {
97     std::streamsize size;
98     return GetPathInfo(path, t, size);
99 }
100 
GetPathInfo(const std::string & path,time_t & t,std::streamsize & size)101 bool AlibabaCloud::OSS::GetPathInfo(const std::string& path, time_t& t, std::streamsize& size)
102 {
103     struct oss_stat buf;
104     auto filename = path.c_str();
105 #if defined(_WIN32) && _MSC_VER < 1900
106     std::string tmp;
107     if (!path.empty() && (path.rbegin()[0] == PATH_DELIMITER)) {
108         tmp = path.substr(0, path.size() - 1);
109         filename = tmp.c_str();
110     }
111 #endif
112     if (oss_stat(filename, &buf) != 0)
113         return false;
114 
115     t = buf.st_mtime;
116     size = static_cast<std::streamsize>(buf.st_size);
117     return true;
118 }
119 
IsFileExist(const std::string & file)120 bool AlibabaCloud::OSS::IsFileExist(const std::string& file)
121 {
122     std::streamsize size;
123     time_t t;
124     return GetPathInfo(file, t, size);
125 }
126 
127 
128 //wchar path
129 #ifdef _WIN32
130 
CreateDirectory(const std::wstring & folder)131 bool AlibabaCloud::OSS::CreateDirectory(const std::wstring &folder)
132 {
133     std::wstring folder_builder;
134     std::wstring sub;
135     sub.reserve(folder.size());
136     for (auto it = folder.begin(); it != folder.end(); ++it) {
137         auto c = *it;
138         sub.push_back(c);
139         if (c == WPATH_DELIMITER || it == folder.end() - 1) {
140             folder_builder.append(sub);
141             if (oss_waccess(folder_builder.c_str()) != 0) {
142                 if (oss_wmkdir(folder_builder.c_str()) != 0) {
143                     return false;
144                 }
145             }
146             sub.clear();
147         }
148     }
149     return true;
150 }
151 
IsDirectoryExist(std::wstring folder)152 bool AlibabaCloud::OSS::IsDirectoryExist(std::wstring folder) {
153     if (folder[folder.length() - 1] != WPATH_DELIMITER && folder[folder.length() - 1] != '/') {
154         folder += WPATH_DELIMITER;
155     }
156     return !oss_waccess(folder.c_str());
157 }
158 
RemoveDirectory(const std::wstring & folder)159 bool AlibabaCloud::OSS::RemoveDirectory(const std::wstring& folder)
160 {
161     return !oss_wrmdir(folder.c_str());
162 }
163 
RemoveFile(const std::wstring & filepath)164 bool AlibabaCloud::OSS::RemoveFile(const std::wstring& filepath)
165 {
166     int ret = oss_wremove(filepath.c_str());
167     return !ret;
168 }
169 
RenameFile(const std::wstring & from,const std::wstring & to)170 bool AlibabaCloud::OSS::RenameFile(const std::wstring& from, const std::wstring& to)
171 {
172     return !oss_wrename(from.c_str(), to.c_str());
173 }
174 
GetPathLastModifyTime(const std::wstring & path,time_t & t)175 bool AlibabaCloud::OSS::GetPathLastModifyTime(const std::wstring& path, time_t& t)
176 {
177     std::streamsize size;
178     return GetPathInfo(path, t, size);
179 }
180 
GetPathInfo(const std::wstring & path,time_t & t,std::streamsize & size)181 bool AlibabaCloud::OSS::GetPathInfo(const std::wstring& path, time_t& t, std::streamsize& size)
182 {
183     struct oss_stat buf;
184     auto filename = path.c_str();
185 #if defined(_WIN32) && _MSC_VER < 1900
186     std::wstring tmp;
187     if (!path.empty() && (path.rbegin()[0] == WPATH_DELIMITER)) {
188         tmp = path.substr(0, path.size() - 1);
189         filename = tmp.c_str();
190     }
191 #endif
192     if (oss_wstat(filename, &buf) != 0)
193         return false;
194 
195     t = buf.st_mtime;
196     size = static_cast<std::streamsize>(buf.st_size);
197     return true;
198 }
199 
IsFileExist(const std::wstring & file)200 bool AlibabaCloud::OSS::IsFileExist(const std::wstring& file)
201 {
202     std::streamsize size;
203     time_t t;
204     return GetPathInfo(file, t, size);
205 }
206 #endif
207 
GetFstreamByPath(const std::string & path,const std::wstring & pathw,std::ios_base::openmode mode)208 std::shared_ptr<std::fstream> AlibabaCloud::OSS::GetFstreamByPath(
209     const std::string& path, const std::wstring& pathw,
210     std::ios_base::openmode mode)
211 {
212 #ifdef _WIN32
213     if (!pathw.empty()) {
214         return std::make_shared<std::fstream>(pathw, mode);
215     }
216 #else
217     ((void)(pathw));
218 #endif
219     return std::make_shared<std::fstream>(path, mode);
220 }
221