Package net.sf.rej.java.attribute

Source Code of net.sf.rej.java.attribute.CodeAttribute

/* Copyright (C) 2004-2007 Sami Koivu
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/
package net.sf.rej.java.attribute;

import java.io.PrintStream;
import java.util.HashMap;
import java.util.Map;

import net.sf.rej.java.Code;
import net.sf.rej.java.Exceptions;
import net.sf.rej.java.constantpool.ConstantPool;
import net.sf.rej.util.ByteArrayByteParser;
import net.sf.rej.util.ByteParser;
import net.sf.rej.util.ByteSerializer;
import net.sf.rej.util.Range;

public class CodeAttribute extends Attribute {

    private int maxStack;
    private int maxLocals;
    private Code code;
    private Exceptions exceptions;

    private Attributes attributes;

    public CodeAttribute(int nameIndex, ConstantPool pool) {
        super(nameIndex, pool);
    }

    public CodeAttribute(int nameIndex, ConstantPool cp, int maxStack, int maxLocals) {
        super(nameIndex, cp);
        this.maxStack = maxStack;
        this.maxLocals = maxLocals;
        this.code = new Code(cp);
        this.exceptions = new Exceptions();
        this.attributes = new Attributes();
    }

    @Override
  public byte[] getPayload() {
        ByteSerializer ser = new ByteSerializer(true);
        ser.addShort(this.maxStack);
        ser.addShort(this.maxLocals);
        byte[] data = this.code.getData();
        ser.addInt(data.length);
        ser.addBytes(data);
        ser.addBytes(this.exceptions.getData());
        ser.addBytes(this.attributes.getData());

        return ser.getBytes();
    }
   
    public static enum OffsetTag {MAX_STACK, MAX_LOCALS, CODE_LENGTH, CODE, EXCEPTIONS, ATTRIBUTES}

    /**
     * Returns a map of offsets of each significant element of this method.
     * The offsets returned by this method are only valid until this
     * object is modified. The keys in the map are
     * of type <code>OffsetTag</code>, <code>Attribute</code>.
     *
     * @return a map of element offsets in class file data.
     */
    public Map<Object, Range> getOffsetMap() {
      Map<Object, Range> map = new HashMap<Object, Range>();
      int offset = 6; // 6 bytes of Attribute serialization data.
      map.put(OffsetTag.MAX_STACK, new Range(offset, 2));
      offset += 2;
      map.put(OffsetTag.MAX_LOCALS, new Range(offset, 2));
      offset += 2;
      map.put(OffsetTag.CODE_LENGTH, new Range(offset, 4));
      offset += 4;
      int codeLength = this.code.getData().length;
      map.put(OffsetTag.CODE, new Range(offset, codeLength));
      offset += codeLength;
      int exceptionsLength = this.exceptions.getData().length;
      map.put(OffsetTag.EXCEPTIONS, new Range(offset, exceptionsLength));
      offset += exceptionsLength;
      map.put(OffsetTag.ATTRIBUTES, new Range(offset, this.attributes.getData().length));
     
      // each attribute
      map.putAll(this.attributes.getOffsetMap(offset));

      return map;
    }
   
    @Override
    public void setPayload(byte[] data) {
        ByteParser parser = new ByteArrayByteParser(data);
        parser.setBigEndian(true);
        this.maxStack = parser.getShortAsInt();
        this.maxLocals = parser.getShortAsInt();
        int codeLength = (int) parser.getInt();
        byte[] codeData = parser.getBytes(codeLength);
        ByteParser newParser = new ByteArrayByteParser(codeData);
        newParser.setBigEndian(true);
        this.code = new Code(newParser, pool);
        this.exceptions = new Exceptions(parser, pool);
        this.attributes = new Attributes(parser, pool);
        LineNumberTableAttribute lnAttr = this.attributes.getLineNumberTable();
        if (lnAttr != null) {
          lnAttr.setCode(this.code);
          this.code.setLineNumberTable(lnAttr);
        }
        this.code.insertLabels(this.exceptions.getLabels());
        LocalVariableTableAttribute lvta = this.attributes.getLocalVariableTable();
        this.code.setLocalVariableTable(lvta);
        this.code.setExceptions(this.exceptions);
        if (lvta != null) {
            this.code.insertLabels(lvta.getVariableLabels());
        }
    }

    public Code getCode() {
        return this.code;
    }

    public int getMaxStackSize() {
        return this.maxStack;
    }

    public void setStackSize(int maxStack) {
        this.maxStack = maxStack;
    }

    public void dump(PrintStream out) {
        this.code.printCode(out, this.attributes.getLineNumberTable(), this.attributes.getLocalVariableTable());
    }

    public Attributes getAttributes() {
        return this.attributes;
    }

    public Exceptions getExceptions() {
        return this.exceptions;
    }

    public void setMaxLocals(int locals) {
        this.maxLocals = locals;
    }

    public int getMaxLocals() {
        return this.maxLocals;
    }

    @Override
  public String toString() {
        return "Code(max locals=" + this.maxLocals + ", max stack=" + this.maxStack + ")";
    }

  public void setCode(Code code) {
    this.code = code;
  }

}
TOP

Related Classes of net.sf.rej.java.attribute.CodeAttribute

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.