Subversion Repositories spk

Rev

Rev 42 | Rev 52 | 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
 
51 cycrow 13
CFileIO::CFileIO () : m_bOpened(false), m_lSize(0), m_bBinary(true)
1 cycrow 14
{
15
}
16
 
51 cycrow 17
CFileIO::CFileIO(CyString filename) : m_bOpened(false), m_lSize(0), m_bBinary(true)
1 cycrow 18
{
19
	Open ( filename, true );
20
}
21
 
51 cycrow 22
CFileIO::CFileIO(C_File *file) : m_bOpened(false), m_lSize(0), m_bBinary(true)
1 cycrow 23
{
24
	Open ( file->GetFilePointer(), true );
25
}
26
 
27
CFileIO::~CFileIO()
28
{
51 cycrow 29
	if ( m_bOpened ) m_fId.close();
1 cycrow 30
}
31
 
32
bool CFileIO::Open ( CyString filename, bool binary )
33
{
34
	m_bBinary = binary;
51 cycrow 35
	m_sFilename = filename.ToString();
36
	m_sFilename = m_sFilename.findReplace("\\", "/");
37
	m_sFilename = m_sFilename.findReplace("//", "/");
1 cycrow 38
 
51 cycrow 39
	if ( m_sFilename.isin('/') ) {
40
		m_sDirIO.SetDir(m_sFilename.tokens("/", 1, -2));
41
		m_sFile = m_sFilename.token("/", -1);
1 cycrow 42
	}
43
	else
51 cycrow 44
		m_sFile = filename.ToString();
1 cycrow 45
 
51 cycrow 46
	this->_readFileSize();
1 cycrow 47
	return true;
48
}
49
bool CFileIO::WritePartFile ( size_t *offsets, size_t numOffset )
50
{
51 cycrow 51
	if ( NoFile() )	return false;
1 cycrow 52
 
51 cycrow 53
	std::fstream File(m_sFilename, _in());
54
	if ( !File.is_open() ) return false;
1 cycrow 55
 
56
	// first find file size
51 cycrow 57
	File.seekg(0, std::ios::end);
58
	size_t fullsize = File.tellg(), size = fullsize;
59
	File.seekg(0, std::ios::beg);
1 cycrow 60
 
51 cycrow 61
	std::fstream writeFile("temp.tmp", _out());
62
	if ( !File.is_open() ) {
63
		File.close();
1 cycrow 64
		return false;
65
	}
66
 
67
	size_t off = 0;
68
	size_t startPos = 0;
69
	size_t remainingSize = fullsize;
51 cycrow 70
 
71
	while ( off < numOffset ) {
72
		startPos = File.tellg();
1 cycrow 73
		size_t offset = offsets[off++];
74
		size_t size = offset - startPos;
51 cycrow 75
		try {
76
			char *data = new char[size];
77
			File.read(data, size);
78
			writeFile.write(data, size);
79
			delete data;
80
		}
81
		catch(std::exception &e) {
82
			CLog::logf(CLog::Log_IO, 2, "CFileIO::WritePartFilea() unable to read data from file: %s (%s)", m_sFilename.c_str(), e.what());
83
			return false;
84
		}
85
 
1 cycrow 86
		size_t datasize = offsets[off++];
51 cycrow 87
		File.seekg(datasize, std::ios::beg);
1 cycrow 88
		remainingSize = fullsize - offset - datasize;
89
	}
90
 
51 cycrow 91
	if ( remainingSize ) {
1 cycrow 92
		char data[1000000];
93
		size_t amountLeft = 1000000;
94
		while ( remainingSize )
95
		{
51 cycrow 96
			if ( amountLeft > remainingSize ) amountLeft = remainingSize;
97
			try {
98
				File.read(data, amountLeft);
99
				writeFile.write(data, amountLeft);
100
			}
101
			catch(std::exception &e) {
102
				CLog::logf(CLog::Log_IO, 2, "CFileIO::WritePartFilea() unable to read data from file: %s (%s)", m_sFilename.c_str(), e.what());
103
				return false;
104
			}
1 cycrow 105
 
106
			remainingSize -= amountLeft;
107
			amountLeft = 1000000;
108
		}
109
	}
110
 
51 cycrow 111
	File.close();
112
	writeFile.close();
1 cycrow 113
 
114
	// now copy to original file
51 cycrow 115
	std::remove(m_sFilename);
116
	std::rename("temp.tmp", m_sFilename);
1 cycrow 117
 
118
	return true;
119
}
120
 
