/// <exception cref="System.IO.IOException"/> public StructMethod(DataInputFullStream @in, StructClass clStruct) { /* * method_info { * u2 access_flags; * u2 name_index; * u2 descriptor_index; * u2 attributes_count; * attribute_info attributes[attributes_count]; * } */ classStruct = clStruct; accessFlags = @in.ReadUnsignedShort(); int nameIndex = @in.ReadUnsignedShort(); int descriptorIndex = @in.ReadUnsignedShort(); ConstantPool pool = clStruct.GetPool(); string[] values = pool.GetClassElement(ConstantPool.Method, clStruct.qualifiedName , nameIndex, descriptorIndex); name = values[0]; descriptor = values[1]; attributes = ReadAttributes(@in, pool); if (codeAttributes != null) { Sharpen.Collections.PutAll(attributes, codeAttributes); codeAttributes = null; } }
/// <exception cref="System.IO.IOException"/> public virtual void Reload(LazyLoader loader) { List <StructClass> lstClasses = new List <StructClass>(); foreach (StructClass cl in classes) { string oldName = cl.qualifiedName; StructClass newCl; using (DataInputFullStream @in = loader.GetClassStream(oldName)) { newCl = new StructClass(@in, cl.IsOwn(), loader); } lstClasses.Add(newCl); LazyLoader.Link lnk = loader.GetClassLink(oldName); loader.RemoveClassLink(oldName); loader.AddClassLink(newCl.qualifiedName, lnk); } classes = lstClasses; }
/// <exception cref="System.IO.IOException"/> private void AddArchive(string path, FileSystemInfo file, int type, bool isOwn) { using (ZipArchive archive = ZipFile.Open((file.FullName), ZipArchiveMode.Read)) { foreach (ZipArchiveEntry entry in archive.Entries) { ContextUnit unit = units.GetOrNull(path + "/" + file.Name); if (unit == null) { unit = new ContextUnit(type, path, file.Name, isOwn, saver, decompiledData); if (type == ContextUnit.Type_Jar) { //TODO: Set file manifest // unit.SetManifest((archive).GetManifest()); } Sharpen.Collections.Put(units, path + "/" + file.Name, unit); } string name = entry.FullName; if (!(entry.FullName.EndsWith('/') || entry.FullName.EndsWith('\\'))) //IsDirectory { if (name.EndsWith(".class")) { byte[] bytes = InterpreterUtil.GetBytes(archive, entry); StructClass cl = new StructClass(bytes, isOwn, loader); Sharpen.Collections.Put(classes, cl.qualifiedName, cl); unit.AddClass(cl, name); loader.AddClassLink(cl.qualifiedName, new LazyLoader.Link(file.FullName, name)); } else { unit.AddOtherEntry(file.FullName, name); } } else { unit.AddDirEntry(Path.GetDirectoryName(entry.FullName)); } } } }
/// <exception cref="System.IO.IOException"/> public StructField(DataInputFullStream @in, StructClass clStruct) { /* * field_info { * u2 access_flags; * u2 name_index; * u2 descriptor_index; * u2 attributes_count; * attribute_info attributes[attributes_count]; * } */ accessFlags = @in.ReadUnsignedShort(); int nameIndex = @in.ReadUnsignedShort(); int descriptorIndex = @in.ReadUnsignedShort(); ConstantPool pool = clStruct.GetPool(); string[] values = pool.GetClassElement(ConstantPool.Field, clStruct.qualifiedName , nameIndex, descriptorIndex); name = values[0]; descriptor = values[1]; attributes = ReadAttributes(@in, pool); }
private void AddSpace(string path, FileSystemInfo file, bool isOwn, int level) { if (file is DirectoryInfo dirInfo) { if (level == 1) { path += dirInfo.Name; } else if (level > 1) { path += "/" + dirInfo.Name; } FileInfo[] files = dirInfo.GetFiles(); if (files != null) { for (int i = files.Length - 1; i >= 0; i--) { AddSpace(path, files[i], isOwn, level + 1); } } } else { string filename = file.Name; bool isArchive = false; try { if (filename.EndsWith(".jar")) { isArchive = true; AddArchive(path, file, ContextUnit.Type_Jar, isOwn); } else if (filename.EndsWith(".zip")) { isArchive = true; AddArchive(path, file, ContextUnit.Type_Zip, isOwn); } } catch (IOException ex) { string message = "Corrupted archive file: " + file; DecompilerContext.GetLogger().WriteMessage(message, ex); } if (isArchive) { return; } ContextUnit unit = units.GetOrNull(path); if (unit == null) { unit = new ContextUnit(ContextUnit.Type_Folder, null, path, isOwn, saver, decompiledData ); Sharpen.Collections.Put(units, path, unit); units.RemoveIf(c => string.IsNullOrEmpty(c.Key)); } if (filename.EndsWith(".class")) { try { using (DataInputFullStream @in = loader.GetClassStream(file.FullName, null )) { StructClass cl = new StructClass(@in, isOwn, loader); Sharpen.Collections.Put(classes, cl.qualifiedName, cl); unit.AddClass(cl, filename); loader.AddClassLink(cl.qualifiedName, new LazyLoader.Link(file.FullName, null)); } } catch (IOException ex) { string message = "Corrupted class file: " + file; DecompilerContext.GetLogger().WriteMessage(message, ex); } } else { unit.AddOtherEntry(file.FullName, filename); } } }
public virtual void Save() { switch (type) { case Type_Folder: { // create folder resultSaver.SaveFolder(filename); // non-class files foreach (string[] pair in otherEntries) { resultSaver.CopyFile(pair[0], filename, pair[1]); } // classes for (int i = 0; i < classes.Count; i++) { StructClass cl = classes[i]; string entryName = decompiledData.GetClassEntryName(cl, classEntries[i]); if (entryName != null) { string content = decompiledData.GetClassContent(cl); if (content != null) { int[] mapping = null; if (DecompilerContext.GetOption(IFernflowerPreferences.Bytecode_Source_Mapping)) { mapping = DecompilerContext.GetBytecodeSourceMapper().GetOriginalLinesMapping(); } resultSaver.SaveClassFile(filename, cl.qualifiedName, entryName, content, mapping ); } } } break; } case Type_Jar: case Type_Zip: { // create archive file resultSaver.SaveFolder(archivePath); resultSaver.CreateArchive(archivePath, filename, manifest); // directory entries foreach (string dirEntry in dirEntries) { resultSaver.SaveDirEntry(archivePath, filename, dirEntry + "\\"); } // non-class entries foreach (string[] pair in otherEntries) { if (type != Type_Jar || !Sharpen.Runtime.EqualsIgnoreCase(Manifest_Name, pair[1])) { resultSaver.CopyEntry(pair[0], archivePath, filename, pair[1]); } } // classes for (int i = 0; i < classes.Count; i++) { StructClass cl = classes[i]; string entryName = decompiledData.GetClassEntryName(cl, classEntries[i]); if (entryName != null) { string content = decompiledData.GetClassContent(cl); resultSaver.SaveClassEntry(archivePath, filename, cl.qualifiedName, entryName, content ); } } resultSaver.CloseArchive(archivePath, filename); break; } } }
public virtual void AddClass(StructClass cl, string entryName) { classes.Add(cl); classEntries.Add(entryName); }