14e3124206a058ceb1be7b893d83b9201744db380Ben Gruver/*
24e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * Copyright 2012, Google Inc.
34e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * All rights reserved.
44e3124206a058ceb1be7b893d83b9201744db380Ben Gruver *
54e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * Redistribution and use in source and binary forms, with or without
64e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * modification, are permitted provided that the following conditions are
74e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * met:
84e3124206a058ceb1be7b893d83b9201744db380Ben Gruver *
94e3124206a058ceb1be7b893d83b9201744db380Ben Gruver *     * Redistributions of source code must retain the above copyright
104e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * notice, this list of conditions and the following disclaimer.
114e3124206a058ceb1be7b893d83b9201744db380Ben Gruver *     * Redistributions in binary form must reproduce the above
124e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * copyright notice, this list of conditions and the following disclaimer
134e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * in the documentation and/or other materials provided with the
144e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * distribution.
154e3124206a058ceb1be7b893d83b9201744db380Ben Gruver *     * Neither the name of Google Inc. nor the names of its
164e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * contributors may be used to endorse or promote products derived from
174e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * this software without specific prior written permission.
184e3124206a058ceb1be7b893d83b9201744db380Ben Gruver *
194e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
204e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
214e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
224e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
234e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
244e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
254e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
264e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
274e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
284e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
294e3124206a058ceb1be7b893d83b9201744db380Ben Gruver * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
304e3124206a058ceb1be7b893d83b9201744db380Ben Gruver */
314e3124206a058ceb1be7b893d83b9201744db380Ben Gruver
324e3124206a058ceb1be7b893d83b9201744db380Ben Gruverpackage org.jf.dexlib2;
334e3124206a058ceb1be7b893d83b9201744db380Ben Gruver
344e3124206a058ceb1be7b893d83b9201744db380Ben Gruverimport java.util.HashMap;
354e3124206a058ceb1be7b893d83b9201744db380Ben Gruver
364e3124206a058ceb1be7b893d83b9201744db380Ben Gruverpublic enum AccessFlags
374e3124206a058ceb1be7b893d83b9201744db380Ben Gruver{
384e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    PUBLIC(0x1, "public", true, true, true),
394e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    PRIVATE(0x2, "private", true, true, true),
404e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    PROTECTED(0x4, "protected", true, true, true),
414e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    STATIC(0x8, "static", true, true, true),
424e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    FINAL(0x10, "final", true, true, true),
434e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    SYNCHRONIZED(0x20, "synchronized", false, true, false),
444e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    VOLATILE(0x40, "volatile", false, false, true),
454e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    BRIDGE(0x40, "bridge", false, true, false),
464e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    TRANSIENT(0x80, "transient", false, false, true),
474e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    VARARGS(0x80, "varargs", false, true, false),
484e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    NATIVE(0x100, "native", false, true, false),
494e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    INTERFACE(0x200, "interface", true, false, false),
504e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    ABSTRACT(0x400, "abstract", true, true, false),
514e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    STRICTFP(0x800, "strictfp", false, true, false),
524e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    SYNTHETIC(0x1000, "synthetic", true, true, true),
534e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    ANNOTATION(0x2000, "annotation", true, false, false),
544e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    ENUM(0x4000, "enum", true, false, true),
554e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    CONSTRUCTOR(0x10000, "constructor", false, true, false),
564e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    DECLARED_SYNCHRONIZED(0x20000, "declared-synchronized", false, true, false);
574e3124206a058ceb1be7b893d83b9201744db380Ben Gruver
584e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    private int value;
594e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    private String accessFlagName;
604e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    private boolean validForClass;
614e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    private boolean validForMethod;
624e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    private boolean validForField;
634e3124206a058ceb1be7b893d83b9201744db380Ben Gruver
644e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    //cache the array of all AccessFlags, because .values() allocates a new array for every call
654e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    private final static AccessFlags[] allFlags;
664e3124206a058ceb1be7b893d83b9201744db380Ben Gruver
674e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    private static HashMap<String, AccessFlags> accessFlagsByName;
684e3124206a058ceb1be7b893d83b9201744db380Ben Gruver
694e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    static {
704e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        allFlags = AccessFlags.values();
714e3124206a058ceb1be7b893d83b9201744db380Ben Gruver
724e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        accessFlagsByName = new HashMap<String, AccessFlags>();
734e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        for (AccessFlags accessFlag: allFlags) {
744e3124206a058ceb1be7b893d83b9201744db380Ben Gruver            accessFlagsByName.put(accessFlag.accessFlagName, accessFlag);
754e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        }
764e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    }
774e3124206a058ceb1be7b893d83b9201744db380Ben Gruver
784e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    private AccessFlags(int value, String accessFlagName, boolean validForClass, boolean validForMethod,
794e3124206a058ceb1be7b893d83b9201744db380Ben Gruver                        boolean validForField) {
804e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        this.value = value;
814e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        this.accessFlagName = accessFlagName;
824e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        this.validForClass = validForClass;
834e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        this.validForMethod = validForMethod;
844e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        this.validForField = validForField;
854e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    }
864e3124206a058ceb1be7b893d83b9201744db380Ben Gruver
874e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    public boolean isSet(int accessFlags) {
884e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        return (this.value & accessFlags) != 0;
894e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    }
904e3124206a058ceb1be7b893d83b9201744db380Ben Gruver
914e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    public static AccessFlags[] getAccessFlagsForClass(int accessFlagValue) {
924e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        int size = 0;
934e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        for (AccessFlags accessFlag: allFlags) {
944e3124206a058ceb1be7b893d83b9201744db380Ben Gruver            if (accessFlag.validForClass && (accessFlagValue & accessFlag.value) != 0) {
954e3124206a058ceb1be7b893d83b9201744db380Ben Gruver                size++;
964e3124206a058ceb1be7b893d83b9201744db380Ben Gruver            }
974e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        }
984e3124206a058ceb1be7b893d83b9201744db380Ben Gruver
994e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        AccessFlags[] accessFlags = new AccessFlags[size];
1004e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        int accessFlagsPosition = 0;
1014e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        for (AccessFlags accessFlag: allFlags) {
1024e3124206a058ceb1be7b893d83b9201744db380Ben Gruver            if (accessFlag.validForClass && (accessFlagValue & accessFlag.value) != 0) {
1034e3124206a058ceb1be7b893d83b9201744db380Ben Gruver                accessFlags[accessFlagsPosition++] = accessFlag;
1044e3124206a058ceb1be7b893d83b9201744db380Ben Gruver            }
1054e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        }
1064e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        return accessFlags;
1074e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    }
1084e3124206a058ceb1be7b893d83b9201744db380Ben Gruver
1094e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    private static String formatAccessFlags(AccessFlags[] accessFlags) {
1104e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        int size = 0;
1114e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        for (AccessFlags accessFlag: accessFlags) {
1124e3124206a058ceb1be7b893d83b9201744db380Ben Gruver            size += accessFlag.toString().length() + 1;
1134e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        }
1144e3124206a058ceb1be7b893d83b9201744db380Ben Gruver
1154e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        StringBuilder sb = new StringBuilder(size);
1164e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        for (AccessFlags accessFlag: accessFlags) {
1174e3124206a058ceb1be7b893d83b9201744db380Ben Gruver            sb.append(accessFlag.toString());
1184e3124206a058ceb1be7b893d83b9201744db380Ben Gruver            sb.append(" ");
1194e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        }
1204e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        if (accessFlags.length > 0) {
1214e3124206a058ceb1be7b893d83b9201744db380Ben Gruver            sb.delete(sb.length() - 1, sb.length());
1224e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        }
1234e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        return sb.toString();
1244e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    }
1254e3124206a058ceb1be7b893d83b9201744db380Ben Gruver
1264e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    public static String formatAccessFlagsForClass(int accessFlagValue) {
1274e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        return formatAccessFlags(getAccessFlagsForClass(accessFlagValue));
1284e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    }
1294e3124206a058ceb1be7b893d83b9201744db380Ben Gruver
1304e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    public static AccessFlags[] getAccessFlagsForMethod(int accessFlagValue) {
1314e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        int size = 0;
1324e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        for (AccessFlags accessFlag: allFlags) {
1334e3124206a058ceb1be7b893d83b9201744db380Ben Gruver            if (accessFlag.validForMethod && (accessFlagValue & accessFlag.value) != 0) {
1344e3124206a058ceb1be7b893d83b9201744db380Ben Gruver                size++;
1354e3124206a058ceb1be7b893d83b9201744db380Ben Gruver            }
1364e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        }
1374e3124206a058ceb1be7b893d83b9201744db380Ben Gruver
1384e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        AccessFlags[] accessFlags = new AccessFlags[size];
1394e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        int accessFlagsPosition = 0;
1404e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        for (AccessFlags accessFlag: allFlags) {
1414e3124206a058ceb1be7b893d83b9201744db380Ben Gruver            if (accessFlag.validForMethod && (accessFlagValue & accessFlag.value) != 0) {
1424e3124206a058ceb1be7b893d83b9201744db380Ben Gruver                accessFlags[accessFlagsPosition++] = accessFlag;
1434e3124206a058ceb1be7b893d83b9201744db380Ben Gruver            }
1444e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        }
1454e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        return accessFlags;
1464e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    }
1474e3124206a058ceb1be7b893d83b9201744db380Ben Gruver
1484e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    public static String formatAccessFlagsForMethod(int accessFlagValue) {
1494e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        return formatAccessFlags(getAccessFlagsForMethod(accessFlagValue));
1504e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    }
1514e3124206a058ceb1be7b893d83b9201744db380Ben Gruver
1524e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    public static AccessFlags[] getAccessFlagsForField(int accessFlagValue) {
1534e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        int size = 0;
1544e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        for (AccessFlags accessFlag: allFlags) {
1554e3124206a058ceb1be7b893d83b9201744db380Ben Gruver            if (accessFlag.validForField && (accessFlagValue & accessFlag.value) != 0) {
1564e3124206a058ceb1be7b893d83b9201744db380Ben Gruver                size++;
1574e3124206a058ceb1be7b893d83b9201744db380Ben Gruver            }
1584e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        }
1594e3124206a058ceb1be7b893d83b9201744db380Ben Gruver
1604e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        AccessFlags[] accessFlags = new AccessFlags[size];
1614e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        int accessFlagsPosition = 0;
1624e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        for (AccessFlags accessFlag: allFlags) {
1634e3124206a058ceb1be7b893d83b9201744db380Ben Gruver            if (accessFlag.validForField && (accessFlagValue & accessFlag.value) != 0) {
1644e3124206a058ceb1be7b893d83b9201744db380Ben Gruver                accessFlags[accessFlagsPosition++] = accessFlag;
1654e3124206a058ceb1be7b893d83b9201744db380Ben Gruver            }
1664e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        }
1674e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        return accessFlags;
1684e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    }
1694e3124206a058ceb1be7b893d83b9201744db380Ben Gruver
1704e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    public static String formatAccessFlagsForField(int accessFlagValue) {
1714e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        return formatAccessFlags(getAccessFlagsForField(accessFlagValue));
1724e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    }
1734e3124206a058ceb1be7b893d83b9201744db380Ben Gruver
1744e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    public static AccessFlags getAccessFlag(String accessFlag) {
1754e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        return accessFlagsByName.get(accessFlag);
1764e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    }
1774e3124206a058ceb1be7b893d83b9201744db380Ben Gruver
1784e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    public int getValue() {
1794e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        return value;
1804e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    }
1814e3124206a058ceb1be7b893d83b9201744db380Ben Gruver
1824e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    public String toString() {
1834e3124206a058ceb1be7b893d83b9201744db380Ben Gruver        return accessFlagName;
1844e3124206a058ceb1be7b893d83b9201744db380Ben Gruver    }
1854e3124206a058ceb1be7b893d83b9201744db380Ben Gruver}
186