189 lines
4.7 KiB
C++
189 lines
4.7 KiB
C++
/*
|
|
* Copyright (C) 2006-2016 Jacek Sieka, arnetheduck on gmail point com
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
#include "adchpp.h"
|
|
|
|
#include "File.h"
|
|
|
|
namespace adchpp {
|
|
|
|
using namespace std;
|
|
|
|
string File::read(uint32_t len) throw(FileException) {
|
|
string tmp;
|
|
tmp.resize(len);
|
|
uint32_t x = read(&tmp[0], len);
|
|
tmp.resize(x);
|
|
return tmp;
|
|
}
|
|
|
|
#ifdef _WIN32
|
|
|
|
File::File(const string& aFileName, int access, int mode) throw(FileException) {
|
|
dcassert(access == WRITE || access == READ || access == (READ | WRITE));
|
|
|
|
int m = 0;
|
|
if(mode & OPEN) {
|
|
if(mode & CREATE) {
|
|
m = (mode & TRUNCATE) ? CREATE_ALWAYS : OPEN_ALWAYS;
|
|
} else {
|
|
m = (mode & TRUNCATE) ? TRUNCATE_EXISTING : OPEN_EXISTING;
|
|
}
|
|
} else {
|
|
if(mode & CREATE) {
|
|
m = (mode & TRUNCATE) ? CREATE_ALWAYS : CREATE_NEW;
|
|
} else {
|
|
dcassert(0);
|
|
}
|
|
}
|
|
int a = 0;
|
|
if(access & READ)
|
|
a |= GENERIC_READ;
|
|
if(access & WRITE)
|
|
a |= GENERIC_WRITE;
|
|
|
|
h = ::CreateFile(aFileName.c_str(), a, FILE_SHARE_READ, NULL, m, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
|
|
|
|
if(h == INVALID_HANDLE_VALUE) {
|
|
throw FileException(Util::translateError(GetLastError()));
|
|
}
|
|
|
|
}
|
|
|
|
int64_t File::getSize() {
|
|
DWORD x;
|
|
DWORD l = ::GetFileSize(h, &x);
|
|
|
|
if( (l == INVALID_FILE_SIZE) && (GetLastError() != NO_ERROR))
|
|
return -1;
|
|
|
|
return (int64_t)l | ((int64_t)x)<<32;
|
|
}
|
|
|
|
int64_t File::getSize(const string& aFileName) {
|
|
WIN32_FIND_DATA fd;
|
|
HANDLE hFind;
|
|
|
|
hFind = FindFirstFile(aFileName.c_str(), &fd);
|
|
|
|
if (hFind == INVALID_HANDLE_VALUE) {
|
|
return -1;
|
|
} else {
|
|
FindClose(hFind);
|
|
return ((int64_t)fd.nFileSizeHigh << 32 | (int64_t)fd.nFileSizeLow);
|
|
}
|
|
}
|
|
|
|
string File::getFilePath(const string& path) throw() {
|
|
string::size_type i = path.find_last_of("\\/");
|
|
return (i != string::npos) ? path.substr(0, i) : path;
|
|
}
|
|
|
|
string File::getFileName(const string& path) throw() {
|
|
string::size_type i = path.find_last_of("\\/");
|
|
return (i != string::npos) ? path.substr(i + 1) : path;
|
|
}
|
|
|
|
bool File::isAbsolutePath(const string& path) throw() {
|
|
return (path.length() >= 3 && path[1] == ':' && (path[2] == '\\' || path[2] == '/')) ||
|
|
(path.length() >= 1 && (path[0] == '\\' || path[0] == '/'));
|
|
}
|
|
|
|
void File::ensureDirectory(const string& aFile) throw() {
|
|
string::size_type start = 0;
|
|
|
|
while( (start = aFile.find_first_of("\\/", start)) != string::npos) {
|
|
::CreateDirectory(aFile.substr(0, start+1).c_str(), NULL);
|
|
start++;
|
|
}
|
|
}
|
|
|
|
#else // _WIN32
|
|
|
|
File::File(const string& aFileName, int access, int mode) throw(FileException) {
|
|
dcassert(access == WRITE || access == READ || access == (READ | WRITE));
|
|
|
|
int m = 0;
|
|
if(access == READ)
|
|
m |= O_RDONLY;
|
|
else if(access == WRITE)
|
|
m |= O_WRONLY;
|
|
else
|
|
m |= O_RDWR;
|
|
|
|
if(mode & CREATE) {
|
|
m |= O_CREAT;
|
|
}
|
|
if(mode & TRUNCATE) {
|
|
m |= O_TRUNC;
|
|
}
|
|
h = open(aFileName.c_str(), m, S_IRUSR | S_IWUSR);
|
|
if(h == -1)
|
|
throw FileException("Could not open file");
|
|
}
|
|
|
|
int64_t File::getSize() {
|
|
struct stat s;
|
|
if(fstat(h, &s) == -1)
|
|
return -1;
|
|
|
|
return (int64_t)s.st_size;
|
|
}
|
|
|
|
int64_t File::getSize(const string& aFileName) {
|
|
struct stat s;
|
|
if(stat(aFileName.c_str(), &s) == -1)
|
|
return -1;
|
|
|
|
return s.st_size;
|
|
}
|
|
|
|
string File::getFilePath(const string& path) throw() {
|
|
string::size_type i = path.rfind('/');
|
|
return (i != string::npos) ? path.substr(0, i) : path;
|
|
}
|
|
|
|
string File::getFileName(const string& path) throw() {
|
|
string::size_type i = path.rfind('/');
|
|
return (i != string::npos) ? path.substr(i + 1) : path;
|
|
}
|
|
|
|
bool File::isAbsolutePath(const string& path) throw() {
|
|
return path.length() >= 1 && path[0] == '/';
|
|
}
|
|
|
|
void File::ensureDirectory(const string& aFile) throw() {
|
|
string::size_type start = 0;
|
|
|
|
while( (start = aFile.find('/', start)) != string::npos) {
|
|
::mkdir(aFile.substr(0, start+1).c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
|
|
start++;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
std::string File::makeAbsolutePath(const std::string& filename) {
|
|
return makeAbsolutePath(Util::getAppPath() + PATH_SEPARATOR, filename);
|
|
}
|
|
|
|
std::string File::makeAbsolutePath(const std::string& path, const std::string& filename) {
|
|
return isAbsolutePath(filename) ? filename : path + filename;
|
|
}
|
|
|
|
}
|