Subversion Repositories spk

Rev

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

Rev Author Line No. Line
1 cycrow 1
#include "MultiSpkFile.h"
2
#include "File.h"
3
#include "XspFile.h"
4
 
5
CMultiSpkFile::~CMultiSpkFile()
6
{
7
	for ( CListNode<SMultiSpkFile> *node = m_lFiles.Front(); node; node = node->next() )
8
	{
9
		SMultiSpkFile *ms = node->Data();
10
		if ( !ms )
11
			continue;
12
 
13
		if ( ms->sData )
14
		{
15
			delete ms->sData;
16
			ms->sData = NULL;
17
		}
18
 
19
		if ( ms->pFile )
20
		{
21
			delete ms->pFile;
22
			ms->pFile = NULL;
23
		}
24
 
25
		node->DeleteData();
26
	}
27
}
28
 
29
void CMultiSpkFile::CreatePackage(SMultiSpkFile *p)
30
{
31
	if ( !p )
32
		return;
33
 
34
	if ( p->iType == TYPE_XSP )
35
		p->pFile = new CXspFile();
36
	else if ( p->iType == TYPE_SPK )
37
		p->pFile = new CSpkFile();
38
	else if ( p->iType == TYPE_BASE )
39
		p->pFile = new CBaseFile();
40
}
41
 
42
bool CMultiSpkFile::AddFileNow ( CyString file, bool on )
43
{
44
	if ( this->AddFile(file, on) )
45
	{
175 cycrow 46
		Utils::String findFile = CFileIO(file).filename();
1 cycrow 47
 
48
		SMultiSpkFile *p = this->FindFile(findFile);
49
		if ( p )
50
		{
51
			this->CreatePackage(p);
175 cycrow 52
			if ( p->pFile->readFile(file.ToString(), SPKREAD_ALL))
1 cycrow 53
				return true;
54
		}
55
	}
56
 
57
	return false;
58
}
59
 
60
bool CMultiSpkFile::AddFile(SMultiSpkFile *ms)
61
{
62
	bool found = false;
63
	// find if theres any files with the same filename
64
	CListNode<SMultiSpkFile> *node;
65
	for ( node = m_lFiles.Front(); node; node = node->next() )
66
	{
67
		SMultiSpkFile *it = node->Data();
68
		if ( it->sName.Compare(ms->sName) )
69
		{
70
			m_lFiles.remove ( it );
71
			found = true;
72
			delete it;
73
			break;
74
		}
75
	}
76
 
77
	// now find if theres a file with the same script/author
78
	for ( node = m_lFiles.Front(); node; node = node->next() )
79
	{
80
		SMultiSpkFile *it = node->Data();
81
		if ( (it->sScriptAuthor.Compare(ms->sScriptAuthor)) && (it->sScriptName.Compare(ms->sScriptName)) )
82
		{
83
			m_lFiles.remove ( it );
84
			found = true;
85
			delete it;
86
			break;
87
		}
88
	}
89
 
90
	m_lFiles.push_back ( ms );
91
 
92
	m_bChanged = true;
93
	return true;
94
}
176 cycrow 95
bool CMultiSpkFile::AddFile ( CyString sFile, bool on )
1 cycrow 96
{
176 cycrow 97
	Utils::String file = sFile.ToString();
1 cycrow 98
	// multipack
176 cycrow 99
	if (file.contains( "::" ))
1 cycrow 100
	{
176 cycrow 101
		Utils::String mfile = file.left(file.findPos("::"));
1 cycrow 102
		CMultiSpkFile spkfile;
103
		if ( spkfile.ReadFile ( mfile, false ) )
104
		{
105
			SMultiSpkFile *ms = new SMultiSpkFile;
106
			ms->bRemove = false;
176 cycrow 107
			ms->sName = file.right((int)(file.length() - file.findPos("::")) - 2 );
1 cycrow 108
			ms->pFile = NULL;
109
			ms->sData = NULL;
110
			if ( spkfile.ExtractData ( ms ) )
111
			{
112
				ms->bOn = on;
113
				AddFile(ms);
114
				return true;
115
			}
116
			delete ms;
117
		}
118
		return false;
119
	}
120
 
121
	// check its a valid file
176 cycrow 122
	int check = CBaseFile::CheckFile(file);
1 cycrow 123
	if ( check == SPKFILE_MULTI )
124
	{
125
		CMultiSpkFile spkfile;
126
		if ( spkfile.ReadFile ( file, false ) )
127
		{
128
			CLinkList<SMultiSpkFile> *list = spkfile.GetFileList();
129
			for ( SMultiSpkFile *it = list->First(); it; it = list->Next() )
130
			{
131
				SMultiSpkFile *ms = new SMultiSpkFile;
132
				ms->bRemove = false;
133
				ms->sName = it->sName;
134
				ms->pFile = NULL;
135
				ms->sData = NULL;
136
				if ( spkfile.ExtractData ( ms ) )
137
				{
138
					ms->bOn = on;
139
					AddFile(ms);
140
				}
141
				else
142
					delete ms;
143
			}
144
			return true;
145
		}
146
		return false;
147
	}
148
	else if ( check != SPKFILE_SINGLE && check != SPKFILE_SINGLESHIP )
149
		return false;
150
 
56 cycrow 151
	CFileIO File(file);
152
	if ( !File.startRead() ) return false;
1 cycrow 153
 
154
	// create entry
155
	SMultiSpkFile *ms = new SMultiSpkFile;
156
	ms->bRemove = false;
157
	ms->pFile = NULL;
176 cycrow 158
	ms->sName = CFileIO(file).filename();
1 cycrow 159
	ms->bOn = on;
160
 
161
	// read data
56 cycrow 162
	ms->sData = (char *)File.readAll((size_t *)&ms->lSize);
163
	File.close();
1 cycrow 164
 
165
	CBaseFile *baseFile = NULL;
166
	if ( check == SPKFILE_SINGLE )
167
		baseFile = new CSpkFile;
168
	else if ( check == SPKFILE_SINGLESHIP )
169
		baseFile = new CXspFile;
170
 
56 cycrow 171
	if ( baseFile ) {
176 cycrow 172
		if ( baseFile->readFile(file, SPKREAD_VALUES)) {
50 cycrow 173
			ms->sScriptAuthor	= baseFile->author();
174
			ms->sScriptName		= baseFile->name();
175
			ms->sScriptVersion	= baseFile->version();
1 cycrow 176
			ms->iType			= baseFile->GetType();
177
		}
178
 
179
		delete baseFile;
180
	}
181
 
182
	AddFile(ms);
183
 
184
	return true;
185
}
186
 
