Subversion Repositories spk

Rev

Rev 200 | Rev 212 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 cycrow 1
#include "File_IO.h"
2
 
3
#ifdef _WIN32
4
#include <windows.h>
5
#endif
6
 
7
#include <locale>
8
 
9
#include "DirIO.h"
10
#include "File.h"
51 cycrow 11
#include "Logging/Log.h"
81 cycrow 12
#include "Packages.h"
1 cycrow 13
 
52 cycrow 14
CFileIO::CFileIO () : m_lSize(0), m_bBinary(true), m_bAutoDelete(false), m_bSeekP(false)
1 cycrow 15
{
16
}
17
 
196 cycrow 18
CFileIO::CFileIO(const Utils::WString &sFilename, bool bBinary) : m_lSize(0), m_bBinary(bBinary), m_bAutoDelete(false)
1 cycrow 19
{
82 cycrow 20
	open(sFilename, bBinary);
1 cycrow 21
}
121 cycrow 22
 
196 cycrow 23
CFileIO::CFileIO(const Utils::WString &filename) : m_lSize(0), m_bBinary(true), m_bAutoDelete(false), m_bSeekP(false)
52 cycrow 24
{
185 cycrow 25
	open(filename, true);
52 cycrow 26
}
1 cycrow 27
 
52 cycrow 28
CFileIO::CFileIO(C_File *file) : m_lSize(0), m_bBinary(true), m_bAutoDelete(false), m_bSeekP(false)
1 cycrow 29
{
129 cycrow 30
	open(file->filePointer(), true);
1 cycrow 31
}
32
 
33
CFileIO::~CFileIO()
34
{
52 cycrow 35
	if ( this->isOpened() ) m_fId.close();
36
	if ( m_bAutoDelete ) this->remove();
1 cycrow 37
}
38
 
52 cycrow 39
void CFileIO::setAutoDelete(bool bDelete)
40
{
41
	m_bAutoDelete = true;
42
}
43
 
196 cycrow 44
bool CFileIO::open(const Utils::WString& sFilename, bool bBinary)
1 cycrow 45
{
82 cycrow 46
	m_bBinary = bBinary;
160 cycrow 47
	_sFilename = sFilename.asFilename();
1 cycrow 48
 
82 cycrow 49
	// check if there are any directories, and split the file and directory parts
196 cycrow 50
	if ( _sFilename.contains('/') ) {
197 cycrow 51
		_sDirIO.setDir(_sFilename.tokens(L"/", 1, -2));
196 cycrow 52
		_sFile = _sFilename.token(L"/", -1);
1 cycrow 53
	}
54
	else
160 cycrow 55
		_sFile = _sFilename;
1 cycrow 56
 
160 cycrow 57
	_sFile.removeFirstSpace();
58
	_sFile.removeChar(13);
95 cycrow 59
 
160 cycrow 60
	_updateFilename();
61
 
51 cycrow 62
	this->_readFileSize();
1 cycrow 63
	return true;
64
}
119 cycrow 65
 
52 cycrow 66
unsigned char *CFileIO::read(size_t iAmount)
67
{
68
	if ( !this->isOpened() ) startRead();
69
	if ( !this->isOpened() ) return NULL;
70
 
71
	if ( iAmount > m_lSize ) iAmount = m_lSize;
72
 
73
	unsigned char *data;
74
	try {
75
		data = new unsigned char[iAmount + 1];
76
	}
77
	catch (std::exception &e) {
78
		CLog::logf(CLog::Log_IO, 2, "ERROR: CFileIO::read(size_t) unable to malloc data, %d (%s)", iAmount + 1, e.what());
79
		return NULL;
80
	}
81
 
82
	if ( !read(data, iAmount, true) ) {
160 cycrow 83
		CLog::logf(CLog::Log_IO, 2, "ERROR: CFileIO::read(size_t) unable to read data from file, %s/%d", _sFilename.c_str(), iAmount);
196 cycrow 84
		delete[] data;
52 cycrow 85
		return NULL;
86
	}
87
 
88
	return data;
89
}
90
 
91
unsigned char *CFileIO::readAll(size_t *pSize)
92
{
93
	if ( pSize ) (*pSize) = 0;
94
	if ( !this->isOpened() ) startRead();
95
	if ( !this->isOpened() ) return NULL;
96
 
97
	unsigned char *data;
98
	try {
99
		data = new unsigned char[m_lSize + 1];
100
	}
101
	catch (std::exception &e) {
102
		CLog::logf(CLog::Log_IO, 2, "ERROR: CFileIO::readAll() unable to malloc data, %d (%s)", m_lSize + 1, e.what());
103
		return NULL;
104
	}
105
 
106
	if ( !read(data, m_lSize, true) ) {
160 cycrow 107
		CLog::logf(CLog::Log_IO, 2, "ERROR: CFileIO::readAll() unable to read data from file, %s/%d", _sFilename.c_str(), m_lSize);
196 cycrow 108
		delete[] data;
52 cycrow 109
		return NULL;
110
	}
111
 
112
	if ( pSize ) (*pSize) = m_lSize;
113
	return data;
114
}
115
 
