001package serp.bytecode;
002
003import java.io.DataInput;
004import java.io.DataOutput;
005import java.io.IOException;
006
007import serp.bytecode.visitor.BCVisitor;
008
009/*
010 * BootstrapMethods_attribute {
011 *     u2 attribute_name_index;
012 *     u4 attribute_length;
013 *     u2 num_bootstrap_methods;
014 *     {   u2 bootstrap_method_ref;
015 *         u2 num_bootstrap_arguments;
016 *         u2 bootstrap_arguments[num_bootstrap_arguments];
017 *     } bootstrap_methods[num_bootstrap_methods];
018 * }
019 */
020public class BootstrapMethods extends Attribute {
021    private BootstrapMethodElement[] _bootstrapMethods = new BootstrapMethodElement[0];
022    
023    BootstrapMethods(int nameIndex, Attributes owner) {
024        super(nameIndex, owner);
025    }
026
027    public void acceptVisit(BCVisitor visitor) {
028        visitor.enterBootstrapMethod(this);
029        visitor.exitBootstrapMethod(this);        
030    }
031    
032    public int getNumberBootstrapMethods() {
033        return _bootstrapMethods.length;
034    }
035    
036    public BootstrapMethodElement[] getBootstrapMethods() {
037        BootstrapMethodElement[] retval = new BootstrapMethodElement[_bootstrapMethods.length];
038        for (int i = 0; i < _bootstrapMethods.length; i++) {
039            retval[i] = _bootstrapMethods[i];
040        }
041        
042        return retval;
043    }
044    
045    public void setBootstrapMethods(BootstrapMethodElement[] methods) {
046        if (methods == null || methods.length == 0) {
047            _bootstrapMethods = new BootstrapMethodElement[0];
048            return;
049        }
050        
051        _bootstrapMethods = new BootstrapMethodElement[methods.length];
052        
053        for (int i = 0; i < methods.length; i++) {
054            _bootstrapMethods[i] = methods[i];
055        }
056    }
057    
058    /**
059     * Return the length of the bytecode representation of this attribute
060     * in bytes, excluding the name index.
061     */
062    int getLength() {
063        int length = 2;
064        
065        for (int i = 0; i < _bootstrapMethods.length; i++) {
066            length += _bootstrapMethods[i].getLength();
067        }
068        
069        return length;
070    }
071
072    void read(DataInput in, int length) throws IOException {
073        int num_bootstrap_methods = in.readShort();
074        _bootstrapMethods = new BootstrapMethodElement[num_bootstrap_methods];
075        
076        for (int i = 0; i < num_bootstrap_methods; i++) {
077            _bootstrapMethods[i] = new BootstrapMethodElement(this, in);
078        }
079    }
080
081    void write(DataOutput out, int length) throws IOException {
082        out.writeShort(_bootstrapMethods.length);
083        
084        for (int i = 0; i < _bootstrapMethods.length; i++) {
085            _bootstrapMethods[i].write(out);
086        }
087    }
088}