Subversion Repositories spk

Rev

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