Subversion Repositories spk

Rev

Rev 222 | Rev 227 | 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
 
170 cycrow 435
size_t CFileIO::readLines(std::vector<Utils::String>& to) const
166 cycrow 436
{
437
	if (_sFilename.empty()) return 0;
83 cycrow 438
 
166 cycrow 439
	Utils::String line;
440
	std::ifstream infile(_sFilename.c_str(), std::ios_base::in);
441
	while (getline(infile, line, '\n')) {
442
		to.push_back(Utils::String(line).removeChar((char)0));
443
	}
1 cycrow 444
 
166 cycrow 445
	infile.close();
446
 
447
	return to.size();
448
}
449
 
197 cycrow 450
size_t CFileIO::readLines(std::vector<Utils::WString>& to) const
451
{
452
	if (_sFilename.empty()) return 0;
453
 
454
	std::wstring line;
455
	std::wifstream infile(_sFilename.c_str(), std::ios_base::in);
456
	while (getline(infile, line, L'\n')) {
457
		to.push_back(Utils::WString(line).remove((char)0));
458
	}
459
 
460
	infile.close();
461
 
462
	return to.size();
463
}
464
 
211 cycrow 465
size_t CFileIO::readLines(Utils::WStringList& to) const
111 cycrow 466
{
211 cycrow 467
	if (_sFilename.empty()) return 0;
111 cycrow 468
 
211 cycrow 469
	std::wstring line;
470
	std::wifstream infile(_sFilename.c_str(), std::ios_base::in);
471
	while (getline(infile, line, L'\n')) {
472
		to.pushBack(Utils::WString(line).remove((char)0));
111 cycrow 473
	}
474
 
475
	infile.close();
476
 
211 cycrow 477
	return to.size();
111 cycrow 478
}
479
 
52 cycrow 480
bool CFileIO::put(const unsigned char c)
1 cycrow 481
{
52 cycrow 482
	if ( !this->isOpened() ) return false;
483
 
484
	m_fId.put(c);
485
	return !m_fId.bad();
1 cycrow 486
}
487
 
123 cycrow 488
bool CFileIO::writeSize(size_t iSize)
1 cycrow 489
{
52 cycrow 490
	if ( !this->isOpened() ) return false;
491
	if ( !this->put(static_cast<unsigned char>(iSize >> 24)) ) return false;
492
	if ( !this->put(static_cast<unsigned char>(iSize >> 16)) ) return false;
493
	if ( !this->put(static_cast<unsigned char>(iSize >> 8)) ) return false;
494
	if ( !this->put(static_cast<unsigned char>(iSize)) ) return false;
495
	m_lSize += 4;
496
	return true;
1 cycrow 497
}
498
 
52 cycrow 499
bool CFileIO::write(CFileIO &file, size_t iSize)
1 cycrow 500
{
52 cycrow 501
	if ( !this->isOpened() ) startWrite();
502
	if ( !this->isOpened() ) return false;
503
 
504
	int iMaxSize = 1000000;
505
 
506
	unsigned char *data;
507
	try {
508
		data = new unsigned char[iMaxSize + 1];
1 cycrow 509
	}
52 cycrow 510
	catch (std::exception &e) {
511
		CLog::logf(CLog::Log_IO, 2, "ERROR: CFileIO::write(CFileIO, size_t) unable to malloc data, %d (%s)", iMaxSize + 1, e.what());
512
		return false;
513
	}
1 cycrow 514
 
52 cycrow 515
	int iSizeLeft = iSize;
516
	bool bSuccess = true;
517
	while ( iSizeLeft > 0 ) {
518
		int iDoSize = iMaxSize;
519
		if ( iDoSize > iSizeLeft ) iDoSize = iSizeLeft;
1 cycrow 520
 
52 cycrow 521
		if ( !file.read(data, iDoSize) ) bSuccess = false;
522
		if ( bSuccess && !this->write(data, iDoSize) ) bSuccess = false;
523
		if ( !bSuccess ) break;
524
		iSizeLeft -= iDoSize;
525
	}
1 cycrow 526
 
52 cycrow 527
	delete data;
1 cycrow 528
 
52 cycrow 529
	return bSuccess;
1 cycrow 530
}
531
 