187
SMultiSpkFile *CMultiSpkFile::AddFileEntry ( CyString filename )
188
{
189
	SMultiSpkFile *ms = new SMultiSpkFile;
190
	ms->bRemove = false;
191
	ms->pFile = NULL;
176 cycrow 192
	ms->sName = filename.ToString();
1 cycrow 193
	ms->bOn = true;
194
	ms->iType = -1;
195
 
196
	m_lFiles.push_back ( ms );
197
	m_bChanged = true;
198
 
199
	return ms;
200
}
201
 
202
CyString CMultiSpkFile::CreateData ()
203
{
176 cycrow 204
	Utils::String ret;
205
	if ( !_sName.empty() )
206
		ret = "Name: " + _sName + "\n";
1 cycrow 207
	for ( CListNode<SMultiSpkFile> *node = m_lFiles.Front(); node; node = node->next() )
208
	{
209
		SMultiSpkFile *ms = node->Data();
210
		if ( ms->iType == TYPE_XSP )
211
			ret += "XspFile: ";
212
		else 
213
			ret += "SpkFile: ";
214
 
215
		if ( ms->bOn )
216
			ret += "1:";
217
		else
218
			ret += "0:";
219
		ret += ms->lSize;
220
		ret += ":";
221
		ret += ms->sName;
176 cycrow 222
		if ( !ms->sScriptName.empty() )
223
			ret += ":" + ms->sScriptName + "|" + ms->sScriptAuthor + "|" + ms->sScriptVersion;
1 cycrow 224
		ret += "\n";
225
	}
226
 
227
	return ret;
228
}
229
 
