/// <summary>
        /// Reads the footer data which is the Ndfbin Dictionary.
        /// </summary>
        /// <returns></returns>
        protected NdfFooter ReadFooter()
        {
            // Footer is 224 bytes
            const int footerLength = 224;
            var       footer       = new NdfFooter();

            using (var ms = new MemoryStream(ContentData, ContentData.Length - footerLength, footerLength))
            {
                var qwdbuffer = new byte[8];
                var dwdbufer  = new byte[4];

                ms.Read(qwdbuffer, 0, qwdbuffer.Length);
                footer.Header = Encoding.ASCII.GetString(qwdbuffer);

                while (ms.Position < ms.Length)
                {
                    var entry = new NdfFooterEntry();

                    ms.Read(dwdbufer, 0, dwdbufer.Length);
                    entry.Name = Encoding.ASCII.GetString(dwdbufer);

                    ms.Seek(4, SeekOrigin.Current);

                    ms.Read(qwdbuffer, 0, qwdbuffer.Length);
                    entry.Offset = BitConverter.ToInt64(qwdbuffer, 0);

                    ms.Read(qwdbuffer, 0, qwdbuffer.Length);
                    entry.Size = BitConverter.ToInt64(qwdbuffer, 0);

                    footer.Entries.Add(entry);
                }
            }

            return(footer);
        }
        protected byte[] GetCompiledContent(NdfBinary ndf)
        {
            var footer = new NdfFooter();

            const long headerSize = (long)NdfbinHeaderSize;

            using (var contentStream = new MemoryStream())
            {
                byte[] buffer = RecompileObj(ndf);
                footer.AddEntry("OBJE", contentStream.Position + headerSize, buffer.Length);
                contentStream.Write(buffer, 0, buffer.Length);

                buffer = RecompileTopo(ndf);
                footer.AddEntry("TOPO", contentStream.Position + headerSize, buffer.Length);
                contentStream.Write(buffer, 0, buffer.Length);

                buffer = RecompileChnk(ndf);
                footer.AddEntry("CHNK", contentStream.Position + headerSize, buffer.Length);
                contentStream.Write(buffer, 0, buffer.Length);

                buffer = RecompileClas(ndf);
                footer.AddEntry("CLAS", contentStream.Position + headerSize, buffer.Length);
                contentStream.Write(buffer, 0, buffer.Length);

                buffer = RecompileProp(ndf);
                footer.AddEntry("PROP", contentStream.Position + headerSize, buffer.Length);
                contentStream.Write(buffer, 0, buffer.Length);

                buffer = RecompileStrTable(ndf.Strings);
                footer.AddEntry("STRG", contentStream.Position + headerSize, buffer.Length);
                contentStream.Write(buffer, 0, buffer.Length);

                buffer = RecompileStrTable(ndf.Trans);
                footer.AddEntry("TRAN", contentStream.Position + headerSize, buffer.Length);
                contentStream.Write(buffer, 0, buffer.Length);

                buffer = RecompileUIntList(ndf.Import);
                footer.AddEntry("IMPR", contentStream.Position + headerSize, buffer.Length);
                contentStream.Write(buffer, 0, buffer.Length);

                buffer = RecompileUIntList(ndf.Export);
                footer.AddEntry("EXPR", contentStream.Position + headerSize, buffer.Length);
                contentStream.Write(buffer, 0, buffer.Length);

                buffer = footer.GetBytes();

                footer.Offset = (ulong)contentStream.Position + NdfbinHeaderSize;
                contentStream.Write(buffer, 0, buffer.Length);

                ndf.Footer = footer;

                return(contentStream.ToArray());
            }
        }
        protected byte[] RecompileContent()
        {
            byte[] buffer;

            var footer = new NdfFooter();

            using (var ms = new MemoryStream())
            {
                buffer = RecompileObj();
                footer.AddEntry("OBJE", ms.Position + 40, buffer.Length);
                ms.Write(buffer, 0, buffer.Length);

                buffer = GetSingleNdfBlockData("TOPO");
                footer.AddEntry("TOPO", ms.Position + 40, buffer.Length);
                ms.Write(buffer, 0, buffer.Length);

                buffer = GetSingleNdfBlockData("CHNK");
                footer.AddEntry("CHNK", ms.Position + 40, buffer.Length);
                ms.Write(buffer, 0, buffer.Length);

                buffer = GetSingleNdfBlockData("CLAS");
                footer.AddEntry("CLAS", ms.Position + 40, buffer.Length);
                ms.Write(buffer, 0, buffer.Length);

                buffer = GetSingleNdfBlockData("PROP");
                footer.AddEntry("PROP", ms.Position + 40, buffer.Length);
                ms.Write(buffer, 0, buffer.Length);

                buffer = RecompileStrTable(Strings);
                footer.AddEntry("STRG", ms.Position + 40, buffer.Length);
                ms.Write(buffer, 0, buffer.Length);

                buffer = RecompileStrTable(Trans);
                footer.AddEntry("TRAN", ms.Position + 40, buffer.Length);
                ms.Write(buffer, 0, buffer.Length);

                buffer = GetSingleNdfBlockData("IMPR");
                footer.AddEntry("IMPR", ms.Position + 40, buffer.Length);
                ms.Write(buffer, 0, buffer.Length);

                buffer = GetSingleNdfBlockData("EXPR");
                footer.AddEntry("EXPR", ms.Position + 40, buffer.Length);
                ms.Write(buffer, 0, buffer.Length);

                buffer = footer.GetBytes();
                ms.Write(buffer, 0, buffer.Length);

                buffer = ms.ToArray();
            }

            Footer = footer;

            return(buffer);
        }
        /// <summary>
        /// Reads the footer data which is the Ndfbin Dictionary.
        /// </summary>
        /// <returns></returns>
        protected NdfFooter ReadFooter(Stream ms, NdfHeader head)
        {
            var footer = new NdfFooter();

            ms.Seek((long)head.FooterOffset, SeekOrigin.Begin);

            var dwdBuffer = new byte[4];
            var qwdbuffer = new byte[8];

            ms.Read(dwdBuffer, 0, dwdBuffer.Length);
            if (BitConverter.ToUInt32(dwdBuffer, 0) != 809717588)
            {
                throw new InvalidDataException("Footer doesnt start with TOC0");
            }


            ms.Read(dwdBuffer, 0, dwdBuffer.Length);
            uint footerEntryCount = BitConverter.ToUInt32(dwdBuffer, 0);

            for (int i = 0; i < footerEntryCount; i++)
            {
                var entry = new NdfFooterEntry();

                ms.Read(qwdbuffer, 0, qwdbuffer.Length);
                entry.Name = Encoding.ASCII.GetString(qwdbuffer).TrimEnd('\0');

                ms.Read(qwdbuffer, 0, qwdbuffer.Length);
                entry.Offset = BitConverter.ToInt64(qwdbuffer, 0);

                ms.Read(qwdbuffer, 0, qwdbuffer.Length);
                entry.Size = BitConverter.ToInt64(qwdbuffer, 0);

                footer.Entries.Add(entry);
            }

            return(footer);
        }