- Add new helper funtion to detect end of buffer.

- Bugfix Obj-loader: If material file is not ended with a newline material loader crashes: Check for end of buffer.
- Refactoring: Rename helper function isSpace to isSeparator to make sense of function much clearer!

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@461 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
pull/1/head
kimmi 2009-08-02 17:11:38 +00:00
parent 98e53f976e
commit eda47a6f0b
5 changed files with 53 additions and 54 deletions

View File

@ -78,7 +78,7 @@ struct Face
//! \param pVertices Pointer to assigned vertex indexbuffer //! \param pVertices Pointer to assigned vertex indexbuffer
//! \param pNormals Pointer to assigned normals indexbuffer //! \param pNormals Pointer to assigned normals indexbuffer
//! \param pTexCoords Pointer to assigned texture indexbuffer //! \param pTexCoords Pointer to assigned texture indexbuffer
Face(std::vector<unsigned int> *pVertices, Face( std::vector<unsigned int> *pVertices,
std::vector<unsigned int> *pNormals, std::vector<unsigned int> *pNormals,
std::vector<unsigned int> *pTexCoords) : std::vector<unsigned int> *pTexCoords) :
m_PrimitiveType( 2 ), m_PrimitiveType( 2 ),
@ -93,18 +93,12 @@ struct Face
//! \brief Destructor //! \brief Destructor
~Face() ~Face()
{ {
if(m_pVertices) { delete m_pVertices;
delete m_pVertices; m_pVertices = NULL;
m_pVertices = NULL; delete m_pNormals;
} m_pNormals = NULL;
if(m_pNormals) { delete m_pTexturCoords;
delete m_pNormals; m_pTexturCoords = NULL;
m_pNormals = NULL;
}
if(m_pTexturCoords) {
delete m_pTexturCoords;
m_pTexturCoords = NULL;
}
} }
}; };
@ -205,7 +199,7 @@ struct Mesh
unsigned int m_uiUVCoordinates[ AI_MAX_NUMBER_OF_TEXTURECOORDS ]; unsigned int m_uiUVCoordinates[ AI_MAX_NUMBER_OF_TEXTURECOORDS ];
/// Material index. /// Material index.
unsigned int m_uiMaterialIndex; unsigned int m_uiMaterialIndex;
/// True, if normals are stored.
bool m_hasNormals; bool m_hasNormals;
/// Constructor /// Constructor
Mesh() : Mesh() :

View File