230
bool CMultiSpkFile::WriteFile ( CyString filename, CProgressInfo *progress )
231
{
52 cycrow 232
	CFileIO File(filename);
233
	if ( !File.startWrite() ) return false;
1 cycrow 234
 
235
	// make sure we remove all packages that have been marked
236
	this->RemovePackages();
237
 
238
	CyString data = CreateData ();
239
 
240
	int comprLen = (int)data.Length(), uncomprLen = comprLen;;
241
	unsigned char *compr = NULL;
242
 
243
	bool compressed = false;
244
	int valueheader = m_SHeader.iCompression;
245
	if ( valueheader == SPKCOMPRESS_7ZIP )
246
		valueheader = SPKCOMPRESS_ZLIB;
247
 
248
	if ( valueheader == SPKCOMPRESS_ZLIB )
249
	{
250
		comprLen = uncomprLen;	
251
		if ( comprLen < 100 )
252
			comprLen = 200;
253
		else if ( comprLen < 1000 )
254
			comprLen *= 2;
255
 
256
		compr = (unsigned char *)calloc((unsigned int)comprLen, 1);
257
		int err = compress ( (unsigned char *)compr, (unsigned long *)&comprLen, (const unsigned char *)data.c_str(), (unsigned long)data.Length(), 0 );
258
		if ( err == Z_OK )
259
			compressed = true;
260
	}
261
 
262
	if ( !compressed )
263
	{
264
		comprLen = uncomprLen;
265
		compr = (unsigned char *)calloc((unsigned int)comprLen, 1);
266
		memcpy ( compr, data.c_str(), comprLen );
267
		valueheader = SPKCOMPRESS_NONE;
268
	}
269
 
270
	// write the main header to the file
52 cycrow 271
	if ( !File.write("MSPKCycrow;%.2f;%d;%d;%d;%d\n", FILEVERSION, valueheader, data.Length(), comprLen, (m_SHeader.bSelection) ? 1 : 0) ) return false;
1 cycrow 272
 
273
	// write the compressed data to file
52 cycrow 274
	File.writeSize(uncomprLen);
275
	File.write(compr, comprLen);
1 cycrow 276
	free ( compr );
277
 
52 cycrow 278
	for ( CListNode<SMultiSpkFile> *node = m_lFiles.Front(); node; node = node->next() ) {
1 cycrow 279
		SMultiSpkFile *ms = node->Data();
280
		if ( progress )
281
			progress->UpdatePackage(ms);
282
		if ( (!ms->sData) && (ms->pFile) )
175 cycrow 283
			ms->pFile->writeData(File, NULL);
1 cycrow 284
		else
52 cycrow 285
			File.write(ms->sData, ms->lSize);
1 cycrow 286
	}
287
 
288
	return true;
289
}
290
 
291
bool CMultiSpkFile::ParseHeader ( CyString header )
292
{
293
	if ( header.GetToken ( 1, ';' ) != "MSPKCycrow" )
294
		return false;
295
 
296
	m_SHeader.fVersion = header.GetToken ( 2, ';' ).ToFloat();
297
	if ( m_SHeader.fVersion > FILEVERSION )
298
		return false;
299
 
300
	m_SHeader.iCompression = header.GetToken ( 3, ';' ).ToInt();
301
	m_SHeader.lUncomprLen = header.GetToken ( 4, ';' ).ToLong();
302
	m_SHeader.lComprLen = header.GetToken ( 5, ';' ).ToLong();
303
	m_SHeader.bSelection = (header.GetToken ( 4, ';' ).ToInt()) ? true : false;
304
 
305
	return true;
306
}
307
 