197 cycrow 116
bool CFileIO::read(wchar_t* buf, size_t iSize, bool bEndChar)
52 cycrow 117
{
197 cycrow 118
	if (!this->isOpened()) startRead();
119
	if (!this->isOpened()) return false;
52 cycrow 120
 
197 cycrow 121
	if (iSize > m_lSize) iSize = m_lSize;
52 cycrow 122
	try {
197 cycrow 123
		m_fId.read((char*)buf, iSize);
52 cycrow 124
	}
197 cycrow 125
	catch (std::exception& e) {
160 cycrow 126
		CLog::logf(CLog::Log_IO, 3, "ERROR: CFileIO::read() unable to read from file: %s (%s)", _sFilename.c_str(), e.what());
52 cycrow 127
		return false;
128
	}
129
 
197 cycrow 130
	if (bEndChar) buf[iSize] = '\0';
52 cycrow 131
 
132
	return !m_fId.bad();
133
}
197 cycrow 134
bool CFileIO::read(unsigned char* buf, size_t iSize, bool bEndChar)
135
{
136
	if (!this->isOpened()) startRead();
137
	if (!this->isOpened()) return false;
52 cycrow 138
 
197 cycrow 139
	if (iSize > m_lSize) iSize = m_lSize;
140
	try {
141
		m_fId.read((char*)buf, iSize);
142
	}
143
	catch (std::exception& e) {
144
		CLog::logf(CLog::Log_IO, 3, "ERROR: CFileIO::read() unable to read from file: %s (%s)", _sFilename.c_str(), e.what());
145
		return false;
146
	}
147
 
148
	if (bEndChar) buf[iSize] = '\0';
149
 
150
	return !m_fId.bad();
151
}
152
 
1 cycrow 153
bool CFileIO::WritePartFile ( size_t *offsets, size_t numOffset )
154
{
51 cycrow 155
	if ( NoFile() )	return false;
1 cycrow 156
 
160 cycrow 157
	std::fstream File(_sFilename, _in());
51 cycrow 158
	if ( !File.is_open() ) return false;
1 cycrow 159
 
160
	// first find file size
51 cycrow 161
	File.seekg(0, std::ios::end);
121 cycrow 162
	size_t fullsize = static_cast<size_t>(File.tellg()), size = fullsize;
51 cycrow 163
	File.seekg(0, std::ios::beg);
1 cycrow 164
 
81 cycrow 165
	std::fstream writeFile(CPackages::tempDirectory() + "/temp.tmp", _out());
51 cycrow 166
	if ( !File.is_open() ) {
167
		File.close();
1 cycrow 168
		return false;
169
	}
170
 
171
	size_t off = 0;
172
	size_t startPos = 0;
173
	size_t remainingSize = fullsize;
51 cycrow 174
 
175
	while ( off < numOffset ) {
121 cycrow 176
		startPos = static_cast<size_t>(File.tellg());
1 cycrow 177
		size_t offset = offsets[off++];
178
		size_t size = offset - startPos;
51 cycrow 179
		try {
180
			char *data = new char[size];
181
			File.read(data, size);
182
			writeFile.write(data, size);
196 cycrow 183
			delete []data;
51 cycrow 184
		}
185
		catch(std::exception &e) {
160 cycrow 186
			CLog::logf(CLog::Log_IO, 2, "CFileIO::WritePartFilea() unable to read data from file: %s (%s)", _sFilename.c_str(), e.what());
51 cycrow 187
			return false;
188
		}
189
 
1 cycrow 190
		size_t datasize = offsets[off++];
51 cycrow 191
		File.seekg(datasize, std::ios::beg);
1 cycrow 192
		remainingSize = fullsize - offset - datasize;
193
	}
194
 
51 cycrow 195
	if ( remainingSize ) {
1 cycrow 196
		char data[1000000];
197
		size_t amountLeft = 1000000;
198
		while ( remainingSize )
199
		{
51 cycrow 200
			if ( amountLeft > remainingSize ) amountLeft = remainingSize;
201
			try {
202
				File.read(data, amountLeft);
203
				writeFile.write(data, amountLeft);
204
			}
205
			catch(std::exception &e) {
160 cycrow 206
				CLog::logf(CLog::Log_IO, 2, "CFileIO::WritePartFilea() unable to read data from file: %s (%s)", _sFilename.c_str(), e.what());
51 cycrow 207
				return false;
208
			}
1 cycrow 209
 
210
			remainingSize -= amountLeft;
211
			amountLeft = 1000000;
212
		}
213
	}
214
 
51 cycrow 215
	File.close();
216
	writeFile.close();
1 cycrow 217
 
218
	// now copy to original file
197 cycrow 219
	CFileIO::Remove(_sFilename);
220
	return CFileIO::Rename(CPackages::tempDirectory() + L"/temp.tmp", _sFilename);
1 cycrow 221
}
222
 
223
 
196 cycrow 224
void CFileIO::setDir(const Utils::WString &dir)
1 cycrow 225
{
160 cycrow 226
	if ( _sFile.empty() )	_sDirIO.setDir(dir);
227
	else					open(dir + "/" + _sFile, m_bBinary);
1 cycrow 228
}
229
 
51 cycrow 230
void CFileIO::_readFileSize ()
1 cycrow 231
{
51 cycrow 232
	m_lSize = 0;
233
 
160 cycrow 234
	std::fstream file(_sFilename, (m_bBinary) ? (std::ios::in | std::ios::binary) : (std::ios::in));
51 cycrow 235
	if ( !file.is_open() ) return;
236
 
237
	file.seekg(0, std::ios::end);
121 cycrow 238
	m_lSize = static_cast<size_t>(file.tellg());
51 cycrow 239
	file.close();
1 cycrow 240
}
241
 
242
bool CFileIO::WipeFile()
243
{
51 cycrow 244
	if ( NoFile() )	return false;
245
	std::ofstream file;
160 cycrow 246
	file.open(_sFilename, std::ios::out | std::ios::trunc);
51 cycrow 247
	bool bDone = file.is_open();
248
	file.close();
1 cycrow 249
 
51 cycrow 250
	return bDone;
1 cycrow 251
}
52 cycrow 252
 
253
 
