etqw-sdk/source/framework/DeclParseHelper.h

171 lines
5.0 KiB
C
Raw Permalink Normal View History

2008-05-29 00:00:00 +00:00
// Copyright (C) 2007 Id Software, Inc.
//
#ifndef __DECL_PARSE_HELPER__
#define __DECL_PARSE_HELPER__
/*
==============
sdDeclParseHelper
A helper class to ensure that binary data generation is handled uniformly across decl types
Should be added to the Parse() member of an idDecl-derived class
To ensure that tokens are generated consistently it should be created after the LEXFL_ parsing flags are set on the input idParser
The destructor handles setting dependencies and storing any binary generated data
==============
*/
/*
============
sdDeclParseHelper
============
*/
class sdDeclParseHelper {
public:
sdDeclParseHelper( idDecl* decl_, const char* text, int textLength, idParser& src_ );
~sdDeclParseHelper();
void GetBinaryBuffer( const byte*& buffer, int& length ) const;
const idFile_Memory* GetOutputFile() const { return binaryOutput; }
void Finish( void );
private:
idParser& src; // parser that we're reading from/settings up
idFile_Memory* binaryOutput; // tokenized parser output to be stored on the decl
idDecl* decl; // source/target decl
idDeclTypeInterface* type; // type of the decl, used for decl type-specific behavior
byte* declBuffer; // binary buffer retrieved from the decl
int declBufferLength; // binary buffer length retrieved from the decl
};
/*
============
sdDeclParseHelper::sdDeclParseHelper
============
*/
ID_INLINE sdDeclParseHelper::sdDeclParseHelper( idDecl* decl_, const char* text, int textLength, idParser& src_ ) :
binaryOutput( NULL ),
decl( decl_ ),
src( src_ ),
declBuffer( NULL ),
declBufferLength( 0 ) {
type = declManager->GetDeclType( decl->GetType() );
idTokenCache* cache = NULL;
if( !type->UsePrivateTokens() ) {
cache = &declManager->GetGlobalTokenCache();
}
if( decl->HasBinaryBuffer() && decl->GetState() != DS_DEFAULTED ) {
decl->GetBinarySource( declBuffer, declBufferLength );
src.LoadMemoryBinary( declBuffer, declBufferLength, va( "%s: %s", decl->GetFileName(), decl->GetName() ), cache );
} else {
// store expanded text (except for templates) so that it's written in its entirety to the binary decl file
if( cvarSystem->GetCVarBool( "com_writeBinaryDecls" ) && !type->WriteBinary() && !type->AlwaysGenerateBinary() && decl->GetState() != DS_DEFAULTED ) {
src.LoadMemory( text, textLength, va( "%s: %s", decl->GetFileName(), decl->GetName() ), decl->GetLineNum() );
if( decl->GetFileLevelIncludeDependencies() != NULL ) {
src.AddIncludes( *( decl->GetFileLevelIncludeDependencies() ) );
}
sdStringBuilder_Heap builder;
idToken token;
while( src.ReadToken( &token )) {
if( token.type == TT_STRING ) {
builder += "\"";
}
builder += token;
if( token.type == TT_STRING ) {
builder += "\"";
}
builder += " ";
}
decl->SetText( builder.c_str() );
src.FreeSource( true );
}
src.LoadMemory( text, textLength, va( "%s: %s", decl->GetFileName(), decl->GetName() ), decl->GetLineNum() );
}
// no need to setup file dependencies in binary mode
if( decl->GetFileLevelIncludeDependencies() != NULL && !decl->HasBinaryBuffer() ) {
src.AddIncludes( *( decl->GetFileLevelIncludeDependencies() ) );
}
if( type->WriteBinary() ) {
if( ( cvarSystem->GetCVarBool( "com_writeBinaryDecls" ) || type->AlwaysGenerateBinary() ) &&
( !decl->HasBinaryBuffer() || ( type->AlwaysGenerateBinary() && decl->GetState() == DS_DEFAULTED ) ) ) {
binaryOutput = fileSystem->OpenMemoryFile( decl->GetName() );
binaryOutput->SetGranularity( 256 );
src.WriteBinary( binaryOutput, cache );
src.ResetBinaryParsing();
}
}
}
/*
============
sdDeclParseHelper::~sdDeclParseHelper
============
*/
ID_INLINE sdDeclParseHelper::~sdDeclParseHelper() {
Finish();
}
/*
============
sdDeclParseHelper::GetBinaryBuffer
============
*/
ID_INLINE void sdDeclParseHelper::GetBinaryBuffer( const byte*& buffer, int& length ) const {
if( declBuffer == NULL || declBufferLength == 0 ) {
if( binaryOutput != NULL ) {
buffer = reinterpret_cast< const byte* >( binaryOutput->GetDataPtr() );
length = binaryOutput->Length();
return;
}
}
buffer = declBuffer;
length = declBufferLength;
}
/*
============
sdDeclParseHelper::Finish
============
*/
ID_INLINE void sdDeclParseHelper::Finish( void ) {
// no dependencies in binary mode, except for types that always generate
if( decl != NULL && ( binaryOutput == NULL || type->AlwaysGenerateBinary() ) ) {
declManager->AddDependencies( decl, src );
}
if( decl != NULL && binaryOutput != NULL && decl->GetState() != DS_DEFAULTED ) {
decl->SetBinarySource( reinterpret_cast< const byte* >( binaryOutput->GetDataPtr() ), binaryOutput->Length() );
}
if( decl != NULL && declBuffer != NULL ) {
decl->FreeSourceBuffer( declBuffer );
declBuffer = NULL;
}
if( binaryOutput != NULL ) {
fileSystem->CloseFile( binaryOutput );
binaryOutput = NULL;
}
decl = NULL;
}
#endif // !__DECL_PARSE_HELPER__