Files
OpenSceneGraph/src/osgPlugins/OpenFlight/RecordInputStream.cpp
2012-03-21 17:36:20 +00:00

87 lines
2.5 KiB
C++

/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//
// OpenFlight® loader for OpenSceneGraph
//
// Copyright (C) 2005-2007 Brede Johansen
//
#include <iostream>
#include "Opcodes.h"
#include "Registry.h"
#include "Document.h"
#include "RecordInputStream.h"
using namespace flt;
using namespace std;
RecordInputStream::RecordInputStream(std::streambuf* sb):
DataInputStream(sb),
_recordSize(0)
{}
bool RecordInputStream::readRecord(Document& document)
{
opcode_type opcode = (opcode_type)readUInt16();
size_type size = (size_type)readUInt16();
return readRecordBody(opcode, size, document);
}
bool RecordInputStream::readRecordBody(opcode_type opcode, size_type size, Document& document)
{
// Correct endian error in Creator v2.5 gallery models.
// Last pop level record in little-endian.
const uint16 LITTLE_ENDIAN_POP_LEVEL_OP = 0x0B00;
if (opcode==LITTLE_ENDIAN_POP_LEVEL_OP)
{
OSG_INFO << "Little endian pop-level record" << std::endl;
opcode=POP_LEVEL_OP;
size=4;
}
_recordSize = size;
// Get prototype record
Record* prototype = Registry::instance()->getPrototype((int)opcode);
if (prototype)
{
#if 0 // for debugging
{
for (int i=0; i<document.level(); i++)
cout << " ";
cout << "opcode=" << opcode << " size=" << size;
if (prototype) std::cout << " " << typeid(*prototype).name();
cout << endl;
}
#endif
// Create from prototype.
osg::ref_ptr<Record> record = prototype->cloneType();
// Read record
record->read(*this,document);
}
else // prototype not found
{
OSG_WARN << "Unknown record, opcode=" << opcode << " size=" << size << std::endl;
// Add to registry so we only have to see this error message once.
Registry::instance()->addPrototype(opcode,new DummyRecord);
}
return good();
}