Descriptor.java revision 3170:dc017a37aac5
1/* 2 * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package com.sun.tools.classfile; 27 28import java.io.IOException; 29 30/** 31 * See JVMS, section 4.4. 32 * 33 * <p><b>This is NOT part of any supported API. 34 * If you write code that depends on this, you do so at your own risk. 35 * This code and its internal interfaces are subject to change or 36 * deletion without notice.</b> 37 */ 38public class Descriptor { 39 public static class InvalidDescriptor extends DescriptorException { 40 private static final long serialVersionUID = 1L; 41 InvalidDescriptor(String desc) { 42 this.desc = desc; 43 this.index = -1; 44 } 45 46 InvalidDescriptor(String desc, int index) { 47 this.desc = desc; 48 this.index = index; 49 } 50 51 @Override 52 public String getMessage() { 53 // i18n 54 if (index == -1) 55 return "invalid descriptor \"" + desc + "\""; 56 else 57 return "descriptor is invalid at offset " + index + " in \"" + desc + "\""; 58 } 59 60 public final String desc; 61 public final int index; 62 63 } 64 65 public Descriptor(ClassReader cr) throws IOException { 66 this(cr.readUnsignedShort()); 67 } 68 69 public Descriptor(int index) { 70 this.index = index; 71 72 } 73 74 public String getValue(ConstantPool constant_pool) throws ConstantPoolException { 75 return constant_pool.getUTF8Value(index); 76 } 77 78 public int getParameterCount(ConstantPool constant_pool) 79 throws ConstantPoolException, InvalidDescriptor { 80 String desc = getValue(constant_pool); 81 int end = desc.indexOf(")"); 82 if (end == -1) 83 throw new InvalidDescriptor(desc); 84 parse(desc, 0, end + 1); 85 return count; 86 87 } 88 89 public String getParameterTypes(ConstantPool constant_pool) 90 throws ConstantPoolException, InvalidDescriptor { 91 String desc = getValue(constant_pool); 92 int end = desc.indexOf(")"); 93 if (end == -1) 94 throw new InvalidDescriptor(desc); 95 return parse(desc, 0, end + 1); 96 } 97 98 public String getReturnType(ConstantPool constant_pool) 99 throws ConstantPoolException, InvalidDescriptor { 100 String desc = getValue(constant_pool); 101 int end = desc.indexOf(")"); 102 if (end == -1) 103 throw new InvalidDescriptor(desc); 104 return parse(desc, end + 1, desc.length()); 105 } 106 107 public String getFieldType(ConstantPool constant_pool) 108 throws ConstantPoolException, InvalidDescriptor { 109 String desc = getValue(constant_pool); 110 return parse(desc, 0, desc.length()); 111 } 112 113 private String parse(String desc, int start, int end) 114 throws InvalidDescriptor { 115 int p = start; 116 StringBuilder sb = new StringBuilder(); 117 int dims = 0; 118 count = 0; 119 120 while (p < end) { 121 String type; 122 char ch; 123 switch (ch = desc.charAt(p++)) { 124 case '(': 125 sb.append('('); 126 continue; 127 128 case ')': 129 sb.append(')'); 130 continue; 131 132 case '[': 133 dims++; 134 continue; 135 136 case 'B': 137 type = "byte"; 138 break; 139 140 case 'C': 141 type = "char"; 142 break; 143 144 case 'D': 145 type = "double"; 146 break; 147 148 case 'F': 149 type = "float"; 150 break; 151 152 case 'I': 153 type = "int"; 154 break; 155 156 case 'J': 157 type = "long"; 158 break; 159 160 case 'L': 161 int sep = desc.indexOf(';', p); 162 if (sep == -1) 163 throw new InvalidDescriptor(desc, p - 1); 164 type = desc.substring(p, sep).replace('/', '.'); 165 p = sep + 1; 166 break; 167 168 case 'S': 169 type = "short"; 170 break; 171 172 case 'Z': 173 type = "boolean"; 174 break; 175 176 case 'V': 177 type = "void"; 178 break; 179 180 default: 181 throw new InvalidDescriptor(desc, p - 1); 182 } 183 184 if (sb.length() > 1 && sb.charAt(0) == '(') 185 sb.append(", "); 186 sb.append(type); 187 for ( ; dims > 0; dims-- ) 188 sb.append("[]"); 189 190 count++; 191 } 192 193 return sb.toString(); 194 } 195 196 public final int index; 197 private int count; 198} 199