Rev 124 | Rev 160 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
#include "File_IO.h"
#ifdef _WIN32
#include <windows.h>
#endif
#include <locale>
#include "DirIO.h"
#include "File.h"
#include "Logging/Log.h"
#include "Packages.h"
CFileIO::CFileIO () : m_lSize(0), m_bBinary(true), m_bAutoDelete(false), m_bSeekP(false)
{
}
CFileIO::CFileIO(const Utils::String &sFilename, bool bBinary) : m_lSize(0), m_bBinary(bBinary), m_bAutoDelete(false)
{
open(sFilename, bBinary);
}
CFileIO::CFileIO(CyString filename) : m_lSize(0), m_bBinary(true), m_bAutoDelete(false), m_bSeekP(false)
{
open(filename.ToString(), true);
}
CFileIO::CFileIO(C_File *file) : m_lSize(0), m_bBinary(true), m_bAutoDelete(false), m_bSeekP(false)
{
open(file->filePointer(), true);
}
CFileIO::~CFileIO()
{
if ( this->isOpened() ) m_fId.close();
if ( m_bAutoDelete ) this->remove();
}
void CFileIO::setAutoDelete(bool bDelete)
{
m_bAutoDelete = true;
}
bool CFileIO::open(const Utils::String &sFilename, bool bBinary)
{
m_bBinary = bBinary;
m_sFilename = sFilename.asFilename();
// check if there are any directories, and split the file and directory parts
if ( m_sFilename.isin('/') ) {
m_sDirIO.SetDir(m_sFilename.tokens("/", 1, -2));
m_sFile = m_sFilename.token("/", -1);
}
else
m_sFile = m_sFilename;
m_sFile.removeFirstSpace();
m_sFile.removeChar(13);
this->_readFileSize();
return true;
}
unsigned char *CFileIO::read(size_t iAmount)
{
if ( !this->isOpened() ) startRead();
if ( !this->isOpened() ) return NULL;
if ( iAmount > m_lSize ) iAmount = m_lSize;
unsigned char *data;
try {
data = new unsigned char[iAmount + 1];
}
catch (std::exception &e) {
CLog::logf(CLog::Log_IO, 2, "ERROR: CFileIO::read(size_t) unable to malloc data, %d (%s)", iAmount + 1, e.what());
return NULL;
}
if ( !read(data, iAmount, true) ) {
CLog::logf(CLog::Log_IO, 2, "ERROR: CFileIO::read(size_t) unable to read data from file, %s/%d", m_sFilename.c_str(), iAmount);
delete data;
return NULL;
}
return data;
}
unsigned char *CFileIO::readAll(size_t *pSize)
{
if ( pSize ) (*pSize) = 0;
if ( !this->isOpened() ) startRead();
if ( !this->isOpened() ) return NULL;
unsigned char *data;
try {
data = new unsigned char[m_lSize + 1];
}
catch (std::exception &e) {
CLog::logf(CLog::Log_IO, 2, "ERROR: CFileIO::readAll() unable to malloc data, %d (%s)", m_lSize + 1, e.what());
return NULL;
}
if ( !read(data, m_lSize, true) ) {
CLog::logf(CLog::Log_IO, 2, "ERROR: CFileIO::readAll() unable to read data from file, %s/%d", m_sFilename.c_str(), m_lSize);
delete data;
return NULL;
}
if ( pSize ) (*pSize) = m_lSize;
return data;
}
bool CFileIO::read(unsigned char *buf, size_t iSize, bool bEndChar)
{
if ( !this->isOpened() ) startRead();
if ( !this->isOpened() ) return false;
if ( iSize > m_lSize ) iSize = m_lSize;
try {
m_fId.read((char *)buf, iSize);
}
catch (std::exception &e) {
CLog::logf(CLog::Log_IO, 3, "ERROR: CFileIO::read() unable to read from file: %s (%s)", m_sFilename.c_str(), e.what());
return false;
}
if ( bEndChar ) buf[iSize] = '\0';
return !m_fId.bad();
}
bool CFileIO::WritePartFile ( size_t *offsets, size_t numOffset )
{
if ( NoFile() ) return false;
std::fstream File(m_sFilename, _in());
if ( !File.is_open() ) return false;
// first find file size
File.seekg(0, std::ios::end);
size_t fullsize = static_cast<size_t>(File.tellg()), size = fullsize;
File.seekg(0, std::ios::beg);
std::fstream writeFile(CPackages::tempDirectory() + "/temp.tmp", _out());
if ( !File.is_open() ) {
File.close();
return false;
}
size_t off = 0;
size_t startPos = 0;
size_t remainingSize = fullsize;
while ( off < numOffset ) {
startPos = static_cast<size_t>(File.tellg());
size_t offset = offsets[off++];
size_t size = offset - startPos;
try {
char *data = new char[size];
File.read(data, size);
writeFile.write(data, size);
delete data;
}
catch(std::exception &e) {
CLog::logf(CLog::Log_IO, 2, "CFileIO::WritePartFilea() unable to read data from file: %s (%s)", m_sFilename.c_str(), e.what());
return false;
}
size_t datasize = offsets[off++];
File.seekg(datasize, std::ios::beg);
remainingSize = fullsize - offset - datasize;
}
if ( remainingSize ) {
char data[1000000];
size_t amountLeft = 1000000;
while ( remainingSize )
{
if ( amountLeft > remainingSize ) amountLeft = remainingSize;
try {
File.read(data, amountLeft);
writeFile.write(data, amountLeft);
}
catch(std::exception &e) {
CLog::logf(CLog::Log_IO, 2, "CFileIO::WritePartFilea() unable to read data from file: %s (%s)", m_sFilename.c_str(), e.what());
return false;
}
remainingSize -= amountLeft;
amountLeft = 1000000;
}
}
File.close();
writeFile.close();
// now copy to original file
std::remove(m_sFilename);
std::rename(CPackages::tempDirectory() + "/temp.tmp", m_sFilename);
return true;
}
void CFileIO::setDir(const Utils::String &dir)
{
if ( m_sFile.empty() ) m_sDirIO.SetDir(dir);
else open(dir + "/" + m_sFile, m_bBinary);
}
void CFileIO::SetDir ( CyString dir )
{
setDir(dir.ToString());
}
void CFileIO::_readFileSize ()
{
m_lSize = 0;
std::fstream file(m_sFilename, (m_bBinary) ? (std::ios::in | std::ios::binary) : (std::ios::in));
if ( !file.is_open() ) return;
file.seekg(0, std::ios::end);
m_lSize = static_cast<size_t>(file.tellg());
file.close();
}
bool CFileIO::WipeFile()
{
if ( NoFile() ) return false;
std::ofstream file;
file.open(m_sFilename, std::ios::out | std::ios::trunc);
bool bDone = file.is_open();
file.close();
return bDone;
}
int CFileIO::TruncateFile ( size_t offset, size_t datasize )
{
if ( NoFile() ) return FILEERR_NOFILE;
if ( !this->startRead() ) return FILEERR_NOOPEN;
if ( (offset + datasize) > m_lSize ) return FILEERR_TOSMALL;
CFileIO File(CPackages::tempDirectory() + "/temp.tmp");
if ( !File.startWrite() ) return FILEERR_NOWRITE;
File.setAutoDelete(true);
if ( !File.write(*this, offset) ) return false;
// next fseek after and write
this->seek(datasize);
size_t size = m_lSize - offset - datasize;
if ( size > 0 ) {
File.write(*this, size);
}
File.close();
this->close();
File.setAutoDelete(false);
// now copy to original file
if ( std::remove(m_sFilename.c_str()) == 0 ) {
std::rename(CPackages::tempDirectory() + "/temp.tmp", m_sFilename.c_str());
size_t oldSize = m_lSize;
size_t checkFileSize = m_lSize - datasize;
this->_readFileSize();
if ( checkFileSize != m_lSize ) {
CLog::log(CLog::Log_IO, 3, Utils::String("WARNING: CFileIO::TruncateFile, file size mismatch, ") + (long)checkFileSize + " => " + (long)m_lSize);
}
return FILEERR_NONE;
}
return FILEERR_NOWRITE;
}
int CFileIO::_in() const
{
if ( m_bBinary ) return std::ios::in | std::ios::binary;
return std::ios::in;
}
int CFileIO::_out() const
{
if ( m_bBinary ) return std::ios::out | std::ios::binary;
return std::ios::out;
}
int CFileIO::_inout() const
{
if ( m_bBinary ) return std::ios::in | std::ios::out | std::ios::binary;
return std::ios::in | std::ios::out;
}
int CFileIO::_append() const
{
if ( m_bBinary ) return std::ios::out | std::ios::binary | std::ios::app;
return std::ios::out | std::ios::app;
}
char *CFileIO::ReadToData ( size_t *size )
{
*size = 0;
if ( NoFile() ) return NULL;
if ( !m_lSize ) this->_readFileSize();
if ( !m_lSize ) return NULL;
std::fstream file(m_sFilename, _in());
if ( !file.is_open() ) return NULL;
char *data;
try {
data = new char[m_lSize + 1];
}
catch (std::exception &e) {
CLog::logf(CLog::Log_IO, 2, "CFileIO::ReadToData() unable to malloc storage, %d (%s)", m_lSize + 1, e.what());
file.close();
return NULL;
}
try {
file.read((char *)data, m_lSize);
}
catch (std::exception &e) {
CLog::logf(CLog::Log_IO, 2, "CFileIO::ReadToData() unable to read data from file (%s)", e.what());
file.close();
return NULL;
}
*size = m_lSize;
file.close();
return data;
}
bool CFileIO::WriteData ( const char *data, size_t size )
{
if ( NoFile() )
return false;
std::fstream File(m_sFilename, _out());
if ( !File.is_open() ) return false;
bool ret = true;
try {
File.write(data, size);
}
catch (std::exception &e) {
CLog::logf(CLog::Log_IO, 2, "CFileIO::ReadToData() unable to read data from file: %s (%s)", m_sFilename.c_str(), e.what());
ret = false;
}
File.close();
if ( ret ) this->_readFileSize();
return ret;
}
bool CFileIO::writeString ( const Utils::String &data )
{
return WriteData ( data.c_str(), data.length() );
}
bool CFileIO::Exists(const Utils::String &filename)
{
std::fstream File(filename, std::ios::in | std::ios::binary);
bool bRet = File.good();
File.close();
return bRet;
}
bool CFileIO::ExistsOld () const
{
return this->exists();
}
bool CFileIO::exists () const
{
if ( this->isOpened() ) return true;
std::fstream File(m_sFilename, _in());
bool bRet = File.good();
File.close();
return bRet;
}
bool CFileIO::startRead()
{
return _start(_in(), false);
}
bool CFileIO::startWrite()
{
return _start(_out(), true);
}
bool CFileIO::startModify()
{
return _start(_inout(), true);
}
bool CFileIO::startAppend()
{
return _start(_append(), false);
}
bool CFileIO::_start(int iFlags, bool bSeekP)
{
if ( !m_sFilename.empty() ) {
if ( this->isOpened() ) this->close();
m_fId.open(m_sFilename, iFlags);
}
m_bSeekP = bSeekP;
return m_fId.is_open();
}
std::vector<Utils::String> *CFileIO::readLines()
{
if ( m_sFilename.empty() ) return 0;
std::vector<Utils::String> *file = new std::vector<Utils::String>;
Utils::String line;
file->clear();
std::ifstream infile (m_sFilename.c_str(), std::ios_base::in);
while (getline(infile, line, '\n')) {
file->push_back(Utils::String(line).removeChar((char)0));
}
infile.close();
return file;
}
std::vector<CyString> *CFileIO::ReadLines()
{
if ( m_sFilename.empty() ) return 0;
std::vector<CyString> *file = new std::vector<CyString>;
Utils::String line;
file->clear();
std::ifstream infile (m_sFilename.c_str(), std::ios_base::in);
while (getline(infile, line, '\n'))
{
CyString l = line;
l.RemoveChar((char)0);
file->push_back(l);
}
infile.close();
return file;
}
CyStringList *CFileIO::ReadLinesStr()
{
if ( m_sFilename.empty() ) return 0;
CyStringList *file = new CyStringList;
Utils::String line;
std::ifstream infile (m_sFilename.c_str(), std::ios_base::in);
while (getline(infile, line, '\n')) {
file->PushBack(CyString(line.removeChar((char)0)));
}
infile.close();
return file;
}
Utils::CStringList *CFileIO::readLinesStr()
{
if ( m_sFilename.empty() ) return 0;
Utils::CStringList *file = new Utils::CStringList();
Utils::String line;
std::ifstream infile (m_sFilename.c_str(), std::ios_base::in);
while (getline(infile, line, '\n')) {
file->pushBack(line.removeChar((char)0));
}
infile.close();
return file;
}
bool CFileIO::put(const unsigned char c)
{
if ( !this->isOpened() ) return false;
m_fId.put(c);
return !m_fId.bad();
}
bool CFileIO::writeSize(size_t iSize)
{
if ( !this->isOpened() ) return false;
if ( !this->put(static_cast<unsigned char>(iSize >> 24)) ) return false;
if ( !this->put(static_cast<unsigned char>(iSize >> 16)) ) return false;
if ( !this->put(static_cast<unsigned char>(iSize >> 8)) ) return false;
if ( !this->put(static_cast<unsigned char>(iSize)) ) return false;
m_lSize += 4;
return true;
}
bool CFileIO::write(CFileIO &file, size_t iSize)
{
if ( !this->isOpened() ) startWrite();
if ( !this->isOpened() ) return false;
int iMaxSize = 1000000;
unsigned char *data;
try {
data = new unsigned char[iMaxSize + 1];
}
catch (std::exception &e) {
CLog::logf(CLog::Log_IO, 2, "ERROR: CFileIO::write(CFileIO, size_t) unable to malloc data, %d (%s)", iMaxSize + 1, e.what());
return false;
}
int iSizeLeft = iSize;
bool bSuccess = true;
while ( iSizeLeft > 0 ) {
int iDoSize = iMaxSize;
if ( iDoSize > iSizeLeft ) iDoSize = iSizeLeft;
if ( !file.read(data, iDoSize) ) bSuccess = false;
if ( bSuccess && !this->write(data, iDoSize) ) bSuccess = false;
if ( !bSuccess ) break;
iSizeLeft -= iDoSize;
}
delete data;
return bSuccess;
}
bool CFileIO::write(const char *buf, size_t iSize)
{
if ( !this->isOpened() ) startWrite();
if ( !this->isOpened() ) return false;
try {
m_fId.write((char *)buf, iSize);
}
catch (std::exception &e) {
CLog::logf(CLog::Log_IO, 2, "CFileIO::write() unable to write to file: %s (%s)", m_sFilename.c_str(), e.what());
return false;
}
m_lSize += iSize;
return !m_fId.bad();
}
bool CFileIO::write(const unsigned char *buf, size_t iSize)
{
return this->write((char *)buf, iSize);
}
bool CFileIO::write(const unsigned char *buf, ...)
{
va_list args;
va_start(args, buf);
bool ret = this->_write((char *)buf, args);
va_end(args);
return ret;
}
bool CFileIO::_write(const char *buf, va_list args)
{
if ( !this->isOpened() ) return false;
char buffer[10000];
vsprintf (buffer, buf, args);
try {
int iLen = strlen(buffer);
m_fId.write((char *)buffer, iLen);
m_lSize += iLen;
}
catch (std::exception &e) {
CLog::logf(CLog::Log_IO, 2, "CFileIO::write() unable to write to file: %s (%s)", m_sFilename.c_str(), e.what());
return false;
}
return !m_fId.bad();
}
bool CFileIO::write(const char *buf, ...)
{
va_list args;
va_start(args, buf);
bool ret = this->_write((char *)buf, args);
va_end(args);
return ret;
}
void CFileIO::_seek(int iPos, int iFrom)
{
if ( !this->isOpened() ) {
if ( !this->startRead() ) return;
}
if ( m_bSeekP ) m_fId.seekp(iPos, iFrom);
else m_fId.seekg(iPos, iFrom);
}
void CFileIO::seek(size_t iPos)
{
_seek(iPos, std::ios::cur);
}
void CFileIO::seekEnd(size_t iPos)
{
_seek(iPos, std::ios::end);
}
void CFileIO::seekStart(size_t iPos)
{
_seek(iPos, std::ios::beg);
}
std::fstream &CFileIO::stream()
{
return m_fId;
}
bool CFileIO::isOpened() const
{
if ( m_fId.is_open() )
return true;
return false;
}
void CFileIO::close()
{
if ( this->isOpened() ) m_fId.close();
this->_readFileSize();
}
int CFileIO::readSize()
{
unsigned char size[4];
if ( this->read(size, 4) ) return (size[0] << 24) + (size[1] << 16) + (size[2] << 8) + size[3];
return 0;
}
bool CFileIO::atEnd() const
{
if ( !this->isOpened() ) return true;
if ( m_fId.eof() ) return true;
return false;
}
bool CFileIO::appendFile ( const Utils::String &filename )
{
std::fstream fromFile(filename, _in());
if ( !fromFile.is_open() ) return false;
std::fstream toFile(m_sFilename, _append());
if ( !toFile.is_open() ) {
fromFile.close();
return false;
}
// move to the end of the file
toFile.seekg(0, std::ios::end);
// get size of file
fromFile.seekg(0, std::ios::end);
size_t size = static_cast<size_t>(fromFile.tellg());
fromFile.seekg(0, std::ios::beg);
char data[500000];
while ( size > 0 )
{
size_t read = 500000;
if ( read > size )
read = size;
size -= read;
fromFile.read(data, read);
toFile.write(data, read);
}
fromFile.close();
toFile.close();
return true;
}
bool CFileIO::AppendFile ( CyString filename )
{
std::fstream fromFile(filename.ToString().c_str(), _in());
if ( !fromFile.is_open() ) return false;
std::fstream toFile(m_sFilename, _append());
if ( !toFile.is_open() ) {
fromFile.close();
return false;
}
// move to the end of the file
toFile.seekg(0, std::ios::end);
// get size of file
fromFile.seekg(0, std::ios::end);
size_t size = static_cast<size_t>(fromFile.tellg());
fromFile.seekg(0, std::ios::beg);
char data[500000];
while ( size > 0 )
{
size_t read = 500000;
if ( read > size )
read = size;
size -= read;
fromFile.read(data, read);
toFile.write(data, read);
}
fromFile.close();
toFile.close();
return true;
}
bool CFileIO::AppendData ( const char *d, size_t size )
{
std::ofstream File(m_sFilename, _append());
if ( !File.is_open() ) return false;
// move to the end of the file
//File.seekg(0, std::ios::end);
char *pos = (char *)d;
while ( size > 0 ) {
size_t read = 500000;
if ( read > size ) read = size;
size -= read;
try {
File.write(pos, read);
}
catch(std::exception &e) {
CLog::logf(CLog::Log_IO, 2, "CFileIO::AppendData() unable to write data to file: %s (%s)", m_sFilename.c_str(), e.what());
File.close();
return false;
}
pos += read;
}
File.close();
return true;
}
bool CFileIO::AppendDataToPos ( const char *d, size_t size, size_t start )
{
if ( start > m_lSize ) return false;
if ( m_lSize <= 0 ) {
if ( !this->startWrite() ) return false;
}
else if ( start == m_lSize ) {
if ( !this->startAppend() ) return false;
}
else {
if ( !this->startModify() ) return false;
this->seekStart(start);
}
return this->write(d, size);
}
Utils::String CFileIO::readEndOfLine()
{
if ( !this->isOpened() ) {
if ( !startRead() ) return "";
}
Utils::String str;
std::getline(m_fId, str, '\n');
return str;
}
Utils::String CFileIO::baseName() const
{
return m_sFile.tokens(".", 1, -2);
}
CyString CFileIO::GetFileExtension ()
{
if ( m_sFilename.empty() ) return NullString;
return m_sFilename.token(".", -1);
}
Utils::String CFileIO::extension ()
{
if ( m_sFilename.empty() ) return Utils::String::Null();
return m_sFilename.token(".", -1);
}
CyString CFileIO::ChangeFileExtension(CyString ext) const
{
return changeFileExtension(ext.ToString());
}
Utils::String CFileIO::changeFileExtension(const Utils::String &ext) const
{
if ( m_sFilename.empty() )
return Utils::String::Null();
return m_sFilename.tokens(".", 1, -2) + "." + ext;
}
bool CFileIO::Remove(const Utils::String &rem)
{
//if ( !Exists() ) return false;
return (std::remove(rem) == 0) ? true : false;
}
bool CFileIO::remove()
{
if ( this->isOpened() ) this->close();
if ( !this->exists() ) return false;
if ( std::remove(m_sFilename.c_str()) == 0 ) return true;
return false;
}
bool CFileIO::WriteFileUTF(std::vector<CyString> *lines)
{
if ( !lines || m_sFilename.empty() )
return false;
// we need to create the directory
if ( !m_sDirIO.exists() )
{
if ( !m_sDirIO.Create() )
return false;
}
#ifdef _WIN32
TCHAR buf[5000];
wsprintf(buf, L"%hs", m_sFilename.c_str());
FILE *id = _wfopen(buf, L"wt+,ccs=UTF-8");
if ( !id )
return false;
// write the rest
for ( int i = 0; i < (int)lines->size(); i++ )
{
CyString l = lines->at(i);
if ( l.IsIn('\n') )
{
int max;
CyString *strs = l.SplitToken("\n", &max);
if ( strs && max )
{
for ( int i = 0; i < max; i++ )
{
CyString line = strs[i];
line += "\n";
int size = wsprintf(buf, L"%hs", line.c_str());
fwrite(buf, sizeof(TCHAR), wcslen(buf), id);
}
CLEANSPLIT(strs, max);
}
}
else
{
l += "\n";
int size = wsprintf(buf, L"%hs", l.c_str());
fwrite(buf, sizeof(TCHAR), wcslen(buf), id);
}
}
fclose(id);
return true;
#else
//TODO: write utf8 file writing function
return false;
#endif
}
bool CFileIO::writeFileUTF(std::vector<Utils::String> *lines)
{
if (!lines || m_sFilename.empty())
return false;
// we need to create the directory
if (!m_sDirIO.exists())
{
if (!m_sDirIO.Create())
return false;
}
#ifdef _WIN32
TCHAR buf[5000];
wsprintf(buf, L"%hs", m_sFilename.c_str());
FILE *id = _wfopen(buf, L"wt+,ccs=UTF-8");
if (!id)
return false;
// write the rest
for(auto itr = lines->begin(); itr != lines->end(); itr++)
{
Utils::String l = (*itr);
if (l.isin('\n'))
{
int max;
Utils::String *strs = l.tokenise("\n", &max);
if (strs && max)
{
for (int i = 0; i < max; i++)
{
Utils::String line = strs[i];
line += "\n";
int size = wsprintf(buf, L"%hs", line.c_str());
fwrite(buf, sizeof(TCHAR), wcslen(buf), id);
}
CLEANSPLIT(strs, max);
}
}
else
{
l += "\n";
int size = wsprintf(buf, L"%hs", l.c_str());
fwrite(buf, sizeof(TCHAR), wcslen(buf), id);
}
}
fclose(id);
return true;
#else
//TODO: write utf8 file writing function
return false;
#endif
}
bool CFileIO::WriteFile(std::vector<CyString> *lines)
{
if ( !lines || m_sFilename.empty() )
return false;
// we need to create the directory
if ( !m_sDirIO.exists() )
{
if ( !m_sDirIO.Create() )
return false;
}
std::ofstream out(m_sFilename.c_str());
if ( !out )
return false;
for ( int i = 0; i < (int)lines->size(); i++ )
{
CyString l = lines->at(i);
out << l.c_str() << std::endl;
}
out.close();
return true;
}
bool CFileIO::WriteFile(CyStringList *lines)
{
if ( !lines || m_sFilename.empty() )
return false;
// we need to create the directory
if ( !m_sDirIO.exists() )
{
if ( !m_sDirIO.Create() )
return false;
}
std::ofstream out(m_sFilename.c_str());
if ( !out )
return false;
/*
if ( utf )
{
unsigned char smarker[4];
smarker[0] = 0xEF;
smarker[1] = 0xBB;
smarker[2] = 0xBF;
smarker[3] = 0x00;
out << smarker;
}
*/
for ( int i = 0; i < (int)lines->Count(); i++ )
{
CyString l = lines->StringAt(i);
out << l.c_str() << std::endl;
}
out.close();
return true;
}
bool CFileIO::writeFile(std::vector<Utils::String> *lines)
{
if (!lines || m_sFilename.empty())
return false;
// we need to create the directory
if (!m_sDirIO.exists())
{
if (!m_sDirIO.Create())
return false;
}
std::ofstream out(m_sFilename.c_str());
if (!out)
return false;
for (auto itr = lines->begin(); itr != lines->end(); itr++)
out << (*itr).c_str() << std::endl;
out.close();
return true;
}
bool CFileIO::writeFile(Utils::CStringList *lines)
{
if (!lines || m_sFilename.empty())
return false;
// we need to create the directory
if (!m_sDirIO.exists())
{
if (!m_sDirIO.Create())
return false;
}
std::ofstream out(m_sFilename.c_str());
if (!out)
return false;
for(auto itr = lines->begin(); itr != lines->end(); itr++)
out << (*itr)->str.c_str() << std::endl;
out.close();
return true;
}
bool CFileIO::Rename(CyString toFile)
{
if ( rename(m_sFilename.c_str(), toFile.c_str()) == 0 )
return true;
return false;
}
CyString CFileIO::GetWindowsFilename()
{
CyString returnString = m_sFilename;
returnString = returnString.FindReplace("/", "\\");
return returnString;
}
void CFileIO::SetCreationTime(time_t time)
{
#ifdef _WIN32
// Note that LONGLONG is a 64-bit value
LONGLONG ll;
FILETIME ft;
ll = Int32x32To64(time, 10000000) + 116444736000000000;
ft.dwLowDateTime = (DWORD)ll;
ft.dwHighDateTime = ll >> 32;
WCHAR str[MAX_PATH];
MultiByteToWideChar(CP_ACP, NULL, GetWindowsFilename().c_str(), -1, str, GetWindowsFilename().Length() + 1);
HANDLE filename = CreateFile(str, FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
// Set the file time on the file
SetFileTime(filename,(LPFILETIME) NULL,(LPFILETIME) NULL,&ft);
// Close our handle.
CloseHandle(filename);
#endif
}
time_t CFileIO::GetCreationTime()
{
return modifiedTime();
}
time_t CFileIO::modifiedTime()
{
#ifdef _WIN32
WCHAR str[MAX_PATH];
MultiByteToWideChar(CP_ACP, NULL, GetWindowsFilename().c_str(), -1, str, GetWindowsFilename().Length() + 1);
WIN32_FILE_ATTRIBUTE_DATA wfad;
GetFileAttributesEx(str, GetFileExInfoStandard, &wfad);
LARGE_INTEGER date, adjust;
date.HighPart = wfad.ftLastWriteTime.dwHighDateTime;
date.LowPart = wfad.ftLastWriteTime.dwLowDateTime;
// 100-nanoseconds = milliseconds * 10000
adjust.QuadPart = 11644473600000 * 10000;
// removes the diff between 1970 and 1601
date.QuadPart -= adjust.QuadPart;
// converts back from 100-nanoseconds to seconds
return (time_t)(date.QuadPart / 10000000);
#else
struct stat fileStat;
if ( !stat(GetWindowsFilename().c_str(), &fileStat) )
return (time_t)fileStat.st_atime;
#endif
return 0;
}
size_t CFileIO::position()
{
return static_cast<size_t>(m_fId.tellg());
}
/**
* Copys the contents of a file to another
*
* Reads and writes the files in block
*/
bool CFileIO::copy(const Utils::String &toFile, bool keepTime)
{
time_t time = GetCreationTime();
CFileIO File(toFile);
if ( File.write(*this, m_lSize) ) {
this->close();
File.close();
if ( keepTime ) File.SetCreationTime(time);
return true;
}
/*
std::fstream f(GetWindowsFilename().c_str(), std::fstream::in | std::fstream::binary);
f << std::noskipws;
std::istream_iterator<unsigned char> begin(f);
std::istream_iterator<unsigned char> end;
std::fstream f2(toFile.c_str(), std::fstream::out | std::fstream::trunc | std::fstream::binary);
std::ostream_iterator<char> begin2(f2);
std::copy(begin, end, begin2);
return f2.good();
*/
return false;
}
size_t CFileIO::fileSize() const
{
return m_lSize;
}