001    package serp.bytecode;
002    
003    import java.io.DataInput;
004    import java.io.DataOutput;
005    import java.io.IOException;
006    
007    import 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     */
020    public 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    }