Subversion Repositories spk

Rev

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