- fbx: parser working now. Drop shared_ptr's in favour of raw pointers to reduce memory overhead (a pity - I want unique_ptr and move semantics in C++03).
This commit is contained in:
@@ -47,38 +47,107 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "FBXTokenizer.h"
|
||||
#include "FBXParser.h"
|
||||
#include "FBXUtil.h"
|
||||
|
||||
using namespace Assimp;
|
||||
using namespace Assimp::FBX;
|
||||
|
||||
namespace Assimp {
|
||||
template<> const std::string LogFunctions<Assimp::FBX::Parser>::log_prefix = "FBX-Parse: ";
|
||||
namespace {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// signal parsing error, this is always unrecoverable. Throws DeadlyImportError.
|
||||
void ParseError(const std::string& message, TokenPtr token)
|
||||
{
|
||||
throw DeadlyImportError(token ? Util::AddTokenText("FBX-Parse",message,token) : ("FBX-Parse " + message));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Element::Element(Parser& parser)
|
||||
{
|
||||
TokenPtr n = NULL;
|
||||
do {
|
||||
n = parser.AdvanceToNextToken();
|
||||
if(!n) {
|
||||
ParseError("unexpected end of file, expected closing bracket",parser.LastToken());
|
||||
}
|
||||
|
||||
if (n->Type() == TokenType_DATA) {
|
||||
tokens.push_back(n);
|
||||
|
||||
n = parser.AdvanceToNextToken();
|
||||
if(!n) {
|
||||
ParseError("unexpected end of file, expected bracket, comma or key",parser.LastToken());
|
||||
}
|
||||
|
||||
const TokenType ty = n->Type();
|
||||
if (ty != TokenType_OPEN_BRACKET && ty != TokenType_CLOSE_BRACKET && ty != TokenType_COMMA && ty != TokenType_KEY) {
|
||||
ParseError("unexpected token; expected bracket, comma or key",n);
|
||||
}
|
||||
}
|
||||
|
||||
if (n->Type() == TokenType_OPEN_BRACKET) {
|
||||
compound.reset(new Scope(parser));
|
||||
|
||||
// compound scopes must appear at the end of an element, so TOK_CLOSE_BRACKET should be next
|
||||
n = parser.CurrentToken();
|
||||
ai_assert(n);
|
||||
|
||||
if (n->Type() != TokenType_CLOSE_BRACKET) {
|
||||
ParseError("expected closing bracket",n);
|
||||
}
|
||||
}
|
||||
}
|
||||
while(n->Type() != TokenType_KEY);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Element::~Element()
|
||||
{
|
||||
std::for_each(tokens.begin(),tokens.end(),Util::delete_fun<Token>());
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Scope::Scope(Parser& parser)
|
||||
Scope::Scope(Parser& parser,bool topLevel)
|
||||
{
|
||||
TokenPtr t = parser.GetNextToken();
|
||||
if (t->Type() != TokenType_OPEN_BRACKET) {
|
||||
parser.ThrowException("Expected open bracket");
|
||||
if(!topLevel) {
|
||||
TokenPtr t = parser.CurrentToken();
|
||||
if (t->Type() != TokenType_OPEN_BRACKET) {
|
||||
ParseError("expected open bracket",t);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX parse members
|
||||
TokenPtr n = parser.AdvanceToNextToken();
|
||||
if(n == NULL) {
|
||||
ParseError("unexpected end of file",NULL);
|
||||
}
|
||||
|
||||
do {
|
||||
if (n->Type() != TokenType_KEY) {
|
||||
ParseError("unexpected token, expected TOK_KEY",n);
|
||||
}
|
||||
|
||||
elements.insert(ElementMap::value_type(n->StringContents(),new_Element(parser)));
|
||||
|
||||
// Element() should stop at the next Key (or Close) token
|
||||
n = parser.CurrentToken();
|
||||
if(n == NULL) {
|
||||
if (topLevel) {
|
||||
return;
|
||||
}
|
||||
ParseError("unexpected end of file",parser.LastToken());
|
||||
}
|
||||
}
|
||||
while(n->Type() != TokenType_CLOSE_BRACKET);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Scope::~Scope()
|
||||
{
|
||||
BOOST_FOREACH(ElementMap::value_type& v, elements) {
|
||||
delete v.second;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -86,8 +155,10 @@ Scope::~Scope()
|
||||
Parser::Parser (const TokenList& tokens)
|
||||
: tokens(tokens)
|
||||
, cursor(tokens.begin())
|
||||
, current()
|
||||
, last()
|
||||
{
|
||||
root = boost::scoped_ptr<Scope>(new Scope(*this));
|
||||
root.reset(new Scope(*this,true));
|
||||
}
|
||||
|
||||
|
||||
@@ -98,24 +169,30 @@ Parser::~Parser()
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
TokenPtr Parser::GetNextToken()
|
||||
TokenPtr Parser::AdvanceToNextToken()
|
||||
{
|
||||
last = current;
|
||||
if (cursor == tokens.end()) {
|
||||
return TokenPtr(NULL);
|
||||
current = NULL;
|
||||
}
|
||||
|
||||
return *cursor++;
|
||||
else {
|
||||
current = *cursor++;
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
TokenPtr Parser::PeekNextToken()
|
||||
TokenPtr Parser::CurrentToken() const
|
||||
{
|
||||
if (cursor == tokens.end()) {
|
||||
return TokenPtr(NULL);
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
return *cursor;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
TokenPtr Parser::LastToken() const
|
||||
{
|
||||
return last;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user