Subversion Repositories spk

Rev

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