예제 #1
0
        /// <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;
            }
        }
예제 #2
0
        /// <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;
        }
예제 #3
0
 /// <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));
             }
         }
     }
 }
예제 #4
0
        /// <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);
        }
예제 #5
0
        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);
                }
            }
        }
예제 #6
0
        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;
            }
            }
        }
예제 #7
0
 public virtual void AddClass(StructClass cl, string entryName)
 {
     classes.Add(cl);
     classEntries.Add(entryName);
 }