Subversion Repositories spk

Rev

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