176 cycrow 308
bool CMultiSpkFile::ParseValueLine ( CyString sLine )
1 cycrow 309
{
176 cycrow 310
	Utils::String line = sLine.ToString();
311
	Utils::String first = line.token(" ", 1);
312
	Utils::String rest  = line.tokens(" ", 2);
1 cycrow 313
 
314
	if ( first == "Name:" )
176 cycrow 315
		_sName = rest;
1 cycrow 316
	else if ( first == "SpkFile:" )
317
	{
318
		SMultiSpkFile *ms = new SMultiSpkFile;
319
		ms->bRemove = false;
320
		ms->pFile = NULL;
176 cycrow 321
		ms->bOn = (rest.token(":", 1).toInt()) ? true : false;
322
		ms->lSize = rest.token(":", 2).toLong();
323
		ms->sName = rest.token (":", 3);
1 cycrow 324
		ms->sData = NULL;
325
		ms->iType = TYPE_SPK;
176 cycrow 326
		Utils::String r = rest.tokens(":", 4);
327
		if (!r.empty())
1 cycrow 328
		{
176 cycrow 329
			ms->sScriptName = r.token("|", 1);
330
			ms->sScriptAuthor = r.token("|", 2);
331
			ms->sScriptVersion = r.tokens("|", 3);
1 cycrow 332
		}
333
		m_lFiles.push_back ( ms );
334
	}
335
	else if ( first == "XspFile:" )
336
	{
337
		SMultiSpkFile *ms = new SMultiSpkFile;
338
		ms->bRemove = false;
339
		ms->pFile = NULL;
176 cycrow 340
		ms->bOn = (rest.token(":", 1).toInt()) ? true : false;
341
		ms->lSize = rest.token(":", 2).toLong();
342
		ms->sName = rest.token(":", 3);
1 cycrow 343
		ms->sData = NULL;
344
		ms->iType = TYPE_XSP;
176 cycrow 345
		Utils::String r = rest.tokens(":", 4);
346
		if ( !r.empty() )
1 cycrow 347
		{
176 cycrow 348
			ms->sScriptName = r.token("|", 1);
349
			ms->sScriptAuthor = r.token("|", 2);
350
			ms->sScriptVersion = r.tokens("|", 3);
1 cycrow 351
		}
352
		m_lFiles.push_back ( ms );
353
	}
354
	else if ( first == "BaseFile:" )
355
	{
356
		SMultiSpkFile *ms = new SMultiSpkFile;
357
		ms->bRemove = false;
358
		ms->pFile = NULL;
176 cycrow 359
		ms->bOn = (rest.token(":", 1).toInt()) ? true : false;
360
		ms->lSize = rest.token(":", 2).toLong();
361
		ms->sName = rest.token(":", 3);
1 cycrow 362
		ms->sData = NULL;
363
		ms->iType = TYPE_BASE;
176 cycrow 364
		Utils::String r = rest.tokens(":", 4);
365
		if (!r.empty())
1 cycrow 366
		{
176 cycrow 367
			ms->sScriptName = r.token("|", 1);
368
			ms->sScriptAuthor = r.token("|", 2);
369
			ms->sScriptVersion = r.tokens("|", 3);
1 cycrow 370
		}
371
		m_lFiles.push_back ( ms );
372
	}
373
	else
374
		return false;
375
 
376
	return true;
377
}
378
 
379
void CMultiSpkFile::RemovePackages()
380
{
381
	for ( CListNode<SMultiSpkFile> *node = m_lFiles.Front(); node; node = node->next() )
382
	{
383
		if ( !node->Data()->bRemove ) continue;
384
		node->DeleteData();
385
	}
386
 
387
	m_lFiles.RemoveEmpty();
388
}
389
 
390
void CMultiSpkFile::ReadValues ( CyString values )
391
{
392
	int num = 0;
393
	CyString *lines = values.SplitToken ( '\n', &num );
394
 
395
	for ( int i = 0; i < num; i++ )
396
		ParseValueLine ( lines[i] );
397
 
398
	CLEANSPLIT(lines, num);
399
}
400
 
56 cycrow 401
bool CMultiSpkFile::ReadFile ( CyString filename, bool bReadData)
1 cycrow 402
{
56 cycrow 403
	CFileIO File(filename);
404
	if ( !File.startRead() ) return false;
1 cycrow 405
 
406
	// first read the header
56 cycrow 407
	if ( !ParseHeader(File.readEndOfLine()) ) return false;
1 cycrow 408
 
409
	ClearFiles ();
410
 
411
	int doneLen = 0;
412
	// next read the data values for the spk files
413
	if ( m_SHeader.lComprLen )
414
	{
415
		// read data to memory
56 cycrow 416
		unsigned long uncomprLen = File.readSize();
417
		unsigned char *readData = File.read(m_SHeader.lComprLen);
1 cycrow 418
 
419
		// check for zlib compression
56 cycrow 420
		if ( m_SHeader.iCompression == SPKCOMPRESS_ZLIB ) {
1 cycrow 421
			// uncomress the data
422
			unsigned char *uncompr = new unsigned char[uncomprLen];
423
 
424
			int err = uncompress ( uncompr, &uncomprLen, readData, m_SHeader.lComprLen );
56 cycrow 425
			if ( err == Z_OK ) ReadValues ( CyString ((char *)uncompr) );
1 cycrow 426
			doneLen = uncomprLen;
427
			delete uncompr;
428
		}
56 cycrow 429
		else if ( m_SHeader.iCompression == SPKCOMPRESS_7ZIP ) {
1 cycrow 430
			long len = uncomprLen;
431
			unsigned char *compr = LZMADecode_C ( readData, m_SHeader.lComprLen, (size_t *)&len, NULL );
56 cycrow 432
			if ( compr ) ReadValues ( CyString ((char *)compr) );
1 cycrow 433
		}
434
		// no compression
435
		else
436
			ReadValues ( CyString ((char *)readData) );
437
 
438
		delete readData;
439
	}
440
 
56 cycrow 441
	if ( bReadData ) {
442
		for ( CListNode<SMultiSpkFile> *node = m_lFiles.Front(); node; node = node->next() ) {
1 cycrow 443
			SMultiSpkFile *ms = node->Data();
56 cycrow 444
			ms->sData = (char *)File.read(ms->lSize);
1 cycrow 445
		}
446
	}
447
 
176 cycrow 448
	_sFilename = filename.ToString();
1 cycrow 449
 
56 cycrow 450
	File.close();
1 cycrow 451
	m_bChanged = false;
452
 
453
	return true;
454
}
455
 