1 cycrow 254
int CFileIO::TruncateFile ( size_t offset, size_t datasize )
255
{
52 cycrow 256
	if ( NoFile() ) return FILEERR_NOFILE;
1 cycrow 257
 
52 cycrow 258
	if ( !this->startRead() ) return FILEERR_NOOPEN;
259
	if ( (offset + datasize) > m_lSize ) return FILEERR_TOSMALL;
1 cycrow 260
 
81 cycrow 261
	CFileIO File(CPackages::tempDirectory() + "/temp.tmp");
52 cycrow 262
	if ( !File.startWrite() ) return FILEERR_NOWRITE;
263
	File.setAutoDelete(true);
1 cycrow 264
 
52 cycrow 265
	if ( !File.write(*this, offset) ) return false;
1 cycrow 266
 
267
	// next fseek after and write
52 cycrow 268
	this->seek(datasize);
269
	size_t size = m_lSize - offset - datasize;
42 cycrow 270
	if ( size > 0 ) {
52 cycrow 271
		File.write(*this, size);
42 cycrow 272
	}
1 cycrow 273
 
52 cycrow 274
	File.close();
275
	this->close();
276
	File.setAutoDelete(false);
1 cycrow 277
 
278
	// now copy to original file
197 cycrow 279
	if (CFileIO::Remove(_sFilename)) {
280
		if (CFileIO::Rename(CPackages::tempDirectory() + L"/temp.tmp", _sFilename))
281
		{
282
			size_t oldSize = m_lSize;
283
			size_t checkFileSize = m_lSize - datasize;
284
			this->_readFileSize();
285
			if (checkFileSize != m_lSize) {
286
				CLog::log(CLog::Log_IO, 3, Utils::WString(L"WARNING: CFileIO::TruncateFile, file size mismatch, ") + (long)checkFileSize + L" => " + (long)m_lSize);
287
			}
288
			return FILEERR_NONE;
84 cycrow 289
		}
197 cycrow 290
		return FILEERR_NOWRITE;
58 cycrow 291
	}
1 cycrow 292
 
58 cycrow 293
	return FILEERR_NOWRITE;
1 cycrow 294
}
295
 
52 cycrow 296
int CFileIO::_in() const
51 cycrow 297
{
298
	if ( m_bBinary ) return std::ios::in | std::ios::binary;
299
	return std::ios::in;
300
}
301
 
52 cycrow 302
int CFileIO::_out() const
51 cycrow 303
{
304
	if ( m_bBinary ) return std::ios::out | std::ios::binary;
305
	return std::ios::out;
306
}
52 cycrow 307
int CFileIO::_inout() const
308
{
309
	if ( m_bBinary ) return std::ios::in | std::ios::out | std::ios::binary;
310
	return std::ios::in | std::ios::out;
311
}
51 cycrow 312
 
52 cycrow 313
int CFileIO::_append() const
51 cycrow 314
{
315
	if ( m_bBinary ) return std::ios::out | std::ios::binary | std::ios::app;
316
	return std::ios::out | std::ios::app;
317
}
318
 
1 cycrow 319
char *CFileIO::ReadToData ( size_t *size )
320
{
321
	*size = 0;
322
 
51 cycrow 323
	if ( NoFile() ) return NULL;
324
	if ( !m_lSize )	this->_readFileSize();
325
	if ( !m_lSize ) return NULL;
1 cycrow 326
 
160 cycrow 327
	std::fstream file(_sFilename, _in());
51 cycrow 328
	if ( !file.is_open() ) return NULL;
1 cycrow 329
 
51 cycrow 330
	char *data;
331
	try {
332
		data = new char[m_lSize + 1];
333
	}
334
	catch (std::exception &e) {
335
		CLog::logf(CLog::Log_IO, 2, "CFileIO::ReadToData() unable to malloc storage, %d (%s)", m_lSize + 1, e.what());
336
		file.close();
1 cycrow 337
		return NULL;
51 cycrow 338
	}
1 cycrow 339
 
51 cycrow 340
	try {
341
		file.read((char *)data, m_lSize);
342
	}
343
	catch (std::exception &e) {
344
		CLog::logf(CLog::Log_IO, 2, "CFileIO::ReadToData() unable to read data from file (%s)", e.what());
345
		file.close();
1 cycrow 346
		return NULL;
347
	}
348
 
349
	*size = m_lSize;
51 cycrow 350
	file.close();
1 cycrow 351
 
352
	return data;
353
}
354
 
355
bool CFileIO::WriteData ( const char *data, size_t size )
356
{
357
	if ( NoFile() )
358
		return false;
359
 
200 cycrow 360
	std::fstream File(_fileData(), _out());
51 cycrow 361
	if ( !File.is_open() ) return false;
1 cycrow 362
 
51 cycrow 363
	bool ret = true;
364
	try {
365
		File.write(data, size);
366
	}
367
	catch (std::exception &e) {
160 cycrow 368
		CLog::logf(CLog::Log_IO, 2, "CFileIO::ReadToData() unable to read data from file: %s (%s)", _sFilename.c_str(), e.what());
51 cycrow 369
		ret = false;
370
	}
1 cycrow 371
 
51 cycrow 372
	File.close();
1 cycrow 373
 
51 cycrow 374
	if ( ret ) this->_readFileSize();
375
	return ret;
1 cycrow 376
}
377
 
82 cycrow 378
bool CFileIO::writeString ( const Utils::String &data )
1 cycrow 379
{
82 cycrow 380
	return WriteData ( data.c_str(), data.length() );
1 cycrow 381
}
382
 
196 cycrow 383
bool CFileIO::Exists(const Utils::WString &filename)
1 cycrow 384
{
197 cycrow 385
	std::wfstream File(filename, std::ios::in | std::ios::binary);
52 cycrow 386
	bool bRet = File.good();
387
	File.close();
388
	return bRet;
389
}
390
 
391
bool CFileIO::ExistsOld () const
392
{
393
	return this->exists();
394
}
395
bool CFileIO::exists () const
396
{
397
	if ( this->isOpened() ) return true;
160 cycrow 398
	std::fstream File(_sFilename, _in());
51 cycrow 399
	bool bRet = File.good();
400
	File.close();
401
	return bRet;
1 cycrow 402
}
403
 
