Subversion Repositories spk

Rev

Rev 53 | Rev 56 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 53 Rev 54
Line 620... Line 620...
620
	return false;
620
	return false;
621
}
621
}
622
 
622
 
623
int C_File::ReadScriptVersion ()
623
int C_File::ReadScriptVersion ()
624
{
624
{
625
	if ( (m_iFileType != FILETYPE_SCRIPT) && (m_iFileType != FILETYPE_UNINSTALL) )
625
	if ( (m_iFileType != FILETYPE_SCRIPT) && (m_iFileType != FILETYPE_UNINSTALL) ) return 0;
626
		return 0;
-
 
627
 
626
 
628
	// check file pointer
-
 
629
	CyString file = GetFilePointer();
-
 
630
	// check file extenstion
-
 
631
	if ( (CFileIO(file).CheckFileExtension("pck")) || (CheckPCK()) )
-
 
632
	{
-
 
633
		size_t size = 0;
-
 
634
		unsigned char *data = UnPCKFile ( &size );
-
 
635
		if ( (data) && (size) )
-
 
636
			m_iVersion = ::ReadScriptVersionFromData ( data, (long)size );
-
 
637
	}
-
 
638
	else if ( (m_sData) && (m_iDataCompression == SPKCOMPRESS_NONE) )
627
	if ( (m_sData) && (m_iDataCompression == SPKCOMPRESS_NONE) )
639
		m_iVersion = ::ReadScriptVersionFromData ( m_sData, m_lDataSize );
628
		m_iVersion = ::ReadScriptVersionFromData ( m_sData, m_lDataSize );
640
	else
629
	else {
641
	{
-
 
642
		FILE *id = fopen ( file.c_str(), "rb+" );
-
 
643
		if ( id )
-
 
644
		{
-
 
645
			fclose ( id );
-
 
646
			std::string line;
-
 
647
			std::ifstream myfile ( file.c_str() );
630
		CFileIO File(GetFilePointer());
648
			if ( myfile.is_open() )
631
		if ( File.startRead() ) {
649
			{
-
 
650
				bool inscript = false;
-
 
651
				while (! myfile.eof() )
-
 
652
				{
-
 
653
					std::getline ( myfile, line );
632
			int iRead = (File.fileSize() > 5000) ? 5000 : File.fileSize();
654
					while ( line[0] == ' ' )
-
 
655
						line.erase ( 0, 1 );
-
 
656
					CyString sLine = line;
633
			unsigned char *data = File.read(iRead);
657
					if ( !inscript )
634
			if ( data ) {
658
					{
-
 
659
						if ( sLine.GetToken ( 1, '>' ) == "<script" )
-
 
660
							inscript = true;
-
 
661
					}
-
 
662
					else
-
 
663
					{
-
 
664
						if ( sLine.GetToken ( 1, '>' ) == "<version" )
-
 
665
						{
-
 
666
							m_iVersion = sLine.GetToken ( 2, '>' ).GetToken ( 1, '<' ).ToInt();
635
				m_iVersion = ::ReadScriptVersionFromData(data, iRead);
667
							break;
636
				delete []data;
668
						}
-
 
669
					}
-
 
670
				}
-
 
671
				myfile.close();
-
 
672
			}
637
			}
673
		}
638
		}
674
	}
639
	}
675
 
640
 
676
	return m_iVersion;
641
	return m_iVersion;
677
}
642
}
678
 
643
 
679
bool C_File::MatchFile ( C_File *file )
644
bool C_File::MatchFile ( C_File *file )
680
{
645
{
681
	if ( file->GetFileType() != m_iFileType )
646
	if ( file->GetFileType() != m_iFileType )
682
		return false;
647
		return false;
683
 
648
 
684
	if ( file->GetDir() != m_sDir )
649
	if ( file->GetDir() != m_sDir )
685
		return false;
650
		return false;
686
 
651
 
687
	if ( file->GetName() != m_sName )
652
	if ( file->GetName() != m_sName )
688
		return false;
653
		return false;
689
 
654
 
690
	return true;
655
	return true;
691
}
656
}
Line 723... Line 688...
723
			fclose(fOut);
688
			fclose(fOut);
724
			if ( err == Z_OK )
689
			if ( err == Z_OK )
