Subversion Repositories spk

Rev

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