Home | History | Annotate | Download | only in dexlib2
      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) {
     74             accessFlagsByName.put(accessFlag.accessFlagName, accessFlag);
     75         }
     76     }
     77 
     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 
     87     public boolean isSet(int accessFlags) {
     88         return (this.value & accessFlags) != 0;
     89     }
     90 
     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 
    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 
    126     public static String formatAccessFlagsForClass(int accessFlagValue) {
    127         return formatAccessFlags(getAccessFlagsForClass(accessFlagValue));
    128     }
    129 
    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 
    148     public static String formatAccessFlagsForMethod(int accessFlagValue) {
    149         return formatAccessFlags(getAccessFlagsForMethod(accessFlagValue));
    150     }
    151 
    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 
    170     public static String formatAccessFlagsForField(int accessFlagValue) {
    171         return formatAccessFlags(getAccessFlagsForField(accessFlagValue));
    172     }
    173 
    174     public static AccessFlags getAccessFlag(String accessFlag) {
    175         return accessFlagsByName.get(accessFlag);
    176     }
    177 
    178     public int getValue() {
    179         return value;
    180     }
    181 
    182     public String toString() {
    183         return accessFlagName;
    184     }
    185 }
    186