Subversion Repositories spk

Rev

Rev 58 | Rev 176 | 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
}
95
bool CMultiSpkFile::AddFile ( CyString file, bool on )
96
{
97
	// multipack
98
	if ( file.IsIn ( "::" ) )
99
	{
100
		CyString mfile = file.Left ( file.FindPos("::") );
101
		CMultiSpkFile spkfile;
102
		if ( spkfile.ReadFile ( mfile, false ) )
103
		{
104
			SMultiSpkFile *ms = new SMultiSpkFile;
105
			ms->bRemove = false;
106
			ms->sName = file.Right ( (int)(file.Length() - file.FindPos("::")) - 2 );
107
			ms->pFile = NULL;
108
			ms->sData = NULL;
109
			if ( spkfile.ExtractData ( ms ) )
110
			{
111
				ms->bOn = on;
112
				AddFile(ms);
113
				return true;
114
			}
115
			delete ms;
116
		}
117
		return false;
118
	}
119
 
120
	// check its a valid file
175 cycrow 121
	int check = CBaseFile::CheckFile(file.ToString());
1 cycrow 122
	if ( check == SPKFILE_MULTI )
123
	{
124
		CMultiSpkFile spkfile;
125
		if ( spkfile.ReadFile ( file, false ) )
126
		{
127
			CLinkList<SMultiSpkFile> *list = spkfile.GetFileList();
128
			for ( SMultiSpkFile *it = list->First(); it; it = list->Next() )
129
			{
130
				SMultiSpkFile *ms = new SMultiSpkFile;
131
				ms->bRemove = false;
132
				ms->sName = it->sName;
133
				ms->pFile = NULL;
134
				ms->sData = NULL;
135
				if ( spkfile.ExtractData ( ms ) )
136
				{
137
					ms->bOn = on;
138
					AddFile(ms);
139
				}
140
				else
141
					delete ms;
142
			}
143
			return true;
144
		}
145
		return false;
146
	}
147
	else if ( check != SPKFILE_SINGLE && check != SPKFILE_SINGLESHIP )
148
		return false;
149
 
56 cycrow 150
	CFileIO File(file);
151
	if ( !File.startRead() ) return false;
1 cycrow 152
 
153
	// create entry
154
	SMultiSpkFile *ms = new SMultiSpkFile;
155
	ms->bRemove = false;
156
	ms->pFile = NULL;
157
	ms->sName = file;
158
	ms->sName = ms->sName.FindReplace ( "\\", "/" );
159
	ms->sName = ms->sName.GetToken ( ms->sName.NumToken('/'), '/' );
160
	ms->bOn = on;
161
 
162
	// read data
56 cycrow 163
	ms->sData = (char *)File.readAll((size_t *)&ms->lSize);
164
	File.close();
1 cycrow 165
 
166
	CBaseFile *baseFile = NULL;
167
	if ( check == SPKFILE_SINGLE )
168
		baseFile = new CSpkFile;
169
	else if ( check == SPKFILE_SINGLESHIP )
170
		baseFile = new CXspFile;
171
 
56 cycrow 172
	if ( baseFile ) {
175 cycrow 173
		if ( baseFile->readFile(file.ToString(), SPKREAD_VALUES)) {
50 cycrow 174
			ms->sScriptAuthor	= baseFile->author();
175
			ms->sScriptName		= baseFile->name();
176
			ms->sScriptVersion	= baseFile->version();
1 cycrow 177
			ms->iType			= baseFile->GetType();
178
		}
179
 
180
		delete baseFile;
181
	}
182
 
183
	AddFile(ms);
184
 
185
	return true;
186
}
187
 
188
SMultiSpkFile *CMultiSpkFile::AddFileEntry ( CyString filename )
189
{
190
	SMultiSpkFile *ms = new SMultiSpkFile;
191
	ms->bRemove = false;
192
	ms->pFile = NULL;
193
	ms->sName = filename;
194
	ms->bOn = true;
195
	ms->iType = -1;
196
 
197
	m_lFiles.push_back ( ms );
198
	m_bChanged = true;
199
 
200
	return ms;
201
}
202
 
