Subversion Repositories spk

Rev

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