52 cycrow 404
bool CFileIO::startRead()
1 cycrow 405
{
52 cycrow 406
	return _start(_in(), false);
407
}
408
 
409
bool CFileIO::startWrite()
410
{
411
	return _start(_out(), true);
412
}
413
 
414
bool CFileIO::startModify()
415
{
416
	return _start(_inout(), true);
417
}
418
 
419
bool CFileIO::startAppend()
420
{
421
	return _start(_append(), false);
422
}
423
 
424
bool CFileIO::_start(int iFlags, bool bSeekP)
425
{
160 cycrow 426
	if ( !_sFilename.empty() ) {
52 cycrow 427
		if ( this->isOpened() ) this->close();
1 cycrow 428
 
160 cycrow 429
		m_fId.open(_sFilename, iFlags);
1 cycrow 430
	}
52 cycrow 431
	m_bSeekP = bSeekP;
432
	return m_fId.is_open();
1 cycrow 433
}
434
 
166 cycrow 435
std::vector<Utils::String>* CFileIO::readLines() const
82 cycrow 436
{
166 cycrow 437
	if (_sFilename.empty()) return 0;
82 cycrow 438
 
166 cycrow 439
	std::vector<Utils::String>* file = new std::vector<Utils::String>;
84 cycrow 440
	Utils::String line;
82 cycrow 441
	file->clear();
166 cycrow 442
	std::ifstream infile(_sFilename.c_str(), std::ios_base::in);
82 cycrow 443
	while (getline(infile, line, '\n')) {
444
		file->push_back(Utils::String(line).removeChar((char)0));
445
	}
446
 
447
	infile.close();
448
 
449
	return file;
450
}
170 cycrow 451
size_t CFileIO::readLines(std::vector<Utils::String>& to) const
166 cycrow 452
{
453
	if (_sFilename.empty()) return 0;
83 cycrow 454
 
166 cycrow 455
	Utils::String line;
456
	std::ifstream infile(_sFilename.c_str(), std::ios_base::in);
457
	while (getline(infile, line, '\n')) {
458
		to.push_back(Utils::String(line).removeChar((char)0));
459
	}
1 cycrow 460
 
166 cycrow 461
	infile.close();
462
 
463
	return to.size();
464
}
465
 
197 cycrow 466
size_t CFileIO::readLines(std::vector<Utils::WString>& to) const
467
{
468
	if (_sFilename.empty()) return 0;
469
 
470
	std::wstring line;
471
	std::wifstream infile(_sFilename.c_str(), std::ios_base::in);
472
	while (getline(infile, line, L'\n')) {
473
		to.push_back(Utils::WString(line).remove((char)0));
474
	}
475
 
476
	infile.close();
477
 
478
	return to.size();
479
}
480
 
170 cycrow 481
size_t CFileIO::readLines(Utils::CStringList& to) const
482
{
483
	if (_sFilename.empty()) return 0;
166 cycrow 484
 
170 cycrow 485
	Utils::String line;
486
	std::ifstream infile(_sFilename.c_str(), std::ios_base::in);
487
	while (getline(infile, line, '\n')) {
488
		to.pushBack(Utils::String(line).removeChar((char)0));
489
	}
490
 
491
	infile.close();
492
 
493
	return to.size();
494
}
211 cycrow 495
size_t CFileIO::readLines(Utils::WStringList& to) const
111 cycrow 496
{
211 cycrow 497
	if (_sFilename.empty()) return 0;
111 cycrow 498
 
211 cycrow 499
	std::wstring line;
500
	std::wifstream infile(_sFilename.c_str(), std::ios_base::in);
501
	while (getline(infile, line, L'\n')) {
502
		to.pushBack(Utils::WString(line).remove((char)0));
111 cycrow 503
	}
504
 
505
	infile.close();
506
 
211 cycrow 507
	return to.size();
111 cycrow 508
}
509
 
52 cycrow 510
bool CFileIO::put(const unsigned char c)
1 cycrow 511
{
52 cycrow 512
	if ( !this->isOpened() ) return false;
513
 
514
	m_fId.put(c);
515
	return !m_fId.bad();
1 cycrow 516
}
517
 
123 cycrow 518
bool CFileIO::writeSize(size_t iSize)
1 cycrow 519
{
52 cycrow 520
	if ( !this->isOpened() ) return false;
521
	if ( !this->put(static_cast<unsigned char>(iSize >> 24)) ) return false;
522
	if ( !this->put(static_cast<unsigned char>(iSize >> 16)) ) return false;
523
	if ( !this->put(static_cast<unsigned char>(iSize >> 8)) ) return false;
524
	if ( !this->put(static_cast<unsigned char>(iSize)) ) return false;
525
	m_lSize += 4;
526
	return true;
1 cycrow 527
}
528
 
52 cycrow 529
bool CFileIO::write(CFileIO &file, size_t iSize)
1 cycrow 530
{
52 cycrow 531
	if ( !this->isOpened() ) startWrite();
532
	if ( !this->isOpened() ) return false;
533
 
534
	int iMaxSize = 1000000;
535
 
536
	unsigned char *data;
537
	try {
538
		data = new unsigned char[iMaxSize + 1];
1 cycrow 539
	}
52 cycrow 540
	catch (std::exception &e) {
541
		CLog::logf(CLog::Log_IO, 2, "ERROR: CFileIO::write(CFileIO, size_t) unable to malloc data, %d (%s)", iMaxSize + 1, e.what());
542
		return false;
543
	}
1 cycrow 544
 
52 cycrow 545
	int iSizeLeft = iSize;
546
	bool bSuccess = true;
547
	while ( iSizeLeft > 0 ) {
548
		int iDoSize = iMaxSize;
549
		if ( iDoSize > iSizeLeft ) iDoSize = iSizeLeft;
1 cycrow 550
 
52 cycrow 551
		if ( !file.read(data, iDoSize) ) bSuccess = false;
552
		if ( bSuccess && !this->write(data, iDoSize) ) bSuccess = false;
553
		if ( !bSuccess ) break;
554
		iSizeLeft -= iDoSize;
555
	}
1 cycrow 556
 
52 cycrow 557
	delete data;
1 cycrow 558
 
52 cycrow 559
	return bSuccess;
1 cycrow 560
}
561
 
