コード例 #1
0
ファイル: FmbUtil.cs プロジェクト: 0x0ade/FmbLib
        public static TypeHandler GenerateHandler(string readerName, Type type)
        {
            TypeHandler handler = null;

            string typeName = getTypeName(readerName, type);

            if (type == null)
            {
                type = FmbHelper.FindType(typeName);
            }

            FmbHelper.Log("Generating TypeHandler for " + typeName);

            Assembly assembly = Assembly.GetExecutingAssembly();

            if (ManifestResourceNames == null)
            {
                ManifestResourceNames = assembly.GetManifestResourceNames();
            }

            string path = null;

            string comparisonReader  = typeName + "Reader.txt";
            string comparisonHandler = typeName + "Handler.txt";

            for (int i = 0; i < ManifestResourceNames.Length; i++)
            {
                if (
                    ManifestResourceNames[i].EndsWith(comparisonReader) ||
                    ManifestResourceNames[i].EndsWith(comparisonHandler)
                    )
                {
                    path = ManifestResourceNames[i];
                    break;
                }
            }

            FmbHelper.Log("Generating TypeHandler<" + typeName + "> from " + path);

            string source;

            using (Stream s = assembly.GetManifestResourceStream(path)) {
                if (s == null)
                {
                    FmbHelper.Log("Resource cannot be loaded.");
                    return(null);
                }
                using (StreamReader sr = new StreamReader(s)) {
                    source = GenerateHandlerSource(sr, typeName, type);
                }
            }

            CompilerParameters parameters = new CompilerParameters();

            parameters.GenerateInMemory = true;
            parameters.CompilerOptions  = "/optimize";

            AssemblyName[] references = assembly.GetReferencedAssemblies();
            for (int i = 0; i < references.Length; i++)
            {
                parameters.ReferencedAssemblies.Add(references[i].Name);
            }
            parameters.ReferencedAssemblies.Add(assembly.Location);
            for (int i = 0; i < GeneratedTypeHandlerAssemblies.Count; i++)
            {
                string reference = GeneratedTypeHandlerAssemblies[i];
                if (parameters.ReferencedAssemblies.Contains(reference))
                {
                    continue;
                }
                parameters.ReferencedAssemblies.Add(reference);
            }

            using (CSharpCodeProvider provider = new CSharpCodeProvider()) {
                try {
                    CompilerResults results = provider.CompileAssemblyFromSource(parameters, source);

                    if (results.Errors.HasErrors)
                    {
                        FmbHelper.Log("Errors while generating TypeHandler:");
                        foreach (CompilerError error in results.Errors)
                        {
                            FmbHelper.Log(error.ToString());
                        }
                        FmbHelper.Log("GeneratedTypeHandler source:");
                        FmbHelper.Log(source);
                        FmbHelper.Log("Referenced assemblies:");
                        for (int i = 0; i < parameters.ReferencedAssemblies.Count; i++)
                        {
                            FmbHelper.Log(parameters.ReferencedAssemblies[i]);
                        }
                    }
                    else
                    {
                        Type compiledType = results.CompiledAssembly.GetType("JIT" + typeName + "Handler");
                        handler = (TypeHandler)compiledType.GetConstructor(new Type[0]).Invoke(new object[0]);
                    }
                } catch (Exception e) {
                    FmbHelper.Log("Error while generating TypeHandler:");
                    FmbHelper.Log(e.ToString());
                    FmbHelper.Log("GeneratedTypeHandler source:");
                    FmbHelper.Log(source);
                    FmbHelper.Log("Referenced assemblies:");
                    for (int i = 0; i < parameters.ReferencedAssemblies.Count; i++)
                    {
                        FmbHelper.Log(parameters.ReferencedAssemblies[i]);
                    }
                }
            }

            return(handler);
        }
コード例 #2
0
ファイル: FmbUtil.cs プロジェクト: 0x0ade/FmbLib
        private static object[] readXNB(ref BinaryReader reader)
        {
            reader.ReadByte(); //w
            reader.ReadByte(); //0x05

            byte flagBits     = reader.ReadByte();
            bool isCompressed = (flagBits & 0x80) == 0x80;

            int size = reader.ReadInt32(); //file size, optionally compressed size

            //FmbLib is currently forced to use an extension for Lzx.
            //Most, if not all current Lzx decompressors in C# require
            //FmbLib to become MSPL / LGPL, not MIT. This further would
            //cause other dependencies to need to change their licenses, too.
            if (isCompressed)
            {
                if (FmbUtil.Setup.CreateLzxDecompressor == null)
                {
                    throw new InvalidOperationException("Cannot read compressed XNBs with FmbUtil.Setup.CreateLzxDecompressor == null");
                }

                byte[]       buffer = new byte[reader.ReadInt32()];
                MemoryStream stream = new MemoryStream(buffer, 0, buffer.Length, true, true);

                ILzxDecompressor lzx      = FmbUtil.Setup.CreateLzxDecompressor(16);
                long             startPos = reader.BaseStream.Position;
                long             pos      = startPos;

                while (pos - startPos < (size - 14))
                {
                    int high      = reader.BaseStream.ReadByte();
                    int low       = reader.BaseStream.ReadByte();
                    int blockSize = (high << 8) | low;
                    int frameSize = 0x8000;
                    if (high == 0xFF)
                    {
                        high      = low;
                        low       = reader.BaseStream.ReadByte();
                        frameSize = (high << 8) | low;
                        high      = reader.BaseStream.ReadByte();
                        low       = reader.BaseStream.ReadByte();
                        blockSize = (high << 8) | low;
                        pos      += 5;
                    }
                    else
                    {
                        pos += 2;
                    }
                    if (blockSize == 0 || frameSize == 0)
                    {
                        break;
                    }
                    lzx.Decompress(reader.BaseStream, blockSize, stream, frameSize);
                    pos += blockSize;
                    reader.BaseStream.Seek(pos, SeekOrigin.Begin);
                }
                stream.Seek(0, SeekOrigin.Begin);

                reader.Close();
                reader = new BinaryReader(stream);
            }

            string[]      readerNames = new string[reader.Read7BitEncodedInt()];
            TypeHandler[] handlers    = new TypeHandler[readerNames.Length];

            for (int i = 0; i < readerNames.Length; i++)
            {
                readerNames[i] = reader.ReadString();
                reader.ReadInt32(); //reader version

                //FmbHelper.Log("debug: handler: " + i + ": " + readerNames[i]);
                handlers[i] = GetTypeHandler(readerNames[i]);
            }

            object[] sharedResources = new object[reader.Read7BitEncodedInt()];

            return(new object[] { readerNames, handlers, sharedResources, reader.Read7BitEncodedInt() - 1 });
        }