Package org.jreversepro.parser.common

Source Code of org.jreversepro.parser.common.AttributeParser

/**
* JReversePro - Java Decompiler / Disassembler.
* Copyright (C) 2008 Karthik Kumar.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*    http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
***/
package org.jreversepro.parser.common;

import java.io.DataInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

import org.jreversepro.CustomLoggerFactory;
import org.jreversepro.jvm.JVMConstants;
import org.jreversepro.jvm.TypeInferrer;
import org.jreversepro.reflect.ConstantPool;
import org.jreversepro.reflect.LocalVariableTable;
import org.jreversepro.reflect.Method;


/**
* <b>Attribute</b> has the ability to read the 'ATTRIBUTES' of the Field ,
* Method and the Class as a whole.
*
* @author Karthik Kumar
* @version 1.00,
*/
public final class AttributeParser {

  private static final Logger logger = CustomLoggerFactory.createLogger();

  /**
   * Manipulates the 'ConstantValue' attribute of the Fields.
   * <p>
   * <b>ConstantValue</b> attribute <br>
   * u2 attribute_name_index; <br>
   * u4 attribute_length;<br>
   * u2 constantvalue_index;<br>
   * </p>
   *
   * @param aDis
   *          DataInputStream containing the bytes of the class.
   * @param aCpInfo
   *          ConstantPool Information.
   * @return a String containing the Constant value, of the field.
   * @throws IOException
   *           Error in Class Stream of bytes.
   */
  public static String readConstantValue(DataInputStream aDis,
      ConstantPool aCpInfo) throws IOException {

    int len = aDis.readInt();
    short index = aDis.readShort();
    return (aCpInfo.getBasicDataTypeValue(index));
  }

  /**
   * Manipulates the 'Deprecated' attribute of the Fields.
   * <p>
   * <b>Deprecated</b> attribute <br>
   * u2 attribute_name_index; <br>
   * u4 attribute_length;<br>
   * </p>
   *
   * @param aDis
   *          DataInputStream containing the bytes of the class.
   * @throws IOException
   *           Error in Class Stream of bytes.
   */
  public static void readDeprecated(DataInputStream aDis) throws IOException {
    int len = aDis.readInt();// len must be zero.
  }

  /**
   * Manipulates the 'Synthetic' attribute of the Fields.
   * <p>
   * <b>Synthetic</b> attribute <br>
   * u2 attribute_name_index; <br>
   * u4 attribute_length;<br>
   * </p>
   *
   * @param aDis
   *          DataInputStream containing the bytes of the class.
   * @throws IOException
   *           Error in Class Stream of bytes.
   */
  public static void readSynthetic(DataInputStream aDis) throws IOException {
    int len = aDis.readInt();// len must be zero.
  }

  /**
   * Manipulates the 'Code' attribute of the Methods.
   * <p>
   * <b>Code</b> attribute <br>
   * u2 attribute_name_index;<br>
   * u4 attribute_length;<br>
   * u2 max_stack; <br>
   * u2 max_locals; <br>
   * u4 code_length; <br>
   * u1 code[code_length];<br>
   * u2 exception_table_length;<br>
   * <br>
   * u2 start_pc; u2 end_pc; u2 handler_pc; u2 catch_type;<br>
   * exception_table[exception_table_length]; <br>
   * u2 attributes_count;<br>
   * attribute_info attributes[attributes_count]; <br>
   * </p>
   *
   * @param aDis
   *          DataInputStream containing the bytes of the class.
   * @param aCpInfo
   *          ConstantPool Information.
   * @param aLocalMethod
   *          Reference to the current method for which the code is to be
   *          manipulated.
   * @throws IOException
   *           Error in Class Stream of bytes.
   */
  public static void readCode(Method aLocalMethod, DataInputStream aDis,
      ConstantPool aCpInfo) throws IOException {

    /*
     * This refers to the Code attribute length. All the attributes start with
     * the index which has a CONSTANT_Utf8 (2 bytes) and then 4 bytes denoting
     * length of the attribute [here Code]. Here we just read it to move the
     * aDis pointer to read and pass the 4 bytes length.
     */
    int len = aDis.readInt();

    short maxStack = aDis.readShort();
    aLocalMethod.setMaxStack(maxStack);

    short maxLocals = aDis.readShort();
    aLocalMethod.setMaxLocals(maxLocals);

    int codeLen = aDis.readInt();

    byte[] btArray = new byte[codeLen];
    aDis.readFully(btArray);
    aLocalMethod.setBytes(btArray);

    // exception_table_length
    short excLen = aDis.readShort();

    /**
     * startPc - Offset of start of try/catch range. endPc - Offset of end of
     * try/catch range. handlerPc - Offset of start of exception handler code.
     * catchType - Type of exception handled.
     */
    for (int i = 0; i < excLen; i++) {
      short startPc = aDis.readShort();
      short endPc = aDis.readShort();
      short handlerPc = aDis.readShort();
      short catchType = aDis.readShort();

      // If type of class caught is any, then CatchType is 0.
      aLocalMethod.addExceptionBlock(startPc, endPc, handlerPc, aCpInfo
          .getClassName(catchType));
    }

    short attrCount = aDis.readShort();

    for (int i = 0; i < attrCount; i++) {
      readCodeAttributes(aDis, aCpInfo, aLocalMethod);
    }
  }