123 cycrow 532
bool CFileIO::write(const char *buf, size_t iSize)
52 cycrow 533
{
534
	if ( !this->isOpened() ) startWrite();
535
	if ( !this->isOpened() ) return false;
536
	try {
197 cycrow 537
		m_fId.write((char*)buf, iSize);
52 cycrow 538
	}
539
	catch (std::exception &e) {
160 cycrow 540
		CLog::logf(CLog::Log_IO, 2, "CFileIO::write() unable to write to file: %s (%s)", _sFilename.c_str(), e.what());
52 cycrow 541
		return false;
542
	}
543
	m_lSize += iSize;
544
	return !m_fId.bad();
545
}
123 cycrow 546
bool CFileIO::write(const unsigned char *buf, size_t iSize)
52 cycrow 547
{
548
	return this->write((char *)buf, iSize);
549
}
550
 
551
bool CFileIO::write(const unsigned char *buf, ...)
552
{
553
	va_list args;
554
	va_start(args, buf);
555
	bool ret = this->_write((char *)buf, args);
556
	va_end(args);
557
	return ret;
558
}
197 cycrow 559
bool CFileIO::_write(const char* buf, va_list args)
52 cycrow 560
{
197 cycrow 561
	if (!this->isOpened()) return false;
52 cycrow 562
 
563
	char buffer[10000];
564
 
197 cycrow 565
	vsprintf(buffer, buf, args);
52 cycrow 566
	try {
567
		int iLen = strlen(buffer);
197 cycrow 568
		m_fId.write((char*)buffer, iLen);
52 cycrow 569
		m_lSize += iLen;
570
	}
197 cycrow 571
	catch (std::exception& e) {
160 cycrow 572
		CLog::logf(CLog::Log_IO, 2, "CFileIO::write() unable to write to file: %s (%s)", _sFilename.c_str(), e.what());
52 cycrow 573
		return false;
574
	}
575
	return !m_fId.bad();
576
}
197 cycrow 577
bool CFileIO::_write(const wchar_t* buf, va_list args)
578
{
579
	if (!this->isOpened()) return false;
52 cycrow 580
 
197 cycrow 581
	wchar_t buffer[10000];
582
 
583
#ifdef _WIN32
584
	vswprintf_s(buffer, 10000, buf, args);
585
#else
586
	vswprintf(buffer, buf, args);
587
#endif
588
	try {
589
		size_t iLen = wcslen(buffer);
590
		m_fId.write((char*)buffer, iLen);
591
		m_lSize += iLen;
592
	}
593
	catch (std::exception& e) {
594
		CLog::logf(CLog::Log_IO, 2, "CFileIO::write() unable to write to file: %ls (%s)", _sFilename.c_str(), e.what());
595
		return false;
596
	}
597
	return !m_fId.bad();
598
}
599
 
52 cycrow 600
bool CFileIO::write(const char *buf, ...)
601
{
602
	va_list args;
603
	va_start(args, buf);
604
	bool ret = this->_write((char *)buf, args);
605
	va_end(args);
606
	return ret;
607
}
608
 
609
void CFileIO::_seek(int iPos, int iFrom)
610
{
611
	if ( !this->isOpened() ) {
612
		if ( !this->startRead() ) return;
613
	}
614
	if ( m_bSeekP ) m_fId.seekp(iPos, iFrom);
615
	else m_fId.seekg(iPos, iFrom);
616
}
617
 
123 cycrow 618
void CFileIO::seek(size_t iPos)
52 cycrow 619
{
620
	_seek(iPos, std::ios::cur);
621
}
622
 
123 cycrow 623
void CFileIO::seekEnd(size_t iPos)
52 cycrow 624
{
53 cycrow 625
	_seek(iPos, std::ios::end);
52 cycrow 626
}
627
 
123 cycrow 628
void CFileIO::seekStart(size_t iPos)
52 cycrow 629
{
630
	_seek(iPos, std::ios::beg);
631
}
632
 
