Beispiel #1
0
        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();
        }
Beispiel #2
0
        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;
            }
        }