  /**
   * Manipulates the 'SourceFile' attribute of the Fields.
   * <p>
   * <b> SourceFile </b> attribute <br>
   * u2 attribute_name_index; <br>
   * u4 attribute_length;<br>
   * u2 sourcefile_index;
   * </p>
   *
   * @param aDis
   *          DataInputStream containing the bytes of the class.
   * @param aCpInfo
   *          ConstantPool Information.
   * @return NO_STRING
   * @throws IOException
   *           Error in Class Stream of bytes.
   */
  public static String readSourceFile(DataInputStream aDis, ConstantPool aCpInfo)
      throws IOException {

    aDis.readInt();
    short srcIndex = aDis.readShort();
    String srcName = aCpInfo.getUtf8String(srcIndex);
    return srcName;
  }

  /**
   * Manipulates the Exceptions attribute.
   * <p>
   * <b> Exceptions_attribute </b> <br>
   * u2 attribute_name_index;<br>
   * u4 attribute_length;<br>
   * u2 number_of_exceptions;<br>
   * u2 exception_index_table[number_of_exceptions]; <br>
   *
   * Present , if there is a throws clause in the declaration of the method.<br>
   * </p>
   *
   * @param aDis
   *          DataInputStream containing the bytes of the class.
   * @param aCpInfo
   *          ConstantPool Information.
   *
   * @return Set of classes present in the 'throws' clause statement.
   * @throws IOException
   *           Error in Class Stream of bytes.
   */
  public static List<String> readExceptions(DataInputStream aDis,
      ConstantPool aCpInfo) throws IOException {
    // Responsible for the 'throws' clause
    List<String> classes = new ArrayList<String>(2);
    aDis.readInt();
    short numException = aDis.readShort();
    for (int i = 0; i < numException; i++) {
      short classIndex = aDis.readShort();
      classes.add(aCpInfo.getClassName(classIndex));
    }
    return classes;
  }

  public static void readInnerClasses(DataInputStream dis) {
    // TODO Auto-generated method stub
   
  }

  /**
   * Reads the possible attributes of Code.
   * <p>
   * Possible attributes of Code are <b> LineNumberTable </b> and <b>
   * LocalVariableTable </b>
   * </p>
   *
   * @param aDis
   *          DataInputStream containing the bytes of the class.
   * @param aCpInfo
   *          ConstantPool Information.
   * @throws IOException
   *           Error in Class Stream of bytes.
   */
  private static void readCodeAttributes(DataInputStream aDis,
      ConstantPool aCpInfo, Method method) throws IOException {

    short attrNameIndex = aDis.readShort();
    String attrName = aCpInfo.getUtf8String(attrNameIndex);

    if (attrName.equals(JVMConstants.ATTRIBUTE_LINENUMBERTABLE)) {
      readLineNumberTable(aDis);
    } else if (attrName.equals(JVMConstants.ATTRIBUTE_LOCALVARIABLETABLE)) {
      readLocalVariableTable(aDis, aCpInfo, method);
    }
  }

  /**
   * Manipulates the LineNumberTable attribute.
   * <p>
   * <b> LineNumberTable_attribute </b> <br>
   * u2 attribute_name_index; <br>
   * u4 attribute_length; <br>
   * u2 line_number_table_length; { <br>
   * u2 start_pc; <br>
   * u2 line_number;<br>
   * line_number_table[line_number_table_length]; <br>
   * </p>
   *
   * @param aDis
   *          DataInputStream containing the bytes of the class.
   * @throws IOException
   *           Error in Class Stream of bytes.
   */
  private static void readLineNumberTable(DataInputStream aDis)
      throws IOException {
    int len = aDis.readInt();
    byte[] btRead = new byte[len];
    // TODO - New: Do some manipulation with the LineNumberTable
    // attribute..
    aDis.readFully(btRead);
  }

  /**
   * Manipulates the LocalVariableTable attribute.
   * <p>
   * LocalVariableTable_attribute { u2 attribute_name_index; u4
   * attribute_length; u2 local_variable_table_length; { u2 start_pc; u2 length;
   * u2 name_index; u2 descriptor_index; u2 index; }
   * local_variable_table[local_variable_table_length]; }
   *
   * @param aDis
   *          DataInputStream containing the bytes of the class.
   * @throws IOException
   *           Error in Class Stream of bytes.
   *
   */
  private static void readLocalVariableTable(DataInputStream aDis,
      ConstantPool constPool, Method method) throws IOException {
    int len = aDis.readInt();

    LocalVariableTable localVarTable = new LocalVariableTable(method.isStatic());

    short localVarArrLen = aDis.readShort();
    for (int ctr = 1; ctr <= localVarArrLen; ctr++) {
      short startPc = aDis.readShort();
      short length = aDis.readShort();
      short nameIndex = aDis.readShort();
      short descIndex = aDis.readShort();
      short frameIndex = aDis.readShort();

      localVarTable.addLocalVariable(startPc, length, nameIndex, descIndex,
          constPool.getEntryValue(nameIndex), constPool
              .getEntryValue(descIndex), frameIndex);

      String jvmType = constPool.getEntryValue(descIndex);
      if (TypeInferrer.doesTypeOccupy2EntriesInVariableTable(jvmType)) {
        // Add another entry.
        localVarTable.addLocalVariable(startPc, length, nameIndex, descIndex,
            constPool.getEntryValue(nameIndex), constPool
                .getEntryValue(descIndex), (short) (frameIndex + 1));

      }

    }

    method.setVariableTable(localVarTable);

  }


}
TOP

Related Classes of org.jreversepro.parser.common.AttributeParser

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.