From fb98c9a83bb4493c1f323907078bca6cefce0935 Mon Sep 17 00:00:00 2001 From: Shon Ferguson <shonferg@users.sourceforge.net> Date: Sun, 13 Nov 2005 22:56:43 +0000 Subject: [PATCH] Fixed up the new header scheme for reading. All 10.0.1.0 files can now be read as long as they don't contain unsupported block types. --- NIF_Blocks.cpp | 14 +++---- NIF_Blocks.h | 2 +- niflib.cpp | 100 +++++++++++++++++++++++++++---------------------- 3 files changed, 63 insertions(+), 53 deletions(-) diff --git a/NIF_Blocks.cpp b/NIF_Blocks.cpp index bf7ad392..f6ca0039 100644 --- a/NIF_Blocks.cpp +++ b/NIF_Blocks.cpp @@ -158,7 +158,7 @@ void ABlock::Read( ifstream& in, unsigned int version ) { //Read Attributes for (unsigned int i = 0; i < _attr_vect.size(); ++i ) { _attr_vect[i]->Read( in, version ); - cout << " " << _attr_vect[i]->GetName() << ": " << _attr_vect[i]->asString() << endl; + //cout << " " << _attr_vect[i]->GetName() << ": " << _attr_vect[i]->asString() << endl; } } @@ -565,7 +565,7 @@ string NiNode::asString() { void AShapeData::Read( ifstream& in, unsigned int version ){ short vert_count = ReadUShort( in ); - bool hasVertices = ReadBool( in, version );; + bool hasVertices = ReadBool( in, version ); if ( hasVertices != 0 ){ vertices.resize( vert_count ); for ( uint i = 0; i < vertices.size(); ++i ){ @@ -625,11 +625,11 @@ void AShapeData::Read( ifstream& in, unsigned int version ){ } } - // Unknown Short here from version 10.0.1.0 on - // Just read it and throw it away for now - //if ( version >= 0x0A000100 ) { - // ReadUShort( in ); - //} + //Unknown Short here from version 10.0.1.0 on + //Just read it and throw it away for now + if ( version >= 0x0A000100 ) { + ReadUShort( in ); + } } string AShapeData::asString() { diff --git a/NIF_Blocks.h b/NIF_Blocks.h index f19d0bc6..775f1d6b 100644 --- a/NIF_Blocks.h +++ b/NIF_Blocks.h @@ -215,7 +215,7 @@ class AExtraData : public AData { public: AExtraData() { _namable = true; - _first_named_ver = 0x10000100; + _first_named_ver = 0x0A000100; //10.0.1.0 AddAttr( attr_link, "Next Extra Data", 0, 0x04020200 ); } ~AExtraData() {}; diff --git a/niflib.cpp b/niflib.cpp index 3a38b1ca..1a9bb260 100644 --- a/niflib.cpp +++ b/niflib.cpp @@ -75,7 +75,8 @@ blk_ref CreateBlock( string block_type ) { block = it->second(); } else { //An unknown type has been encountered - block = new UnknownBlock( block_type ); + return blk_ref(-1); //Return null block_ref + //block = new UnknownBlock( block_type ); } return blk_ref(block); @@ -123,9 +124,9 @@ vector<blk_ref> ReadNifList( string file_name ) { in.getline( header_string, 256 ); uint version = ReadUInt( in ); - //There is an unknownInt here from version 5.0.0.1 on + //There is an unknownInt here from version 10.1.0.0 on uint unknownInt1; - if ( version >= 0x05000001 ) { + if ( version >= 0x0A010000 ) { unknownInt1 = ReadUInt( in ); } @@ -147,34 +148,34 @@ vector<blk_ref> ReadNifList( string file_name ) { } uint unknownInt2 = ReadUInt( in ); - uint unknownInt3 = ReadUInt( in ); - - //Output - cout << endl << endl - << "====[ " << file_name << " | File Header ]====" << endl - << "Header: " << header_string << endl - << "Version: " << Hex(version) << endl - << "Unknown Int 1: " << unknownInt1 << endl - << "Number of Blocks: " << int(numBlocks) << endl - << "Block Types: " << uint(blockTypes.size()) << endl; - - for ( uint i = 0; i < blockTypes.size(); ++i ) { - cout << " " << i + 1 << ": " << blockTypes[i] << endl; - } - - cout << "Block Type Indices: " << numBlocks << endl; - for ( uint i = 0; i < blockTypeIndex.size(); ++i ) { - cout << " " << i + 1 << ": " << blockTypeIndex[i] << endl; - } - - cout << "Unknown Int 2: " << unknownInt2 << endl; + //uint unknownInt3 = ReadUInt( in ); + + ////Output + //cout << endl << endl + // << "====[ " << file_name << " | File Header ]====" << endl + // << "Header: " << header_string << endl + // << "Version: " << Hex(version) << endl + // << "Unknown Int 1: " << unknownInt1 << endl + // << "Number of Blocks: " << int(numBlocks) << endl + // << "Block Types: " << uint(blockTypes.size()) << endl; + + //for ( uint i = 0; i < blockTypes.size(); ++i ) { + // cout << " " << i + 1 << ": " << blockTypes[i] << endl; + //} + + //cout << "Block Type Indices: " << numBlocks << endl; + //for ( uint i = 0; i < blockTypeIndex.size(); ++i ) { + // cout << " " << i + 1 << ": " << blockTypeIndex[i] << endl; + //} + + //cout << "Unknown Int 2: " << unknownInt2 << endl; } else { - //Output - cout << endl << endl - << "====[ " << file_name << " | File Header ]====" << endl - << "Header: " << header_string << endl - << "Version: " << Hex(version) << endl - << "Number of Blocks: " << int(numBlocks) << endl; + ////Output + //cout << endl << endl + // << "====[ " << file_name << " | File Header ]====" << endl + // << "Header: " << header_string << endl + // << "Version: " << Hex(version) << endl + // << "Number of Blocks: " << int(numBlocks) << endl; } @@ -185,6 +186,16 @@ vector<blk_ref> ReadNifList( string file_name ) { //There are two ways to read blocks, one before version 5.0.0.1 and one after that if ( version >= 0x05000001 ) { + //From version 5.0.0.1 on there is a zero byte at the end of each block + //Throw an exception if it's not zero + uint checkValue = ReadUInt( in ); + if ( checkValue != 0 ) { + cout << "ERROR! Bad block position. Invalid check value\a" << endl; + cout << "====[ " << file_name << " | Block " << i - 1 << " | " << blocks[i - 1]->GetBlockType() << " ]====" << endl; + cout << blocks[i - 1]->asString(); + throw runtime_error("Read failue - Bad block position"); + } + // Find which block type this is by using the header arrays blockName = blockTypes[ blockTypeIndex[i] ]; } else { @@ -209,11 +220,24 @@ vector<blk_ref> ReadNifList( string file_name ) { } } - cout << endl << i << ": " << blockName; + //cout << endl << i << ": " << blockName; //Create Block of the type that was found blocks[i] = CreateBlock(blockName); + //Check for an unknown block type + if ( blocks[i].is_null() == true ) { + //For version 5.0.0.1 and up, throw an exception - there's nothing we can do + if ( version >= 0x05000001 ) { + stringstream str; + str << "Unknown block type encountered during file read: " << blockName; + throw runtime_error( str.str() ); + } else { + //We can skip over this block in older versions + blocks[i] = new UnknownBlock(blockName); + } + } + //Get internal interface IBlockInternal * bk_intl = (IBlockInternal*)blocks[i]->QueryInterface( BlockInternal ); @@ -224,20 +248,6 @@ vector<blk_ref> ReadNifList( string file_name ) { //Read the block from the file bk_intl->Read( in, version ); - //From version 5.0.0.1 on there is a zero byte at the end of each block - //Throw an exception if it's not zero - if ( version >= 0x05000001 ) { - uint checkByte = ReadUInt( in ); - - /*if ( checkByte != 0 ) { - cout << "ERROR! Bad block position. Invalid check value\a" << endl; - cout << "====[ " << file_name << " | Block " << i - 1 << " | " << blocks[i - 1]->GetBlockType() << " ]====" << endl; - cout << blocks[i - 1]->asString(); - throw runtime_error("Read failue - Bad block position"); - }*/ - } - - //cout << blocks[i]->asString() << endl; } else { -- GitLab