725
			{
690
			{
726
				DeleteData ();
691
				DeleteData ();
727
 
692
 
728
				FILE *id = fopen ( "tempcompr.dat", "rb" );
693
				CFileIO File("tempcompr.dat");
729
				if ( id )
-
 
730
				{
-
 
731
					fseek ( id, 0, SEEK_END );
694
				File.setAutoDelete(true);
732
					m_lDataSize = ftell ( id );
695
				if ( File.startRead() ) {
733
					rewind ( id );
-
 
734
					m_sData = new unsigned char[m_lDataSize];
696
					m_sData = File.readAll((size_t *)&m_lDataSize);
735
					if ( !m_sData ) { fclose ( id ); m_iLastError = SPKERR_MALLOC; }
-
 
736
					else
-
 
737
					{
-
 
738
						fread ( m_sData, sizeof(unsigned char), m_lDataSize, id );
-
 
739
						if ( ferror(id) )
697
					if ( !m_sData ) {
740
						{
-
 
741
							m_iLastError = SPKERR_FILEREAD;
698
						m_iLastError = SPKERR_FILEREAD;
742
							DeleteData ();
-
 
743
							m_lDataSize = 0;
699
						m_lDataSize = 0;
744
						}
700
					}
745
						else
701
					else {
746
						{
-
 
747
							ret = true;
-
 
748
							m_iLastError = SPKERR_NONE;
702
						m_iLastError = SPKERR_NONE;
749
							m_iDataCompression = SPKCOMPRESS_ZLIB;
703
						m_iDataCompression = SPKCOMPRESS_ZLIB;
750
						}
704
						ret = true;
751
					}
705
					}
752
 
-
 
753
					fclose(id);
-
 
754
				}
706
				}
-
 
707
				File.close();
755
			}
708
			}
756
		}
709
		}
757
		CFileIO::Remove("tempcompr.dat");
-
 
758
 
-
 
759
		fclose(fIn);
710
		fclose(fIn);
760
	}
711
	}
761
 
712
 
762
	CFileIO::Remove("tempuncompr.dat");
713
	CFileIO::Remove("tempuncompr.dat");
763
 
714
 
Line 771... Line 722...
771
		return false;
722
		return false;
772
 
723
 
773
	// laready compressed to correct type
724
	// laready compressed to correct type
774
	if ( compressionType == m_iDataCompression )
725
	if ( compressionType == m_iDataCompression )
775
		return true;
726
		return true;
776
 
727
 
777
	// otherwise, lets recompress the file
728
	// otherwise, lets recompress the file
778
	// first we uncompress the data
729
	// first we uncompress the data
779
	if ( !this->UncompressData(progress) )
730
	if ( !this->UncompressData(progress) )
780
		return false;
731
		return false;
781
 
732
 
Line 810... Line 761...
810
						break;
761
						break;
811
				}	
762
				}	
812
 
763
 
813
				// if its compressed ok, remove old data and use new one
764
				// if its compressed ok, remove old data and use new one
814
				if ( err == Z_OK )
765
				if ( err == Z_OK )
815
				{
766
				{
816
					unsigned char *retData = new unsigned char[comprLen];
767
					unsigned char *retData = new unsigned char[comprLen];
817
					(*outSize) = comprLen;
768
					(*outSize) = comprLen;
818
					memcpy(retData, compr, comprLen);
769
					memcpy(retData, compr, comprLen);
819
					free(compr);
770
					free(compr);
820
					return retData;
771
					return retData;
821
				}
772
				}
822
 
773
 
823
				free(compr);
774
				free(compr);
824
				return NULL;
775
				return NULL;
825
			}
776
			}
826
			break;
777
			break;
827
 
778
 
828
		case SPKCOMPRESS_LZMA:
779
		case SPKCOMPRESS_LZMA:
Line 865... Line 816...
865
	if ( compressionType == SPKCOMPRESS_ZLIB && (this->CheckFileExt("pck") || this->CheckFileExt("cat") || this->CheckFileExt("dat") || this->CheckFileExt("pbb") || this->CheckFileExt("pbd")) )
816
	if ( compressionType == SPKCOMPRESS_ZLIB && (this->CheckFileExt("pck") || this->CheckFileExt("cat") || this->CheckFileExt("dat") || this->CheckFileExt("pbb") || this->CheckFileExt("pbd")) )
866
		compressionType = SPKCOMPRESS_LZMA;