@ -101,14 +101,15 @@ void ObjFileImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
throw new ImportErrorException( "OBJ-file is too small."); throw new ImportErrorException( "OBJ-file is too small.");
// Allocate buffer and read file into it // Allocate buffer and read file into it
m_Buffer.resize( fileSize ); m_Buffer.resize( fileSize + 1 );
const size_t readsize = file->Read(&m_Buffer.front(), sizeof(char), fileSize); m_Buffer[ fileSize ] = '\0';
assert (readsize == fileSize); const size_t readsize = file->Read( &m_Buffer.front(), sizeof(char), fileSize );
assert( readsize == fileSize );
// //
std::string strDirectory(1,io.getOsSeparator()), strModelName; std::string strDirectory( 1, io.getOsSeparator() ), strModelName;
std::string::size_type pos = pFile.find_last_of(io.getOsSeparator()); std::string::size_type pos = pFile.find_last_of( io.getOsSeparator() );
if (pos != std::string::npos) if ( pos != std::string::npos )
{ {
strDirectory = pFile.substr(0, pos); strDirectory = pFile.substr(0, pos);
strModelName = pFile.substr(pos+1, pFile.size() - pos - 1); strModelName = pFile.substr(pos+1, pFile.size() - pos - 1);
@ -314,16 +315,8 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
// Allocate buffer for texture coordinates // Allocate buffer for texture coordinates
if ( !pModel->m_TextureCoord.empty() && pObjMesh->m_uiUVCoordinates[0] ) if ( !pModel->m_TextureCoord.empty() && pObjMesh->m_uiUVCoordinates[0] )
{ {
// FIXME (@Kimmi): cleanup, I don't see the intention behind this pMesh->mNumUVComponents[ 0 ] = 2;
// for ( size_t i=0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; i++ ) pMesh->mTextureCoords[ 0 ] = new aiVector3D[ pMesh->mNumVertices ];
// {
// const unsigned int num_uv = pObjMesh->m_uiUVCoordinates[ i ];
// if ( num_uv > 0 )
// {
pMesh->mNumUVComponents[ 0 ] = 2;
pMesh->mTextureCoords[ 0 ] = new aiVector3D[ pMesh->mNumVertices ];
// }
// }
} }
// Copy vertices, normals and textures into aiMesh instance // Copy vertices, normals and textures into aiMesh instance

View File

@ -62,7 +62,7 @@ ObjFileMtlImporter::ObjFileMtlImporter( std::vector<char> &buffer,
ai_assert( NULL != m_pModel ); ai_assert( NULL != m_pModel );
if ( NULL == m_pModel->m_pDefaultMaterial ) if ( NULL == m_pModel->m_pDefaultMaterial )
{ {
m_pModel->m_pDefaultMaterial = new ObjFile::Material(); m_pModel->m_pDefaultMaterial = new ObjFile::Material;
m_pModel->m_pDefaultMaterial->MaterialName.Set( "default" ); m_pModel->m_pDefaultMaterial->MaterialName.Set( "default" );
} }
load(); load();
@ -220,7 +220,7 @@ void ObjFileMtlImporter::getFloatValue( float &value )
// Creates a material from loaded data. // Creates a material from loaded data.
void ObjFileMtlImporter::createMaterial() void ObjFileMtlImporter::createMaterial()
{ {
std::string strName; std::string strName( "" );
m_DataIt = getName<DataArrayIt>( m_DataIt, m_DataItEnd, strName ); m_DataIt = getName<DataArrayIt>( m_DataIt, m_DataItEnd, strName );
if ( m_DataItEnd == m_DataIt ) if ( m_DataItEnd == m_DataIt )
return; return;

View File

@ -186,7 +186,7 @@ void ObjFileParser::copyNextWord(char *pBuffer, size_t length)
{ {
size_t index = 0; size_t index = 0;
m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd); m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd);
while (!isSpace(*m_DataIt) && m_DataIt != m_DataItEnd) while ( !isSeparator(*m_DataIt) && m_DataIt != m_DataItEnd )
{ {
pBuffer[index] = *m_DataIt; pBuffer[index] = *m_DataIt;
index++; index++;
@ -293,7 +293,7 @@ void ObjFileParser::getFace()
} }
iPos++; iPos++;
} }
else if (isSpace(*pPtr)) else if ( isSeparator(*pPtr) )
{ {
iPos = 0; iPos = 0;
} }
@ -374,7 +374,7 @@ void ObjFileParser::getMaterialDesc()
return; return;
char *pStart = &(*m_DataIt); char *pStart = &(*m_DataIt);
while ( !isSpace(*m_DataIt) && m_DataIt != m_DataItEnd ) while ( !isSeparator(*m_DataIt) && m_DataIt != m_DataItEnd )
++m_DataIt; ++m_DataIt;
// Get name // Get name
@ -452,7 +452,8 @@ void ObjFileParser::getMaterialLib()
// Import material library data from file // Import material library data from file
size_t size = pFile->FileSize(); size_t size = pFile->FileSize();
std::vector<char> buffer(size); std::vector<char> buffer( size + 1 );
buffer[ size ] = '\0';
pFile->Read( &buffer[ 0 ], sizeof( char ), size ); pFile->Read( &buffer[ 0 ], sizeof( char ), size );
io->Close( pFile ); io->Close( pFile );
@ -471,7 +472,7 @@ void ObjFileParser::getNewMaterial()
char *pStart = &(*m_DataIt); char *pStart = &(*m_DataIt);
std::string strMat(pStart, *m_DataIt); std::string strMat(pStart, *m_DataIt);
while (isSpace(*m_DataIt)) while ( isSeparator( *m_DataIt ) )
m_DataIt++; m_DataIt++;
std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find( strMat ); std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find( strMat );
if (it == m_pModel->m_MaterialMap.end()) if (it == m_pModel->m_MaterialMap.end())
@ -514,12 +515,12 @@ void ObjFileParser::getGroupName()
// Get next word from data buffer // Get next word from data buffer
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd); m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd); m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd);
if ( m_DataIt == m_DataItEnd ) if ( isEndOfBuffer( m_DataIt, m_DataItEnd ) )
return; return;
// Store groupname in group library // Store groupname in group library
char *pStart = &(*m_DataIt); char *pStart = &(*m_DataIt);
while (!isSpace(*m_DataIt)) while ( !isSeparator(*m_DataIt) )
m_DataIt++; m_DataIt++;
std::string strGroupName(pStart, &(*m_DataIt)); std::string strGroupName(pStart, &(*m_DataIt));
@ -564,7 +565,7 @@ void ObjFileParser::getObjectName()
if (m_DataIt == m_DataItEnd) if (m_DataIt == m_DataItEnd)
return; return;
char *pStart = &(*m_DataIt); char *pStart = &(*m_DataIt);
while (!isSpace(*m_DataIt)) while (!isSeparator(*m_DataIt))
m_DataIt++; m_DataIt++;
std::string strObjectName(pStart, &(*m_DataIt)); std::string strObjectName(pStart, &(*m_DataIt));

View File

