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); }
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 }); }