Subversion Repositories spk

Rev

Rev 95 | Rev 118 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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