456
unsigned int CMultiSpkFile::GetAvailableFiles()
457
{
458
	unsigned int size = 0;
459
	for ( CListNode<SMultiSpkFile> *node = m_lFiles.Front(); node; node = node->next() )
460
	{
461
		if ( node->Data()->bRemove ) continue;
462
		++size;
463
	}
464
 
465
	return size;
466
}
467
 
468
unsigned long CMultiSpkFile::GetFileSize()
469
{
470
	unsigned int size = 0;
471
	for ( CListNode<SMultiSpkFile> *node = m_lFiles.Front(); node; node = node->next() )
472
	{
473
		if ( node->Data()->bRemove ) continue;
474
		size += node->Data()->lSize;
475
	}
476
 
477
	return size;
478
}
479
 
480
void CMultiSpkFile::ClearFiles ()
481
{
482
	m_lFiles.clear(true);
483
}
484
 
485
bool CMultiSpkFile::ExtractData ( SMultiSpkFile *ms )
486
{
176 cycrow 487
	FILE *id = fopen (_sFilename.c_str(), "rb");
1 cycrow 488
	if ( !id )
489
		return false;
490
 
491
	// skip past the header
492
	CSpkFile::GetEndOfLine ( id, NULL, false );
493
	// seek past the values
494
	fseek ( id, 4, SEEK_CUR );
495
	fseek ( id, m_SHeader.lComprLen, SEEK_CUR );
496
 
497
	bool found = false;
498
	for ( CListNode<SMultiSpkFile> *node = m_lFiles.Front(); node; node = node->next() )
499
	{
500
		SMultiSpkFile *it = node->Data();
501
		if ( ms->sName.Compare(it->sName) )
502
		{
503
			ms->lSize = it->lSize;
504
			ms->sScriptAuthor = it->sScriptAuthor;
505
			ms->sScriptName = it->sScriptName;
506
			ms->sScriptVersion = it->sScriptVersion;
507
			ms->bOn = it->bOn;
508
			ms->iType = it->iType;
509
			ms->sData = new char[ms->lSize];
510
			if ( it->sData )
511
				memcpy ( ms->sData, it->sData, ms->lSize );
512
			else
513
				fread ( ms->sData, sizeof(char), ms->lSize, id );
514
			found = true;
515
			break;
516
		}
517
		else
518
			fseek ( id, it->lSize, SEEK_CUR );
519
	}
520
 
521
	fclose ( id );
522
	return found;
523
}
524
 
525
bool CMultiSpkFile::ReadFileToMemory ( SMultiSpkFile *ms )
526
{
527
	if ( ms->sData )
528
		return true;
529
 
176 cycrow 530
	FILE *id = fopen(_sFilename.c_str(), "rb");
1 cycrow 531
	if ( !id )
532
		return false;
533
 
534
	// skip past the header
535
	CSpkFile::GetEndOfLine ( id, NULL, false );
536
	// seek past the values
537
	fseek ( id, 4, SEEK_CUR );
538
	fseek ( id, m_SHeader.lComprLen, SEEK_CUR );
539
 
540
	bool found = false;
541
	for ( CListNode<SMultiSpkFile> *node = m_lFiles.Front(); node; node = node->next() )
542
	{
543
		SMultiSpkFile *it = node->Data();
544
		if ( it == ms )
545
		{
546
			ms->sData = new char[ms->lSize];
547
			fread ( ms->sData, sizeof(char), ms->lSize, id );
548
			found = true;
549
			break;
550
		}
551
		else
552
			fseek ( id, it->lSize, SEEK_CUR );
553
	}
554
 
555
	fclose ( id );
556
	return found;
557
}
558
 
