|
@@ -87,59 +87,60 @@ static void dummy_free (void* /*opaque*/, void* address) {
|
|
// ------------------------------------------------------------------------------------------------
|
|
// ------------------------------------------------------------------------------------------------
|
|
// Constructor. Creates a data structure out of the XFile given in the memory block.
|
|
// Constructor. Creates a data structure out of the XFile given in the memory block.
|
|
XFileParser::XFileParser( const std::vector<char>& pBuffer)
|
|
XFileParser::XFileParser( const std::vector<char>& pBuffer)
|
|
-{
|
|
|
|
- mMajorVersion = mMinorVersion = 0;
|
|
|
|
- mIsBinaryFormat = false;
|
|
|
|
- mBinaryNumCount = 0;
|
|
|
|
- P = End = NULL;
|
|
|
|
- mLineNumber = 0;
|
|
|
|
- mScene = NULL;
|
|
|
|
-
|
|
|
|
|
|
+: mMajorVersion( 0 )
|
|
|
|
+, mMinorVersion( 0 )
|
|
|
|
+, mIsBinaryFormat( false )
|
|
|
|
+, mBinaryNumCount( 0 )
|
|
|
|
+, mP( nullptr )
|
|
|
|
+, mEnd( nullptr )
|
|
|
|
+, mLineNumber( 0 )
|
|
|
|
+, mScene( nullptr ) {
|
|
// vector to store uncompressed file for INFLATE'd X files
|
|
// vector to store uncompressed file for INFLATE'd X files
|
|
std::vector<char> uncompressed;
|
|
std::vector<char> uncompressed;
|
|
|
|
|
|
// set up memory pointers
|
|
// set up memory pointers
|
|
- P = &pBuffer.front();
|
|
|
|
- End = P + pBuffer.size() - 1;
|
|
|
|
|
|
+ mP = &pBuffer.front();
|
|
|
|
+ mEnd = mP + pBuffer.size() - 1;
|
|
|
|
|
|
// check header
|
|
// check header
|
|
- if( strncmp( P, "xof ", 4) != 0)
|
|
|
|
- throw DeadlyImportError( "Header mismatch, file is not an XFile.");
|
|
|
|
|
|
+ if ( 0 != strncmp( mP, "xof ", 4 ) ) {
|
|
|
|
+ throw DeadlyImportError( "Header mismatch, file is not an XFile." );
|
|
|
|
+ }
|
|
|
|
|
|
// read version. It comes in a four byte format such as "0302"
|
|
// read version. It comes in a four byte format such as "0302"
|
|
- mMajorVersion = (unsigned int)(P[4] - 48) * 10 + (unsigned int)(P[5] - 48);
|
|
|
|
- mMinorVersion = (unsigned int)(P[6] - 48) * 10 + (unsigned int)(P[7] - 48);
|
|
|
|
|
|
+ mMajorVersion = (unsigned int)(mP[4] - 48) * 10 + (unsigned int)(mP[5] - 48);
|
|
|
|
+ mMinorVersion = (unsigned int)(mP[6] - 48) * 10 + (unsigned int)(mP[7] - 48);
|
|
|
|
|
|
bool compressed = false;
|
|
bool compressed = false;
|
|
|
|
|
|
// txt - pure ASCII text format
|
|
// txt - pure ASCII text format
|
|
- if( strncmp( P + 8, "txt ", 4) == 0)
|
|
|
|
|
|
+ if( strncmp( mP + 8, "txt ", 4) == 0)
|
|
mIsBinaryFormat = false;
|
|
mIsBinaryFormat = false;
|
|
|
|
|
|
// bin - Binary format
|
|
// bin - Binary format
|
|
- else if( strncmp( P + 8, "bin ", 4) == 0)
|
|
|
|
|
|
+ else if( strncmp( mP + 8, "bin ", 4) == 0)
|
|
mIsBinaryFormat = true;
|
|
mIsBinaryFormat = true;
|
|
|
|
|
|
// tzip - Inflate compressed text format
|
|
// tzip - Inflate compressed text format
|
|
- else if( strncmp( P + 8, "tzip", 4) == 0)
|
|
|
|
|
|
+ else if( strncmp( mP + 8, "tzip", 4) == 0)
|
|
{
|
|
{
|
|
mIsBinaryFormat = false;
|
|
mIsBinaryFormat = false;
|
|
compressed = true;
|
|
compressed = true;
|
|
}
|
|
}
|
|
// bzip - Inflate compressed binary format
|
|
// bzip - Inflate compressed binary format
|
|
- else if( strncmp( P + 8, "bzip", 4) == 0)
|
|
|
|
|
|
+ else if( strncmp( mP + 8, "bzip", 4) == 0)
|
|
{
|
|
{
|
|
mIsBinaryFormat = true;
|
|
mIsBinaryFormat = true;
|
|
compressed = true;
|
|
compressed = true;
|
|
}
|
|
}
|
|
else ThrowException( format() << "Unsupported xfile format '" <<
|
|
else ThrowException( format() << "Unsupported xfile format '" <<
|
|
- P[8] << P[9] << P[10] << P[11] << "'");
|
|
|
|
|
|
+ mP[8] << mP[9] << mP[10] << mP[11] << "'");
|
|
|
|
|
|
// float size
|
|
// float size
|
|
- mBinaryFloatSize = (unsigned int)(P[12] - 48) * 1000
|
|
|
|
- + (unsigned int)(P[13] - 48) * 100
|
|
|
|
- + (unsigned int)(P[14] - 48) * 10
|
|
|
|
- + (unsigned int)(P[15] - 48);
|
|
|
|
|
|
+ mBinaryFloatSize = (unsigned int)(mP[12] - 48) * 1000
|
|
|
|
+ + (unsigned int)(mP[13] - 48) * 100
|
|
|
|
+ + (unsigned int)(mP[14] - 48) * 10
|
|
|
|
+ + (unsigned int)(mP[15] - 48);
|
|
|
|
|
|
if( mBinaryFloatSize != 32 && mBinaryFloatSize != 64)
|
|
if( mBinaryFloatSize != 32 && mBinaryFloatSize != 64)
|
|
ThrowException( format() << "Unknown float size " << mBinaryFloatSize << " specified in xfile header." );
|
|
ThrowException( format() << "Unknown float size " << mBinaryFloatSize << " specified in xfile header." );
|
|
@@ -147,7 +148,7 @@ XFileParser::XFileParser( const std::vector<char>& pBuffer)
|
|
// The x format specifies size in bits, but we work in bytes
|
|
// The x format specifies size in bits, but we work in bytes
|
|
mBinaryFloatSize /= 8;
|
|
mBinaryFloatSize /= 8;
|
|
|
|
|
|
- P += 16;
|
|
|
|
|
|
+ mP += 16;
|
|
|
|
|
|
// If this is a compressed X file, apply the inflate algorithm to it
|
|
// If this is a compressed X file, apply the inflate algorithm to it
|
|
if (compressed)
|
|
if (compressed)
|
|
@@ -186,13 +187,13 @@ XFileParser::XFileParser( const std::vector<char>& pBuffer)
|
|
::inflateInit2(&stream, -MAX_WBITS);
|
|
::inflateInit2(&stream, -MAX_WBITS);
|
|
|
|
|
|
// skip unknown data (checksum, flags?)
|
|
// skip unknown data (checksum, flags?)
|
|
- P += 6;
|
|
|
|
|
|
+ mP += 6;
|
|
|
|
|
|
// First find out how much storage we'll need. Count sections.
|
|
// First find out how much storage we'll need. Count sections.
|
|
- const char* P1 = P;
|
|
|
|
|
|
+ const char* P1 = mP;
|
|
unsigned int est_out = 0;
|
|
unsigned int est_out = 0;
|
|
|
|
|
|
- while (P1 + 3 < End)
|
|
|
|
|
|
+ while (P1 + 3 < mEnd)
|
|
{
|
|
{
|
|
// read next offset
|
|
// read next offset
|
|
uint16_t ofs = *((uint16_t*)P1);
|
|
uint16_t ofs = *((uint16_t*)P1);
|
|
@@ -216,18 +217,18 @@ XFileParser::XFileParser( const std::vector<char>& pBuffer)
|
|
// Allocate storage and terminating zero and do the actual uncompressing
|
|
// Allocate storage and terminating zero and do the actual uncompressing
|
|
uncompressed.resize(est_out + 1);
|
|
uncompressed.resize(est_out + 1);
|
|
char* out = &uncompressed.front();
|
|
char* out = &uncompressed.front();
|
|
- while (P + 3 < End)
|
|
|
|
|
|
+ while (mP + 3 < mEnd)
|
|
{
|
|
{
|
|
- uint16_t ofs = *((uint16_t*)P);
|
|
|
|
|
|
+ uint16_t ofs = *((uint16_t*)mP);
|
|
AI_SWAP2(ofs);
|
|
AI_SWAP2(ofs);
|
|
- P += 4;
|
|
|
|
|
|
+ mP += 4;
|
|
|
|
|
|
- if (P + ofs > End + 2) {
|
|
|
|
|
|
+ if (mP + ofs > mEnd + 2) {
|
|
throw DeadlyImportError("X: Unexpected EOF in compressed chunk");
|
|
throw DeadlyImportError("X: Unexpected EOF in compressed chunk");
|
|
}
|
|
}
|
|
|
|
|
|
// push data to the stream
|
|
// push data to the stream
|
|
- stream.next_in = (Bytef*)P;
|
|
|
|
|
|
+ stream.next_in = (Bytef*)mP;
|
|
stream.avail_in = ofs;
|
|
stream.avail_in = ofs;
|
|
stream.next_out = (Bytef*)out;
|
|
stream.next_out = (Bytef*)out;
|
|
stream.avail_out = MSZIP_BLOCK;
|
|
stream.avail_out = MSZIP_BLOCK;
|
|
@@ -242,15 +243,15 @@ XFileParser::XFileParser( const std::vector<char>& pBuffer)
|
|
|
|
|
|
// and advance to the next offset
|
|
// and advance to the next offset
|
|
out += MSZIP_BLOCK - stream.avail_out;
|
|
out += MSZIP_BLOCK - stream.avail_out;
|
|
- P += ofs;
|
|
|
|
|
|
+ mP += ofs;
|
|
}
|
|
}
|
|
|
|
|
|
// terminate zlib
|
|
// terminate zlib
|
|
::inflateEnd(&stream);
|
|
::inflateEnd(&stream);
|
|
|
|
|
|
// ok, update pointers to point to the uncompressed file data
|
|
// ok, update pointers to point to the uncompressed file data
|
|
- P = &uncompressed[0];
|
|
|
|
- End = out;
|
|
|
|
|
|
+ mP = &uncompressed[0];
|
|
|
|
+ mEnd = out;
|
|
|
|
|
|
// FIXME: we don't need the compressed data anymore, could release
|
|
// FIXME: we don't need the compressed data anymore, could release
|
|
// it already for better memory usage. Consider breaking const-co.
|
|
// it already for better memory usage. Consider breaking const-co.
|
|
@@ -647,8 +648,8 @@ void XFileParser::ParseDataObjectMeshVertexColors( Mesh* pMesh)
|
|
if( !mIsBinaryFormat)
|
|
if( !mIsBinaryFormat)
|
|
{
|
|
{
|
|
FindNextNoneWhiteSpace();
|
|
FindNextNoneWhiteSpace();
|
|
- if( *P == ';' || *P == ',')
|
|
|
|
- P++;
|
|
|
|
|
|
+ if( *mP == ';' || *mP == ',')
|
|
|
|
+ mP++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -678,8 +679,8 @@ void XFileParser::ParseDataObjectMeshMaterialList( Mesh* pMesh)
|
|
// commented out version check, as version 03.03 exported from blender also has 2 semicolons
|
|
// commented out version check, as version 03.03 exported from blender also has 2 semicolons
|
|
if( !mIsBinaryFormat) // && MajorVersion == 3 && MinorVersion <= 2)
|
|
if( !mIsBinaryFormat) // && MajorVersion == 3 && MinorVersion <= 2)
|
|
{
|
|
{
|
|
- if(P < End && *P == ';')
|
|
|
|
- ++P;
|
|
|
|
|
|
+ if(mP < mEnd && *mP == ';')
|
|
|
|
+ ++mP;
|
|
}
|
|
}
|
|
|
|
|
|
// if there was only a single material index, replicate it on all faces
|
|
// if there was only a single material index, replicate it on all faces
|
|
@@ -1029,12 +1030,12 @@ void XFileParser::TestForSeparator()
|
|
return;
|
|
return;
|
|
|
|
|
|
FindNextNoneWhiteSpace();
|
|
FindNextNoneWhiteSpace();
|
|
- if( P >= End)
|
|
|
|
|
|
+ if( mP >= mEnd)
|
|
return;
|
|
return;
|
|
|
|
|
|
// test and skip
|
|
// test and skip
|
|
- if( *P == ';' || *P == ',')
|
|
|
|
- P++;
|
|
|
|
|
|
+ if( *mP == ';' || *mP == ',')
|
|
|
|
+ mP++;
|
|
}
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
// ------------------------------------------------------------------------------------------------
|
|
@@ -1062,46 +1063,54 @@ std::string XFileParser::GetNextToken()
|
|
// in binary mode it will only return NAME and STRING token
|
|
// in binary mode it will only return NAME and STRING token
|
|
// and (correctly) skip over other tokens.
|
|
// and (correctly) skip over other tokens.
|
|
|
|
|
|
- if( End - P < 2) return s;
|
|
|
|
|
|
+ if( mEnd - mP < 2) return s;
|
|
unsigned int tok = ReadBinWord();
|
|
unsigned int tok = ReadBinWord();
|
|
unsigned int len;
|
|
unsigned int len;
|
|
|
|
|
|
// standalone tokens
|
|
// standalone tokens
|
|
switch( tok)
|
|
switch( tok)
|
|
{
|
|
{
|
|
- case 1:
|
|
|
|
- // name token
|
|
|
|
- if( End - P < 4) return s;
|
|
|
|
- len = ReadBinDWord();
|
|
|
|
- if( End - P < int(len)) return s;
|
|
|
|
- s = std::string(P, len);
|
|
|
|
- P += len;
|
|
|
|
|
|
+ case 1: {
|
|
|
|
+ // name token
|
|
|
|
+ if ( mEnd - mP < 4 ) return s;
|
|
|
|
+ len = ReadBinDWord();
|
|
|
|
+ const int bounds( mEnd - mP );
|
|
|
|
+ const int iLen( len );
|
|
|
|
+ if ( iLen < 0 ) {
|
|
|
|
+ return s;
|
|
|
|
+ }
|
|
|
|
+ if ( bounds < iLen ) {
|
|
|
|
+ return s;
|
|
|
|
+ }
|
|
|
|
+ s = std::string( mP, len );
|
|
|
|
+ mP += len;
|
|
|
|
+ }
|
|
return s;
|
|
return s;
|
|
case 2:
|
|
case 2:
|
|
// string token
|
|
// string token
|
|
- if( End - P < 4) return s;
|
|
|
|
|
|
+ if( mEnd - mP < 4) return s;
|
|
len = ReadBinDWord();
|
|
len = ReadBinDWord();
|
|
- if( End - P < int(len)) return s;
|
|
|
|
- s = std::string(P, len);
|
|
|
|
- P += (len + 2);
|
|
|
|
|
|
+ if( mEnd - mP < int(len)) return s;
|
|
|
|
+ s = std::string(mP, len);
|
|
|
|
+ mP += (len + 2);
|
|
return s;
|
|
return s;
|
|
case 3:
|
|
case 3:
|
|
// integer token
|
|
// integer token
|
|
- P += 4;
|
|
|
|
|
|
+ mP += 4;
|
|
return "<integer>";
|
|
return "<integer>";
|
|
case 5:
|
|
case 5:
|
|
// GUID token
|
|
// GUID token
|
|
- P += 16;
|
|
|
|
|
|
+ mP += 16;
|
|
return "<guid>";
|
|
return "<guid>";
|
|
case 6:
|
|
case 6:
|
|
- if( End - P < 4) return s;
|
|
|
|
|
|
+ if( mEnd - mP < 4) return s;
|
|
len = ReadBinDWord();
|
|
len = ReadBinDWord();
|
|
- P += (len * 4);
|
|
|
|
|
|
+ mP += (len * 4);
|
|
return "<int_list>";
|
|
return "<int_list>";
|
|
case 7:
|
|
case 7:
|
|
- if( End - P < 4) return s;
|
|
|
|
|
|
+ if( mEnd - mP < 4) return s;
|
|
len = ReadBinDWord();
|
|
len = ReadBinDWord();
|
|
- P += (len * mBinaryFloatSize);
|
|
|
|
|
|
+ mP += (len * mBinaryFloatSize);
|
|
return "<flt_list>";
|
|
return "<flt_list>";
|
|
case 0x0a:
|
|
case 0x0a:
|
|
return "{";
|
|
return "{";
|
|
@@ -1159,19 +1168,19 @@ std::string XFileParser::GetNextToken()
|
|
else
|
|
else
|
|
{
|
|
{
|
|
FindNextNoneWhiteSpace();
|
|
FindNextNoneWhiteSpace();
|
|
- if( P >= End)
|
|
|
|
|
|
+ if( mP >= mEnd)
|
|
return s;
|
|
return s;
|
|
|
|
|
|
- while( (P < End) && !isspace( (unsigned char) *P))
|
|
|
|
|
|
+ while( (mP < mEnd) && !isspace( (unsigned char) *mP))
|
|
{
|
|
{
|
|
// either keep token delimiters when already holding a token, or return if first valid char
|
|
// either keep token delimiters when already holding a token, or return if first valid char
|
|
- if( *P == ';' || *P == '}' || *P == '{' || *P == ',')
|
|
|
|
|
|
+ if( *mP == ';' || *mP == '}' || *mP == '{' || *mP == ',')
|
|
{
|
|
{
|
|
if( !s.size())
|
|
if( !s.size())
|
|
- s.append( P++, 1);
|
|
|
|
|
|
+ s.append( mP++, 1);
|
|
break; // stop for delimiter
|
|
break; // stop for delimiter
|
|
}
|
|
}
|
|
- s.append( P++, 1);
|
|
|
|
|
|
+ s.append( mP++, 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return s;
|
|
return s;
|
|
@@ -1186,18 +1195,18 @@ void XFileParser::FindNextNoneWhiteSpace()
|
|
bool running = true;
|
|
bool running = true;
|
|
while( running )
|
|
while( running )
|
|
{
|
|
{
|
|
- while( P < End && isspace( (unsigned char) *P))
|
|
|
|
|
|
+ while( mP < mEnd && isspace( (unsigned char) *mP))
|
|
{
|
|
{
|
|
- if( *P == '\n')
|
|
|
|
|
|
+ if( *mP == '\n')
|
|
mLineNumber++;
|
|
mLineNumber++;
|
|
- ++P;
|
|
|
|
|
|
+ ++mP;
|
|
}
|
|
}
|
|
|
|
|
|
- if( P >= End)
|
|
|
|
|
|
+ if( mP >= mEnd)
|
|
return;
|
|
return;
|
|
|
|
|
|
// check if this is a comment
|
|
// check if this is a comment
|
|
- if( (P[0] == '/' && P[1] == '/') || P[0] == '#')
|
|
|
|
|
|
+ if( (mP[0] == '/' && mP[1] == '/') || mP[0] == '#')
|
|
ReadUntilEndOfLine();
|
|
ReadUntilEndOfLine();
|
|
else
|
|
else
|
|
break;
|
|
break;
|
|
@@ -1214,22 +1223,22 @@ void XFileParser::GetNextTokenAsString( std::string& poString)
|
|
}
|
|
}
|
|
|
|
|
|
FindNextNoneWhiteSpace();
|
|
FindNextNoneWhiteSpace();
|
|
- if( P >= End)
|
|
|
|
|
|
+ if( mP >= mEnd)
|
|
ThrowException( "Unexpected end of file while parsing string");
|
|
ThrowException( "Unexpected end of file while parsing string");
|
|
|
|
|
|
- if( *P != '"')
|
|
|
|
|
|
+ if( *mP != '"')
|
|
ThrowException( "Expected quotation mark.");
|
|
ThrowException( "Expected quotation mark.");
|
|
- ++P;
|
|
|
|
|
|
+ ++mP;
|
|
|
|
|
|
- while( P < End && *P != '"')
|
|
|
|
- poString.append( P++, 1);
|
|
|
|
|
|
+ while( mP < mEnd && *mP != '"')
|
|
|
|
+ poString.append( mP++, 1);
|
|
|
|
|
|
- if( P >= End-1)
|
|
|
|
|
|
+ if( mP >= mEnd-1)
|
|
ThrowException( "Unexpected end of file while parsing string");
|
|
ThrowException( "Unexpected end of file while parsing string");
|
|
|
|
|
|
- if( P[1] != ';' || P[0] != '"')
|
|
|
|
|
|
+ if( mP[1] != ';' || mP[0] != '"')
|
|
ThrowException( "Expected quotation mark and semicolon at the end of a string.");
|
|
ThrowException( "Expected quotation mark and semicolon at the end of a string.");
|
|
- P+=2;
|
|
|
|
|
|
+ mP+=2;
|
|
}
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
// ------------------------------------------------------------------------------------------------
|
|
@@ -1238,35 +1247,35 @@ void XFileParser::ReadUntilEndOfLine()
|
|
if( mIsBinaryFormat)
|
|
if( mIsBinaryFormat)
|
|
return;
|
|
return;
|
|
|
|
|
|
- while( P < End)
|
|
|
|
|
|
+ while( mP < mEnd)
|
|
{
|
|
{
|
|
- if( *P == '\n' || *P == '\r')
|
|
|
|
|
|
+ if( *mP == '\n' || *mP == '\r')
|
|
{
|
|
{
|
|
- ++P; mLineNumber++;
|
|
|
|
|
|
+ ++mP; mLineNumber++;
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- ++P;
|
|
|
|
|
|
+ ++mP;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
// ------------------------------------------------------------------------------------------------
|
|
unsigned short XFileParser::ReadBinWord()
|
|
unsigned short XFileParser::ReadBinWord()
|
|
{
|
|
{
|
|
- ai_assert(End - P >= 2);
|
|
|
|
- const unsigned char* q = (const unsigned char*) P;
|
|
|
|
|
|
+ ai_assert(mEnd - mP >= 2);
|
|
|
|
+ const unsigned char* q = (const unsigned char*) mP;
|
|
unsigned short tmp = q[0] | (q[1] << 8);
|
|
unsigned short tmp = q[0] | (q[1] << 8);
|
|
- P += 2;
|
|
|
|
|
|
+ mP += 2;
|
|
return tmp;
|
|
return tmp;
|
|
}
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
// ------------------------------------------------------------------------------------------------
|
|
-unsigned int XFileParser::ReadBinDWord()
|
|
|
|
-{
|
|
|
|
- ai_assert(End - P >= 4);
|
|
|
|
- const unsigned char* q = (const unsigned char*) P;
|
|
|
|
|
|
+unsigned int XFileParser::ReadBinDWord() {
|
|
|
|
+ ai_assert(mEnd - mP >= 4);
|
|
|
|
+
|
|
|
|
+ const unsigned char* q = (const unsigned char*) mP;
|
|
unsigned int tmp = q[0] | (q[1] << 8) | (q[2] << 16) | (q[3] << 24);
|
|
unsigned int tmp = q[0] | (q[1] << 8) | (q[2] << 16) | (q[3] << 24);
|
|
- P += 4;
|
|
|
|
|
|
+ mP += 4;
|
|
return tmp;
|
|
return tmp;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1275,20 +1284,20 @@ unsigned int XFileParser::ReadInt()
|
|
{
|
|
{
|
|
if( mIsBinaryFormat)
|
|
if( mIsBinaryFormat)
|
|
{
|
|
{
|
|
- if( mBinaryNumCount == 0 && End - P >= 2)
|
|
|
|
|
|
+ if( mBinaryNumCount == 0 && mEnd - mP >= 2)
|
|
{
|
|
{
|
|
unsigned short tmp = ReadBinWord(); // 0x06 or 0x03
|
|
unsigned short tmp = ReadBinWord(); // 0x06 or 0x03
|
|
- if( tmp == 0x06 && End - P >= 4) // array of ints follows
|
|
|
|
|
|
+ if( tmp == 0x06 && mEnd - mP >= 4) // array of ints follows
|
|
mBinaryNumCount = ReadBinDWord();
|
|
mBinaryNumCount = ReadBinDWord();
|
|
else // single int follows
|
|
else // single int follows
|
|
mBinaryNumCount = 1;
|
|
mBinaryNumCount = 1;
|
|
}
|
|
}
|
|
|
|
|
|
--mBinaryNumCount;
|
|
--mBinaryNumCount;
|
|
- if ( End - P >= 4) {
|
|
|
|
|
|
+ if ( mEnd - mP >= 4) {
|
|
return ReadBinDWord();
|
|
return ReadBinDWord();
|
|
} else {
|
|
} else {
|
|
- P = End;
|
|
|
|
|
|
+ mP = mEnd;
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
} else
|
|
} else
|
|
@@ -1299,24 +1308,24 @@ unsigned int XFileParser::ReadInt()
|
|
|
|
|
|
// check preceding minus sign
|
|
// check preceding minus sign
|
|
bool isNegative = false;
|
|
bool isNegative = false;
|
|
- if( *P == '-')
|
|
|
|
|
|
+ if( *mP == '-')
|
|
{
|
|
{
|
|
isNegative = true;
|
|
isNegative = true;
|
|
- P++;
|
|
|
|
|
|
+ mP++;
|
|
}
|
|
}
|
|
|
|
|
|
// at least one digit expected
|
|
// at least one digit expected
|
|
- if( !isdigit( *P))
|
|
|
|
|
|
+ if( !isdigit( *mP))
|
|
ThrowException( "Number expected.");
|
|
ThrowException( "Number expected.");
|
|
|
|
|
|
// read digits
|
|
// read digits
|
|
unsigned int number = 0;
|
|
unsigned int number = 0;
|
|
- while( P < End)
|
|
|
|
|
|
+ while( mP < mEnd)
|
|
{
|
|
{
|
|
- if( !isdigit( *P))
|
|
|
|
|
|
+ if( !isdigit( *mP))
|
|
break;
|
|
break;
|
|
- number = number * 10 + (*P - 48);
|
|
|
|
- P++;
|
|
|
|
|
|
+ number = number * 10 + (*mP - 48);
|
|
|
|
+ mP++;
|
|
}
|
|
}
|
|
|
|
|
|
CheckForSeparator();
|
|
CheckForSeparator();
|
|
@@ -1329,10 +1338,10 @@ ai_real XFileParser::ReadFloat()
|
|
{
|
|
{
|
|
if( mIsBinaryFormat)
|
|
if( mIsBinaryFormat)
|
|
{
|
|
{
|
|
- if( mBinaryNumCount == 0 && End - P >= 2)
|
|
|
|
|
|
+ if( mBinaryNumCount == 0 && mEnd - mP >= 2)
|
|
{
|
|
{
|
|
unsigned short tmp = ReadBinWord(); // 0x07 or 0x42
|
|
unsigned short tmp = ReadBinWord(); // 0x07 or 0x42
|
|
- if( tmp == 0x07 && End - P >= 4) // array of floats following
|
|
|
|
|
|
+ if( tmp == 0x07 && mEnd - mP >= 4) // array of floats following
|
|
mBinaryNumCount = ReadBinDWord();
|
|
mBinaryNumCount = ReadBinDWord();
|
|
else // single float following
|
|
else // single float following
|
|
mBinaryNumCount = 1;
|
|
mBinaryNumCount = 1;
|
|
@@ -1341,22 +1350,22 @@ ai_real XFileParser::ReadFloat()
|
|
--mBinaryNumCount;
|
|
--mBinaryNumCount;
|
|
if( mBinaryFloatSize == 8)
|
|
if( mBinaryFloatSize == 8)
|
|
{
|
|
{
|
|
- if( End - P >= 8) {
|
|
|
|
- ai_real result = (ai_real) (*(double*) P);
|
|
|
|
- P += 8;
|
|
|
|
|
|
+ if( mEnd - mP >= 8) {
|
|
|
|
+ ai_real result = (ai_real) (*(double*) mP);
|
|
|
|
+ mP += 8;
|
|
return result;
|
|
return result;
|
|
} else {
|
|
} else {
|
|
- P = End;
|
|
|
|
|
|
+ mP = mEnd;
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
} else
|
|
} else
|
|
{
|
|
{
|
|
- if( End - P >= 4) {
|
|
|
|
- ai_real result = *(ai_real*) P;
|
|
|
|
- P += 4;
|
|
|
|
|
|
+ if( mEnd - mP >= 4) {
|
|
|
|
+ ai_real result = *(ai_real*) mP;
|
|
|
|
+ mP += 4;
|
|
return result;
|
|
return result;
|
|
} else {
|
|
} else {
|
|
- P = End;
|
|
|
|
|
|
+ mP = mEnd;
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -1367,21 +1376,21 @@ ai_real XFileParser::ReadFloat()
|
|
// check for various special strings to allow reading files from faulty exporters
|
|
// check for various special strings to allow reading files from faulty exporters
|
|
// I mean you, Blender!
|
|
// I mean you, Blender!
|
|
// Reading is safe because of the terminating zero
|
|
// Reading is safe because of the terminating zero
|
|
- if( strncmp( P, "-1.#IND00", 9) == 0 || strncmp( P, "1.#IND00", 8) == 0)
|
|
|
|
|
|
+ if( strncmp( mP, "-1.#IND00", 9) == 0 || strncmp( mP, "1.#IND00", 8) == 0)
|
|
{
|
|
{
|
|
- P += 9;
|
|
|
|
|
|
+ mP += 9;
|
|
CheckForSeparator();
|
|
CheckForSeparator();
|
|
return 0.0;
|
|
return 0.0;
|
|
} else
|
|
} else
|
|
- if( strncmp( P, "1.#QNAN0", 8) == 0)
|
|
|
|
|
|
+ if( strncmp( mP, "1.#QNAN0", 8) == 0)
|
|
{
|
|
{
|
|
- P += 8;
|
|
|
|
|
|
+ mP += 8;
|
|
CheckForSeparator();
|
|
CheckForSeparator();
|
|
return 0.0;
|
|
return 0.0;
|
|
}
|
|
}
|
|
|
|
|
|
ai_real result = 0.0;
|
|
ai_real result = 0.0;
|
|
- P = fast_atoreal_move<ai_real>( P, result);
|
|
|
|
|
|
+ mP = fast_atoreal_move<ai_real>( mP, result);
|
|
|
|
|
|
CheckForSeparator();
|
|
CheckForSeparator();
|
|
|
|
|