Home | History | Annotate | Download | only in Util
      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) {
     71             accessFlagsByName.put(accessFlag.accessFlagName, accessFlag);
     72         }
     73     }
     74 
     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 
     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 
    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 
    119     public static String formatAccessFlagsForClass(int accessFlagValue) {
    120         return formatAccessFlags(getAccessFlagsForClass(accessFlagValue));
    121     }
    122 
    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 
    141     public static String formatAccessFlagsForMethod(int accessFlagValue) {
    142         return formatAccessFlags(getAccessFlagsForMethod(accessFlagValue));
    143     }
    144 
    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 
    163     public static String formatAccessFlagsForField(int accessFlagValue) {
    164         return formatAccessFlags(getAccessFlagsForField(accessFlagValue));
    165     }
    166 
    167     public static AccessFlags getAccessFlag(String accessFlag) {
    168         return accessFlagsByName.get(accessFlag);
    169     }
    170 
    171     public int getValue() {
    172         return value;
    173     }
    174 
    175     public String toString() {
    176         return accessFlagName;
    177     }
    178 }
    179