From Paul Marz : "Input.h, Input.cpp -- Here's where support for reading the continuation
record goes. I added a new function to read a continued record body. I added code in the existing ReadRecord routine to peek ahead for a CONTINUATION_OP if the current record could possibly be continued. opcodes.h -- Besides adding the opcode for CONTINUATION_OP, I also added new 15.8 opcodes. I labeled opcodes as "ignored" if I could easily discern that our loader wasn't doing anything with them. For historical reasons, I added all obsolete opcodes, prefixed with "OBS_". LocalVertexPoolRecord.h, LocalVertexPoolRecord.cpp -- This is one of three types of records that can be continued with a CONTINUATION_OP record. I removed all invalid assertions that assumed the record length would always be less than 65535. I replaced the "vertex size" calculation with a more efficient method based on caching the size from attribute bits, rather than taking the length of the record and dividing it by numVerts (which would have been incorrect if the record had been continued)."
This commit is contained in:
@@ -127,6 +127,20 @@ bool FileInput::_readBody(SRecHeader* pData)
|
||||
}
|
||||
|
||||
|
||||
bool FileInput::_readContinuedBody(char* pData, int nBytes)
|
||||
{
|
||||
// Read record body
|
||||
if (nBytes > 0)
|
||||
{
|
||||
int nItemsRead = _read(pData, nBytes);
|
||||
if (nItemsRead != 1)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
SRecHeader* FileInput::readRecord()
|
||||
{
|
||||
SRecHeader hdr;
|
||||
@@ -151,6 +165,56 @@ SRecHeader* FileInput::readRecord()
|
||||
if (!_readBody(pData))
|
||||
return NULL;
|
||||
|
||||
|
||||
// Add support for OpenFlight 15.7 (1570) continuation records
|
||||
//
|
||||
|
||||
// Record and FaceRecord both want to rewindLast, so save and restore
|
||||
// the current file offset.
|
||||
const long lRecOffsetSave = _lRecOffset;
|
||||
|
||||
int nTotalLen = hdr.length();
|
||||
// From spec, in practice only these three records can be continued:
|
||||
bool bContinuationPossible = (
|
||||
(hdr.opcode()==COLOR_NAME_PALETTE_OP) ||
|
||||
(hdr.opcode()==EXTENSION_OP) ||
|
||||
(hdr.opcode()==LOCAL_VERTEX_POOL_OP) );
|
||||
|
||||
while (bContinuationPossible)
|
||||
{
|
||||
SRecHeader hdr2;
|
||||
if (_readHeader( &hdr2 ))
|
||||
{
|
||||
if (hdr2.opcode() == CONTINUATION_OP)
|
||||
{
|
||||
int nNewChunkLen = hdr2.length() - 4;
|
||||
size_t nNewLen = nTotalLen + nNewChunkLen;
|
||||
pData = (SRecHeader*)::realloc( (void*)pData, nNewLen );
|
||||
if (pData == NULL)
|
||||
return NULL;
|
||||
|
||||
if (!_readContinuedBody( ((char*)pData) + nTotalLen, nNewChunkLen ))
|
||||
return NULL;
|
||||
nTotalLen = (int)nNewLen;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not a continuation record. Rewind, then exit loop.
|
||||
rewindLast();
|
||||
bContinuationPossible = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
// Probably EOF
|
||||
bContinuationPossible = false;
|
||||
}
|
||||
|
||||
_lRecOffset = lRecOffsetSave;
|
||||
|
||||
//
|
||||
// END support for continuation records
|
||||
|
||||
|
||||
return pData;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user