559
bool CMultiSpkFile::ExtractFile ( const CyString &file, CyString dir )
560
{
561
	SMultiSpkFile *ms = FindFile(file);
562
	if ( !ms ) return false;
563
	return ExtractFile(ms, dir);
564
}
565
 
566
bool CMultiSpkFile::ExtractFile ( SMultiSpkFile *ms, CyString dir )
567
{
568
	if ( !ms->sData )
569
	{
570
		if ( !ReadFileToMemory ( ms ) )
571
			return false;
572
	}
573
 
574
	CyString filename = dir;
575
	if ( !dir.Empty() )
576
		filename += "/";
577
	filename += ms->sName;
578
 
579
	FILE *id = fopen ( filename.c_str(), "wb" );
580
	if ( !id )
581
		return false;
582
 
583
	fwrite ( ms->sData, sizeof(char), ms->lSize, id );
584
	fclose ( id );
585
 
586
	return true;
587
}
588
 
589
bool CMultiSpkFile::ExtractAll ( CyString dir )
590
{
176 cycrow 591
	if (_sFilename.empty())
1 cycrow 592
		return false;
593
 
594
	if ( !ReadAllFilesToMemory () )
595
		return false;
596
 
597
	for ( CListNode<SMultiSpkFile> *node = m_lFiles.Front(); node; node = node->next() )
598
	{
599
		SMultiSpkFile *ms = node->Data();
600
		if ( ms->bRemove ) continue;
601
		if ( !ms->sData )
602
			continue;
603
 
604
		FILE *id = fopen ( CyString(dir + "/" + ms->sName).c_str(), "wb" );
605
		if ( !id )
606
			continue;
607
 
608
		fwrite ( ms->sData, sizeof(char), ms->lSize, id );
609
		fclose ( id );
610
	}
611
	return true;
612
}
613
 
614
bool CMultiSpkFile::SplitMulti ( CyString filename, CyString destdir )
615
{
616
	if ( !ReadFile ( filename ) )
617
		return false;
618
 
619
	bool doneone = false;
620
	for ( CListNode<SMultiSpkFile> *node = m_lFiles.Front(); node; node = node->next() )
621
	{
622
		SMultiSpkFile *ms = node->Data();
623
		if ( ms->bRemove ) continue;
624
		if ( !ms->sData )
625
			continue;
626
 
627
		CyString destfile = destdir;
628
		if ( !destfile.Empty() )
629
			destfile += "/";
630
		destfile += ms->sName;
631
		FILE *id = fopen ( destfile.c_str(), "wb" );
632
		if ( !id )
633
			continue;
634
 
635
		fwrite ( ms->sData, sizeof(char), ms->lSize, id );
636
		fclose ( id );
637
		doneone = true;
638
	}
639
 
640
	return doneone;
641
}
642
 
643
bool CMultiSpkFile::ReadAllFilesToMemory (CProgressInfo *progress)
644
{
645
	// no file to read from
176 cycrow 646
	if (_sFilename.empty())
1 cycrow 647
		return false;
648
 
649
	// now open the file
176 cycrow 650
	FILE *id = fopen(_sFilename.c_str(), "rb");
1 cycrow 651
	if ( !id )
652
		return false;
653
 
654
	// read the header
655
	CSpkFile::GetEndOfLine ( id, NULL, false );
656
	// skip past values
657
	fseek ( id, 4, SEEK_CUR );
658
	fseek ( id, m_SHeader.lComprLen, SEEK_CUR );
659
 
660
	for ( CListNode<SMultiSpkFile> *node = m_lFiles.Front(); node; node = node->next() )
661
	{
662
		SMultiSpkFile *ms = node->Data();
663
		if ( ms->bRemove ) continue;
664
		if ( progress )
665
			progress->UpdatePackage(ms);
666
		if ( !ms->sData )
667
		{
668
			ms->sData = new char[ms->lSize];
669
			fread ( ms->sData, sizeof(char), ms->lSize, id );
670
		}
671
		else
672
			fseek ( id, ms->lSize, SEEK_CUR );
673
	}
674
 
675
	return true;
676
}
677
 