817
		compressionType = SPKCOMPRESS_LZMA;
867
 
818
 
868
	// if its already compressed, no need to compress again
819
	// if its already compressed, no need to compress again
869
	if ( compressionType == m_iDataCompression )
820
	if ( compressionType == m_iDataCompression )
870
		return true;
821
		return true;
871
 
822
 
872
	// no need to change the compression
823
	// no need to change the compression
873
	if ( m_iDataCompression != SPKCOMPRESS_NONE )
824
	if ( m_iDataCompression != SPKCOMPRESS_NONE )
874
		return true;
825
		return true;
875
 
826
 
876
	m_lUncomprDataSize = m_lDataSize;
827
	m_lUncomprDataSize = m_lDataSize;
Line 912... Line 863...
912
					delete compr;
863
					delete compr;
913
			}
864
			}
914
		}
865
		}
915
 
866
 
916
		if ( bestCompress != -1 && bestCompr )
867
		if ( bestCompress != -1 && bestCompr )
917
		{
868
		{
918
			DeleteData ();
869
			DeleteData ();
919
			m_sData = bestCompr;
870
			m_sData = bestCompr;
920
			m_bUsedMalloc = false;
871
			m_bUsedMalloc = false;
921
			m_lDataSize = bestSize;
872
			m_lDataSize = bestSize;
922
			m_iDataCompression = bestCompress;
873
			m_iDataCompression = bestCompress;
923
			return true;
874
			return true;
Line 944... Line 895...
944
 
895
 
945
	return false;
896
	return false;
946
}
897
}
947
 
898
 
948
bool C_File::UncompressData ( CProgressInfo *progress )
899
bool C_File::UncompressData ( CProgressInfo *progress )
949
{
900
{
950
	// no data to try to uncompress
901
	// no data to try to uncompress
951
	if ( (!m_sData) || (!m_lDataSize) ) {
902
	if ( (!m_sData) || (!m_lDataSize) ) {
952
		return (m_lSize) ? false : true;
903
		return (m_lSize) ? false : true;
953
	}
904
	}
954
 
905
 
Line 1130... Line 1081...
1130
}
1081
}
1131
 
1082
 
1132
bool C_File::WriteToFile ( CyString filename, unsigned char *cData, long len )
1083
bool C_File::WriteToFile ( CyString filename, unsigned char *cData, long len )
1133
{
1084
{
1134
	unsigned char *data = cData;
1085
	unsigned char *data = cData;
1135
	if ( (!len) || (!data) )
1086
	if ( (!len) || (!data) ) {
1136
	{
-
 
1137
		len = m_lDataSize;
1087
		len = m_lDataSize;
1138
		data = m_sData;
1088
		data = m_sData;
1139
	}
1089
	}
1140
 
1090
 
1141
	if ( (!len) || (!data) ) {
1091
	if ( (!len) || (!data) ) {
1142
		if ( m_lSize ) return false;
1092
		if ( m_lSize ) return false;
1143
	}
1093
	}
-
 
1094
 
-
 
1095
	bool ret = false;
1144
 
1096
 
1145
	// check for cat file
1097
	// check for cat file
1146
	if ( filename.IsIn ( "::" ) )
1098
	if ( filename.IsIn ( "::" ) ) {
1147
	{
-
 
1148
		CyString catfile = filename.GetToken ( ";::", 1, 1 );
1099
		Utils::String catfile = filename.GetToken ( ";::", 1, 1 ).ToString();
1149
		CyString file = filename.GetToken ( ";::", 2, 2 );
1100
		Utils::String file = filename.GetToken ( ";::", 2, 2 ).ToString();
1150
 
1101
 
1151
		CCatFile newcat;
1102
		CCatFile newcat;
1152
		return newcat.AddData ( catfile, data, len, file, true, true );
1103
		return newcat.AddData ( catfile, data, len, file, true, true );
1153
	}
1104
	}
1154
	else
1105
	else {
1155
	{
-
 
1156
		CyString filen = filename.FindReplace ( "/", "\\" );
1106
		Utils::String filen = filename.FindReplace ( "/", "\\" ).ToString();
1157
		filen = filen.FindReplace ( "\\\\", "\\" );
1107
		filen = filen.findReplace ( "\\\\", "\\" );
1158
 
-
 
1159
		FILE *id = fopen ( filen.c_str(), "wb" );
-
 
1160
		if ( !id )
-
 
1161
			return false;
-
 
1162
 
1108
 
1163
		bool ret = true;
-
 
1164
		if ( len && data ) {
1109
		if ( len && data ) {
1165
			fwrite ( data, sizeof(unsigned char), len, id );
-
 
1166
 
-
 
1167
			if ( ferror(id) )
-
 
1168
				ret = false;
1110
			CFileIO File(filen);
1169
 
-
 
1170
			fclose ( id );
1111
			if ( File.startWrite() ) ret = File.write(data, len);
1171
		}
1112
		}
1172
		return ret;
-
 
1173
	}
1113
	}
1174
 
1114
 
1175
	return false;
1115
	return ret;
1176
}
1116
}
1177
 