123 cycrow 562
bool CFileIO::write(const char *buf, size_t iSize)
52 cycrow 563
{
564
	if ( !this->isOpened() ) startWrite();
565
	if ( !this->isOpened() ) return false;
566
	try {
197 cycrow 567
		m_fId.write((char*)buf, iSize);
52 cycrow 568
	}
569
	catch (std::exception &e) {
160 cycrow 570
		CLog::logf(CLog::Log_IO, 2, "CFileIO::write() unable to write to file: %s (%s)", _sFilename.c_str(), e.what());
52 cycrow 571
		return false;
572
	}
573
	m_lSize += iSize;
574
	return !m_fId.bad();
575
}
123 cycrow 576
bool CFileIO::write(const unsigned char *buf, size_t iSize)
52 cycrow 577
{
578
	return this->write((char *)buf, iSize);
579
}
580
 
581
bool CFileIO::write(const unsigned char *buf, ...)
582
{
583
	va_list args;
584
	va_start(args, buf);
585
	bool ret = this->_write((char *)buf, args);
586
	va_end(args);
587
	return ret;
588
}
197 cycrow 589
bool CFileIO::_write(const char* buf, va_list args)
52 cycrow 590
{
197 cycrow 591
	if (!this->isOpened()) return false;
52 cycrow 592
 
593
	char buffer[10000];
594
 
197 cycrow 595
	vsprintf(buffer, buf, args);
52 cycrow 596
	try {
597
		int iLen = strlen(buffer);
197 cycrow 598
		m_fId.write((char*)buffer, iLen);
52 cycrow 599
		m_lSize += iLen;
600
	}
197 cycrow 601
	catch (std::exception& e) {
160 cycrow 602
		CLog::logf(CLog::Log_IO, 2, "CFileIO::write() unable to write to file: %s (%s)", _sFilename.c_str(), e.what());
52 cycrow 603
		return false;
604
	}
605
	return !m_fId.bad();
606
}
197 cycrow 607
bool CFileIO::_write(const wchar_t* buf, va_list args)
608
{
609
	if (!this->isOpened()) return false;
52 cycrow 610
 
197 cycrow 611
	wchar_t buffer[10000];
612
 
613
#ifdef _WIN32
614
	vswprintf_s(buffer, 10000, buf, args);
615
#else
616
	vswprintf(buffer, buf, args);
617
#endif
618
	try {
619
		size_t iLen = wcslen(buffer);
620
		m_fId.write((char*)buffer, iLen);
621
		m_lSize += iLen;
622
	}
623
	catch (std::exception& e) {
624
		CLog::logf(CLog::Log_IO, 2, "CFileIO::write() unable to write to file: %ls (%s)", _sFilename.c_str(), e.what());
625
		return false;
626
	}
627
	return !m_fId.bad();
628
}
629
 
52 cycrow 630
bool CFileIO::write(const char *buf, ...)
631
{
632
	va_list args;
633
	va_start(args, buf);
634
	bool ret = this->_write((char *)buf, args);
635
	va_end(args);
636
	return ret;
637
}
638
 
639
void CFileIO::_seek(int iPos, int iFrom)
640
{
641
	if ( !this->isOpened() ) {
642
		if ( !this->startRead() ) return;
643
	}
644
	if ( m_bSeekP ) m_fId.seekp(iPos, iFrom);
645
	else m_fId.seekg(iPos, iFrom);
646
}
647
 
123 cycrow 648
void CFileIO::seek(size_t iPos)
52 cycrow 649
{
650
	_seek(iPos, std::ios::cur);
651
}
652
 
123 cycrow 653
void CFileIO::seekEnd(size_t iPos)
52 cycrow 654
{
53 cycrow 655
	_seek(iPos, std::ios::end);
52 cycrow 656
}
657
 
123 cycrow 658
void CFileIO::seekStart(size_t iPos)
52 cycrow 659
{
660
	_seek(iPos, std::ios::beg);
661
}
662
 
663
std::fstream &CFileIO::stream()
664
{
665
	return m_fId;
666
}
667
 
668
bool CFileIO::isOpened() const
669
{
670
	if ( m_fId.is_open() )
671
		return true;
672
	return false;
673
}
674
 
675
void CFileIO::close()
676
{
677
	if ( this->isOpened() ) m_fId.close();
84 cycrow 678
	this->_readFileSize();
52 cycrow 679
}
680
 
56 cycrow 681
int CFileIO::readSize()
1 cycrow 682
{
56 cycrow 683
	unsigned char size[4];
684
	if ( this->read(size, 4) ) return (size[0] << 24) + (size[1] << 16) + (size[2] << 8) + size[3];
685
	return 0;
686
}
687
 
688
bool CFileIO::atEnd() const
689
{
52 cycrow 690
	if ( !this->isOpened() ) return true;
51 cycrow 691
	if ( m_fId.eof() )		 return true;
1 cycrow 692
	return false;
693
}
694
 
82 cycrow 695
bool CFileIO::appendFile ( const Utils::String &filename )
696
{
697
	std::fstream fromFile(filename, _in());
698
	if ( !fromFile.is_open() ) return false;
699
 
160 cycrow 700
	std::fstream toFile(_sFilename, _append());
82 cycrow 701
	if ( !toFile.is_open() ) {
702
		fromFile.close();
703
		return false;
704
	}
705
 
706
	// move to the end of the file
707
	toFile.seekg(0, std::ios::end);
708
 
709
	// get size of file
710
	fromFile.seekg(0, std::ios::end);
121 cycrow 711
	size_t size = static_cast<size_t>(fromFile.tellg());
82 cycrow 712
	fromFile.seekg(0, std::ios::beg);
713
 
714
	char data[500000];
715
	while ( size > 0 )
716
	{
717
		size_t read = 500000;
718
		if ( read > size )
719
			read = size;
720
 
721
		size -= read;
722
 
723
		fromFile.read(data, read);
724
		toFile.write(data, read);
725
	}
726
 
727
	fromFile.close();
728
	toFile.close();
729
	return true;
730
}
731
 
