public void WriteConstant(HighFileBuilder fileBuilder, HighRegionBuilder regionBuilder, BinaryWriter writer) { if (!this.IsConstant) throw new Exception("Can't use non-constant as a constant"); writer.Write((byte)m_valueType); writer.Write(fileBuilder.IndexTypeSpecTag(m_type)); if (m_valueType == HighValueType.Null) { } else if (m_valueType == HighValueType.ConstantString) writer.Write(fileBuilder.IndexString((string)m_constValue)); else if (m_valueType == HighValueType.ConstantValue) { TypeSpecClassTag classTag = (TypeSpecClassTag)m_type; TypeNameTag className = classTag.TypeName; string classNameStr = className.TypeName; if (classNameStr == "SByte") writer.Write((sbyte)m_constValue); else if (classNameStr == "Byte") writer.Write((byte)m_constValue); else if (classNameStr == "Int16") writer.Write((short)m_constValue); else if (classNameStr == "UInt16") writer.Write((ushort)m_constValue); else if (classNameStr == "Int32") writer.Write((int)m_constValue); else if (classNameStr == "UInt32") writer.Write((uint)m_constValue); else if (classNameStr == "Int64") writer.Write((long)m_constValue); else if (classNameStr == "UInt64") writer.Write((ulong)m_constValue); else if (classNameStr == "IntPtr") writer.Write((long)m_constValue); else if (classNameStr == "UIntPtr") writer.Write((ulong)m_constValue); else if (classNameStr == "Single") writer.Write((float)m_constValue); else if (classNameStr == "Double") writer.Write((double)m_constValue); else throw new ArgumentException(); } else throw new Exception(); }
public CppBuilder(string exportDir, string stubDir, CLRAssemblyCollection assemblies, IDictionary<CLRAssembly, string> pdbPaths) { m_assemblies = assemblies; m_exportPath = exportDir; m_stubDir = stubDir; m_typeSpecClasses = new Dictionary<CLRTypeSpec, CppClass>(); m_fullNameClasses = new Dictionary<string, CppClass>(); m_pdbs = new Dictionary<CLRAssembly, PdbDebugInfo>(); foreach (KeyValuePair<CLRAssembly, string> pdbPath in pdbPaths) { using (System.IO.FileStream fs = new FileStream(pdbPath.Value, FileMode.Open, FileAccess.Read)) { PdbDebugInfo pdbDebugInfo = new PdbDebugInfo(fs); m_pdbs.Add(pdbPath.Key, pdbDebugInfo); } } // Generate type def cache foreach (CLRAssembly assm in assemblies) { CLRMetaDataTables tables = assm.MetaData.MetaDataTables; ICLRTable typeDefs = tables.GetTable(CLRMetaDataTables.TableIndex.TypeDef); for (uint i = 0; i < typeDefs.NumRows; i++) { CLRTypeDefRow typeDef = (CLRTypeDefRow)typeDefs.GetRow(i); CacheTypeDef(typeDef); } } // Export everything foreach (CLRAssembly assm in assemblies) { CLRMetaDataTables tables = assm.MetaData.MetaDataTables; ICLRTable typeDefs = tables.GetTable(CLRMetaDataTables.TableIndex.TypeDef); ICLRTable assemblyTable = tables.GetTable(CLRMetaDataTables.TableIndex.Assembly); CLRAssemblyRow assemblyRow = (CLRAssemblyRow)assemblyTable.GetRow(0); Clarity.Rpa.HighFileBuilder fileBuilder = new Clarity.Rpa.HighFileBuilder(); using (FileStream fs = new FileStream(exportDir + assemblyRow.Name + ".rpa", FileMode.Create)) { using (BinaryWriter writer = new BinaryWriter(fs)) { using (MemoryStream objDataStream = new MemoryStream()) { using (BinaryWriter objDataWriter = new BinaryWriter(objDataStream)) { uint numUsableTypes = 0; for (uint i = 0; i < typeDefs.NumRows; i++) { CLRTypeDefRow typeDef = (CLRTypeDefRow)typeDefs.GetRow(i); if (typeDef.Extends == null) { if (typeDef.TypeNamespace == "" && typeDef.TypeName == "<Module>") continue; if (typeDef.Semantics != CLRTypeDefRow.TypeSemantics.Interface && (typeDef.TypeNamespace != "System" || typeDef.TypeName != "Object")) throw new Exception("Unexpected parentless type"); } numUsableTypes++; } objDataWriter.Write(numUsableTypes); for (uint i = 0; i < typeDefs.NumRows; i++) { CLRTypeDefRow typeDef = (CLRTypeDefRow)typeDefs.GetRow(i); if (typeDef.Extends == null && typeDef.TypeNamespace == "" && typeDef.TypeName == "<Module>") continue; ExportTypeDef(fileBuilder, objDataWriter, typeDef); } uint assemblyNameIndex = fileBuilder.IndexString(assemblyRow.Name); writer.Write(0x41503252); // R2PA fileBuilder.FlushAndWriteCatalogs(writer); writer.Write(assemblyNameIndex); writer.Flush(); objDataWriter.Flush(); objDataStream.WriteTo(fs); } } } } } }