121
 
122
void CFileIO::SetDir ( CyString dir )
123
{
51 cycrow 124
	if ( m_sFile.empty() )	m_sDirIO.SetDir(dir);
125
	else					Open(dir + "/" + m_sFile, m_bBinary);
1 cycrow 126
}
127
 
51 cycrow 128
void CFileIO::_readFileSize ()
1 cycrow 129
{
51 cycrow 130
	m_lSize = 0;
131
 
132
	std::fstream file(m_sFilename, (m_bBinary) ? (std::ios::in | std::ios::binary) : (std::ios::in));
133
	if ( !file.is_open() ) return;
134
 
135
	file.seekg(0, std::ios::end);
136
	m_lSize = file.tellg();
137
	file.close();
1 cycrow 138
}
139
 
140
bool CFileIO::WipeFile()
141
{
51 cycrow 142
	if ( NoFile() )	return false;
143
	std::ofstream file;
144
	file.open(m_sFilename, std::ios::out | std::ios::trunc);
145
	bool bDone = file.is_open();
146
	file.close();
1 cycrow 147
 
51 cycrow 148
	return bDone;
1 cycrow 149
}
150
int CFileIO::TruncateFile ( size_t offset, size_t datasize )
151
{
152
	if ( NoFile() )
153
		return FILEERR_NOFILE;
154
 
155
	FILE *id = fopen ( m_sFilename.c_str(), (m_bBinary) ? "rb+" : "r+" );
156
	if ( !id )
157
		return FILEERR_NOOPEN;
158
 
159
	// first find file size
160
	fseek ( id, 0, SEEK_END );
161
	size_t fullsize = ftell ( id ), size = fullsize;
162
	fseek ( id, 0, SEEK_SET );
163
 
164
	if ( (offset + datasize) > fullsize )
165
		return FILEERR_TOSMALL;
166
//	char data[500000];
167
 
168
#ifdef _WIN32
169
	FILE *writeId = fopen ( "temp.tmp", (m_bBinary) ? "wb" : "w" );
170
	if ( !writeId )
171
	{
172
		fclose ( id );
173
		return FILEERR_NOWRITE;
174
	}
175
 
176
	char *data = new char[offset];
177
	fread ( data, sizeof(unsigned char), offset, id );
178
	fwrite ( data, sizeof(unsigned char), offset, writeId );
179
	delete data;
180
 
181
	// next fseek after and write
182
	fseek ( id, datasize, SEEK_CUR );
183
	size = fullsize - offset - datasize;
42 cycrow 184
	if ( size > 0 ) {
185
		data = new char[size];
186
		fread ( data, sizeof(unsigned char), size, id );
187
		fwrite ( data, sizeof(unsigned char), size, writeId );
188
		delete data;
189
	}
1 cycrow 190
 
191
	fclose ( writeId );
192
	fclose ( id );
193
 
194
	// now copy to original file
51 cycrow 195
	std::remove(m_sFilename.c_str());
196
	std::rename("temp.tmp", m_sFilename.c_str());
1 cycrow 197
 
198
#else
199
	// move to beginning of file data to remove
200
	fseek ( id, offset, SEEK_SET );
201
 
202
	size_t writepos = offset;
203
	size_t readpos = offset + datasize;
204
 
205
	size -= readpos;
206
 
207
	while ( size > 0 )
208
	{
209
		int read = 500000;
210
		if ( read > size )
211
			read = size;
212
 
213
		// read data
214
		fseek ( id, readpos, SEEK_SET );
215
		fread ( data, sizeof(unsigned char), read, id );
216
		size -= read;
217
		readpos += read;
218
 
219
		// now seek back and write
220
		fseek ( id, writepos, SEEK_SET );
221
		fwrite ( data, sizeof(unsigned char), read, id );
222
		writepos += read;
223
 
224
	}
225
 
226
	truncate ( m_sFilename.c_str(), fullsize - datasize );
227
	fclose ( id );
228
#endif
229
 
230
	return FILEERR_NONE;
231
}
232
 
51 cycrow 233
int CFileIO::_in()
234
{
235
	if ( m_bBinary ) return std::ios::in | std::ios::binary;
236
	return std::ios::in;
237
}
238
 
239
int CFileIO::_out()
240
{
241
	if ( m_bBinary ) return std::ios::out | std::ios::binary;
242
	return std::ios::out;
243
}
244
 