@ -49,11 +49,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp namespace Assimp
{ {
/** @brief Returns true, if the last entry of the buffer is reached.
* @param it Iterator of current position.
* @param end Iterator with end of buffer.
* @return true, if the end of the buffer is reached.
*/
template<class char_t>
inline bool isEndOfBuffer( char_t it, char_t end )
{
end--;
return ( it == end );
}
/** @brief Returns true, if token is a space on any supported platform /** @brief Returns true, if token is a space on any supported platform
* @param token Token to search in * @param token Token to search in
* @return true, if token is a space * @return true, if token is a space
*/ */
inline bool isSpace( char token ) inline bool isSeparator( char token )
{ {
return ( token == ' ' || return ( token == ' ' ||
token == '\n' || token == '\n' ||
@ -79,9 +91,9 @@ inline bool isNewLine( char token )
template<class Char_T> template<class Char_T>
inline Char_T getNextWord( Char_T pBuffer, Char_T pEnd ) inline Char_T getNextWord( Char_T pBuffer, Char_T pEnd )
{ {
while (pBuffer != pEnd) while ( !isEndOfBuffer( pBuffer, pEnd ) )
{ {
if (!isSpace(*pBuffer)) if ( !isSeparator( *pBuffer ) )
break; break;
pBuffer++; pBuffer++;
} }
@ -96,9 +108,9 @@ inline Char_T getNextWord( Char_T pBuffer, Char_T pEnd )
template<class Char_T> template<class Char_T>
inline Char_T getNextToken( Char_T pBuffer, Char_T pEnd ) inline Char_T getNextToken( Char_T pBuffer, Char_T pEnd )
{ {
while (pBuffer != pEnd) while ( !isEndOfBuffer( pBuffer, pEnd ) )
{ {
if ( isSpace( *pBuffer ) ) if ( isSeparator( *pBuffer ) )
break; break;
pBuffer++; pBuffer++;
} }
@ -114,14 +126,14 @@ inline Char_T getNextToken( Char_T pBuffer, Char_T pEnd )
template<class char_t> template<class char_t>
inline char_t skipLine( char_t it, char_t end, unsigned int &uiLine ) inline char_t skipLine( char_t it, char_t end, unsigned int &uiLine )
{ {
while ( it != end && *it != '\n' ) while ( !isEndOfBuffer( it, end ) && *it != '\n' )
++it; ++it;
if ( it != end ) if ( it != end )
{ {
++it; ++it;
++uiLine; ++uiLine;
} }
/* fix .. from time to time there are spaces at the beginning of a material line */ // fix .. from time to time there are spaces at the beginning of a material line
while ( it != end && (*it == '\t' || *it == ' ') ) while ( it != end && (*it == '\t' || *it == ' ') )
++it; ++it;
return it; return it;
@ -138,15 +150,15 @@ inline char_t getName( char_t it, char_t end, std::string &name )
{ {
name = ""; name = "";
it = getNextToken<char_t>( it, end ); it = getNextToken<char_t>( it, end );
if ( it == end ) if ( isEndOfBuffer( it, end ) )
return end; return end;
char *pStart = &(*it); char *pStart = &( *it );
while ( !isSpace(*it) && it != end ) while ( !isEndOfBuffer( it, end ) && !isSeparator( *it ) )
++it; ++it;
// Get name // Get name
std::string strName(pStart, &(*it)); std::string strName( pStart, &(*it) );
if ( strName.empty() ) if ( strName.empty() )
return it; return it;
else else
@ -167,7 +179,7 @@ inline char_t CopyNextWord( char_t it, char_t end, char *pBuffer, size_t length
{ {
size_t index = 0; size_t index = 0;
it = getNextWord<char_t>( it, end ); it = getNextWord<char_t>( it, end );
while (!isSpace( *it ) && it != end ) while ( !isSeparator( *it ) && !isEndOfBuffer( it, end ) )
{ {
pBuffer[index] = *it ; pBuffer[index] = *it ;
index++; index++;
@ -175,7 +187,7 @@ inline char_t CopyNextWord( char_t it, char_t end, char *pBuffer, size_t length
break; break;
++it; ++it;
} }
pBuffer[index] = '\0'; pBuffer[ index ] = '\0';
return it; return it;
} }
@ -190,7 +202,6 @@ inline char_t getFloat( char_t it, char_t end, float &value )
{ {
static const size_t BUFFERSIZE = 1024; static const size_t BUFFERSIZE = 1024;
char buffer[ BUFFERSIZE ]; char buffer[ BUFFERSIZE ];
//memset( buffer, '\0', BUFFERSIZE );
it = CopyNextWord<char_t>( it, end, buffer, BUFFERSIZE ); it = CopyNextWord<char_t>( it, end, buffer, BUFFERSIZE );
value = (float) fast_atof( buffer ); value = (float) fast_atof( buffer );