Subversion Repositories spk

Rev

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