Subversion Repositories spk

Rev

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