Subversion Repositories spk

Rev

Details | Last modification | View Log | RSS feed

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