private NitroFile(params Type[] blockTypes) { // Check that all types heredites from NitroBlock foreach (Type t in blockTypes) { if (!t.IsSubclassOf(typeof(NitroBlock))) { throw new ArgumentException("Invalid type passed."); } } this.hasOffsets = false; this.blockTypes = blockTypes; this.blocks = new BlockCollection(); }
protected virtual void Read(Stream strIn, int size) { long basePosition = strIn.Position; BinaryReader br = new BinaryReader(strIn); // Nitro header this.magicStamp = this.ReadMagicStamp(br); ushort bom = br.ReadUInt16(); if (bom != BomLittleEndiannes) // Byte Order Mark { if (bom == 0) { Console.WriteLine("##ERROR?## There is no BOM value."); } else { throw new InvalidDataException("The data is not little endiannes."); } } this.version = br.ReadUInt16(); uint fileSize = br.ReadUInt32(); if (fileSize > size) { throw new FormatException("File size doesn't match (smaller)."); } else if (fileSize + 4 < size) // It could be padding bytes. { Console.WriteLine("##ERROR?## File size doesn't match (bigger)."); } else if (fileSize < size) { Console.WriteLine("##WARNING## File field is smaller than specified. {0}", size - fileSize); } ushort blocksStart = br.ReadUInt16(); ushort numBlocks = br.ReadUInt16(); strIn.Position = basePosition + blocksStart; uint[] offsets = null; if (this.hasOffsets) { offsets = new uint[numBlocks]; for (int i = 0; i < numBlocks; i++) { offsets[i] = br.ReadUInt32(); } } this.blocks = new BlockCollection(numBlocks); for (int i = 0; i < numBlocks; i++) { if (this.hasOffsets) { strIn.Position = basePosition + offsets[i]; } if (strIn.Position == strIn.Length) { Console.WriteLine("##ERROR?## Missing {0} blocks", numBlocks - i); return; } long blockPosition = strIn.Position; // First get block parameters string blockName = this.ReadMagicStamp(br); int blockSize = br.ReadInt32(); strIn.Position = blockPosition; Type blockType = Array.Find <Type>( this.blockTypes, b => b.Name.ToLower() == blockName.ToLower()); if (blockType == null) { throw new FormatException("Unknown block --> " + blockName); } NitroBlock block = (NitroBlock)Activator.CreateInstance(blockType, this); block.Read(strIn); this.blocks.Add(block); strIn.Position = blockPosition + blockSize; } }