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