Subversion Repositories spk

Rev

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