245
int CFileIO::_append()
246
{
247
	if ( m_bBinary ) return std::ios::out | std::ios::binary | std::ios::app;
248
	return std::ios::out | std::ios::app;
249
}
250
 
1 cycrow 251
char *CFileIO::ReadToData ( size_t *size )
252
{
253
	*size = 0;
254
 
51 cycrow 255
	if ( NoFile() ) return NULL;
256
	if ( !m_lSize )	this->_readFileSize();
257
	if ( !m_lSize ) return NULL;
1 cycrow 258
 
51 cycrow 259
	std::fstream file(m_sFilename, _in());
260
	if ( !file.is_open() ) return NULL;
1 cycrow 261
 
51 cycrow 262
	char *data;
263
	try {
264
		data = new char[m_lSize + 1];
265
	}
266
	catch (std::exception &e) {
267
		CLog::logf(CLog::Log_IO, 2, "CFileIO::ReadToData() unable to malloc storage, %d (%s)", m_lSize + 1, e.what());
268
		file.close();
1 cycrow 269
		return NULL;
51 cycrow 270
	}
1 cycrow 271
 
51 cycrow 272
	try {
273
		file.read((char *)data, m_lSize);
274
	}
275
	catch (std::exception &e) {
276
		CLog::logf(CLog::Log_IO, 2, "CFileIO::ReadToData() unable to read data from file (%s)", e.what());
277
		file.close();
1 cycrow 278
		return NULL;
279
	}
280
 
281
	*size = m_lSize;
51 cycrow 282
	file.close();
1 cycrow 283
 
284
	return data;
285
}
286
 
287
bool CFileIO::WriteData ( const char *data, size_t size )
288
{
289
	if ( NoFile() )
290
		return false;
291
 
51 cycrow 292
	std::fstream File(m_sFilename, _out());
293
	if ( !File.is_open() ) return false;
1 cycrow 294
 
51 cycrow 295
	bool ret = true;
296
	try {
297
		File.write(data, size);
298
	}
299
	catch (std::exception &e) {
300
		CLog::logf(CLog::Log_IO, 2, "CFileIO::ReadToData() unable to read data from file: %s (%s)", m_sFilename.c_str(), e.what());
301
		ret = false;
302
	}
1 cycrow 303
 
51 cycrow 304
	File.close();
1 cycrow 305
 
51 cycrow 306
	if ( ret ) this->_readFileSize();
307
	return ret;
1 cycrow 308
}
309
 
310
bool CFileIO::WriteString ( CyString data )
311
{
312
	return WriteData ( data.c_str(), data.Length() );
313
}
314
 
315
bool CFileIO::Exists ()
316
{
51 cycrow 317
	std::fstream File(m_sFilename, _in());
318
	bool bRet = File.good();
319
	File.close();
320
	return bRet;
1 cycrow 321
}
322
 
323
bool CFileIO::StartRead()
324
{
51 cycrow 325
	if ( !m_sFilename.empty() ) {
326
		if ( m_bOpened ) StopRead();
1 cycrow 327
 
51 cycrow 328
		m_fId.open(m_sFilename, _in());
329
		if ( m_fId.is_open() ) {
1 cycrow 330
			m_bOpened = true;
331
			return true;
332
		}
333
	}
334
	return false;
335
}
336
 
337
std::vector<CyString> *CFileIO::ReadLines()
338
{
51 cycrow 339
	if ( m_sFilename.empty() ) return 0;
1 cycrow 340
 
341
	std::vector<CyString> *file = new std::vector<CyString>;
342
	std::string line;
343
	file->clear();
344
	std::ifstream infile (m_sFilename.c_str(), std::ios_base::in);
345
	while (getline(infile, line, '\n'))
346
	{
347
		CyString l = line;
348
		l.RemoveChar((char)0);
349
		file->push_back(l);
350
	}
351
 
352
	infile.close();
353
 
354
	return file;
355
}
356
 
357
CyStringList *CFileIO::ReadLinesStr()
358
{
51 cycrow 359
	if ( m_sFilename.empty() ) return 0;
1 cycrow 360
 
361
	CyStringList *file = new CyStringList;
362
	std::string line;
363
	std::ifstream infile (m_sFilename.c_str(), std::ios_base::in);
364
	while (getline(infile, line, '\n'))
365
	{
366
		CyString l = line;
367
		l.RemoveChar((char)0);
368
		file->PushBack(l);
369
	}
370
 
371
	infile.close();
372
 
373
	return file;
374
}
375
 
