ClassTransformer.java 2.12 KB
/*
 * This file is part of LiteLoader.
 * Copyright (C) 2012-16 Adam Mummery-Smith
 * All Rights Reserved.
 */
package com.mumfrey.liteloader.transformers;

import org.spongepowered.asm.lib.ClassReader;
import org.spongepowered.asm.lib.ClassWriter;
import org.spongepowered.asm.lib.tree.ClassNode;

import net.minecraft.launchwrapper.IClassTransformer;

/**
 * Base class for transformers which work via ClassNode
 * 
 * @author Adam Mummery-Smith
 */
public abstract class ClassTransformer implements IClassTransformer
{
    public static final String HORIZONTAL_RULE =
            "----------------------------------------------------------------------------------------------------";

    private ClassReader classReader;
    private ClassNode classNode;

    /**
     * @param basicClass
     */
    protected final ClassNode readClass(byte[] basicClass, boolean cacheReader)
    {
        ClassReader classReader = new ClassReader(basicClass);
        if (cacheReader) this.classReader = classReader;

        ClassNode classNode = new ClassNode();
        classReader.accept(classNode, ClassReader.EXPAND_FRAMES);
        return classNode;
    }

    /**
     * @param classNode
     */
    protected final byte[] writeClass(ClassNode classNode)
    {
        // Use optimised writer for speed
        if (this.classReader != null && this.classNode == classNode)
        {
            this.classNode = null;
            IsolatedClassWriter writer = new IsolatedClassWriter(this.classReader, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
            this.classReader = null;
            classNode.accept(writer);
            return writer.toByteArray();
        }

        this.classNode = null;

        IsolatedClassWriter writer = new IsolatedClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
        classNode.accept(writer);
        return writer.toByteArray();
    }

    protected static String getSimpleClassName(ClassNode classNode)
    {
        String className = classNode.name.replace('/', '.');
        int dotPos = className.lastIndexOf('.');
        return dotPos == -1 ? className : className.substring(dotPos + 1);
    }
}