633
std::fstream &CFileIO::stream()
634
{
635
	return m_fId;
636
}
637
 
638
bool CFileIO::isOpened() const
639
{
640
	if ( m_fId.is_open() )
641
		return true;
642
	return false;
643
}
644
 
645
void CFileIO::close()
646
{
647
	if ( this->isOpened() ) m_fId.close();
84 cycrow 648
	this->_readFileSize();
52 cycrow 649
}
650
 
56 cycrow 651
int CFileIO::readSize()
1 cycrow 652
{
56 cycrow 653
	unsigned char size[4];
654
	if ( this->read(size, 4) ) return (size[0] << 24) + (size[1] << 16) + (size[2] << 8) + size[3];
655
	return 0;
656
}
657
 
658
bool CFileIO::atEnd() const
659
{
52 cycrow 660
	if ( !this->isOpened() ) return true;
51 cycrow 661
	if ( m_fId.eof() )		 return true;
1 cycrow 662
	return false;
663
}
664
 
82 cycrow 665
bool CFileIO::appendFile ( const Utils::String &filename )
666
{
667
	std::fstream fromFile(filename, _in());
668
	if ( !fromFile.is_open() ) return false;
669
 
160 cycrow 670
	std::fstream toFile(_sFilename, _append());
82 cycrow 671
	if ( !toFile.is_open() ) {
672
		fromFile.close();
673
		return false;
674
	}
675
 
676
	// move to the end of the file
677
	toFile.seekg(0, std::ios::end);
678
 
679
	// get size of file
680
	fromFile.seekg(0, std::ios::end);
121 cycrow 681
	size_t size = static_cast<size_t>(fromFile.tellg());
82 cycrow 682
	fromFile.seekg(0, std::ios::beg);
683
 
684
	char data[500000];
685
	while ( size > 0 )
686
	{
687
		size_t read = 500000;
688
		if ( read > size )
689
			read = size;
690
 
691
		size -= read;
692
 
693
		fromFile.read(data, read);
694
		toFile.write(data, read);
695
	}
696
 
697
	fromFile.close();
698
	toFile.close();
699
	return true;
700
}
701
 
1 cycrow 702
 
703
bool CFileIO::AppendData ( const char *d, size_t size )
704
{
160 cycrow 705
	std::ofstream File(_sFilename, _append());
51 cycrow 706
	if ( !File.is_open() ) return false;
1 cycrow 707
 
708
	// move to the end of the file
58 cycrow 709
	//File.seekg(0, std::ios::end);
1 cycrow 710
 
711
	char *pos = (char *)d;
51 cycrow 712
	while ( size > 0 ) {
1 cycrow 713
		size_t read = 500000;
51 cycrow 714
		if ( read > size ) read = size;
1 cycrow 715
 
716
		size -= read;
717
 
51 cycrow 718
		try {
719
			File.write(pos, read);
720
		} 
721
		catch(std::exception &e) {
160 cycrow 722
			CLog::logf(CLog::Log_IO, 2, "CFileIO::AppendData() unable to write data to file: %s (%s)", _sFilename.c_str(), e.what());
51 cycrow 723
			File.close();
724
			return false;
725
		}
1 cycrow 726
		pos += read;
727
	}
728
 
51 cycrow 729
	File.close();
1 cycrow 730
	return true;
731
}
732
 
733
bool CFileIO::AppendDataToPos ( const char *d, size_t size, size_t start )
734
{
52 cycrow 735
	if ( start > m_lSize ) return false;
736
	if ( m_lSize <= 0 ) {
737
		if ( !this->startWrite() ) return false;
1 cycrow 738
	}
52 cycrow 739
	else if ( start == m_lSize ) {
740
		if ( !this->startAppend() ) return false;
42 cycrow 741
	}
742
	else {
52 cycrow 743
		if ( !this->startModify() ) return false;
744
		this->seekStart(start);
42 cycrow 745
	}
1 cycrow 746
 
52 cycrow 747
	return this->write(d, size);
748
}
1 cycrow 749
 