203
CyString CMultiSpkFile::CreateData ()
204
{
205
	CyString ret;
206
	if ( !m_sName.Empty() )
207
		ret = CyString("Name: ") + m_sName + "\n";
208
	for ( CListNode<SMultiSpkFile> *node = m_lFiles.Front(); node; node = node->next() )
209
	{
210
		SMultiSpkFile *ms = node->Data();
211
		if ( ms->iType == TYPE_XSP )
212
			ret += "XspFile: ";
213
		else 
214
			ret += "SpkFile: ";
215
 
216
		if ( ms->bOn )
217
			ret += "1:";
218
		else
219
			ret += "0:";
220
		ret += ms->lSize;
221
		ret += ":";
222
		ret += ms->sName;
223
		if ( !ms->sScriptName.Empty() )
224
			ret += (CyString(":") + ms->sScriptName + "|" + ms->sScriptAuthor + "|" + ms->sScriptVersion);
225
		ret += "\n";
226
	}
227
 
228
	return ret;
229
}
230
 
231
bool CMultiSpkFile::WriteFile ( CyString filename, CProgressInfo *progress )
232
{
52 cycrow 233
	CFileIO File(filename);
234
	if ( !File.startWrite() ) return false;
1 cycrow 235
 
236
	// make sure we remove all packages that have been marked
237
	this->RemovePackages();
238
 
239
	CyString data = CreateData ();
240
 
241
	int comprLen = (int)data.Length(), uncomprLen = comprLen;;
242
	unsigned char *compr = NULL;
243
 
244
	bool compressed = false;
245
	int valueheader = m_SHeader.iCompression;
246
	if ( valueheader == SPKCOMPRESS_7ZIP )
247
		valueheader = SPKCOMPRESS_ZLIB;
248
 
249
	if ( valueheader == SPKCOMPRESS_ZLIB )
250
	{
251
		comprLen = uncomprLen;	
252
		if ( comprLen < 100 )
253
			comprLen = 200;
254
		else if ( comprLen < 1000 )
255
			comprLen *= 2;
256
 
257
		compr = (unsigned char *)calloc((unsigned int)comprLen, 1);
258
		int err = compress ( (unsigned char *)compr, (unsigned long *)&comprLen, (const unsigned char *)data.c_str(), (unsigned long)data.Length(), 0 );
259
		if ( err == Z_OK )
260
			compressed = true;
261
	}
262
 
263
	if ( !compressed )
264
	{
265
		comprLen = uncomprLen;
266
		compr = (unsigned char *)calloc((unsigned int)comprLen, 1);
267
		memcpy ( compr, data.c_str(), comprLen );
268
		valueheader = SPKCOMPRESS_NONE;
269
	}
270
 
271
	// write the main header to the file
52 cycrow 272
	if ( !File.write("MSPKCycrow;%.2f;%d;%d;%d;%d\n", FILEVERSION, valueheader, data.Length(), comprLen, (m_SHeader.bSelection) ? 1 : 0) ) return false;
1 cycrow 273
 
274
	// write the compressed data to file
52 cycrow 275
	File.writeSize(uncomprLen);
276
	File.write(compr, comprLen);
1 cycrow 277
	free ( compr );
278
 
52 cycrow 279
	for ( CListNode<SMultiSpkFile> *node = m_lFiles.Front(); node; node = node->next() ) {
1 cycrow 280
		SMultiSpkFile *ms = node->Data();
281
		if ( progress )
282
			progress->UpdatePackage(ms);
283
		if ( (!ms->sData) && (ms->pFile) )
175 cycrow 284
			ms->pFile->writeData(File, NULL);
1 cycrow 285
		else
52 cycrow 286
			File.write(ms->sData, ms->lSize);
1 cycrow 287
	}
288
 
289
	return true;
290
}
291
 
