• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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