197 cycrow 750
Utils::String CFileIO::readEndOfLineStr()
52 cycrow 751
{
197 cycrow 752
	if (!this->isOpened()) {
753
		if (!startRead())	return "";
1 cycrow 754
	}
755
 
197 cycrow 756
	std::string str;
52 cycrow 757
	std::getline(m_fId, str, '\n');
758
	return str;
1 cycrow 759
}
197 cycrow 760
Utils::WString CFileIO::readEndOfLine()
761
{
762
	if (!this->isOpened()) {
763
		if (!startRead())	return L"";
764
	}
1 cycrow 765
 
197 cycrow 766
	std::string str;
767
	std::getline(m_fId, str, '\n');
768
	return str;
769
}
770
 
196 cycrow 771
Utils::WString CFileIO::baseName() const
1 cycrow 772
{
197 cycrow 773
	return _sFile.tokens(L".", 1, -2);
1 cycrow 774
}
775
 
196 cycrow 776
const Utils::WString& CFileIO::fullFilename() const { return _sFilename; }
777
const Utils::WString& CFileIO::filename() const { return _sFile; }
778
 
779
Utils::WString CFileIO::extension () const
58 cycrow 780
{
196 cycrow 781
	if ( _sFilename.empty() ) return Utils::WString::Null();
782
	return _sFilename.token(L".", -1);
58 cycrow 783
}
784
 
196 cycrow 785
Utils::WString CFileIO::changeFileExtension(const Utils::WString &ext) const
124 cycrow 786
{
160 cycrow 787
	if ( _sFilename.empty() )
196 cycrow 788
		return Utils::WString::Null();
51 cycrow 789
 
196 cycrow 790
	return _sFilename.tokens(L".", 1, -2) + L"." + ext;
1 cycrow 791
}
792
 
197 cycrow 793
bool CFileIO::Remove(const Utils::WString& rem)
1 cycrow 794
{
197 cycrow 795
#ifdef _WIN32
796
	return DeleteFile(rem.c_str());
797
#else
52 cycrow 798
	//if ( !Exists() ) return false;
196 cycrow 799
	return (std::remove(_toFileData(rem)) == 0) ? true : false;
197 cycrow 800
#endif
52 cycrow 801
}
1 cycrow 802
 
197 cycrow 803
bool CFileIO::Rename(const Utils::WString& from, const Utils::WString &to) 
804
{
805
	if (std::rename(_toFileData(from).c_str(), _toFileData(to).c_str()) == 0)
806
		return true;
807
	return false;
808
}
809
 
52 cycrow 810
bool CFileIO::remove()
811
{
812
	if ( this->isOpened() ) this->close();
813
	if ( !this->exists() ) return false;
197 cycrow 814
	if ( CFileIO::Remove(_sFilename)) return true;
1 cycrow 815
	return false;
816
}
817
 
197 cycrow 818
bool CFileIO::writeFileUTF(std::vector<Utils::WString>* lines)
819
{
820
	if (!lines || _sFilename.empty())
821
		return false;
822
 
823
	// we need to create the directory
824
	if (!_sDirIO.exists())
825
	{
826
		if (!_sDirIO.create())
827
			return false;
828
	}
829
 
830
#ifdef _WIN32
831
	FILE* id = _wfopen(_sFilename.c_str(), L"wt+,ccs=UTF-8");
832
	if (!id)
833
		return false;
834
 
835
	// write the rest
836
	for (auto itr = lines->begin(); itr != lines->end(); itr++)
837
	{
838
		Utils::WString l = (*itr);
839
		if (l.contains('\n'))
840
		{
841
			std::vector<Utils::WString> strs;
842
			if(l.tokenise(L"\n", strs) && !strs.empty())
843
			{
844
				for(auto itr = strs.begin(); itr != strs.end(); itr++)
845
				{
846
					Utils::WString line = *itr;
847
					line += L"\n";
848
					fwrite(l.c_str(), sizeof(TCHAR), wcslen(l.c_str()), id);
849
				}
850
			}
851
		}
852
		else
853
		{
854
			l += L"\n";
855
			fwrite(l.c_str(), sizeof(TCHAR), wcslen(l.c_str()), id);
856
		}
857
	}
858
 
859
	fclose(id);
860
 
861
	return true;
862
#else
863
	//TODO: write utf8 file writing function
864
	return false;
865
#endif
866
}
867
 
