0
|
1 /*
|
|
2 * Copyright 2002-2003 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.
|
|
8 *
|
|
9 * This code is distributed in the hope that it will be useful, but WITHOUT
|
|
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
12 * version 2 for more details (a copy is included in the LICENSE file that
|
|
13 * accompanied this code).
|
|
14 *
|
|
15 * You should have received a copy of the GNU General Public License version
|
|
16 * 2 along with this work; if not, write to the Free Software Foundation,
|
|
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
18 *
|
|
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
|
20 * CA 95054 USA or visit www.sun.com if you need additional information or
|
|
21 * have any questions.
|
|
22 *
|
|
23 */
|
|
24
|
|
25 package sun.jvm.hotspot.jdi;
|
|
26
|
|
27 import java.util.List;
|
|
28 import java.util.ArrayList;
|
|
29
|
|
30 public class JNITypeParser {
|
|
31
|
|
32 static final char SIGNATURE_ENDCLASS = ';';
|
|
33 static final char SIGNATURE_FUNC = '(';
|
|
34 static final char SIGNATURE_ENDFUNC = ')';
|
|
35
|
|
36 private String signature;
|
|
37 private List typeNameList;
|
|
38 private List signatureList;
|
|
39 private int currentIndex;
|
|
40
|
|
41 JNITypeParser(String signature) {
|
|
42 this.signature = signature;
|
|
43 }
|
|
44
|
|
45 static String typeNameToSignature(String signature) {
|
|
46 StringBuffer buffer = new StringBuffer();
|
|
47 int firstIndex = signature.indexOf('[');
|
|
48 int index = firstIndex;
|
|
49 while (index != -1) {
|
|
50 buffer.append('[');
|
|
51 index = signature.indexOf('[', index + 1);
|
|
52 }
|
|
53
|
|
54 if (firstIndex != -1) {
|
|
55 signature = signature.substring(0, firstIndex);
|
|
56 }
|
|
57
|
|
58 if (signature.equals("boolean")) {
|
|
59 buffer.append('Z');
|
|
60 } else if (signature.equals("byte")) {
|
|
61 buffer.append('B');
|
|
62 } else if (signature.equals("char")) {
|
|
63 buffer.append('C');
|
|
64 } else if (signature.equals("short")) {
|
|
65 buffer.append('S');
|
|
66 } else if (signature.equals("int")) {
|
|
67 buffer.append('I');
|
|
68 } else if (signature.equals("long")) {
|
|
69 buffer.append('J');
|
|
70 } else if (signature.equals("float")) {
|
|
71 buffer.append('F');
|
|
72 } else if (signature.equals("double")) {
|
|
73 buffer.append('D');
|
|
74 } else {
|
|
75 buffer.append('L');
|
|
76 buffer.append(signature.replace('.', '/'));
|
|
77 buffer.append(';');
|
|
78 }
|
|
79
|
|
80 return buffer.toString();
|
|
81 }
|
|
82
|
|
83 String typeName() {
|
|
84 return (String)typeNameList().get(typeNameList().size()-1);
|
|
85 }
|
|
86
|
|
87 List argumentTypeNames() {
|
|
88 return typeNameList().subList(0, typeNameList().size() - 1);
|
|
89 }
|
|
90
|
|
91 String signature() {
|
|
92 return (String)signatureList().get(signatureList().size()-1);
|
|
93 }
|
|
94
|
|
95 List argumentSignatures() {
|
|
96 return signatureList().subList(0, signatureList().size() - 1);
|
|
97 }
|
|
98
|
|
99 int dimensionCount() {
|
|
100 int count = 0;
|
|
101 String signature = signature();
|
|
102 while (signature.charAt(count) == '[') {
|
|
103 count++;
|
|
104 }
|
|
105 return count;
|
|
106 }
|
|
107
|
|
108 String componentSignature(int level) {
|
|
109 return signature().substring(level);
|
|
110 }
|
|
111
|
|
112 private synchronized List signatureList() {
|
|
113 if (signatureList == null) {
|
|
114 signatureList = new ArrayList(10);
|
|
115 String elem;
|
|
116
|
|
117 currentIndex = 0;
|
|
118
|
|
119 while(currentIndex < signature.length()) {
|
|
120 elem = nextSignature();
|
|
121 signatureList.add(elem);
|
|
122 }
|
|
123 if (signatureList.size() == 0) {
|
|
124 throw new IllegalArgumentException("Invalid JNI signature '" +
|
|
125 signature + "'");
|
|
126 }
|
|
127 }
|
|
128 return signatureList;
|
|
129 }
|
|
130
|
|
131 private synchronized List typeNameList() {
|
|
132 if (typeNameList == null) {
|
|
133 typeNameList = new ArrayList(10);
|
|
134 String elem;
|
|
135
|
|
136 currentIndex = 0;
|
|
137
|
|
138 while(currentIndex < signature.length()) {
|
|
139 elem = nextTypeName();
|
|
140 typeNameList.add(elem);
|
|
141 }
|
|
142 if (typeNameList.size() == 0) {
|
|
143 throw new IllegalArgumentException("Invalid JNI signature '" +
|
|
144 signature + "'");
|
|
145 }
|
|
146 }
|
|
147 return typeNameList;
|
|
148 }
|
|
149
|
|
150 private String nextSignature() {
|
|
151 char key = signature.charAt(currentIndex++);
|
|
152
|
|
153 switch(key) {
|
|
154 case '[':
|
|
155 return key + nextSignature();
|
|
156
|
|
157 case 'L':
|
|
158 int endClass = signature.indexOf(SIGNATURE_ENDCLASS,
|
|
159 currentIndex);
|
|
160 String retVal = signature.substring(currentIndex - 1,
|
|
161 endClass + 1);
|
|
162 currentIndex = endClass + 1;
|
|
163 return retVal;
|
|
164
|
|
165 case 'V':
|
|
166 case 'Z':
|
|
167 case 'B':
|
|
168 case 'C':
|
|
169 case 'S':
|
|
170 case 'I':
|
|
171 case 'J':
|
|
172 case 'F':
|
|
173 case 'D':
|
|
174 return String.valueOf(key);
|
|
175
|
|
176 case SIGNATURE_FUNC:
|
|
177 case SIGNATURE_ENDFUNC:
|
|
178 return nextSignature();
|
|
179
|
|
180 default:
|
|
181 throw new IllegalArgumentException(
|
|
182 "Invalid JNI signature character '" + key + "'");
|
|
183
|
|
184 }
|
|
185 }
|
|
186
|
|
187 private String nextTypeName() {
|
|
188 char key = signature.charAt(currentIndex++);
|
|
189
|
|
190 switch(key) {
|
|
191 case '[':
|
|
192 return nextTypeName() + "[]";
|
|
193
|
|
194 case 'B':
|
|
195 return "byte";
|
|
196
|
|
197 case 'C':
|
|
198 return "char";
|
|
199
|
|
200 case 'L':
|
|
201 int endClass = signature.indexOf(SIGNATURE_ENDCLASS,
|
|
202 currentIndex);
|
|
203 String retVal = signature.substring(currentIndex,
|
|
204 endClass);
|
|
205 retVal = retVal.replace('/','.');
|
|
206 currentIndex = endClass + 1;
|
|
207 return retVal;
|
|
208
|
|
209 case 'F':
|
|
210 return "float";
|
|
211
|
|
212 case 'D':
|
|
213 return "double";
|
|
214
|
|
215 case 'I':
|
|
216 return "int";
|
|
217
|
|
218 case 'J':
|
|
219 return "long";
|
|
220
|
|
221 case 'S':
|
|
222 return "short";
|
|
223
|
|
224 case 'V':
|
|
225 return "void";
|
|
226
|
|
227 case 'Z':
|
|
228 return "boolean";
|
|
229
|
|
230 case SIGNATURE_ENDFUNC:
|
|
231 case SIGNATURE_FUNC:
|
|
232 return nextTypeName();
|
|
233
|
|
234 default:
|
|
235 throw new IllegalArgumentException(
|
|
236 "Invalid JNI signature character '" + key + "'");
|
|
237
|
|
238 }
|
|
239 }
|
|
240 }
|