blob: 6151d5293e2293225f13fcb6da94062a98bed726 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1998-1999 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package com.sun.tools.jdi;
27
28import java.util.List;
29import java.util.ArrayList;
30
31public class JNITypeParser {
32
33 static final char SIGNATURE_ENDCLASS = ';';
34 static final char SIGNATURE_FUNC = '(';
35 static final char SIGNATURE_ENDFUNC = ')';
36
37 private String signature;
38 private List<String> typeNameList;
39 private List<String> signatureList;
40 private int currentIndex;
41
42 JNITypeParser(String signature) {
43 this.signature = signature;
44 }
45
46 static String typeNameToSignature(String signature) {
47 StringBuffer buffer = new StringBuffer();
48 int firstIndex = signature.indexOf('[');
49 int index = firstIndex;
50 while (index != -1) {
51 buffer.append('[');
52 index = signature.indexOf('[', index + 1);
53 }
54
55 if (firstIndex != -1) {
56 signature = signature.substring(0, firstIndex);
57 }
58
59 if (signature.equals("boolean")) {
60 buffer.append('Z');
61 } else if (signature.equals("byte")) {
62 buffer.append('B');
63 } else if (signature.equals("char")) {
64 buffer.append('C');
65 } else if (signature.equals("short")) {
66 buffer.append('S');
67 } else if (signature.equals("int")) {
68 buffer.append('I');
69 } else if (signature.equals("long")) {
70 buffer.append('J');
71 } else if (signature.equals("float")) {
72 buffer.append('F');
73 } else if (signature.equals("double")) {
74 buffer.append('D');
75 } else {
76 buffer.append('L');
77 buffer.append(signature.replace('.', '/'));
78 buffer.append(';');
79 }
80
81 return buffer.toString();
82 }
83
84 String typeName() {
85 return (String)typeNameList().get(typeNameList().size()-1);
86 }
87
88 List<String> argumentTypeNames() {
89 return typeNameList().subList(0, typeNameList().size() - 1);
90 }
91
92 String signature() {
93 return (String)signatureList().get(signatureList().size()-1);
94 }
95
96 List<String> argumentSignatures() {
97 return signatureList().subList(0, signatureList().size() - 1);
98 }
99
100 int dimensionCount() {
101 int count = 0;
102 String signature = signature();
103 while (signature.charAt(count) == '[') {
104 count++;
105 }
106 return count;
107 }
108
109 String componentSignature(int level) {
110 return signature().substring(level);
111 }
112
113 private synchronized List<String> signatureList() {
114 if (signatureList == null) {
115 signatureList = new ArrayList<String>(10);
116 String elem;
117
118 currentIndex = 0;
119
120 while(currentIndex < signature.length()) {
121 elem = nextSignature();
122 signatureList.add(elem);
123 }
124 if (signatureList.size() == 0) {
125 throw new IllegalArgumentException("Invalid JNI signature '" +
126 signature + "'");
127 }
128 }
129 return signatureList;
130 }
131
132 private synchronized List<String> typeNameList() {
133 if (typeNameList == null) {
134 typeNameList = new ArrayList<String>(10);
135 String elem;
136
137 currentIndex = 0;
138
139 while(currentIndex < signature.length()) {
140 elem = nextTypeName();
141 typeNameList.add(elem);
142 }
143 if (typeNameList.size() == 0) {
144 throw new IllegalArgumentException("Invalid JNI signature '" +
145 signature + "'");
146 }
147 }
148 return typeNameList;
149 }
150
151 private String nextSignature() {
152 char key = signature.charAt(currentIndex++);
153
154 switch(key) {
155 case (JDWP.Tag.ARRAY):
156 return key + nextSignature();
157
158 case (JDWP.Tag.OBJECT):
159 int endClass = signature.indexOf(SIGNATURE_ENDCLASS,
160 currentIndex);
161 String retVal = signature.substring(currentIndex - 1,
162 endClass + 1);
163 currentIndex = endClass + 1;
164 return retVal;
165
166 case (JDWP.Tag.VOID):
167 case (JDWP.Tag.BOOLEAN):
168 case (JDWP.Tag.BYTE):
169 case (JDWP.Tag.CHAR):
170 case (JDWP.Tag.SHORT):
171 case (JDWP.Tag.INT):
172 case (JDWP.Tag.LONG):
173 case (JDWP.Tag.FLOAT):
174 case (JDWP.Tag.DOUBLE):
175 return String.valueOf(key);
176
177 case SIGNATURE_ENDFUNC:
178 case SIGNATURE_FUNC:
179 return nextSignature();
180
181 default:
182 throw new IllegalArgumentException(
183 "Invalid JNI signature character '" + key + "'");
184
185 }
186 }
187
188 private String nextTypeName() {
189 char key = signature.charAt(currentIndex++);
190
191 switch(key) {
192 case (JDWP.Tag.ARRAY):
193 return nextTypeName() + "[]";
194
195 case (JDWP.Tag.BYTE):
196 return "byte";
197
198 case (JDWP.Tag.CHAR):
199 return "char";
200
201 case (JDWP.Tag.OBJECT):
202 int endClass = signature.indexOf(SIGNATURE_ENDCLASS,
203 currentIndex);
204 String retVal = signature.substring(currentIndex,
205 endClass);
206 retVal = retVal.replace('/','.');
207 currentIndex = endClass + 1;
208 return retVal;
209
210 case (JDWP.Tag.FLOAT):
211 return "float";
212
213 case (JDWP.Tag.DOUBLE):
214 return "double";
215
216 case (JDWP.Tag.INT):
217 return "int";
218
219 case (JDWP.Tag.LONG):
220 return "long";
221
222 case (JDWP.Tag.SHORT):
223 return "short";
224
225 case (JDWP.Tag.VOID):
226 return "void";
227
228 case (JDWP.Tag.BOOLEAN):
229 return "boolean";
230
231 case SIGNATURE_ENDFUNC:
232 case SIGNATURE_FUNC:
233 return nextTypeName();
234
235 default:
236 throw new IllegalArgumentException(
237 "Invalid JNI signature character '" + key + "'");
238
239 }
240 }
241}