176 cycrow 678
bool CMultiSpkFile::RemoveFile ( CyString sFile )
1 cycrow 679
{
176 cycrow 680
	Utils::String file = sFile.ToString();
1 cycrow 681
	int num = 0;
682
	for ( CListNode<SMultiSpkFile> *node = m_lFiles.Front(); node; node = node->next() )
683
	{
684
		SMultiSpkFile *it = node->Data();
685
		if ( file.Compare(it->sName) )
686
			return RemoveFile ( num );
687
		++num;
688
	}
689
	return false;
690
}
691
 
692
bool CMultiSpkFile::RemoveFile ( SMultiSpkFile *ms )
693
{
694
	int num = 0;
695
	for ( CListNode<SMultiSpkFile> *node = m_lFiles.Front(); node; node = node->next() )
696
	{
697
		SMultiSpkFile *it = node->Data();
698
		if ( it == ms )
699
			return RemoveFile ( num );
700
		++num;
701
	}
702
	return false;
703
}
704
 
705
bool CMultiSpkFile::RemoveFile ( int id )
706
{
707
	if ( (id < 0) || (id >= m_lFiles.size()) )
708
		return false;
709
 
710
	SMultiSpkFile *file = m_lFiles.Get ( id );
711
	m_lFiles.erase ( id + 1 );
712
 
713
	if ( file )
714
		delete file;
715
 
716
	m_bChanged = true;
717
	return true;
718
}
719
 
176 cycrow 720
bool CMultiSpkFile::MarkRemoveFile ( CyString sFile )
1 cycrow 721
{
176 cycrow 722
	Utils::String file = sFile.ToString();
1 cycrow 723
	int num = 0;
724
	for ( CListNode<SMultiSpkFile> *node = m_lFiles.Front(); node; node = node->next() )
725
	{
726
		SMultiSpkFile *it = node->Data();
727
		if ( file.Compare(it->sName) )
728
			return MarkRemoveFile ( num );
729
		num++;
730
	}
731
	return false;
732
}
733
 
734
bool CMultiSpkFile::MarkRemoveFile ( SMultiSpkFile *ms )
735
{
736
	int num = 0;
737
	for ( CListNode<SMultiSpkFile> *node = m_lFiles.Front(); node; node = node->next() )
738
	{
739
		SMultiSpkFile *it = node->Data();
740
		if ( it == ms )
741
			return MarkRemoveFile ( num );
742
		++num;
743
	}
744
	return false;
745
}
746
 
747
bool CMultiSpkFile::MarkRemoveFile ( int id )
748
{
749
	if ( (id < 0) || (id >= m_lFiles.size()) )
750
		return false;
751
 
752
	SMultiSpkFile *file = m_lFiles.Get ( id );
753
	file->bRemove = true;
754
	m_bChanged = true;
755
	return true;
756
}
757
 
758
void CMultiSpkFile::MarkRemoveAll()
759
{
760
	for ( CListNode<SMultiSpkFile> *node = m_lFiles.Front(); node; node = node->next() )
761
		node->Data()->bRemove = true;
762
	m_bChanged = true;
763
}
764
 
765
 
766
bool CMultiSpkFile::ReadSpk( SMultiSpkFile *ms, int type )
767
{
768
	if ( ms->pFile->IsFullyLoaded() )
769
		return true;
770
 
771
	// no file to read from
176 cycrow 772
	if (_sFilename.empty())
1 cycrow 773
		return false;
774
 
775
	// now open the file
176 cycrow 776
	CFileIO File(_sFilename);
58 cycrow 777
	if ( !File.startRead() ) return false;
1 cycrow 778
 
779
	// read the header
58 cycrow 780
	File.readEndOfLine();
1 cycrow 781
	// skip past values
58 cycrow 782
	File.seek(4 + m_SHeader.lComprLen);
1 cycrow 783
 
784
	bool ret = false;
51 cycrow 785
	for ( CListNode<SMultiSpkFile> *node = m_lFiles.Front(); node; node = node->next() ) {
1 cycrow 786
		SMultiSpkFile *it = node->Data();
787
		if ( it == ms )
788
		{
789
			if ( !ms->pFile )
790
			{
791
				if ( ms->iType == TYPE_XSP )
792
					ms->pFile = new CXspFile;
793
				else
794
					ms->pFile = new CSpkFile;
795
			}
58 cycrow 796
			ret = it->pFile->readFile(File, type, NULL);
1 cycrow 797
			break;
798
		}
799
		else
58 cycrow 800
			File.seek(it->lSize);
1 cycrow 801
	}
802
 
58 cycrow 803
	File.close();
1 cycrow 804
	return ret;
805
}
806
 
