Subversion Repositories spk

Rev

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