1 cycrow 732
 
733
bool CFileIO::AppendData ( const char *d, size_t size )
734
{
160 cycrow 735
	std::ofstream File(_sFilename, _append());
51 cycrow 736
	if ( !File.is_open() ) return false;
1 cycrow 737
 
738
	// move to the end of the file
58 cycrow 739
	//File.seekg(0, std::ios::end);
1 cycrow 740
 
741
	char *pos = (char *)d;
51 cycrow 742
	while ( size > 0 ) {
1 cycrow 743
		size_t read = 500000;
51 cycrow 744
		if ( read > size ) read = size;
1 cycrow 745
 
746
		size -= read;
747
 
51 cycrow 748
		try {
749
			File.write(pos, read);
750
		} 
751
		catch(std::exception &e) {
160 cycrow 752
			CLog::logf(CLog::Log_IO, 2, "CFileIO::AppendData() unable to write data to file: %s (%s)", _sFilename.c_str(), e.what());
51 cycrow 753
			File.close();
754
			return false;
755
		}
1 cycrow 756
		pos += read;
757
	}
758
 
51 cycrow 759
	File.close();
1 cycrow 760
	return true;
761
}
762
 
763
bool CFileIO::AppendDataToPos ( const char *d, size_t size, size_t start )
764
{
52 cycrow 765
	if ( start > m_lSize ) return false;
766
	if ( m_lSize <= 0 ) {
767
		if ( !this->startWrite() ) return false;
1 cycrow 768
	}
52 cycrow 769
	else if ( start == m_lSize ) {
770
		if ( !this->startAppend() ) return false;
42 cycrow 771
	}
772
	else {
52 cycrow 773
		if ( !this->startModify() ) return false;
774
		this->seekStart(start);
42 cycrow 775
	}
1 cycrow 776
 
52 cycrow 777
	return this->write(d, size);
778
}
1 cycrow 779
 
197 cycrow 780
Utils::String CFileIO::readEndOfLineStr()
52 cycrow 781
{
197 cycrow 782
	if (!this->isOpened()) {
783
		if (!startRead())	return "";
1 cycrow 784
	}
785
 
197 cycrow 786
	std::string str;
52 cycrow 787
	std::getline(m_fId, str, '\n');
788
	return str;
1 cycrow 789
}
197 cycrow 790
Utils::WString CFileIO::readEndOfLine()
791
{
792
	if (!this->isOpened()) {
793
		if (!startRead())	return L"";
794
	}
1 cycrow 795
 
197 cycrow 796
	std::string str;
797
	std::getline(m_fId, str, '\n');
798
	return str;
799
}
800
 
196 cycrow 801
Utils::WString CFileIO::baseName() const
1 cycrow 802
{
197 cycrow 803
	return _sFile.tokens(L".", 1, -2);
1 cycrow 804
}
805
 
196 cycrow 806
const Utils::WString& CFileIO::fullFilename() const { return _sFilename; }
807
const Utils::WString& CFileIO::filename() const { return _sFile; }
808
 
809
const Utils::String CFileIO::fullFilenameStr() const { return _sFilename.toString(); }
810
const Utils::String CFileIO::filenameStr() const { return _sFile.toString(); }
811
 
812
Utils::WString CFileIO::extension () const
58 cycrow 813
{
196 cycrow 814
	if ( _sFilename.empty() ) return Utils::WString::Null();
815
	return _sFilename.token(L".", -1);
58 cycrow 816
}
817
 
196 cycrow 818
Utils::WString CFileIO::changeFileExtension(const Utils::WString &ext) const
124 cycrow 819
{
160 cycrow 820
	if ( _sFilename.empty() )
196 cycrow 821
		return Utils::WString::Null();
51 cycrow 822
 
196 cycrow 823
	return _sFilename.tokens(L".", 1, -2) + L"." + ext;
1 cycrow 824
}
825
 
197 cycrow 826
bool CFileIO::Remove(const Utils::WString& rem)
1 cycrow 827
{
197 cycrow 828
#ifdef _WIN32
829
	return DeleteFile(rem.c_str());
830
#else
52 cycrow 831
	//if ( !Exists() ) return false;
196 cycrow 832
	return (std::remove(_toFileData(rem)) == 0) ? true : false;
197 cycrow 833
#endif
52 cycrow 834
}
1 cycrow 835
 
197 cycrow 836
bool CFileIO::Rename(const Utils::WString& from, const Utils::WString &to) 
837
{
838
	if (std::rename(_toFileData(from).c_str(), _toFileData(to).c_str()) == 0)
839
		return true;
840
	return false;
841
}
842
 
52 cycrow 843
bool CFileIO::remove()
844
{
845
	if ( this->isOpened() ) this->close();
846
	if ( !this->exists() ) return false;
197 cycrow 847
	if ( CFileIO::Remove(_sFilename)) return true;
1 cycrow 848
	return false;
849
}
850
 
