Subversion Repositories spk

Rev

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