String annotation reading/writing
This commit is contained in:
41
src/main/java/net/runelite/deob/attributes/Annotations.java
Normal file
41
src/main/java/net/runelite/deob/attributes/Annotations.java
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
package net.runelite.deob.attributes;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import net.runelite.deob.attributes.annotation.Annotation;
|
||||||
|
|
||||||
|
public class Annotations extends Attribute
|
||||||
|
{
|
||||||
|
private final List<Annotation> annotations = new ArrayList<>();
|
||||||
|
|
||||||
|
public Annotations(Attributes attributes)
|
||||||
|
{
|
||||||
|
super(attributes, AttributeType.RUNTIMEVISIBLEANNOTATIONS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void loadAttribute(DataInputStream is) throws IOException
|
||||||
|
{
|
||||||
|
int num_annotations = is.readUnsignedShort();
|
||||||
|
for (int i = 0; i < num_annotations; ++i)
|
||||||
|
{
|
||||||
|
Annotation a = new Annotation(this);
|
||||||
|
a.load(is);
|
||||||
|
annotations.add(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeAttr(DataOutputStream out) throws IOException
|
||||||
|
{
|
||||||
|
out.writeShort(annotations.size());
|
||||||
|
for (Annotation a : annotations)
|
||||||
|
{
|
||||||
|
a.write(out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ public enum AttributeType
|
|||||||
CONSTANT_VALUE("ConstantValue", ConstantValue.class),
|
CONSTANT_VALUE("ConstantValue", ConstantValue.class),
|
||||||
CODE("Code", Code.class),
|
CODE("Code", Code.class),
|
||||||
EXCEPTIONS("Exceptions", Exceptions.class),
|
EXCEPTIONS("Exceptions", Exceptions.class),
|
||||||
|
RUNTIMEVISIBLEANNOTATIONS("RuntimeVisibleAnnotations", Annotations.class),
|
||||||
UNKNOWN(null, Unknown.class);
|
UNKNOWN(null, Unknown.class);
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package net.runelite.deob.attributes.annotation;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import net.runelite.deob.ConstantPool;
|
||||||
|
import net.runelite.deob.attributes.Annotations;
|
||||||
|
import net.runelite.deob.signature.Type;
|
||||||
|
|
||||||
|
public class Annotation
|
||||||
|
{
|
||||||
|
private final Annotations annotations;
|
||||||
|
private Type type;
|
||||||
|
private List<Element> elements = new ArrayList<>();
|
||||||
|
|
||||||
|
public Annotation(Annotations annotations)
|
||||||
|
{
|
||||||
|
this.annotations = annotations;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Annotations getAnnotations()
|
||||||
|
{
|
||||||
|
return annotations;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void load(DataInputStream is) throws IOException
|
||||||
|
{
|
||||||
|
ConstantPool pool = annotations.getAttributes().getClassFile().getPool();
|
||||||
|
|
||||||
|
int typeIndex = is.readUnsignedShort();
|
||||||
|
type = new Type(pool.getUTF8(typeIndex));
|
||||||
|
|
||||||
|
int pairs = is.readUnsignedShort();
|
||||||
|
for (int i = 0; i < pairs; ++i)
|
||||||
|
{
|
||||||
|
Element e = new Element(this);
|
||||||
|
e.load(is);
|
||||||
|
elements.add(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(DataOutputStream out) throws IOException
|
||||||
|
{
|
||||||
|
ConstantPool pool = annotations.getAttributes().getClassFile().getPool();
|
||||||
|
|
||||||
|
out.writeShort(pool.makeUTF8(type.toString()));
|
||||||
|
out.writeShort(elements.size());
|
||||||
|
for (Element e : elements)
|
||||||
|
{
|
||||||
|
e.write(out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package net.runelite.deob.attributes.annotation;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import net.runelite.deob.ConstantPool;
|
||||||
|
import net.runelite.deob.signature.Type;
|
||||||
|
|
||||||
|
public class Element
|
||||||
|
{
|
||||||
|
private final Annotation annotation;
|
||||||
|
private Type type;
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
public Element(Annotation annotation)
|
||||||
|
{
|
||||||
|
this.annotation = annotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void load(DataInputStream is) throws IOException
|
||||||
|
{
|
||||||
|
ConstantPool pool = annotation.getAnnotations().getAttributes().getClassFile().getPool();
|
||||||
|
|
||||||
|
int typeIndex = is.readShort();
|
||||||
|
type = new Type(pool.getUTF8(typeIndex));
|
||||||
|
|
||||||
|
byte type = is.readByte();
|
||||||
|
|
||||||
|
if (type != 's')
|
||||||
|
throw new RuntimeException("can't parse non string annotation element");
|
||||||
|
|
||||||
|
int index = is.readShort(); // pool index to String
|
||||||
|
|
||||||
|
value = pool.getUTF8(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(DataOutputStream out) throws IOException
|
||||||
|
{
|
||||||
|
ConstantPool pool = annotation.getAnnotations().getAttributes().getClassFile().getPool();
|
||||||
|
|
||||||
|
out.writeShort(pool.makeUTF8(type.toString()));
|
||||||
|
out.write('s');
|
||||||
|
out.writeShort(pool.makeUTF8(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package net.runelite.deob.annotations;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import net.runelite.deob.ClassFile;
|
||||||
|
import net.runelite.deob.ClassGroup;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class AnnotationTest
|
||||||
|
{
|
||||||
|
@Test
|
||||||
|
public void testAnnotation() throws Exception
|
||||||
|
{
|
||||||
|
InputStream in = this.getClass().getClassLoader().getResourceAsStream("net/runelite/deob/annotations/TestClass.class");
|
||||||
|
Assert.assertNotNull(in);
|
||||||
|
|
||||||
|
ClassGroup group = new ClassGroup();
|
||||||
|
|
||||||
|
ClassFile cf = new ClassFile(group, new DataInputStream(in));
|
||||||
|
group.addClass(cf);
|
||||||
|
|
||||||
|
ByteArrayOutputStream bout = new ByteArrayOutputStream();
|
||||||
|
DataOutputStream out = new DataOutputStream(bout);
|
||||||
|
cf.write(out); // write it out
|
||||||
|
|
||||||
|
// parse it again
|
||||||
|
cf = new ClassFile(group, new DataInputStream(new ByteArrayInputStream(bout.toByteArray())));
|
||||||
|
|
||||||
|
System.out.println(cf);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package net.runelite.deob.annotations;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface MyAnnotation
|
||||||
|
{
|
||||||
|
String value();
|
||||||
|
}
|
||||||
10
src/test/java/net/runelite/deob/annotations/TestClass.java
Normal file
10
src/test/java/net/runelite/deob/annotations/TestClass.java
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package net.runelite.deob.annotations;
|
||||||
|
|
||||||
|
public class TestClass
|
||||||
|
{
|
||||||
|
@MyAnnotation("field1")
|
||||||
|
public int field1;
|
||||||
|
|
||||||
|
@MyAnnotation("method1")
|
||||||
|
public void method1() { }
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user