197 cycrow 851
bool CFileIO::writeFileUTF(std::vector<Utils::String>* lines)
121 cycrow 852
{
160 cycrow 853
	if (!lines || _sFilename.empty())
121 cycrow 854
		return false;
855
 
856
	// we need to create the directory
160 cycrow 857
	if (!_sDirIO.exists())
121 cycrow 858
	{
160 cycrow 859
		if (!_sDirIO.create())
121 cycrow 860
			return false;
861
	}
862
 
863
#ifdef _WIN32
864
	TCHAR buf[5000];
197 cycrow 865
	FILE* id = _wfopen(_sFilename.c_str(), L"wt+,ccs=UTF-8");
121 cycrow 866
	if (!id)
867
		return false;
868
 
869
	// write the rest
197 cycrow 870
	for (auto itr = lines->begin(); itr != lines->end(); itr++)
121 cycrow 871
	{
872
		Utils::String l = (*itr);
873
		if (l.isin('\n'))
874
		{
875
			int max;
197 cycrow 876
			Utils::String* strs = l.tokenise("\n", &max);
121 cycrow 877
			if (strs && max)
878
			{
879
				for (int i = 0; i < max; i++)
880
				{
881
					Utils::String line = strs[i];
882
					line += "\n";
883
					int size = wsprintf(buf, L"%hs", line.c_str());
884
					fwrite(buf, sizeof(TCHAR), wcslen(buf), id);
885
				}
886
 
887
				CLEANSPLIT(strs, max);
888
			}
889
		}
890
		else
891
		{
892
			l += "\n";
893
			int size = wsprintf(buf, L"%hs", l.c_str());
894
			fwrite(buf, sizeof(TCHAR), wcslen(buf), id);
895
		}
896
	}
897
 
898
	fclose(id);
899
 
900
	return true;
901
#else
902
	//TODO: write utf8 file writing function
903
	return false;
904
#endif
905
}
906
 
197 cycrow 907
bool CFileIO::writeFileUTF(std::vector<Utils::WString>* lines)
908
{
909
	if (!lines || _sFilename.empty())
910
		return false;
911
 
912
	// we need to create the directory
913
	if (!_sDirIO.exists())
914
	{
915
		if (!_sDirIO.create())
916
			return false;
917
	}
918
 
919
#ifdef _WIN32
920
	FILE* id = _wfopen(_sFilename.c_str(), L"wt+,ccs=UTF-8");
921
	if (!id)
922
		return false;
923
 
924
	// write the rest
925
	for (auto itr = lines->begin(); itr != lines->end(); itr++)
926
	{
927
		Utils::WString l = (*itr);
928
		if (l.contains('\n'))
929
		{
930
			std::vector<Utils::WString> strs;
931
			if(l.tokenise(L"\n", strs) && !strs.empty())
932
			{
933
				for(auto itr = strs.begin(); itr != strs.end(); itr++)
934
				{
935
					Utils::WString line = *itr;
936
					line += L"\n";
937
					fwrite(l.c_str(), sizeof(TCHAR), wcslen(l.c_str()), id);
938
				}
939
			}
940
		}
941
		else
942
		{
943
			l += L"\n";
944
			fwrite(l.c_str(), sizeof(TCHAR), wcslen(l.c_str()), id);
945
		}
946
	}
947
 
948
	fclose(id);
949
 
950
	return true;
951
#else
952
	//TODO: write utf8 file writing function
953
	return false;
954
#endif
955
}
956
 
121 cycrow 957
bool CFileIO::writeFile(std::vector<Utils::String> *lines)
958
{
160 cycrow 959
	if (!lines || _sFilename.empty())
121 cycrow 960
		return false;
961
 
962
	// we need to create the directory
160 cycrow 963
	if (!_sDirIO.exists())
121 cycrow 964
	{
160 cycrow 965
		if (!_sDirIO.create())
121 cycrow 966
			return false;
967
	}
968
 
969
 
160 cycrow 970
	std::ofstream out(_sFilename.c_str());
121 cycrow 971
	if (!out)
972
		return false;
973
 
974
	for (auto itr = lines->begin(); itr != lines->end(); itr++)
975
		out << (*itr).c_str() << std::endl;
976
 
977
	out.close();
978
 
979
	return true;
980
}
981
 
197 cycrow 982
bool CFileIO::writeFile(const std::vector<Utils::WString> &lines) const
983
{
984
	if (lines.empty() || _sFilename.empty())
985
		return false;
986
 
987
	// we need to create the directory
988
	if (!_sDirIO.exists())
989
	{
990
		if (!_sDirIO.create())
991
			return false;
992
	}
993
 
994
 
995
	std::wofstream out(_sFilename.c_str());
996
	if (!out)
997
		return false;
998
 
999
	for (auto itr = lines.begin(); itr != lines.end(); itr++)
1000
		out << (*itr).c_str() << std::endl;
1001
 
1002
	out.close();
1003
 
1004
	return true;
1005
}
1006
 
1007
 
196 cycrow 1008
bool CFileIO::writeFile(Utils::WStringList* lines)
121 cycrow 1009
{
160 cycrow 1010
	if (!lines || _sFilename.empty())
121 cycrow 1011
		return false;
1012
 
1013
	// we need to create the directory
160 cycrow 1014
	if (!_sDirIO.exists())
121 cycrow 1015
	{
160 cycrow 1016
		if (!_sDirIO.create())
121 cycrow 1017
			return false;
1018
	}
1019
 
197 cycrow 1020
	std::wofstream out(_sFilename.c_str());
121 cycrow 1021
	if (!out)
1022
		return false;
1023
 
196 cycrow 1024
	for (auto itr = lines->begin(); itr != lines->end(); itr++)
1025
		out << (*itr)->str.c_str() << std::endl;
1026
 
1027
	out.close();
1028
 
1029
	return true;
1030
}
1031
bool CFileIO::writeFile(Utils::CStringList* lines)
1032
{
1033
	if (!lines || _sFilename.empty())
1034
		return false;
1035
 
1036
	// we need to create the directory
1037
	if (!_sDirIO.exists())
1038
	{
1039
		if (!_sDirIO.create())
1040
			return false;
1041
	}
1042
 
1043
	std::ofstream out(_sFilename.c_str());
1044
	if (!out)
1045
		return false;
1046
 
121 cycrow 1047
	for(auto itr = lines->begin(); itr != lines->end(); itr++)
1048
		out << (*itr)->str.c_str() << std::endl;
1049
 
1050
	out.close();
1051
 
1052
	return true;
1053
}
1054
 