1117
 
1178
CyString C_File::GetFullFileToDir ( CyString dir, bool includedir, CBaseFile *file )
1118
CyString C_File::GetFullFileToDir ( CyString dir, bool includedir, CBaseFile *file )
1179
{
1119
{
1180
	CyString fullfile = dir;
1120
	CyString fullfile = dir;
Line 1466... Line 1406...
1466
bool C_File::CheckPCK ()
1406
bool C_File::CheckPCK ()
1467
{
1407
{
1468
	if ( (m_sData) && (m_lDataSize) && (m_iDataCompression == SPKCOMPRESS_NONE) )
1408
	if ( (m_sData) && (m_lDataSize) && (m_iDataCompression == SPKCOMPRESS_NONE) )
1469
		return IsDataPCK ( m_sData, m_lDataSize );
1409
		return IsDataPCK ( m_sData, m_lDataSize );
1470
 
1410
 
1471
	CyString filename = GetFilePointer();
1411
	Utils::String filename = GetFilePointer().ToString();
1472
	if ( !filename.Empty() )
1412
	if ( !filename.empty() ) {
1473
	{
-
 
1474
		FILE *id = fopen ( filename.c_str(), "rb+" );
1413
		CFileIO File(filename);
1475
		if ( id )
1414
		if ( File.startRead() ) {
1476
		{
-
 
1477
			unsigned char data[3];
1415
			unsigned char data[4];
1478
			fread ( data, sizeof(unsigned char), 3, id );
-
 
1479
			fclose ( id );
-
 
1480
 
-
 
1481
			return IsDataPCK ( data, 3 );
1416
			if ( File.read(data, 3) ) return IsDataPCK ( data, 3 );
1482
		}
1417
		}
1483
	}
1418
	}
1484
 
1419
 
1485
	if ( CheckFileExt("pck") || CheckFileExt("pbb") || CheckFileExt("pbd") )
1420
	if ( CheckFileExt("pck") || CheckFileExt("pbb") || CheckFileExt("pbd") ) return true;
1486
		return true;
-
 
1487
	return false;
1421
	return false;
1488
}
1422
}
1489
 
1423
 
1490
bool C_File::PCKFile()
1424
bool C_File::PCKFile()
1491
{
1425
{
1492
	if ( !m_lDataSize || !m_sData )
1426
	if ( !m_lDataSize || !m_sData )
1493
	{
1427
	{
1494
		if ( !this->ReadFromFile() )
1428
		if ( !this->ReadFromFile() )
1495
			return false;
1429
			return false;
1496
	}
1430
	}
1497
 
1431
 
1498
	if ( m_lDataSize && m_sData )
1432
	if ( m_lDataSize && m_sData )
1499
	{
1433
	{
1500
		if ( !this->UncompressData() )
1434
		if ( !this->UncompressData() )
1501
			return false;
1435
			return false;
1502
 
1436
 
1503
		size_t size;
1437
		size_t size;
1504
		unsigned char *data = PCKData(m_sData, m_lDataSize, &size, false);
1438
		unsigned char *data = PCKData(m_sData, m_lDataSize, &size, false);
1505
		if ( data && size )
1439
		if ( data && size )
1506
		{
1440
		{
1507
			m_lUncomprDataSize = m_lDataSize;
1441
			m_lUncomprDataSize = m_lDataSize;
1508
			this->DeleteData();
1442
			this->DeleteData();
1509
			m_bUsedMalloc = false;
1443
			m_bUsedMalloc = false;
1510
			m_lDataSize = (long)size;
1444
			m_lDataSize = (long)size;
1511
			m_sData = new unsigned char[size];
1445
			m_sData = new unsigned char[size];
1512
			memcpy(m_sData, data, size);
1446
			memcpy(m_sData, data, size);
1513
			delete [] data;
1447
			delete [] data;
1514
		}
1448
		}
1515
 
1449
 
1516
		return true;
1450
		return true;
1517
	}
1451
	}
Line 1524... Line 1458...
1524
	unsigned char *data = NULL;
1458
	unsigned char *data = NULL;
1525
	size_t datasize = 0;
1459
	size_t datasize = 0;
1526
 
1460
 
1527
	if ( CheckValidFilePointer() )
1461
	if ( CheckValidFilePointer() )
1528
	{
1462
	{
1529
		FILE *id = fopen ( GetFilePointer().c_str(), "rb+" );
1463
		CFileIO File(GetFilePointer().ToString());
1530
		if ( id )
-
 
1531
		{
-
 
1532
			fseek ( id, 0, SEEK_END );
-
 
1533
			datasize = ftell ( id );
-
 
1534
			rewind ( id );
-
 
1535
 
-
 
1536
			data = new unsigned char[datasize];
-
 
1537
			fread ( data, sizeof(unsigned char), datasize, id );
1464
		if ( File.startRead() ) data = File.readAll(&datasize);
1538
			fclose ( id );
-
 
1539
		}
-
 
1540
	}
1465
	}
1541
 
1466
 
1542
	if ( !data )
1467
	if ( !data )
1543
	{
1468
	{
1544
		if ( !m_lDataSize )
1469
		if ( !m_lDataSize )
Line 1554... Line 1479...
1554
	if ( data )
1479
	if ( data )
1555
	{
1480
	{
1556
		unsigned char *newdata = UnPCKData ( data, datasize, len, CheckPCK() );
1481
		unsigned char *newdata = UnPCKData ( data, datasize, len, CheckPCK() );
1557
		delete data;
1482
		delete data;
1558
		return newdata;
1483
		return newdata;
1559
	}
1484
	}
1560
 
1485
 
1561
	return NULL;
1486
	return NULL;
1562
}
1487
}
1563
 
1488
 
1564
bool C_File::UnPCKFile()
1489
bool C_File::UnPCKFile()
1565
{
1490
{
1566
	if ( !m_lDataSize || !m_sData )
1491
	if ( !m_lDataSize || !m_sData )
Line 1592... Line 1517...
1592
	return false;
1517
	return false;
1593
}
1518
}
1594
 
1519
 
1595
unsigned char *UnPCKFile ( const char *file, size_t *len, bool nocrypt )
1520
unsigned char *UnPCKFile ( const char *file, size_t *len, bool nocrypt )
1596
{
1521
{
1597
	FILE *id = fopen ( file, "rb" );
1522
	CFileIO File(file);
1598
	if ( !id )
-
 
1599
		return NULL;
1523
	if ( !File.startRead() ) return NULL;
1600
 
1524
 
1601
	fseek ( id, 0, SEEK_END );
-
 
1602
	size_t size = ftell ( id );
1525
	size_t size;
1603
	fseek ( id, 0, SEEK_SET );
-
 
1604
 
-
 
1605
	unsigned char *data = new unsigned char[size];
1526
	unsigned char *data = File.readAll(&size);
1606
	fread ( data, sizeof(unsigned char), size, id );
-
 
1607
 
-
 
1608
	if ( ferror(id) )
-
 
1609
	{
-
 
1610
		delete data;
-
 
1611
		data = NULL;
-
 
1612
	}
-
 
1613
 
1527
 
1614
	fclose ( id );
-
 
1615
 
-
 
1616
	if ( data )
1528
	if ( data ) {
1617
	{
-
 
1618
		unsigned char *unData = UnPCKData ( data, size, len, nocrypt );
1529
		unsigned char *unData = UnPCKData ( data, size, len, nocrypt );
1619
		delete data;
1530
		delete data;
1620
		return unData;
1531
		return unData;
1621
	}
1532
	}
1622
 
1533
 
Line 1744... Line 1655...
1744
	return false;
1655
	return false;
1745
}
1656
}
1746
 
1657
 
1747
int ReadScriptVersionFromData ( unsigned char *data, long size )
1658
int ReadScriptVersionFromData ( unsigned char *data, long size )
1748
{
1659
{
-
 
1660
	int iVersion = 0;
-
 
1661
 
1749
	if ( IsDataPCK ( data, size ) )
1662
	if ( IsDataPCK ( data, size ) )
1750
	{
1663
	{
1751
		size_t unpckSize = 0;
1664
		size_t unpckSize = 0;
1752
		unsigned char *unpckData = UnPCKData ( data, size, &unpckSize );
1665
		unsigned char *unpckData = UnPCKData ( data, size, &unpckSize );
1753
		if ( (unpckData) && (unpckSize) )
1666
		if ( (unpckData) && (unpckSize) ) {
1754
			return ReadScriptVersionFromData ( unpckData, (long)unpckSize );
1667
			iVersion = ReadScriptVersionFromData ( unpckData, (long)unpckSize );
-
 
1668
			delete unpckData;
-
 
1669
		}
1755
		return 0;
1670
		return iVersion;
1756
	}
1671
	}
1757
 
1672
 
-
 
1673
	// only check the beginning of the file
-
 
1674
	int iMax = (size > 5000) ? 5000 : size;
-
 
1675
 
1758
	int pos = 0;
1676
	int pos = 0;
1759
	bool found = false;
1677
	bool found = false;
1760
	int iVersion = 0;
-
 
1761
 
-
 
1762
	// skip past initial space
1678
	// skip past initial space
-
 
1679
	char tag[21];
1763
	while ( !found )
1680
	while ( pos < iMax )
1764
	{
1681
	{
-
 
1682
		// skip past whitespace
1765
		while ( (pos < size) && (data[pos] == ' ') )
1683
		while ( (pos < iMax) && (data[pos] == ' ') ) ++pos;
-
 
1684
		// find the first '<'
-
 
1685
		while ( (pos < iMax) && (data[pos] != '<') ) ++pos;
-
 
1686
		if ( data[pos] != '<' ) break; //not found
-
 
1687
 
-
 
1688
		// find end tag '>'
1766
			++pos;
1689
		int iStartPos = pos;
-
 
1690
		while ( (pos < iMax) && (data[pos] != '>') ) ++pos;
-
 
1691
		if ( data[pos] != '>' ) break; //not found
-
 
1692
		if ( (pos - iStartPos) > 20 ) continue;
1767
 
1693
 
1768
		if ( data[pos] == '<' )
-
 
1769
		{
-
 
1770
			CyString checktag;
-
 
1771
			while ( (pos < size) && (data[pos] != '>') )
1694
		// check if the tag is what we're looking for
1772
			{
-
 
1773
				checktag += (char)data[pos];
1695
		memcpy(tag, data + iStartPos, pos - iStartPos);
1774
				++pos;
-
 
1775
			}
-
 
1776
			++pos;
-
 
1777
 
-
 
1778
			if ( checktag == &quot;&lt;version"; )
1696
		tag[pos - iStartPos] = &apos;\0&apos;;
1779
			{
-
 
1780
				CyString version;
1697
		Utils::String sTag(tag);
1781
				while ( (pos < size) && (data[pos] != '<') )
-
 
1782
				{
-
 
1783
					version += (char)data[pos];
-
 
1784
					++pos;
-
 
1785
				}
-
 
1786
				iVersion = version.ToInt();
1698
		if ( !sTag.Compare("<version") ) continue;
1787
				found = true;
-
 
1788
				break;
-
 
1789
			}
-
 
1790
		}
1699
		
1791
 
-
 
1792
		if ( found )
1700
		//extract the tag data
1793
			break;
-
 
1794
 
-
 
1795
		// skip to next line
1701
		iStartPos = pos + 1;
1796
		while ( (pos < size) && (data[pos] != '\n&apos;) )
1702
		while ( (pos < iMax) && (data[pos] != '<&apos;) ) ++pos;
1797
			++pos;
1703
		if ( (pos - iStartPos) > 20 ) continue;
1798
		++pos;
1704
		memcpy(tag, data + iStartPos, pos - iStartPos);
1799
 
-
 
1800
		if ( pos &gt;= size )
1705
		tag[pos - iStartPos] = &apos;\0';
1801
			break;
1706
		return atoi(tag);
1802
	}
1707
	}
1803
 
1708
 
1804
	return iVersion;
1709
	return iVersion;
1805
}
1710
}
1806
 
1711