805 lines · 31.1 KB · Java
RawDownload
                result[i] = (byte) constPool.getIntAt(index);            } else {                skipMemberValue(tag, buf);                typeMismatch = true;            }        }        return typeMismatch ? exceptionProxy(tag) : result;    }     private static Object parseCharArray(int length,                                  ByteBuffer buf, ConstantPool constPool) {        char[] result = new char[length];        boolean typeMismatch = false;        byte tag = 0;         for (int i = 0; i < length; i++) {            tag = buf.get();            if (tag == 'C') {                int index = buf.getShort() & 0xFFFF;                result[i] = (char) constPool.getIntAt(index);            } else {                skipMemberValue(tag, buf);                typeMismatch = true;            }        }        return typeMismatch ? exceptionProxy(tag) : result;    }     private static Object parseDoubleArray(int length,                                    ByteBuffer buf, ConstantPool constPool) {        double[] result = new  double[length];        boolean typeMismatch = false;        int tag = 0;         for (int i = 0; i < length; i++) {            tag = buf.get();            if (tag == 'D') {                int index = buf.getShort() & 0xFFFF;                result[i] = constPool.getDoubleAt(index);            } else {                skipMemberValue(tag, buf);                typeMismatch = true;            }        }        return typeMismatch ? exceptionProxy(tag) : result;    }     private static Object parseFloatArray(int length,                                   ByteBuffer buf, ConstantPool constPool) {        float[] result = new float[length];        boolean typeMismatch = false;        int tag = 0;         for (int i = 0; i < length; i++) {            tag = buf.get();            if (tag == 'F') {                int index = buf.getShort() & 0xFFFF;                result[i] = constPool.getFloatAt(index);            } else {                skipMemberValue(tag, buf);                typeMismatch = true;            }        }        return typeMismatch ? exceptionProxy(tag) : result;    }     private static Object parseIntArray(int length,                                 ByteBuffer buf, ConstantPool constPool) {        int[] result = new  int[length];        boolean typeMismatch = false;        int tag = 0;         for (int i = 0; i < length; i++) {            tag = buf.get();            if (tag == 'I') {                int index = buf.getShort() & 0xFFFF;                result[i] = constPool.getIntAt(index);            } else {                skipMemberValue(tag, buf);                typeMismatch = true;            }        }        return typeMismatch ? exceptionProxy(tag) : result;    }     private static Object parseLongArray(int length,                                  ByteBuffer buf, ConstantPool constPool) {        long[] result = new long[length];        boolean typeMismatch = false;        int tag = 0;         for (int i = 0; i < length; i++) {            tag = buf.get();            if (tag == 'J') {                int index = buf.getShort() & 0xFFFF;                result[i] = constPool.getLongAt(index);            } else {                skipMemberValue(tag, buf);                typeMismatch = true;            }        }        return typeMismatch ? exceptionProxy(tag) : result;    }     private static Object parseShortArray(int length,                                   ByteBuffer buf, ConstantPool constPool) {        short[] result = new short[length];        boolean typeMismatch = false;        int tag = 0;         for (int i = 0; i < length; i++) {            tag = buf.get();            if (tag == 'S') {                int index = buf.getShort() & 0xFFFF;                result[i] = (short) constPool.getIntAt(index);            } else {                skipMemberValue(tag, buf);                typeMismatch = true;            }        }        return typeMismatch ? exceptionProxy(tag) : result;    }     private static Object parseBooleanArray(int length,                                     ByteBuffer buf, ConstantPool constPool) {        boolean[] result = new boolean[length];        boolean typeMismatch = false;        int tag = 0;         for (int i = 0; i < length; i++) {            tag = buf.get();            if (tag == 'Z') {                int index = buf.getShort() & 0xFFFF;                result[i] = (constPool.getIntAt(index) != 0);            } else {                skipMemberValue(tag, buf);                typeMismatch = true;            }        }        return typeMismatch ? exceptionProxy(tag) : result;    }     private static Object parseStringArray(int length,                                    ByteBuffer buf,  ConstantPool constPool) {        String[] result = new String[length];        boolean typeMismatch = false;        int tag = 0;         for (int i = 0; i < length; i++) {            tag = buf.get();            if (tag == 's') {                int index = buf.getShort() & 0xFFFF;                result[i] = constPool.getUTF8At(index);            } else {                skipMemberValue(tag, buf);                typeMismatch = true;            }        }        return typeMismatch ? exceptionProxy(tag) : result;    }     private static Object parseClassArray(int length,                                          ByteBuffer buf,                                          ConstantPool constPool,                                          Class<?> container) {        Object[] result = new Class<?>[length];        boolean typeMismatch = false;        int tag = 0;         for (int i = 0; i < length; i++) {            tag = buf.get();            if (tag == 'c') {                result[i] = parseClassValue(buf, constPool, container);            } else {                skipMemberValue(tag, buf);                typeMismatch = true;            }        }        return typeMismatch ? exceptionProxy(tag) : result;    }     private static Object parseEnumArray(int length, Class<? extends Enum> enumType,                                         ByteBuffer buf,                                         ConstantPool constPool,                                         Class<?> container) {        Object[] result = (Object[]) Array.newInstance(enumType, length);        boolean typeMismatch = false;        int tag = 0;         for (int i = 0; i < length; i++) {            tag = buf.get();            if (tag == 'e') {                result[i] = parseEnumValue(enumType, buf, constPool, container);            } else {                skipMemberValue(tag, buf);                typeMismatch = true;            }        }        return typeMismatch ? exceptionProxy(tag) : result;    }     private static Object parseAnnotationArray(int length,                                               Class<? extends Annotation> annotationType,                                               ByteBuffer buf,                                               ConstantPool constPool,                                               Class<?> container) {        Object[] result = (Object[]) Array.newInstance(annotationType, length);        boolean typeMismatch = false;        int tag = 0;         for (int i = 0; i < length; i++) {            tag = buf.get();            if (tag == '@') {                result[i] = parseAnnotation(buf, constPool, container, true);            } else {                skipMemberValue(tag, buf);                typeMismatch = true;            }        }        return typeMismatch ? exceptionProxy(tag) : result;    }     /**     * Return an appropriate exception proxy for a mismatching array     * annotation where the erroneous array has the specified tag.     */    private static ExceptionProxy exceptionProxy(int tag) {        return new AnnotationTypeMismatchExceptionProxy(            "Array with component tag: " + tag);    }     /**     * Skips the annotation at the current position in the specified     * byte buffer.  The cursor of the byte buffer must point to     * an "annotation structure" OR two bytes into an annotation     * structure (i.e., after the type index).     *     * @parameter complete true if the byte buffer points to the beginning     *     of an annotation structure (rather than two bytes in).     */    private static void skipAnnotation(ByteBuffer buf, boolean complete) {        if (complete)            buf.getShort();   // Skip type index        int numMembers = buf.getShort() & 0xFFFF;        for (int i = 0; i < numMembers; i++) {            buf.getShort();   // Skip memberNameIndex            skipMemberValue(buf);        }    }     /**     * Skips the annotation member value at the current position in the     * specified byte buffer.  The cursor of the byte buffer must point to a     * "member_value structure."     */    private static void skipMemberValue(ByteBuffer buf) {        int tag = buf.get();        skipMemberValue(tag, buf);    }     /**     * Skips the annotation member value at the current position in the     * specified byte buffer.  The cursor of the byte buffer must point     * immediately after the tag in a "member_value structure."     */    private static void skipMemberValue(int tag, ByteBuffer buf) {        switch(tag) {          case 'e': // Enum value            buf.getInt();  // (Two shorts, actually.)            break;          case '@':            skipAnnotation(buf, true);            break;          case '[':            skipArray(buf);            break;          default:            // Class, primitive, or String            buf.getShort();        }    }     /**     * Skips the array value at the current position in the specified byte     * buffer.  The cursor of the byte buffer must point to an array value     * struct.     */    private static void skipArray(ByteBuffer buf) {        int length = buf.getShort() & 0xFFFF;        for (int i = 0; i < length; i++)            skipMemberValue(buf);    }     /*     * This method converts the annotation map returned by the parseAnnotations()     * method to an array.  It is called by Field.getDeclaredAnnotations(),     * Method.getDeclaredAnnotations(), and Constructor.getDeclaredAnnotations().     * This avoids the reflection classes to load the Annotation class until     * it is needed.     */    private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0];    public static Annotation[] toArray(Map<Class<? extends Annotation>, Annotation> annotations) {        return annotations.values().toArray(EMPTY_ANNOTATION_ARRAY);    }}

Lines 501–805 of 805. Previous lines