376
void CFileIO::StopRead()
377
{
51 cycrow 378
	if ( m_fId.is_open() ) m_fId.close();
1 cycrow 379
	m_bOpened = false;
380
}
381
 
382
bool CFileIO::IsOpened()
383
{
384
	if ( m_fId.is_open() )
385
		return true;
386
	return false;
387
}
388
 
389
CyString CFileIO::ReadToEndLine(bool autoclose)
390
{
391
	if ( !this->IsOpened() )
392
	{
393
		if ( !StartRead() )
394
			return "";
395
	}
396
 
397
	int pos = 0;
398
	char sLine[10000];
399
	char cur = 0;
400
 
51 cycrow 401
	std::string line;
402
	if ( getline(m_fId, line, '\n') )
403
		return CyString(line);
1 cycrow 404
 
405
	sLine[pos] = 0;
51 cycrow 406
	if ( pos ) return CyString(sLine);
1 cycrow 407
 
408
	if ( autoclose )
409
		StopRead();
410
	return "";
411
}
412
 
413
bool CFileIO::AtEnd()
414
{
51 cycrow 415
	if ( !this->IsOpened() ) return true;
416
	if ( m_fId.eof() )		 return true;
1 cycrow 417
	return false;
418
}
419
 
420
bool CFileIO::AppendFile ( CyString filename )
421
{
51 cycrow 422
	std::fstream fromFile(filename.ToString().c_str(), _in());
423
	if ( !fromFile.is_open() ) return false;
1 cycrow 424
 
51 cycrow 425
	std::fstream toFile(m_sFilename, _append());
426
	if ( !toFile.is_open() ) {
427
		fromFile.close();
1 cycrow 428
		return false;
429
	}
430
 
431
	// move to the end of the file
51 cycrow 432
	toFile.seekg(0, std::ios::end);
1 cycrow 433
 
434
	// get size of file
51 cycrow 435
	fromFile.seekg(0, std::ios::end);
436
	size_t size = fromFile.tellg();
437
	fromFile.seekg(0, std::ios::beg);
1 cycrow 438
 
439
	char data[500000];
440
	while ( size > 0 )
441
	{
442
		size_t read = 500000;
443
		if ( read > size )
444
			read = size;
445
 
446
		size -= read;
447
 
51 cycrow 448
		fromFile.read(data, read);
449
		toFile.write(data, read);
1 cycrow 450
	}
451
 
51 cycrow 452
	fromFile.close();
453
	toFile.close();
1 cycrow 454
	return true;
455
}
456
 
457
 
458
bool CFileIO::AppendData ( const char *d, size_t size )
459
{
51 cycrow 460
	std::fstream File(m_sFilename, _append());
461
	if ( !File.is_open() ) return false;
1 cycrow 462
 
463
	// move to the end of the file
51 cycrow 464
	File.seekg(0, std::ios::end);
1 cycrow 465
 
466
	char *pos = (char *)d;
51 cycrow 467
	while ( size > 0 ) {
1 cycrow 468
		size_t read = 500000;
51 cycrow 469
		if ( read > size ) read = size;
1 cycrow 470
 
471
		size -= read;
472
 
51 cycrow 473
		try {
474
			File.write(pos, read);
475
		} 
476
		catch(std::exception &e) {
477
			CLog::logf(CLog::Log_IO, 2, "CFileIO::AppendData() unable to write data to file: %s (%s)", m_sFilename.c_str(), e.what());
478
			File.close();
479
			return false;
480
		}
1 cycrow 481
		pos += read;
482
	}
483
 
51 cycrow 484
	File.close();
1 cycrow 485
	return true;
486
}
487
 
488
bool CFileIO::AppendDataToPos ( const char *d, size_t size, size_t start )
489
{
490
	FILE *aid = fopen ( m_sFilename.c_str(), (m_bBinary) ? "ab" : "a" );
491
	if ( !aid )
492
		return false;
493
 
494
	// move to the end of the file
495
	fseek ( aid, 0, SEEK_END );
496
	size_t end = ftell(aid);
497
	if ( start > end )
498
	{
499
		fclose ( aid);
500
		return false;
501
	}
502
 
42 cycrow 503
	if ( start == end ) {
504
		fseek(aid, 0, SEEK_END);
505
	}
506
	else {
507
		fseek ( aid, start, SEEK_SET );
508
	}
1 cycrow 509
 
510
	char *pos = (char *)d;
511
	while ( size > 0 )
512
	{
513
		size_t read = 500000;
514
		if ( read > size )
515
			read = size;
516
 
517
		size -= read;
518
 
519
		fwrite ( pos, sizeof(char), read, aid );
520
		pos += read;
521
	}
522
 
523
	fclose ( aid );
524
	return true;
525
}
526
 
