1 /* 2 * Copyright 2012, Google Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * * Redistributions in binary form must reproduce the above 12 * copyright notice, this list of conditions and the following disclaimer 13 * in the documentation and/or other materials provided with the 14 * distribution. 15 * * Neither the name of Google Inc. nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 package org.jf.dexlib2; 33 34 import java.util.HashMap; 35 36 public enum AccessFlags 37 { 38 PUBLIC(0x1, "public", true, true, true), 39 PRIVATE(0x2, "private", true, true, true), 40 PROTECTED(0x4, "protected", true, true, true), 41 STATIC(0x8, "static", true, true, true), 42 FINAL(0x10, "final", true, true, true), 43 SYNCHRONIZED(0x20, "synchronized", false, true, false), 44 VOLATILE(0x40, "volatile", false, false, true), 45 BRIDGE(0x40, "bridge", false, true, false), 46 TRANSIENT(0x80, "transient", false, false, true), 47 VARARGS(0x80, "varargs", false, true, false), 48 NATIVE(0x100, "native", false, true, false), 49 INTERFACE(0x200, "interface", true, false, false), 50 ABSTRACT(0x400, "abstract", true, true, false), 51 STRICTFP(0x800, "strictfp", false, true, false), 52 SYNTHETIC(0x1000, "synthetic", true, true, true), 53 ANNOTATION(0x2000, "annotation", true, false, false), 54 ENUM(0x4000, "enum", true, false, true), 55 CONSTRUCTOR(0x10000, "constructor", false, true, false), 56 DECLARED_SYNCHRONIZED(0x20000, "declared-synchronized", false, true, false); 57 58 private int value; 59 private String accessFlagName; 60 private boolean validForClass; 61 private boolean validForMethod; 62 private boolean validForField; 63 64 //cache the array of all AccessFlags, because .values() allocates a new array for every call 65 private final static AccessFlags[] allFlags; 66 67 private static HashMap<String, AccessFlags> accessFlagsByName; 68 69 static { 70 allFlags = AccessFlags.values(); 71 72 accessFlagsByName = new HashMap<String, AccessFlags>(); 73 for (AccessFlags accessFlag: allFlags) { accessFlagsByName.put(accessFlag.accessFlagName, accessFlag)74 accessFlagsByName.put(accessFlag.accessFlagName, accessFlag); 75 } 76 } 77 AccessFlags(int value, String accessFlagName, boolean validForClass, boolean validForMethod, boolean validForField)78 private AccessFlags(int value, String accessFlagName, boolean validForClass, boolean validForMethod, 79 boolean validForField) { 80 this.value = value; 81 this.accessFlagName = accessFlagName; 82 this.validForClass = validForClass; 83 this.validForMethod = validForMethod; 84 this.validForField = validForField; 85 } 86 isSet(int accessFlags)87 public boolean isSet(int accessFlags) { 88 return (this.value & accessFlags) != 0; 89 } 90 getAccessFlagsForClass(int accessFlagValue)91 public static AccessFlags[] getAccessFlagsForClass(int accessFlagValue) { 92 int size = 0; 93 for (AccessFlags accessFlag: allFlags) { 94 if (accessFlag.validForClass && (accessFlagValue & accessFlag.value) != 0) { 95 size++; 96 } 97 } 98 99 AccessFlags[] accessFlags = new AccessFlags[size]; 100 int accessFlagsPosition = 0; 101 for (AccessFlags accessFlag: allFlags) { 102 if (accessFlag.validForClass && (accessFlagValue & accessFlag.value) != 0) { 103 accessFlags[accessFlagsPosition++] = accessFlag; 104 } 105 } 106 return accessFlags; 107 } 108 formatAccessFlags(AccessFlags[] accessFlags)109 private static String formatAccessFlags(AccessFlags[] accessFlags) { 110 int size = 0; 111 for (AccessFlags accessFlag: accessFlags) { 112 size += accessFlag.toString().length() + 1; 113 } 114 115 StringBuilder sb = new StringBuilder(size); 116 for (AccessFlags accessFlag: accessFlags) { 117 sb.append(accessFlag.toString()); 118 sb.append(" "); 119 } 120 if (accessFlags.length > 0) { 121 sb.delete(sb.length() - 1, sb.length()); 122 } 123 return sb.toString(); 124 } 125 formatAccessFlagsForClass(int accessFlagValue)126 public static String formatAccessFlagsForClass(int accessFlagValue) { 127 return formatAccessFlags(getAccessFlagsForClass(accessFlagValue)); 128 } 129 getAccessFlagsForMethod(int accessFlagValue)130 public static AccessFlags[] getAccessFlagsForMethod(int accessFlagValue) { 131 int size = 0; 132 for (AccessFlags accessFlag: allFlags) { 133 if (accessFlag.validForMethod && (accessFlagValue & accessFlag.value) != 0) { 134 size++; 135 } 136 } 137 138 AccessFlags[] accessFlags = new AccessFlags[size]; 139 int accessFlagsPosition = 0; 140 for (AccessFlags accessFlag: allFlags) { 141 if (accessFlag.validForMethod && (accessFlagValue & accessFlag.value) != 0) { 142 accessFlags[accessFlagsPosition++] = accessFlag; 143 } 144 } 145 return accessFlags; 146 } 147 formatAccessFlagsForMethod(int accessFlagValue)148 public static String formatAccessFlagsForMethod(int accessFlagValue) { 149 return formatAccessFlags(getAccessFlagsForMethod(accessFlagValue)); 150 } 151 getAccessFlagsForField(int accessFlagValue)152 public static AccessFlags[] getAccessFlagsForField(int accessFlagValue) { 153 int size = 0; 154 for (AccessFlags accessFlag: allFlags) { 155 if (accessFlag.validForField && (accessFlagValue & accessFlag.value) != 0) { 156 size++; 157 } 158 } 159 160 AccessFlags[] accessFlags = new AccessFlags[size]; 161 int accessFlagsPosition = 0; 162 for (AccessFlags accessFlag: allFlags) { 163 if (accessFlag.validForField && (accessFlagValue & accessFlag.value) != 0) { 164 accessFlags[accessFlagsPosition++] = accessFlag; 165 } 166 } 167 return accessFlags; 168 } 169 formatAccessFlagsForField(int accessFlagValue)170 public static String formatAccessFlagsForField(int accessFlagValue) { 171 return formatAccessFlags(getAccessFlagsForField(accessFlagValue)); 172 } 173 getAccessFlag(String accessFlag)174 public static AccessFlags getAccessFlag(String accessFlag) { 175 return accessFlagsByName.get(accessFlag); 176 } 177 getValue()178 public int getValue() { 179 return value; 180 } 181 toString()182 public String toString() { 183 return accessFlagName; 184 } 185 } 186