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