1 19 20 package jode.bytecode; 21 import java.io.DataInputStream ; 22 import java.io.DataOutputStream ; 23 import java.io.EOFException ; 24 import java.io.FilterInputStream ; 25 import java.io.IOException ; 26 import java.io.InputStream ; 27 import jode.util.SimpleMap; 28 29 import java.util.Map ; 30 import java.util.Collections ; 31 import java.util.Iterator ; 32 33 34 38 public class BinaryInfo { 39 public static final int HIERARCHY = 0x01; 40 public static final int FIELDS = 0x02; 41 public static final int METHODS = 0x04; 42 public static final int CONSTANTS = 0x08; 43 public static final int KNOWNATTRIBS = 0x10; 44 public static final int INNERCLASSES = 0x20; 45 public static final int OUTERCLASSES = 0x40; 46 public static final int UNKNOWNATTRIBS = 0x80; 47 public static final int FULLINFO = 0xff; 48 public static final int MOSTINFO = 0x7f; 49 public static final int REFLECTINFO = 0x6f; 50 51 private Map unknownAttributes = null; 52 53 protected void skipAttributes(DataInputStream input) throws IOException { 54 int count = input.readUnsignedShort(); 55 for (int i=0; i< count; i++) { 56 input.readUnsignedShort(); long length = input.readInt(); 58 while (length > 0) { 59 long skipped = input.skip(length); 60 if (skipped == 0) 61 throw new EOFException ("Can't skip. EOF?"); 62 length -= skipped; 63 } 64 } 65 } 66 67 protected int getKnownAttributeCount() { 68 return 0; 69 } 70 71 protected void readAttribute(String name, int length, 72 ConstantPool constantPool, 73 DataInputStream input, 74 int howMuch) throws IOException { 75 byte[] data = new byte[length]; 76 input.readFully(data); 77 if ((howMuch & UNKNOWNATTRIBS) != 0) { 78 if (unknownAttributes == null) 79 unknownAttributes = new SimpleMap(); 80 unknownAttributes.put(name, data); 81 } 82 } 83 84 static class ConstrainedInputStream extends FilterInputStream { 85 int length; 86 87 public ConstrainedInputStream(int attrLength, InputStream input) { 88 super(input); 89 length = attrLength; 90 } 91 92 public int read() throws IOException { 93 if (length > 0) { 94 int data = super.read(); 95 length--; 96 return data; 97 } 98 throw new EOFException (); 99 } 100 101 public int read(byte[] b, int off, int len) throws IOException { 102 if (length < len) { 103 len = length; 104 } 105 if (len == 0) 106 return -1; 107 int count = super.read(b, off, len); 108 length -= count; 109 return count; 110 } 111 112 public int read(byte[] b) throws IOException { 113 return read(b, 0, b.length); 114 } 115 116 public long skip(long count) throws IOException { 117 if (length < count) { 118 count = length; 119 } 120 count = super.skip(count); 121 length -= (int) count; 122 return count; 123 } 124 125 public void skipRemaining() throws IOException { 126 while (length > 0) { 127 int skipped = (int) skip(length); 128 if (skipped == 0) 129 throw new EOFException (); 130 length -= skipped; 131 } 132 } 133 } 134 135 protected void readAttributes(ConstantPool constantPool, 136 DataInputStream input, 137 int howMuch) throws IOException { 138 int count = input.readUnsignedShort(); 139 unknownAttributes = null; 140 for (int i=0; i< count; i++) { 141 String attrName = 142 constantPool.getUTF8(input.readUnsignedShort()); 143 final int attrLength = input.readInt(); 144 ConstrainedInputStream constrInput = 145 new ConstrainedInputStream(attrLength, input); 146 readAttribute(attrName, attrLength, 147 constantPool, new DataInputStream (constrInput), 148 howMuch); 149 constrInput.skipRemaining(); 150 } 151 } 152 153 public void dropInfo(int howMuch) { 154 if ((howMuch & UNKNOWNATTRIBS) != 0) 155 unknownAttributes = null; 156 } 157 158 protected void prepareAttributes(GrowableConstantPool gcp) { 159 if (unknownAttributes == null) 160 return; 161 Iterator i = unknownAttributes.keySet().iterator(); 162 while (i.hasNext()) 163 gcp.putUTF8((String ) i.next()); 164 } 165 166 protected void writeKnownAttributes 167 (GrowableConstantPool constantPool, 168 DataOutputStream output) throws IOException { 169 } 170 171 protected void writeAttributes 172 (GrowableConstantPool constantPool, 173 DataOutputStream output) throws IOException { 174 int count = getKnownAttributeCount(); 175 if (unknownAttributes != null) 176 count += unknownAttributes.size(); 177 output.writeShort(count); 178 writeKnownAttributes(constantPool, output); 179 if (unknownAttributes != null) { 180 Iterator i = unknownAttributes.entrySet().iterator(); 181 while (i.hasNext()) { 182 Map.Entry e = (Map.Entry) i.next(); 183 String name = (String ) e.getKey(); 184 byte[] data = (byte[]) e.getValue(); 185 output.writeShort(constantPool.putUTF8(name)); 186 output.writeInt(data.length); 187 output.write(data); 188 } 189 } 190 } 191 192 public int getAttributeSize() { 193 int size = 2; 194 if (unknownAttributes != null) { 195 Iterator i = unknownAttributes.values().iterator(); 196 while (i.hasNext()) 197 size += 2 + 4 + ((byte[]) i.next()).length; 198 } 199 return size; 200 } 201 202 public byte[] findAttribute(String name) { 203 if (unknownAttributes != null) 204 return (byte[]) unknownAttributes.get(name); 205 return null; 206 } 207 208 public Iterator getAttributes() { 209 if (unknownAttributes != null) 210 return unknownAttributes.values().iterator(); 211 return Collections.EMPTY_SET.iterator(); 212 } 213 214 public void setAttribute(String name, byte[] content) { 215 if (unknownAttributes == null) 216 unknownAttributes = new SimpleMap(); 217 unknownAttributes.put(name, content); 218 } 219 220 public byte[] removeAttribute(String name) { 221 if (unknownAttributes != null) 222 return (byte[]) unknownAttributes.remove(name); 223 return null; 224 } 225 226 public void removeAllAttributes() { 227 unknownAttributes = null; 228 } 229 } 230 | Popular Tags |