Exemple #1
0
        /// <summary>
        /// Reads a file block and returns it.
        /// If the block is SDNA, initializes and returns an instance of <pre>StructureDNA</pre>.
        /// </summary>
        /// <param name="file">A blend file with the reader at the start of a file block.</param>
        /// <param name="pointerSize">The pointer size of the current file.</param>
        /// <returns>A parsed FileBlock.</returns>
        public static FileBlock ReadBlock(BinaryReader file, int pointerSize)
        {
            if (pointerSize != 4 && pointerSize != 8)
            {
                throw new ArgumentException("Impossible for pointerSize to be " + pointerSize);
            }

            string code;
            int    size, sdna, count;

            byte[] data;
            ulong  address;

            // read block header
            code    = new string(file.ReadChars(4));
            size    = file.ReadInt32();
            address = pointerSize == 4 ? file.ReadUInt32() : file.ReadUInt64();
            sdna    = file.ReadInt32();
            count   = file.ReadInt32();
            data    = file.ReadBytes(size);

            FileBlock block = code == "DNA1" ? new StructureDNA(code, size, sdna, count, data) :
                              new FileBlock(code, size, sdna, count, data);

            // blocks are aligned at four bytes
            while (file.BaseStream.Position % 4 != 0 && file.BaseStream.Position < file.BaseStream.Length) // don't want to read off the file by accident
            {
                file.ReadByte();
            }

            // I'm not 100% sure why this is done here.
            block.OldMemoryAddress = address;
            return(block);
        }
        /// <summary>
        /// Parses a file block. If the file block is SDNA or another block with block.count == 0, it will return null.
        /// </summary>
        /// <param name="block">The block to parse.</param>
        /// <param name="blocksParsed">Number of blocks parsed so far.</param>
        /// <param name="file">Source file for the structures.</param>
        /// <returns>An array of PopulatedStructures, or { null } if no structures are defined.</returns>
        public static Structure[] ParseFileBlock(FileBlock block, int blocksParsed, BlenderFile file)
        {
            if (block.Count == 0 || block.Code == "DNA1")
            {
                return(null);
            }

            StructureDNA sdna = file.StructureDNA;

            if (block.Data.Length != sdna.StructureList[block.SDNAIndex].StructureTypeSize * block.Count)
            {
                // generally, these are things like raw data; packed files, preview images, and arrays of pointers that are themselves pointed to.
                // I have no idea what TEST and REND do.
                file.RawBlockMessages.Add(blocksParsed + " " + block.OldMemoryAddress.ToString("X" + (file.PointerSize * 2)) + " " + block.Code + " " + block.SDNAIndex + " " + sdna.StructureList[block.SDNAIndex].StructureTypeSize * block.Count + " " + block.Data.Length);
                return(null);
            }

            Structure[] output = new Structure[block.Count];

            if (block.Count > 1)
            {
                for (int i = 0; i < block.Count; i++)
                {
                    byte[] data = new byte[block.Size / block.Count];
                    for (int j = 0; j < block.Size / block.Count; j++)
                    {
                        data[j] = block.Data[i * (block.Size / block.Count) + j];
                    }
                    output[i]                 = new Structure(data, sdna.StructureList[block.SDNAIndex], file);
                    output[i].Size            = sdna.StructureList[block.SDNAIndex].StructureTypeSize;
                    output[i].TypeName        = sdna.StructureList[block.SDNAIndex].StructureTypeName;
                    output[i].ContainingBlock = block;
                }
            }
            else
            {
                output[0]                 = new Structure(block.Data, sdna.StructureList[block.SDNAIndex], file);
                output[0].Size            = sdna.StructureList[block.SDNAIndex].StructureTypeSize;
                output[0].TypeName        = sdna.StructureList[block.SDNAIndex].StructureTypeName;
                output[0].ContainingBlock = block;
            }

            return(output);
        }
Exemple #3
0
        /// <summary>
        /// Reads the file blocks from the file. Returns the block with the code <pre>DNA1</pre>, which is the file's
        /// structure DNA.
        /// </summary>
        /// <param name="fileReader">Reference to file reader for current file.</param>
        /// <returns>File's Structure DNA.</returns>
        private StructureDNA readBlocks(BinaryReader fileReader)
        {
            StructureDNA dna = null;

            do
            {
                FileBlock b = FileBlock.ReadBlock(fileReader, PointerSize);
                if (b.Code == "DNA1")
                {
                    dna = (StructureDNA)b;
                }
                fileBlocks.Add(b);
            } while(fileReader.BaseStream.Position < fileReader.BaseStream.Length);

            if (dna == null)
            {
                throw new InvalidDataException("This file contains no structure DNA! What are you trying to pull?!");
            }

            return(dna);
        }