527
CyString CFileIO::GetBaseName()
528
{
51 cycrow 529
	return m_sFile.token(".", -2);
1 cycrow 530
}
531
CyString CFileIO::GetFileExtension ()
532
{
51 cycrow 533
	if ( m_sFilename.empty() ) return NullString;
534
	return m_sFilename.token(".", -1);
1 cycrow 535
}
536
 
537
CyString CFileIO::ChangeFileExtension ( CyString ext )
538
{
51 cycrow 539
	if ( m_sFilename.empty() )
1 cycrow 540
		return NullString;
51 cycrow 541
 
542
	return m_sFilename.tokens(".", 1, -2) + "." + ext.ToString();
1 cycrow 543
}
544
 
545
bool CFileIO::Remove()
546
{
547
	if ( !Exists() )
548
		return false;
549
 
51 cycrow 550
	if ( std::remove(m_sFilename.c_str()) == 0 )
1 cycrow 551
		return true;
552
 
553
	return false;
554
}
555
 
556
bool CFileIO::WriteFileUTF(std::vector<CyString> *lines)
557
{
51 cycrow 558
	if ( !lines || m_sFilename.empty() )
1 cycrow 559
		return false;
560
 
561
	// we need to create the directory
562
	if ( !m_sDirIO.Exists() )
563
	{
564
		if ( !m_sDirIO.Create() )
565
			return false;
566
	}
567
 
568
#ifdef _WIN32
569
	TCHAR buf[5000];
570
	wsprintf(buf, L"%hs", m_sFilename.c_str());
571
	FILE *id = _wfopen(buf, L"wt+,ccs=UTF-8");
572
	if ( !id )
573
		return false;
574
 
575
	// write the rest
576
	for ( int i = 0; i < (int)lines->size(); i++ )
577
	{
578
		CyString l = lines->at(i);
579
		if ( l.IsIn('\n') )
580
		{
581
			int max;
582
			CyString *strs = l.SplitToken("\n", &max);
583
			if ( strs && max )
584
			{
585
				for ( int i = 0; i < max; i++ )
586
				{
587
					CyString line = strs[i];
588
					line += "\n";
589
					int size = wsprintf(buf, L"%hs", line.c_str());
590
					fwrite(buf, sizeof(TCHAR), wcslen(buf), id);
591
				}
592
 
593
				CLEANSPLIT(strs, max);
594
			}
595
		}
596
		else
597
		{
598
			l += "\n";
599
			int size = wsprintf(buf, L"%hs", l.c_str());
600
			fwrite(buf, sizeof(TCHAR), wcslen(buf), id);
601
		}
602
	}
603
 
604
	fclose(id);
605
 
606
	return true;
607
#else
608
    //TODO: write utf8 file writing function
609
    return false;
610
#endif
611
}
612
 
613
bool CFileIO::WriteFile(std::vector<CyString> *lines)
614
{
51 cycrow 615
	if ( !lines || m_sFilename.empty() )
1 cycrow 616
		return false;
617
 
618
	// we need to create the directory
619
	if ( !m_sDirIO.Exists() )
620
	{
621
		if ( !m_sDirIO.Create() )
622
			return false;
623
	}
624
 
625
 
626
	std::ofstream out(m_sFilename.c_str());
627
	if ( !out )
628
		return false;
629
 
630
	for ( int i = 0; i < (int)lines->size(); i++ )
631
	{
632
		CyString l = lines->at(i);
633
		out << l.c_str() << std::endl;
634
	}
635
 
636
	out.close();
637
 
638
	return true;
639
}
640
 
