/* * Created on Oct 13, 2005 * * TODO To change the template for this generated file go to * Window - Preferences - Java - Code Style - Code Templates */ package org.apache.bcel.classfile; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import org.apache.bcel.SignatureConstants; /** * @author dorina * * TODO To change the template for this generated type comment go to * Window - Preferences - Java - Code Style - Code Templates */ public class LinkAttribute extends Attribute { /** * */ private static final long serialVersionUID = -6979030289206998650L; byte []links; public LinkAttribute(byte constant_attr, int name_index, int length, byte[] links, ConstantPool cp) { super(constant_attr, name_index, length, cp); this.links = links; } public LinkAttribute(byte constant_attr, int name_index, int length, DataInputStream str, ConstantPool cp) throws IOException { this(constant_attr, name_index, length, (byte [])null, cp); if( length > 0) { links = new byte[length]; for(int i = 0; i < length; i++) { links[i] = str.readByte(); } } } /* (non-Javadoc) * @see org.apache.bcel.classfile.Node#accept(org.apache.bcel.classfile.Visitor) */ public void accept(Visitor v) { // TODO Auto-generated method stub } /* (non-Javadoc) * @see org.apache.bcel.classfile.Attribute#copy(org.apache.bcel.classfile.ConstantPool) */ public Attribute copy(ConstantPool constant_pool) { LinkAttribute copy = (LinkAttribute)clone(); System.arraycopy(links,0,copy.links,0,links.length); return copy; } public final void dump(DataOutputStream file) throws IOException { super.dump(file); // FIXME: sort the output ? for(int i = 0; i < links.length; i++) { file.writeByte(links[i]); //file.writeByte(i%2); } } public String toString() { return toString("LinkAttribute"); } public String toString(String name) { return LinkAttribute.print(name, this.links); } public int getLinkCount() { int index = 0; byte codification = links[index++]; boolean isNewSign = (codification & SignatureConstants.ACC_NEW_SIGNATURE) != 0; index += SignatureConstants.LABEL_BYTECODE_SIZE; //number of links int length = 0; if((codification & SignatureConstants.CODIF_4B) != 0) { length = SignatureConstants.readInt(links, index, 1); } else { System.err.println(" Unsupported codification ! "); return -1; } return length; } public int[] getLink(int ind) { int index = 0; byte codification = links[index++]; boolean isNewSign = (codification & SignatureConstants.ACC_NEW_SIGNATURE) != 0; index += SignatureConstants.LABEL_BYTECODE_SIZE; if((codification & SignatureConstants.CODIF_4B) != 0) index += 1; else { System.err.println(" Unsupported codification ! "); return null; } // Skip to wanted link index += ind * 2; int line = 0; int column = 0; column = links[index] & 0xF; line = (links[index] >> 4) & 0xF; index += 1; byte value = links[index]; return new int[]{column, line, (value < 0? value+128: value)}; //return new int[]{column, line, (value < 0? value+256: value)}; } public static String print(String name, byte[] links) { StringBuffer buf = new StringBuffer(name+"("); int index = 0; byte codification = links[index++]; boolean isNewSign = (codification & SignatureConstants.ACC_NEW_SIGNATURE) != 0; buf.append("codification = "+codification+", "); //int dim = SignatureConstants.readInt(links, index, SignatureConstants.LABEL_BYTECODE_SIZE); index += SignatureConstants.LABEL_BYTECODE_SIZE; //number of links int length = 0; if((codification & SignatureConstants.CODIF_4B) != 0) { length = SignatureConstants.readInt(links, index, 1); index += 1; } else if((codification & SignatureConstants.CODIF_8B) !=0){ length = SignatureConstants.readInt(links, index, 2); index += 2; } else { System.err.println(" codification error! "); return null; } if(isNewSign) buf.append("no of links = "+length+", "); else buf.append("no of links to add = "+length+", "); for(int i=0; i < length; i++) { buf.append("[ "); int line = 0; int column = 0; if((codification & SignatureConstants.CODIF_4B) != 0){ column = links[index] & 0xF; line = (links[index] >> 4) & 0xF; index += 1; } else if((codification & SignatureConstants.CODIF_8B) != 0){ line = SignatureConstants.readInt(links, index, 1); index += 1; column = SignatureConstants.readInt(links, index, 1); index += 1; break; } byte value = links[index++]; buf.append(line+" ,"+column+" ,"+value+" ]"); if(i < length - 1) buf.append(", "); } buf.append(')'); if(!isNewSign){ if((codification & SignatureConstants.CODIF_4B) != 0){ length = SignatureConstants.readInt(links, index, 1); index += 1; } else if((codification & SignatureConstants.CODIF_8B) != 0){ length = SignatureConstants.readInt(links, index, 2); index += 2; } else { System.err.println(" codification error! "); return null; } buf.append("no of links to delete= "+length+", "); for(int i=0; i < length; i++) { buf.append("[ "); int line = 0; int column = 0; if((codification & SignatureConstants.CODIF_4B) != 0){ column = links[index] & 0xF; line = (links[index] >> 4) & 0xF; index += 1; } else if((codification & SignatureConstants.CODIF_8B) != 0){ line = SignatureConstants.readInt(links, index, 1); index += 1; column = SignatureConstants.readInt(links, index, 1); index += 1; break; } byte value = links[index++]; buf.append(line+" ,"+column+" ,"+value+" ]"); if(i < length - 1) buf.append(", "); } buf.append(')'); } return buf.toString(); } /** * * @param links * @return */ public static int getLength(byte[] links) { int index = 0; byte codification = links[index++]; //int dim = SignatureConstants.readInt(links, index, SignatureConstants.LABEL_BYTECODE_SIZE); index += SignatureConstants.LABEL_BYTECODE_SIZE; int length = 0; int totalSize = 1; switch(codification) { case SignatureConstants.CODIF_4B: length = SignatureConstants.readInt(links, index, 1); totalSize += 1; totalSize += (length * 2); break; case SignatureConstants.CODIF_8B: length = SignatureConstants.readInt(links, index, 2); totalSize += 2; totalSize += (length * 3); break; default: System.err.println(" codification error! "); return 0; } return totalSize; } }