Package jadx.core.dex.nodes.parser

Source Code of jadx.core.dex.nodes.parser.EncValueParser

package jadx.core.dex.nodes.parser;

import jadx.core.dex.info.FieldInfo;
import jadx.core.dex.info.MethodInfo;
import jadx.core.dex.nodes.DexNode;
import jadx.core.utils.exceptions.DecodeException;

import java.util.ArrayList;
import java.util.List;

import com.android.dex.Dex.Section;
import com.android.dex.Leb128;

public class EncValueParser {

  private static final int ENCODED_BYTE = 0x00;
  private static final int ENCODED_SHORT = 0x02;
  private static final int ENCODED_CHAR = 0x03;
  private static final int ENCODED_INT = 0x04;
  private static final int ENCODED_LONG = 0x06;
  private static final int ENCODED_FLOAT = 0x10;
  private static final int ENCODED_DOUBLE = 0x11;
  private static final int ENCODED_STRING = 0x17;
  private static final int ENCODED_TYPE = 0x18;
  private static final int ENCODED_FIELD = 0x19;
  private static final int ENCODED_ENUM = 0x1b;
  private static final int ENCODED_METHOD = 0x1a;
  private static final int ENCODED_ARRAY = 0x1c;
  private static final int ENCODED_ANNOTATION = 0x1d;
  private static final int ENCODED_NULL = 0x1e;
  private static final int ENCODED_BOOLEAN = 0x1f;

  protected final Section in;

  private final DexNode dex;

  public EncValueParser(DexNode dex, Section in) {
    this.in = in;
    this.dex = dex;
  }

  public Object parseValue() throws DecodeException {
    int argAndType = readByte();
    int type = argAndType & 0x1F;
    int arg = (argAndType & 0xE0) >> 5;
    int size = arg + 1;

    switch (type) {
      case ENCODED_NULL:
        return null;

      case ENCODED_BOOLEAN:
        return arg == 1;
      case ENCODED_BYTE:
        return in.readByte();

      case ENCODED_SHORT:
        return (short) parseNumber(size, true);
      case ENCODED_CHAR:
        return (char) parseUnsignedInt(size);
      case ENCODED_INT:
        return (int) parseNumber(size, true);
      case ENCODED_LONG:
        return parseNumber(size, true);

      case ENCODED_FLOAT:
        return Float.intBitsToFloat((int) parseNumber(size, false, 4));
      case ENCODED_DOUBLE:
        return Double.longBitsToDouble(parseNumber(size, false, 8));

      case ENCODED_STRING:
        return dex.getString(parseUnsignedInt(size));

      case ENCODED_TYPE:
        return dex.getType(parseUnsignedInt(size));

      case ENCODED_METHOD:
        return MethodInfo.fromDex(dex, parseUnsignedInt(size));

      case ENCODED_FIELD:
      case ENCODED_ENUM:
        return FieldInfo.fromDex(dex, parseUnsignedInt(size));

      case ENCODED_ARRAY:
        int count = Leb128.readUnsignedLeb128(in);
        List<Object> values = new ArrayList<Object>(count);
        for (int i = 0; i < count; i++) {
          values.add(parseValue());
        }
        return values;

      case ENCODED_ANNOTATION:
        return AnnotationsParser.readAnnotation(dex, in, false);
    }
    throw new DecodeException("Unknown encoded value type: 0x" + Integer.toHexString(type));
  }

  private int parseUnsignedInt(int byteCount) {
    return (int) parseNumber(byteCount, false, 0);
  }

  private long parseNumber(int byteCount, boolean isSignExtended) {
    return parseNumber(byteCount, isSignExtended, 0);
  }

  private long parseNumber(int byteCount, boolean isSignExtended, int fillOnRight) {
    long result = 0;
    long last = 0;
    for (int i = 0; i < byteCount; i++) {
      last = readByte();
      result |= last << i * 8;
    }
    if (fillOnRight != 0) {
      for (int i = byteCount; i < fillOnRight; i++) {
        result <<= 8;
      }
    } else {
      if (isSignExtended && (last & 0x80) != 0) {
        for (int i = byteCount; i < 8; i++) {
          result |= (long) 0xFF << i * 8;
        }
      }
    }
    return result;
  }

  private int readByte() {
    return in.readByte() & 0xFF;
  }
}
TOP

Related Classes of jadx.core.dex.nodes.parser.EncValueParser

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.