121 cycrow 868
bool CFileIO::writeFile(std::vector<Utils::String> *lines)
869
{
160 cycrow 870
	if (!lines || _sFilename.empty())
121 cycrow 871
		return false;
872
 
873
	// we need to create the directory
160 cycrow 874
	if (!_sDirIO.exists())
121 cycrow 875
	{
160 cycrow 876
		if (!_sDirIO.create())
121 cycrow 877
			return false;
878
	}
879
 
880
 
160 cycrow 881
	std::ofstream out(_sFilename.c_str());
121 cycrow 882
	if (!out)
883
		return false;
884
 
885
	for (auto itr = lines->begin(); itr != lines->end(); itr++)
886
		out << (*itr).c_str() << std::endl;
887
 
888
	out.close();
889
 
890
	return true;
891
}
892
 
197 cycrow 893
bool CFileIO::writeFile(const std::vector<Utils::WString> &lines) const
894
{
895
	if (lines.empty() || _sFilename.empty())
896
		return false;
897
 
898
	// we need to create the directory
899
	if (!_sDirIO.exists())
900
	{
901
		if (!_sDirIO.create())
902
			return false;
903
	}
904
 
905
 
906
	std::wofstream out(_sFilename.c_str());
907
	if (!out)
908
		return false;
909
 
910
	for (auto itr = lines.begin(); itr != lines.end(); itr++)
911
		out << (*itr).c_str() << std::endl;
912
 
913
	out.close();
914
 
915
	return true;
916
}
917
 
918
 
196 cycrow 919
bool CFileIO::writeFile(Utils::WStringList* lines)
121 cycrow 920
{
160 cycrow 921
	if (!lines || _sFilename.empty())
121 cycrow 922
		return false;
923
 
924
	// we need to create the directory
160 cycrow 925
	if (!_sDirIO.exists())
121 cycrow 926
	{
160 cycrow 927
		if (!_sDirIO.create())
121 cycrow 928
			return false;
929
	}
930
 
197 cycrow 931
	std::wofstream out(_sFilename.c_str());
121 cycrow 932
	if (!out)
933
		return false;
934
 
196 cycrow 935
	for (auto itr = lines->begin(); itr != lines->end(); itr++)
936
		out << (*itr)->str.c_str() << std::endl;
937
 
938
	out.close();
939
 
940
	return true;
941
}
942
bool CFileIO::Rename(const Utils::WString &toFile)
197 cycrow 943
{	
944
	return CFileIO::Rename(_sFilename, toFile);
1 cycrow 945
}
946
 
196 cycrow 947
Utils::WString CFileIO::getWindowsFilename() const
1 cycrow 948
{
196 cycrow 949
	return _sFilename.findReplace(L"/", L"\\");
1 cycrow 950
}
951
 