196 cycrow 1055
bool CFileIO::Rename(const Utils::WString &toFile)
197 cycrow 1056
{	
1057
	return CFileIO::Rename(_sFilename, toFile);
1 cycrow 1058
}
1059
 
196 cycrow 1060
Utils::WString CFileIO::getWindowsFilename() const
1 cycrow 1061
{
196 cycrow 1062
	return _sFilename.findReplace(L"/", L"\\");
1 cycrow 1063
}
1064
 
160 cycrow 1065
void CFileIO::setCreationTime(time_t time)
1 cycrow 1066
{
1067
#ifdef _WIN32
1068
	// Note that LONGLONG is a 64-bit value
1069
    LONGLONG ll;
1070
 
1071
	FILETIME ft;
1072
    ll = Int32x32To64(time, 10000000) + 116444736000000000;
1073
    ft.dwLowDateTime = (DWORD)ll;
1074
    ft.dwHighDateTime = ll >> 32;
1075
 
196 cycrow 1076
	Utils::WString windowsFilename = getWindowsFilename();
160 cycrow 1077
 
196 cycrow 1078
	HANDLE filename = CreateFile(windowsFilename.c_str(), FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1 cycrow 1079
	// Set the file time on the file
1080
	SetFileTime(filename,(LPFILETIME) NULL,(LPFILETIME) NULL,&ft);
1081
	// Close our handle.
1082
	CloseHandle(filename);
52 cycrow 1083
 
1 cycrow 1084
#endif
1085
}
1086
 
160 cycrow 1087
time_t CFileIO::creationTime() const
1 cycrow 1088
{
52 cycrow 1089
	return modifiedTime();
1090
}
1091
 
160 cycrow 1092
time_t CFileIO::modifiedTime() const
52 cycrow 1093
{
1 cycrow 1094
#ifdef _WIN32
196 cycrow 1095
	Utils::WString windowsFilename = getWindowsFilename();
52 cycrow 1096
 
1 cycrow 1097
	WIN32_FILE_ATTRIBUTE_DATA wfad;
196 cycrow 1098
	GetFileAttributesEx(windowsFilename.c_str(), GetFileExInfoStandard, &wfad);
1 cycrow 1099
 
1100
	LARGE_INTEGER date, adjust;
52 cycrow 1101
	date.HighPart = wfad.ftLastWriteTime.dwHighDateTime;
1102
	date.LowPart = wfad.ftLastWriteTime.dwLowDateTime;
1 cycrow 1103
 
1104
	// 100-nanoseconds = milliseconds * 10000
1105
	adjust.QuadPart = 11644473600000 * 10000;
1106
 
1107
	// removes the diff between 1970 and 1601
1108
	date.QuadPart -= adjust.QuadPart;
1109
 
1110
	// converts back from 100-nanoseconds to seconds
1111
	return (time_t)(date.QuadPart / 10000000);
1112
#else
1113
	struct stat fileStat;
1114
	if ( !stat(GetWindowsFilename().c_str(), &fileStat) )
1115
		return (time_t)fileStat.st_atime;
1116
#endif
1117
	return 0;
1118
}
58 cycrow 1119
 
1120
size_t CFileIO::position()
1121
{
121 cycrow 1122
	return static_cast<size_t>(m_fId.tellg());
58 cycrow 1123
}
1124
 
1 cycrow 1125
/**
1126
 * Copys the contents of a file to another
1127
 *
1128
 * Reads and writes the files in block
1129
 */
196 cycrow 1130
bool CFileIO::copy(const Utils::WString &toFile, bool keepTime)
1 cycrow 1131
{
160 cycrow 1132
	time_t time = creationTime();
1 cycrow 1133
 
52 cycrow 1134
	CFileIO File(toFile);
1135
	if ( File.write(*this, m_lSize) ) {
86 cycrow 1136
		this->close();
1137
		File.close();
160 cycrow 1138
		if ( keepTime )	File.setCreationTime(time);
52 cycrow 1139
		return true;
1 cycrow 1140
	}
52 cycrow 1141
/*
1142
	std::fstream f(GetWindowsFilename().c_str(), std::fstream::in | std::fstream::binary);
1143
	f << std::noskipws;
1144
	std::istream_iterator<unsigned char> begin(f);
1145
	std::istream_iterator<unsigned char> end;
1146
 
1147
	std::fstream f2(toFile.c_str(), std::fstream::out | std::fstream::trunc | std::fstream::binary);
1148
	std::ostream_iterator<char> begin2(f2);
1149
 
1150
	std::copy(begin, end, begin2);
1151
	return f2.good();
1152
*/
1153
	return false;
1154
}
1 cycrow 1155
 
52 cycrow 1156
size_t CFileIO::fileSize() const
1157
{
1158
	return m_lSize;
1 cycrow 1159
}
160 cycrow 1160
 
1161
 
1162
void CFileIO::_updateFilename()
1163
{
196 cycrow 1164
	if (_sFilename.empty()) _sExt = Utils::WString::Null();
1165
	_sExt = _sFilename.token(L".", -1);
160 cycrow 1166
}
196 cycrow 1167
 
197 cycrow 1168
std::string CFileIO::_fileData() const
196 cycrow 1169
{
197 cycrow 1170
	return _toFileData(_sFilename);
196 cycrow 1171
}
197 cycrow 1172
std::string CFileIO::_toFileData(const Utils::WString &str)
196 cycrow 1173
{
211 cycrow 1174
#pragma warning(disable:4244)
197 cycrow 1175
	return std::string(str.begin(), str.end());
211 cycrow 1176
#pragma warning(default:4244)
196 cycrow 1177
}