807
bool CMultiSpkFile::ReadAllPackages( int type, CLinkList<CBaseFile> *addToList )
808
{
809
	// no file to read from
176 cycrow 810
	if (_sFilename.empty())
1 cycrow 811
		return false;
812
 
813
	// now open the file
176 cycrow 814
	CFileIO File(_sFilename);
58 cycrow 815
	if ( !File.startRead() ) return false;
1 cycrow 816
 
817
	// read the header
58 cycrow 818
	File.readEndOfLine();
1 cycrow 819
	// skip past values
58 cycrow 820
	File.seek(4 + m_SHeader.lComprLen);
1 cycrow 821
 
51 cycrow 822
	for ( CListNode<SMultiSpkFile> *node = m_lFiles.Front(); node; node = node->next() ) {
1 cycrow 823
		SMultiSpkFile *ms = node->Data();
824
		CBaseFile *package = NULL;
825
		if ( ms->iType == TYPE_XSP )
826
			package = new CXspFile;
827
		else
828
			package = new CSpkFile;
829
 
51 cycrow 830
		if ( !addToList ) {
831
			if ( ms->pFile ) {
1 cycrow 832
				delete package;
833
				package = ms->pFile;
834
			}
835
		}
836
 
51 cycrow 837
		if ( !package->IsFullyLoaded() ) {
58 cycrow 838
			long tell = File.position();
839
			package->readFile(File, type, NULL);
1 cycrow 840
 
51 cycrow 841
			if ( addToList ) {
1 cycrow 842
				addToList->push_back(package);
843
				package->SetEnabled(ms->bOn);
844
			}
845
			else if ( package )
846
				ms->pFile = package;
847
 
848
			// move to correct position in file for next stream of data
849
			// should be fine, this is more of a failsafe
58 cycrow 850
			File.seekStart(tell);
1 cycrow 851
		}
58 cycrow 852
		File.seek(ms->lSize);
1 cycrow 853
	}
854
 
58 cycrow 855
	File.close();
1 cycrow 856
	return true;
857
}
858
 
859
 
176 cycrow 860
SMultiSpkFile *CMultiSpkFile::FindFile ( CyString sName )
1 cycrow 861
{
176 cycrow 862
	Utils::String name = sName.ToString();
1 cycrow 863
	for ( CListNode<SMultiSpkFile> *node = m_lFiles.Front(); node; node = node->next() )
864
	{
865
		SMultiSpkFile *ms = node->Data();
866
		if ( ms->sName.Compare(name) )
867
			return ms;
868
	}
869
	return NULL;
870
}
871
 
872
void CMultiSpkFile::UpdatedPackage(CBaseFile *p)
873
{
874
	SMultiSpkFile *s = this->FindPackage(p);
875
	if ( s )
876
	{
877
		if ( s->sData )
878
			delete s->sData;
879
		s->sData = (char *)p->CreateData((size_t*)&s->lSize);
880
	}
881
}
882
 
883
SMultiSpkFile *CMultiSpkFile::FindPackage(CBaseFile *p)
884
{
885
	for ( CListNode<SMultiSpkFile> *node = m_lFiles.Front(); node; node = node->next() )
886
	{
887
		SMultiSpkFile *ms = node->Data();
888
		if ( ms->pFile == p )
889
			return ms;
890
	}
891
 
892
	return NULL;
893
}
894
 
895
SMultiSpkFile *CMultiSpkFile::FindPackage(CyString name, CyString author)
896
{
897
	for ( CListNode<SMultiSpkFile> *node = m_lFiles.Front(); node; node = node->next() )
898
	{
899
		SMultiSpkFile *ms = node->Data();
900
		if ( !ms->pFile )
901
			continue;
902
 
50 cycrow 903
		if ( ms->pFile->name().Compare(name.ToString()) && ms->pFile->author().Compare(author.ToString()) )
1 cycrow 904
			return ms;
905
	}
906
 
907
	return NULL;
908
}