292
bool CMultiSpkFile::ParseHeader ( CyString header )
293
{
294
	if ( header.GetToken ( 1, ';' ) != "MSPKCycrow" )
295
		return false;
296
 
297
	m_SHeader.fVersion = header.GetToken ( 2, ';' ).ToFloat();
298
	if ( m_SHeader.fVersion > FILEVERSION )
299
		return false;
300
 
301
	m_SHeader.iCompression = header.GetToken ( 3, ';' ).ToInt();
302
	m_SHeader.lUncomprLen = header.GetToken ( 4, ';' ).ToLong();
303
	m_SHeader.lComprLen = header.GetToken ( 5, ';' ).ToLong();
304
	m_SHeader.bSelection = (header.GetToken ( 4, ';' ).ToInt()) ? true : false;
305
 
306
	return true;
307
}
308
 
309
bool CMultiSpkFile::ParseValueLine ( CyString line )
310
{
311
	CyString first = line.GetToken ( 1, ' ' );
312
	CyString rest  = line.GetToken ( 2, -1, ' ' );
313
 
314
	if ( first == "Name:" )
315
		m_sName = rest;
316
	else if ( first == "SpkFile:" )
317
	{
318
		SMultiSpkFile *ms = new SMultiSpkFile;
319
		ms->bRemove = false;
320
		ms->pFile = NULL;
321
		ms->bOn = (rest.GetToken ( 1, ':' ).ToInt()) ? true : false;
322
		ms->lSize = rest.GetToken ( 2, ':' ).ToLong();
323
		ms->sName = rest.GetToken ( 3, ':' );
324
		ms->sData = NULL;
325
		ms->iType = TYPE_SPK;
326
		CyString r = rest.GetToken ( 4, -1, ':' );
327
		if ( !r.Empty() )
328
		{
329
			ms->sScriptName = r.GetToken ( 1, '|' );
330
			ms->sScriptAuthor = r.GetToken ( 2, '|' );
331
			ms->sScriptVersion = r.GetToken ( 3, -1, '|' );
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;
340
		ms->bOn = (rest.GetToken ( 1, ':' ).ToInt()) ? true : false;
341
		ms->lSize = rest.GetToken ( 2, ':' ).ToLong();
342
		ms->sName = rest.GetToken ( 3, ':' );
343
		ms->sData = NULL;
344
		ms->iType = TYPE_XSP;
345
		CyString r = rest.GetToken ( 4, -1, ':' );
346
		if ( !r.Empty() )
347
		{
348
			ms->sScriptName = r.GetToken ( 1, '|' );
349
			ms->sScriptAuthor = r.GetToken ( 2, '|' );
350
			ms->sScriptVersion = r.GetToken ( 3, -1, '|' );
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;
359
		ms->bOn = (rest.GetToken ( 1, ':' ).ToInt()) ? true : false;
360
		ms->lSize = rest.GetToken ( 2, ':' ).ToLong();
361
		ms->sName = rest.GetToken ( 3, ':' );
362
		ms->sData = NULL;
363
		ms->iType = TYPE_BASE;
364
		CyString r = rest.GetToken ( 4, -1, ':' );
365
		if ( !r.Empty() )
366
		{
367
			ms->sScriptName = r.GetToken ( 1, '|' );
368
			ms->sScriptAuthor = r.GetToken ( 2, '|' );
369
			ms->sScriptVersion = r.GetToken ( 3, -1, '|' );
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
 
448
	m_sFilename = filename;
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
{
487
	FILE *id = fopen ( m_sFilename.c_str(), "rb" );
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
 
530
	FILE *id = fopen ( m_sFilename.c_str(), "rb" );
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
{
591
	if ( m_sFilename.Empty() )
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
646
	if ( m_sFilename.Empty() )
647
		return false;
648
 
649
	// now open the file
650
	FILE *id = fopen ( m_sFilename.c_str(), "rb" );
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
 
678
bool CMultiSpkFile::RemoveFile ( CyString file )
679
{
680
	int num = 0;
681
	for ( CListNode<SMultiSpkFile> *node = m_lFiles.Front(); node; node = node->next() )
682
	{
683
		SMultiSpkFile *it = node->Data();
684
		if ( file.Compare(it->sName) )
685
			return RemoveFile ( num );
686
		++num;
687
	}
688
	return false;
689
}
690
 
691
bool CMultiSpkFile::RemoveFile ( SMultiSpkFile *ms )
692
{
693
	int num = 0;
694
	for ( CListNode<SMultiSpkFile> *node = m_lFiles.Front(); node; node = node->next() )
695
	{
696
		SMultiSpkFile *it = node->Data();
697
		if ( it == ms )
698
			return RemoveFile ( num );
699
		++num;
700
	}
701
	return false;
702
}
703
 
704
bool CMultiSpkFile::RemoveFile ( int id )
705
{
706
	if ( (id < 0) || (id >= m_lFiles.size()) )
707
		return false;
708
 
709
	SMultiSpkFile *file = m_lFiles.Get ( id );
710
	m_lFiles.erase ( id + 1 );
711
 
712
	if ( file )
713
		delete file;
714
 
715
	m_bChanged = true;
716
	return true;
717
}
718
 
719
bool CMultiSpkFile::MarkRemoveFile ( CyString file )
720
{
721
	int num = 0;
722
	for ( CListNode<SMultiSpkFile> *node = m_lFiles.Front(); node; node = node->next() )
723
	{
724
		SMultiSpkFile *it = node->Data();
725
		if ( file.Compare(it->sName) )
726
			return MarkRemoveFile ( num );
727
		num++;
728
	}
729
	return false;
730
}
731
 
732
bool CMultiSpkFile::MarkRemoveFile ( SMultiSpkFile *ms )
733
{
734
	int num = 0;
735
	for ( CListNode<SMultiSpkFile> *node = m_lFiles.Front(); node; node = node->next() )
736
	{
737
		SMultiSpkFile *it = node->Data();
738
		if ( it == ms )
739
			return MarkRemoveFile ( num );
740
		++num;
741
	}
742
	return false;
743
}
744
 
745
bool CMultiSpkFile::MarkRemoveFile ( int id )
746
{
747
	if ( (id < 0) || (id >= m_lFiles.size()) )
748
		return false;
749
 
750
	SMultiSpkFile *file = m_lFiles.Get ( id );
751
	file->bRemove = true;
752
	m_bChanged = true;
753
	return true;
754
}
755
 
756
void CMultiSpkFile::MarkRemoveAll()
757
{
758
	for ( CListNode<SMultiSpkFile> *node = m_lFiles.Front(); node; node = node->next() )
759
		node->Data()->bRemove = true;
760
	m_bChanged = true;
761
}
762
 
763
 
764
bool CMultiSpkFile::ReadSpk( SMultiSpkFile *ms, int type )
765
{
766
	if ( ms->pFile->IsFullyLoaded() )
767
		return true;
768
 
769
	// no file to read from
770
	if ( m_sFilename.Empty() )
771
		return false;
772
 
773
	// now open the file
58 cycrow 774
	CFileIO File(m_sFilename.ToString());
775
	if ( !File.startRead() ) return false;
1 cycrow 776
 
777
	// read the header
58 cycrow 778
	File.readEndOfLine();
1 cycrow 779
	// skip past values
58 cycrow 780
	File.seek(4 + m_SHeader.lComprLen);
1 cycrow 781
 
782
	bool ret = false;
51 cycrow 783
	for ( CListNode<SMultiSpkFile> *node = m_lFiles.Front(); node; node = node->next() ) {
1 cycrow 784
		SMultiSpkFile *it = node->Data();
785
		if ( it == ms )
786
		{
787
			if ( !ms->pFile )
788
			{
789
				if ( ms->iType == TYPE_XSP )
790
					ms->pFile = new CXspFile;
791
				else
792
					ms->pFile = new CSpkFile;
793
			}
58 cycrow 794
			ret = it->pFile->readFile(File, type, NULL);
1 cycrow 795
			break;
796
		}
797
		else
58 cycrow 798
			File.seek(it->lSize);
1 cycrow 799
	}
800
 
58 cycrow 801
	File.close();
1 cycrow 802
	return ret;
803
}
804
 
805
bool CMultiSpkFile::ReadAllPackages( int type, CLinkList<CBaseFile> *addToList )
806
{
807
	// no file to read from
808
	if ( m_sFilename.Empty() )
809
		return false;
810
 
811
	// now open the file
58 cycrow 812
	CFileIO File(m_sFilename.ToString());
813
	if ( !File.startRead() ) return false;
1 cycrow 814
 
815
	// read the header
58 cycrow 816
	File.readEndOfLine();
1 cycrow 817
	// skip past values
58 cycrow 818
	File.seek(4 + m_SHeader.lComprLen);
1 cycrow 819
 
51 cycrow 820
	for ( CListNode<SMultiSpkFile> *node = m_lFiles.Front(); node; node = node->next() ) {
1 cycrow 821
		SMultiSpkFile *ms = node->Data();
822
		CBaseFile *package = NULL;
823
		if ( ms->iType == TYPE_XSP )
824
			package = new CXspFile;
825
		else
826
			package = new CSpkFile;
827
 
51 cycrow 828
		if ( !addToList ) {
829
			if ( ms->pFile ) {
1 cycrow 830
				delete package;
831
				package = ms->pFile;
832
			}
833
		}
834
 
51 cycrow 835
		if ( !package->IsFullyLoaded() ) {
58 cycrow 836
			long tell = File.position();
837
			package->readFile(File, type, NULL);
1 cycrow 838
 
51 cycrow 839
			if ( addToList ) {
1 cycrow 840
				addToList->push_back(package);
841
				package->SetEnabled(ms->bOn);
842
			}
843
			else if ( package )
844
				ms->pFile = package;
845
 
846
			// move to correct position in file for next stream of data
847
			// should be fine, this is more of a failsafe
58 cycrow 848
			File.seekStart(tell);
1 cycrow 849
		}
58 cycrow 850
		File.seek(ms->lSize);
1 cycrow 851
	}
852
 
58 cycrow 853
	File.close();
1 cycrow 854
	return true;
855
}
856
 
857
 
858
SMultiSpkFile *CMultiSpkFile::FindFile ( CyString name )
859
{
860
	for ( CListNode<SMultiSpkFile> *node = m_lFiles.Front(); node; node = node->next() )
861
	{
862
		SMultiSpkFile *ms = node->Data();
863
		if ( ms->sName.Compare(name) )
864
			return ms;
865
	}
866
	return NULL;
867
}
868
 
869
void CMultiSpkFile::UpdatedPackage(CBaseFile *p)
870
{
871
	SMultiSpkFile *s = this->FindPackage(p);
872
	if ( s )
873
	{
874
		if ( s->sData )
875
			delete s->sData;
876
		s->sData = (char *)p->CreateData((size_t*)&s->lSize);
877
	}
878
}
879
 
880
SMultiSpkFile *CMultiSpkFile::FindPackage(CBaseFile *p)
881
{
882
	for ( CListNode<SMultiSpkFile> *node = m_lFiles.Front(); node; node = node->next() )
883
	{
884
		SMultiSpkFile *ms = node->Data();
885
		if ( ms->pFile == p )
886
			return ms;
887
	}
888
 
889
	return NULL;
890
}
891
 
892
SMultiSpkFile *CMultiSpkFile::FindPackage(CyString name, CyString author)
893
{
894
	for ( CListNode<SMultiSpkFile> *node = m_lFiles.Front(); node; node = node->next() )
895
	{
896
		SMultiSpkFile *ms = node->Data();
897
		if ( !ms->pFile )
898
			continue;
899
 
50 cycrow 900
		if ( ms->pFile->name().Compare(name.ToString()) && ms->pFile->author().Compare(author.ToString()) )
1 cycrow 901
			return ms;
902
	}
903
 
904
	return NULL;
905
}