641
bool CFileIO::WriteFile(CyStringList *lines)
642
{
51 cycrow 643
	if ( !lines || m_sFilename.empty() )
1 cycrow 644
		return false;
645
 
646
	// we need to create the directory
647
	if ( !m_sDirIO.Exists() )
648
	{
649
		if ( !m_sDirIO.Create() )
650
			return false;
651
	}
652
 
653
	std::ofstream out(m_sFilename.c_str());
654
	if ( !out )
655
		return false;
656
 
657
	/*
658
	if ( utf )
659
	{
660
		unsigned char smarker[4];
661
		smarker[0] = 0xEF;
662
		smarker[1] = 0xBB;
663
		smarker[2] = 0xBF;
664
		smarker[3] = 0x00;
665
 
666
		out << smarker;
667
	}
668
*/
669
	for ( int i = 0; i < (int)lines->Count(); i++ )
670
	{
671
		CyString l = lines->StringAt(i);
672
		out << l.c_str() << std::endl;
673
	}
674
 
675
	out.close();
676
 
677
	return true;
678
}
679
 
680
bool CFileIO::Rename(CyString toFile)
681
{
682
	if ( rename(m_sFilename.c_str(), toFile.c_str()) == 0 )
683
		return true;
684
	return false;
685
}
686
 
687
CyString CFileIO::GetWindowsFilename()
688
{
689
	CyString returnString = m_sFilename;
690
	returnString = returnString.FindReplace("/", "\\");
691
	return returnString;
692
}
693
 
694
void CFileIO::SetCreationTime(time_t time)
695
{
696
#ifdef _WIN32
697
	// Note that LONGLONG is a 64-bit value
698
    LONGLONG ll;
699
 
700
	FILETIME ft;
701
    ll = Int32x32To64(time, 10000000) + 116444736000000000;
702
    ft.dwLowDateTime = (DWORD)ll;
703
    ft.dwHighDateTime = ll >> 32;
704
 
705
	HANDLE filename = CreateFile((LPCWSTR)GetWindowsFilename().c_str(), FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
706
	// Set the file time on the file
707
	SetFileTime(filename,(LPFILETIME) NULL,(LPFILETIME) NULL,&ft);
708
	// Close our handle.
709
	CloseHandle(filename);
710
#endif
711
}
712
 
713
time_t CFileIO::GetCreationTime()
714
{
715
#ifdef _WIN32
716
	WIN32_FILE_ATTRIBUTE_DATA wfad;
717
	GetFileAttributesEx((LPCWSTR)GetWindowsFilename().c_str(), GetFileExInfoStandard, &wfad);
718
 
719
	LARGE_INTEGER date, adjust;
720
	date.HighPart = wfad.ftCreationTime.dwHighDateTime;
721
	date.LowPart = wfad.ftCreationTime.dwLowDateTime;
722
 
723
	// 100-nanoseconds = milliseconds * 10000
724
	adjust.QuadPart = 11644473600000 * 10000;
725
 
726
	// removes the diff between 1970 and 1601
727
	date.QuadPart -= adjust.QuadPart;
728
 
729
	// converts back from 100-nanoseconds to seconds
730
	return (time_t)(date.QuadPart / 10000000);
731
#else
732
	struct stat fileStat;
733
	if ( !stat(GetWindowsFilename().c_str(), &fileStat) )
734
		return (time_t)fileStat.st_atime;
735
#endif
736
	return 0;
737
}
738
/**
739
 * Copys the contents of a file to another
740
 *
741
 * Reads and writes the files in block
742
 */
743
bool CFileIO::Copy(CyString toFile, bool keepTime)
744
{
745
	//open both files
746
	FILE *id = fopen(GetWindowsFilename().c_str(), "rb");
747
	if ( !id )
748
		return false;
749
	FILE *toID = fopen(toFile.c_str(), "wb");
750
	if ( !toID )
751
	{
752
		fclose(id);
753
		return false;
754
	}
755
 
756
	time_t time = GetCreationTime();
757
 
758
	// get length of file
759
	fseek(id, 0, SEEK_END);
760
	size_t remainingLen = ftell(id);
761
	fseek(id, 0, SEEK_SET);
762
 
763
	if ( remainingLen <= 0 )
764
	{
765
		fclose(id);
766
		fclose(toID);
767
		return false;
768
	}
769
 
770
 
771
	// read then write a block
772
	char block[100000];
773
	while ( remainingLen )
774
	{
775
		size_t amt = 100000;
776
		if ( amt > remainingLen )
777
			amt = remainingLen;
778
 
779
		fread(block, amt, sizeof(char), id);
780
		fwrite(block, amt, sizeof(char), toID);
781
 
782
		remainingLen -= amt;
783
	}
784
 
785
	fclose(id);
786
	fclose(toID);
787
 
788
	if ( keepTime )
789
		CFileIO(toFile.c_str()).SetCreationTime(time);
790
 
791
 
792
	return true;
793
}