160 cycrow 952
void CFileIO::setCreationTime(time_t time)
1 cycrow 953
{
954
#ifdef _WIN32
955
	// Note that LONGLONG is a 64-bit value
956
    LONGLONG ll;
957
 
958
	FILETIME ft;
959
    ll = Int32x32To64(time, 10000000) + 116444736000000000;
960
    ft.dwLowDateTime = (DWORD)ll;
961
    ft.dwHighDateTime = ll >> 32;
962
 
196 cycrow 963
	Utils::WString windowsFilename = getWindowsFilename();
160 cycrow 964
 
196 cycrow 965
	HANDLE filename = CreateFile(windowsFilename.c_str(), FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1 cycrow 966
	// Set the file time on the file
967
	SetFileTime(filename,(LPFILETIME) NULL,(LPFILETIME) NULL,&ft);
968
	// Close our handle.
969
	CloseHandle(filename);
52 cycrow 970
 
1 cycrow 971
#endif
972
}
973
 
160 cycrow 974
time_t CFileIO::creationTime() const
1 cycrow 975
{
52 cycrow 976
	return modifiedTime();
977
}
978
 
160 cycrow 979
time_t CFileIO::modifiedTime() const
52 cycrow 980
{
1 cycrow 981
#ifdef _WIN32
196 cycrow 982
	Utils::WString windowsFilename = getWindowsFilename();
52 cycrow 983
 
1 cycrow 984
	WIN32_FILE_ATTRIBUTE_DATA wfad;
196 cycrow 985
	GetFileAttributesEx(windowsFilename.c_str(), GetFileExInfoStandard, &wfad);
1 cycrow 986
 
987
	LARGE_INTEGER date, adjust;
52 cycrow 988
	date.HighPart = wfad.ftLastWriteTime.dwHighDateTime;
989
	date.LowPart = wfad.ftLastWriteTime.dwLowDateTime;
1 cycrow 990
 
991
	// 100-nanoseconds = milliseconds * 10000
992
	adjust.QuadPart = 11644473600000 * 10000;
993
 
994
	// removes the diff between 1970 and 1601
995
	date.QuadPart -= adjust.QuadPart;
996
 
997
	// converts back from 100-nanoseconds to seconds
998
	return (time_t)(date.QuadPart / 10000000);
999
#else
1000
	struct stat fileStat;
1001
	if ( !stat(GetWindowsFilename().c_str(), &fileStat) )
1002
		return (time_t)fileStat.st_atime;
1003
#endif
1004
	return 0;
1005
}
58 cycrow 1006
 
1007
size_t CFileIO::position()
1008
{
121 cycrow 1009
	return static_cast<size_t>(m_fId.tellg());
58 cycrow 1010
}
1011
 
1 cycrow 1012
/**
1013
 * Copys the contents of a file to another
1014
 *
1015
 * Reads and writes the files in block
1016
 */
196 cycrow 1017
bool CFileIO::copy(const Utils::WString &toFile, bool keepTime)
1 cycrow 1018
{
160 cycrow 1019
	time_t time = creationTime();
1 cycrow 1020
 
52 cycrow 1021
	CFileIO File(toFile);
1022
	if ( File.write(*this, m_lSize) ) {
86 cycrow 1023
		this->close();
1024
		File.close();
160 cycrow 1025
		if ( keepTime )	File.setCreationTime(time);
52 cycrow 1026
		return true;
1 cycrow 1027
	}
52 cycrow 1028
/*
1029
	std::fstream f(GetWindowsFilename().c_str(), std::fstream::in | std::fstream::binary);
1030
	f << std::noskipws;
1031
	std::istream_iterator<unsigned char> begin(f);
1032
	std::istream_iterator<unsigned char> end;
1033
 
1034
	std::fstream f2(toFile.c_str(), std::fstream::out | std::fstream::trunc | std::fstream::binary);
1035
	std::ostream_iterator<char> begin2(f2);
1036
 
1037
	std::copy(begin, end, begin2);
1038
	return f2.good();
1039
*/
1040
	return false;
1041
}
1 cycrow 1042
 
52 cycrow 1043
size_t CFileIO::fileSize() const
1044
{
1045
	return m_lSize;
1 cycrow 1046
}
160 cycrow 1047
 
1048
 
1049
void CFileIO::_updateFilename()
1050
{
196 cycrow 1051
	if (_sFilename.empty()) _sExt = Utils::WString::Null();
1052
	_sExt = _sFilename.token(L".", -1);
160 cycrow 1053
}
196 cycrow 1054
 
197 cycrow 1055
std::string CFileIO::_fileData() const
196 cycrow 1056
{
197 cycrow 1057
	return _toFileData(_sFilename);
196 cycrow 1058
}
197 cycrow 1059
std::string CFileIO::_toFileData(const Utils::WString &str)
196 cycrow 1060
{
211 cycrow 1061
#pragma warning(disable:4244)
197 cycrow 1062
	return std::string(str.begin(), str.end());
211 cycrow 1063
#pragma warning(default:4244)
196 cycrow 1064
}