14e3124206a058ceb1be7b893d83b9201744db380Ben Gruver/* 24e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * Copyright 2012, Google Inc. 34e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * All rights reserved. 44e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * 54e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * Redistribution and use in source and binary forms, with or without 64e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * modification, are permitted provided that the following conditions are 74e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * met: 84e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * 94e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * * Redistributions of source code must retain the above copyright 104e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * notice, this list of conditions and the following disclaimer. 114e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * * Redistributions in binary form must reproduce the above 124e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * copyright notice, this list of conditions and the following disclaimer 134e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * in the documentation and/or other materials provided with the 144e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * distribution. 154e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * * Neither the name of Google Inc. nor the names of its 164e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * contributors may be used to endorse or promote products derived from 174e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * this software without specific prior written permission. 184e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * 194e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 204e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 214e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 224e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 234e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 244e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 254e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 264e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 274e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 284e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 294e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 304e3124206a058ceb1be7b893d83b9201744db380Ben Gruver */ 314e3124206a058ceb1be7b893d83b9201744db380Ben Gruver 324e3124206a058ceb1be7b893d83b9201744db380Ben Gruverpackage org.jf.dexlib2; 334e3124206a058ceb1be7b893d83b9201744db380Ben Gruver 344e3124206a058ceb1be7b893d83b9201744db380Ben Gruverimport java.util.HashMap; 354e3124206a058ceb1be7b893d83b9201744db380Ben Gruver 364e3124206a058ceb1be7b893d83b9201744db380Ben Gruverpublic enum AccessFlags 374e3124206a058ceb1be7b893d83b9201744db380Ben Gruver{ 384e3124206a058ceb1be7b893d83b9201744db380Ben Gruver PUBLIC(0x1, "public", true, true, true), 394e3124206a058ceb1be7b893d83b9201744db380Ben Gruver PRIVATE(0x2, "private", true, true, true), 404e3124206a058ceb1be7b893d83b9201744db380Ben Gruver PROTECTED(0x4, "protected", true, true, true), 414e3124206a058ceb1be7b893d83b9201744db380Ben Gruver STATIC(0x8, "static", true, true, true), 424e3124206a058ceb1be7b893d83b9201744db380Ben Gruver FINAL(0x10, "final", true, true, true), 434e3124206a058ceb1be7b893d83b9201744db380Ben Gruver SYNCHRONIZED(0x20, "synchronized", false, true, false), 444e3124206a058ceb1be7b893d83b9201744db380Ben Gruver VOLATILE(0x40, "volatile", false, false, true), 454e3124206a058ceb1be7b893d83b9201744db380Ben Gruver BRIDGE(0x40, "bridge", false, true, false), 464e3124206a058ceb1be7b893d83b9201744db380Ben Gruver TRANSIENT(0x80, "transient", false, false, true), 474e3124206a058ceb1be7b893d83b9201744db380Ben Gruver VARARGS(0x80, "varargs", false, true, false), 484e3124206a058ceb1be7b893d83b9201744db380Ben Gruver NATIVE(0x100, "native", false, true, false), 494e3124206a058ceb1be7b893d83b9201744db380Ben Gruver INTERFACE(0x200, "interface", true, false, false), 504e3124206a058ceb1be7b893d83b9201744db380Ben Gruver ABSTRACT(0x400, "abstract", true, true, false), 514e3124206a058ceb1be7b893d83b9201744db380Ben Gruver STRICTFP(0x800, "strictfp", false, true, false), 524e3124206a058ceb1be7b893d83b9201744db380Ben Gruver SYNTHETIC(0x1000, "synthetic", true, true, true), 534e3124206a058ceb1be7b893d83b9201744db380Ben Gruver ANNOTATION(0x2000, "annotation", true, false, false), 544e3124206a058ceb1be7b893d83b9201744db380Ben Gruver ENUM(0x4000, "enum", true, false, true), 554e3124206a058ceb1be7b893d83b9201744db380Ben Gruver CONSTRUCTOR(0x10000, "constructor", false, true, false), 564e3124206a058ceb1be7b893d83b9201744db380Ben Gruver DECLARED_SYNCHRONIZED(0x20000, "declared-synchronized", false, true, false); 574e3124206a058ceb1be7b893d83b9201744db380Ben Gruver 584e3124206a058ceb1be7b893d83b9201744db380Ben Gruver private int value; 594e3124206a058ceb1be7b893d83b9201744db380Ben Gruver private String accessFlagName; 604e3124206a058ceb1be7b893d83b9201744db380Ben Gruver private boolean validForClass; 614e3124206a058ceb1be7b893d83b9201744db380Ben Gruver private boolean validForMethod; 624e3124206a058ceb1be7b893d83b9201744db380Ben Gruver private boolean validForField; 634e3124206a058ceb1be7b893d83b9201744db380Ben Gruver 644e3124206a058ceb1be7b893d83b9201744db380Ben Gruver //cache the array of all AccessFlags, because .values() allocates a new array for every call 654e3124206a058ceb1be7b893d83b9201744db380Ben Gruver private final static AccessFlags[] allFlags; 664e3124206a058ceb1be7b893d83b9201744db380Ben Gruver 674e3124206a058ceb1be7b893d83b9201744db380Ben Gruver private static HashMap<String, AccessFlags> accessFlagsByName; 684e3124206a058ceb1be7b893d83b9201744db380Ben Gruver 694e3124206a058ceb1be7b893d83b9201744db380Ben Gruver static { 704e3124206a058ceb1be7b893d83b9201744db380Ben Gruver allFlags = AccessFlags.values(); 714e3124206a058ceb1be7b893d83b9201744db380Ben Gruver 724e3124206a058ceb1be7b893d83b9201744db380Ben Gruver accessFlagsByName = new HashMap<String, AccessFlags>(); 734e3124206a058ceb1be7b893d83b9201744db380Ben Gruver for (AccessFlags accessFlag: allFlags) { 744e3124206a058ceb1be7b893d83b9201744db380Ben Gruver accessFlagsByName.put(accessFlag.accessFlagName, accessFlag); 754e3124206a058ceb1be7b893d83b9201744db380Ben Gruver } 764e3124206a058ceb1be7b893d83b9201744db380Ben Gruver } 774e3124206a058ceb1be7b893d83b9201744db380Ben Gruver 784e3124206a058ceb1be7b893d83b9201744db380Ben Gruver private AccessFlags(int value, String accessFlagName, boolean validForClass, boolean validForMethod, 794e3124206a058ceb1be7b893d83b9201744db380Ben Gruver boolean validForField) { 804e3124206a058ceb1be7b893d83b9201744db380Ben Gruver this.value = value; 814e3124206a058ceb1be7b893d83b9201744db380Ben Gruver this.accessFlagName = accessFlagName; 824e3124206a058ceb1be7b893d83b9201744db380Ben Gruver this.validForClass = validForClass; 834e3124206a058ceb1be7b893d83b9201744db380Ben Gruver this.validForMethod = validForMethod; 844e3124206a058ceb1be7b893d83b9201744db380Ben Gruver this.validForField = validForField; 854e3124206a058ceb1be7b893d83b9201744db380Ben Gruver } 864e3124206a058ceb1be7b893d83b9201744db380Ben Gruver 874e3124206a058ceb1be7b893d83b9201744db380Ben Gruver public boolean isSet(int accessFlags) { 884e3124206a058ceb1be7b893d83b9201744db380Ben Gruver return (this.value & accessFlags) != 0; 894e3124206a058ceb1be7b893d83b9201744db380Ben Gruver } 904e3124206a058ceb1be7b893d83b9201744db380Ben Gruver 914e3124206a058ceb1be7b893d83b9201744db380Ben Gruver public static AccessFlags[] getAccessFlagsForClass(int accessFlagValue) { 924e3124206a058ceb1be7b893d83b9201744db380Ben Gruver int size = 0; 934e3124206a058ceb1be7b893d83b9201744db380Ben Gruver for (AccessFlags accessFlag: allFlags) { 944e3124206a058ceb1be7b893d83b9201744db380Ben Gruver if (accessFlag.validForClass && (accessFlagValue & accessFlag.value) != 0) { 954e3124206a058ceb1be7b893d83b9201744db380Ben Gruver size++; 964e3124206a058ceb1be7b893d83b9201744db380Ben Gruver } 974e3124206a058ceb1be7b893d83b9201744db380Ben Gruver } 984e3124206a058ceb1be7b893d83b9201744db380Ben Gruver 994e3124206a058ceb1be7b893d83b9201744db380Ben Gruver AccessFlags[] accessFlags = new AccessFlags[size]; 1004e3124206a058ceb1be7b893d83b9201744db380Ben Gruver int accessFlagsPosition = 0; 1014e3124206a058ceb1be7b893d83b9201744db380Ben Gruver for (AccessFlags accessFlag: allFlags) { 1024e3124206a058ceb1be7b893d83b9201744db380Ben Gruver if (accessFlag.validForClass && (accessFlagValue & accessFlag.value) != 0) { 1034e3124206a058ceb1be7b893d83b9201744db380Ben Gruver accessFlags[accessFlagsPosition++] = accessFlag; 1044e3124206a058ceb1be7b893d83b9201744db380Ben Gruver } 1054e3124206a058ceb1be7b893d83b9201744db380Ben Gruver } 1064e3124206a058ceb1be7b893d83b9201744db380Ben Gruver return accessFlags; 1074e3124206a058ceb1be7b893d83b9201744db380Ben Gruver } 1084e3124206a058ceb1be7b893d83b9201744db380Ben Gruver 1094e3124206a058ceb1be7b893d83b9201744db380Ben Gruver private static String formatAccessFlags(AccessFlags[] accessFlags) { 1104e3124206a058ceb1be7b893d83b9201744db380Ben Gruver int size = 0; 1114e3124206a058ceb1be7b893d83b9201744db380Ben Gruver for (AccessFlags accessFlag: accessFlags) { 1124e3124206a058ceb1be7b893d83b9201744db380Ben Gruver size += accessFlag.toString().length() + 1; 1134e3124206a058ceb1be7b893d83b9201744db380Ben Gruver } 1144e3124206a058ceb1be7b893d83b9201744db380Ben Gruver 1154e3124206a058ceb1be7b893d83b9201744db380Ben Gruver StringBuilder sb = new StringBuilder(size); 1164e3124206a058ceb1be7b893d83b9201744db380Ben Gruver for (AccessFlags accessFlag: accessFlags) { 1174e3124206a058ceb1be7b893d83b9201744db380Ben Gruver sb.append(accessFlag.toString()); 1184e3124206a058ceb1be7b893d83b9201744db380Ben Gruver sb.append(" "); 1194e3124206a058ceb1be7b893d83b9201744db380Ben Gruver } 1204e3124206a058ceb1be7b893d83b9201744db380Ben Gruver if (accessFlags.length > 0) { 1214e3124206a058ceb1be7b893d83b9201744db380Ben Gruver sb.delete(sb.length() - 1, sb.length()); 1224e3124206a058ceb1be7b893d83b9201744db380Ben Gruver } 1234e3124206a058ceb1be7b893d83b9201744db380Ben Gruver return sb.toString(); 1244e3124206a058ceb1be7b893d83b9201744db380Ben Gruver } 1254e3124206a058ceb1be7b893d83b9201744db380Ben Gruver 1264e3124206a058ceb1be7b893d83b9201744db380Ben Gruver public static String formatAccessFlagsForClass(int accessFlagValue) { 1274e3124206a058ceb1be7b893d83b9201744db380Ben Gruver return formatAccessFlags(getAccessFlagsForClass(accessFlagValue)); 1284e3124206a058ceb1be7b893d83b9201744db380Ben Gruver } 1294e3124206a058ceb1be7b893d83b9201744db380Ben Gruver 1304e3124206a058ceb1be7b893d83b9201744db380Ben Gruver public static AccessFlags[] getAccessFlagsForMethod(int accessFlagValue) { 1314e3124206a058ceb1be7b893d83b9201744db380Ben Gruver int size = 0; 1324e3124206a058ceb1be7b893d83b9201744db380Ben Gruver for (AccessFlags accessFlag: allFlags) { 1334e3124206a058ceb1be7b893d83b9201744db380Ben Gruver if (accessFlag.validForMethod && (accessFlagValue & accessFlag.value) != 0) { 1344e3124206a058ceb1be7b893d83b9201744db380Ben Gruver size++; 1354e3124206a058ceb1be7b893d83b9201744db380Ben Gruver } 1364e3124206a058ceb1be7b893d83b9201744db380Ben Gruver } 1374e3124206a058ceb1be7b893d83b9201744db380Ben Gruver 1384e3124206a058ceb1be7b893d83b9201744db380Ben Gruver AccessFlags[] accessFlags = new AccessFlags[size]; 1394e3124206a058ceb1be7b893d83b9201744db380Ben Gruver int accessFlagsPosition = 0; 1404e3124206a058ceb1be7b893d83b9201744db380Ben Gruver for (AccessFlags accessFlag: allFlags) { 1414e3124206a058ceb1be7b893d83b9201744db380Ben Gruver if (accessFlag.validForMethod && (accessFlagValue & accessFlag.value) != 0) { 1424e3124206a058ceb1be7b893d83b9201744db380Ben Gruver accessFlags[accessFlagsPosition++] = accessFlag; 1434e3124206a058ceb1be7b893d83b9201744db380Ben Gruver } 1444e3124206a058ceb1be7b893d83b9201744db380Ben Gruver } 1454e3124206a058ceb1be7b893d83b9201744db380Ben Gruver return accessFlags; 1464e3124206a058ceb1be7b893d83b9201744db380Ben Gruver } 1474e3124206a058ceb1be7b893d83b9201744db380Ben Gruver 1484e3124206a058ceb1be7b893d83b9201744db380Ben Gruver public static String formatAccessFlagsForMethod(int accessFlagValue) { 1494e3124206a058ceb1be7b893d83b9201744db380Ben Gruver return formatAccessFlags(getAccessFlagsForMethod(accessFlagValue)); 1504e3124206a058ceb1be7b893d83b9201744db380Ben Gruver } 1514e3124206a058ceb1be7b893d83b9201744db380Ben Gruver 1524e3124206a058ceb1be7b893d83b9201744db380Ben Gruver public static AccessFlags[] getAccessFlagsForField(int accessFlagValue) { 1534e3124206a058ceb1be7b893d83b9201744db380Ben Gruver int size = 0; 1544e3124206a058ceb1be7b893d83b9201744db380Ben Gruver for (AccessFlags accessFlag: allFlags) { 1554e3124206a058ceb1be7b893d83b9201744db380Ben Gruver if (accessFlag.validForField && (accessFlagValue & accessFlag.value) != 0) { 1564e3124206a058ceb1be7b893d83b9201744db380Ben Gruver size++; 1574e3124206a058ceb1be7b893d83b9201744db380Ben Gruver } 1584e3124206a058ceb1be7b893d83b9201744db380Ben Gruver } 1594e3124206a058ceb1be7b893d83b9201744db380Ben Gruver 1604e3124206a058ceb1be7b893d83b9201744db380Ben Gruver AccessFlags[] accessFlags = new AccessFlags[size]; 1614e3124206a058ceb1be7b893d83b9201744db380Ben Gruver int accessFlagsPosition = 0; 1624e3124206a058ceb1be7b893d83b9201744db380Ben Gruver for (AccessFlags accessFlag: allFlags) { 1634e3124206a058ceb1be7b893d83b9201744db380Ben Gruver if (accessFlag.validForField && (accessFlagValue & accessFlag.value) != 0) { 1644e3124206a058ceb1be7b893d83b9201744db380Ben Gruver accessFlags[accessFlagsPosition++] = accessFlag; 1654e3124206a058ceb1be7b893d83b9201744db380Ben Gruver } 1664e3124206a058ceb1be7b893d83b9201744db380Ben Gruver } 1674e3124206a058ceb1be7b893d83b9201744db380Ben Gruver return accessFlags; 1684e3124206a058ceb1be7b893d83b9201744db380Ben Gruver } 1694e3124206a058ceb1be7b893d83b9201744db380Ben Gruver 1704e3124206a058ceb1be7b893d83b9201744db380Ben Gruver public static String formatAccessFlagsForField(int accessFlagValue) { 1714e3124206a058ceb1be7b893d83b9201744db380Ben Gruver return formatAccessFlags(getAccessFlagsForField(accessFlagValue)); 1724e3124206a058ceb1be7b893d83b9201744db380Ben Gruver } 1734e3124206a058ceb1be7b893d83b9201744db380Ben Gruver 1744e3124206a058ceb1be7b893d83b9201744db380Ben Gruver public static AccessFlags getAccessFlag(String accessFlag) { 1754e3124206a058ceb1be7b893d83b9201744db380Ben Gruver return accessFlagsByName.get(accessFlag); 1764e3124206a058ceb1be7b893d83b9201744db380Ben Gruver } 1774e3124206a058ceb1be7b893d83b9201744db380Ben Gruver 1784e3124206a058ceb1be7b893d83b9201744db380Ben Gruver public int getValue() { 1794e3124206a058ceb1be7b893d83b9201744db380Ben Gruver return value; 1804e3124206a058ceb1be7b893d83b9201744db380Ben Gruver } 1814e3124206a058ceb1be7b893d83b9201744db380Ben Gruver 1824e3124206a058ceb1be7b893d83b9201744db380Ben Gruver public String toString() { 1834e3124206a058ceb1be7b893d83b9201744db380Ben Gruver return accessFlagName; 1844e3124206a058ceb1be7b893d83b9201744db380Ben Gruver } 1854e3124206a058ceb1be7b893d83b9201744db380Ben Gruver} 186