• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 1998, 2008, 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 
26 package com.sun.tools.jdi;
27 
28 import java.util.List;
29 import java.util.ArrayList;
30 
31 public 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 
JNITypeParser(String signature)42     JNITypeParser(String signature) {
43         this.signature = signature;
44     }
45 
typeNameToSignature(String signature)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 
typeName()84     String typeName() {
85         return typeNameList().get(typeNameList().size()-1);
86     }
87 
argumentTypeNames()88     List<String> argumentTypeNames() {
89         return typeNameList().subList(0, typeNameList().size() - 1);
90     }
91 
signature()92     String signature() {
93         return signatureList().get(signatureList().size()-1);
94     }
95 
argumentSignatures()96     List<String> argumentSignatures() {
97         return signatureList().subList(0, signatureList().size() - 1);
98     }
99 
dimensionCount()100     int dimensionCount() {
101         int count = 0;
102         String signature = signature();
103         while (signature.charAt(count) == '[') {
104             count++;
105         }
106         return count;
107     }
108 
componentSignature(int level)109     String componentSignature(int level) {
110         return signature().substring(level);
111     }
112 
signatureList()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 
typeNameList()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 
nextSignature()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 
nextTypeName()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 }
242