public void ConvertToStruct_Should_Throw_StructConverterException_When_Content_Parameter_Null_Or_Empty()
        {
            var genericStructConverter = new GenericStructConverter();

            Assert.Throws<StructConverterException>(() => genericStructConverter.ConvertToStruct<TestStruct>(null, 0));
            Assert.Throws<StructConverterException>(() => genericStructConverter.ConvertToStruct<TestStruct>(new byte[0], 0));
        }
        public void ConvertToStruct_Should_Throw_StructConverterException_When_StartIndex_Smaller_Then_Zero_Or_BiggerEq_Then_Content_Length()
        {
            var genericStructConverter = new GenericStructConverter();

            var bytes = new byte[] { 1 };

            Assert.Throws<StructConverterException>(() => genericStructConverter.ConvertToStruct<TestStruct>(bytes, -1));
            Assert.Throws<StructConverterException>(() => genericStructConverter.ConvertToStruct<TestStruct>(bytes, bytes.Length + 1));
        }
        static void Main(string[] args)
        {
            Bootstrapper bootstrapper = Bootstrapper.Create()
                .RegisterInstaller(new ResourceBuilderInstaller())
                .RegisterInstaller(new StructInstaller());

            string chittinKeyPath = Path.Combine(@"C:\Program Files (x86)\Baldur's Gate Enhanced Edition\Data\00766", "CHITIN.KEY");
            string dialogPath = Path.Combine(@"C:\Program Files (x86)\Baldur's Gate Enhanced Edition\Data\data\lang\en_US", "dialog.tlk");

            ResourceFileProvider provider = new ResourceFileProvider();
            GenericStructConverter genericStructConverter = new GenericStructConverter();
            byte[] byteContentOfFile = provider.GetByteContentOfFile(chittinKeyPath);

            var header = genericStructConverter.ConvertToStruct<Header>(byteContentOfFile, 0);

            uint biffEntriesCount = header.BiffEntriesCount;
            uint resourceEntriesCount = header.ResourceEntriesCount;
            uint biffEntriesOffset = header.BiffEntriesOffset;
            uint resourceEntriesOffset = header.ResourceEntriesOffset;
            int headerSize = 24;

            const string StructTemplate = @"using System.Runtime.InteropServices;

            namespace CodeFiction.InfinityFiction.Structure.Structures.Key
            {{
                [StructLayout(LayoutKind.Explicit)]
                public struct KeyStruct
                {{
                    [FieldOffset(0)]
                    public Header Header;

                    [FieldOffset({0}), MarshalAs(UnmanagedType.ByValArray, SizeConst = {2})]
                    public BiffEntry[] BiffEntries;

                    [FieldOffset({1}), MarshalAs(UnmanagedType.ByValArray, SizeConst = {3})]
                    public ResourceEntry[] ResourceEntries;
                }}
            }}";

            string source = string.Format(StructTemplate, biffEntriesOffset, resourceEntriesOffset, biffEntriesCount, resourceEntriesCount);

            Assembly compileSource = CompileSource(source);

            Type type = compileSource.GetType("CodeFiction.InfinityFiction.Structure.Structures.Key.KeyStruct");
            object convertToStruct = genericStructConverter.ConvertToStruct(type, byteContentOfFile, 0);

            KeyResourceBuilder keyResourceBuilder = new KeyResourceBuilder(genericStructConverter, new ResourceConverter(genericStructConverter, new DelegateHelper()), new StructGenerator());

            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            KeyResource buildKeyResource = keyResourceBuilder.BuildKeyResource(byteContentOfFile);
            stopwatch.Stop();
            Console.WriteLine("Miliseconds : {0} - Ticks {1}", stopwatch.ElapsedMilliseconds, stopwatch.ElapsedTicks);

            stopwatch.Reset();

            stopwatch.Start();
            KeyResource buildKeyResourceNew = keyResourceBuilder.BuildKeyResourceNew2(byteContentOfFile, type);
            stopwatch.Stop();
            Console.WriteLine("Miliseconds : {0} - Ticks {1}", stopwatch.ElapsedMilliseconds, stopwatch.ElapsedTicks);

            Console.ReadLine();
        }