Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/jtreg/vmTestbase/vm/share/options/PrimitiveParser.java
41155 views
1
/*
2
* Copyright (c) 2008, 2018, 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.
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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*/
23
24
25
package vm.share.options;
26
27
import java.lang.reflect.Array;
28
import java.util.HashMap;
29
import java.util.Map;
30
import nsk.share.TestBug;
31
32
/**
33
* A utility class used to parse arguments of various primitive types.
34
*/
35
public class PrimitiveParser
36
{
37
/**
38
* Checks if the parser can handle passed type ("primitive/wrapper" or one-dim array of those).
39
* Note that one-dim arrays of primitives/strings/wrappers are also supported.
40
* @param type the type to parse against
41
* @return true, if can parse.
42
*/
43
public static boolean canHandle(Class<?> type)
44
{
45
46
if(type.isArray())
47
{
48
Class<?> compType = type.getComponentType();
49
if(compType.isArray()) return false; // Cannot handle multidimensional arrays
50
return canHandle(compType);
51
}
52
type = convertPrimitiveTypeToWrapper(type);
53
return parsers.containsKey(type);
54
}
55
56
/**
57
* A simple helper method.
58
* @param type the type to check for
59
* @return the parser to use, null if there is none.
60
*/
61
private static PParser getParser(Class<?> type)
62
{
63
return parsers.get(convertPrimitiveTypeToWrapper(type));
64
}
65
66
/**
67
* The main API method of this class.
68
* @param param the parameter to parse
69
* @param type parameter type to parse against
70
* @return returns the object of a given type.
71
* @throws vm.share.options.PrimitiveParser.ParserException
72
*/
73
public static Object parse(String param, Class<?> type) throws ParserException
74
{
75
if(type.isArray())
76
{
77
Class<?> compType = type.getComponentType();
78
if(compType.isArray())
79
throw new ParserException("Cannot handle multidimensional arrays");
80
81
if(!canHandle(compType))
82
throw new ParserException("Unable to parse unknown array component type " + compType);
83
84
String[] params = param.split(",");
85
Object arr = Array.newInstance(compType, params.length);
86
for (int i = 0; i < params.length; i++)
87
{
88
String par = params[i].trim();
89
Array.set(arr, i, parse(par, compType));
90
}
91
return arr;
92
}
93
else
94
{
95
if(!canHandle(type))
96
throw new ParserException("Unable to parse unknown type " + type);
97
return getParser(type).parse(param);
98
}
99
}
100
101
// I'm not sure, if generics are of any use here...
102
static private abstract class PParser<T>
103
{
104
abstract T parse(String param) throws ParserException;
105
106
// Class<T> getClassKey()
107
// {
108
// return PrimitiveParser.(Class<T>) T.getClass();
109
// }
110
}
111
112
/**
113
* Converts primitive types to corresponding wrapper classes.
114
* We could register int.class, boolean.class etc in the hashtable instead.
115
* (Or Integer.TYPE, etc.)
116
* @param type to convert to wrapper
117
* @return wrapper class or type if it is not primitive
118
*/
119
public static Class<?> convertPrimitiveTypeToWrapper(Class<?> type)
120
{
121
if(!type.isPrimitive()) return type;
122
Object arr = Array.newInstance(type, 1);
123
Object v = Array.get(arr, 0);
124
return v.getClass();
125
}
126
127
128
//"kind of state" machine stuff
129
130
private static Map<Class<?>, PParser<?>> parsers;
131
132
static
133
{
134
parsers = new HashMap<Class<?>, PrimitiveParser.PParser<?>>(16);
135
parsers.put(Integer.class, new PParser<Integer>()
136
{
137
@Override Integer parse(String param) throws ParserException
138
{
139
if ( param.startsWith("0x") )
140
return Integer.parseInt(param.substring(2));
141
else
142
return Integer.valueOf(param);
143
}
144
});
145
parsers.put(Boolean.class, new PParser<Boolean>()
146
{
147
@Override Boolean parse(String param) throws ParserException
148
{
149
//special behavior for options
150
if(param == null) return true;
151
if(param.trim().length()==0) return true;
152
return Boolean.valueOf(param);
153
}
154
});
155
156
parsers.put(String.class, new PParser<String>()
157
{
158
@Override String parse(String param) throws ParserException
159
{
160
if(param == null) throw new ParserException(" Got null value string.");
161
return param;
162
}
163
});
164
165
166
parsers.put(Character.class, new PParser<Character>()
167
{
168
@Override Character parse(String param) throws ParserException
169
{
170
if(param.length()!=1)
171
throw new TestBug("Found Character type option of length != 1");
172
return Character.valueOf(param.charAt(0));
173
}
174
});
175
176
parsers.put(Byte.class, new PParser<Byte>()
177
{
178
@Override Byte parse(String param) throws ParserException
179
{
180
if ( param.startsWith("0x") )
181
return Byte.parseByte(param.substring(2));
182
else
183
return Byte.valueOf(param);
184
}
185
});
186
187
parsers.put(Short.class, new PParser<Short>()
188
{
189
@Override Short parse(String param) throws ParserException
190
{
191
if ( param.startsWith("0x") )
192
return Short.parseShort(param.substring(2));
193
else
194
return Short.valueOf(param);
195
}
196
});
197
198
parsers.put(Long.class, new PParser<Long>()
199
{
200
@Override Long parse(String param) throws ParserException
201
{
202
if ( param.startsWith("0x") )
203
return Long.parseLong(param.substring(2));
204
else
205
return Long.valueOf(param);
206
}
207
});
208
209
parsers.put(Float.class, new PParser<Float>()
210
{
211
@Override Float parse(String param) throws ParserException
212
{
213
return Float.valueOf(param);
214
}
215
});
216
217
parsers.put(Double.class, new PParser<Double>()
218
{
219
@Override Double parse(String param) throws ParserException
220
{
221
return Double.valueOf(param);
222
}
223
});
224
}
225
226
227
/* Discussion
228
* 1. It was proposed to use instead of the convertPrimitive the following
229
*
230
* private static Map<Class<?>, Class<?>> wrapperClasses = new HashMap<Class<?>, Class<?>>();
231
*
232
* so we could do if(type.isPrimitive())
233
type = wrapperClasses.get(type);
234
static {
235
wrapperClasses.put(boolean.class, Boolean.class);
236
wrapperClasses.put(short.class, Short.class);
237
wrapperClasses.put(int.class, Integer.class);
238
wrapperClasses.put(Long.Type, Long.class); // we can do it this way!
239
wrapperClasses.put(float.class, Float.class);
240
wrapperClasses.put(double.class, Double.class);
241
}
242
* The alternative is to register PParsers with corresponding Primitive type too.
243
*
244
* Also canHandle() could use
245
return wrapperClasses.keySet().contains(type) || wrapperClasses.entrySet().contains(type);
246
247
* 2. Parsing can be implemented via reflection
248
return type.getMethod("valueOf", new Class[]{String.class}).invoke(null, string);
249
250
* I don't like using reflection as it prevents optimisation,
251
* also now Strings and Characters are handled in a nice fashion.
252
*
253
* As for convertToPrimitive trick both ways are good,
254
* but current looks more generic though tricky
255
*/
256
257
//// some test, should it be commented out?
258
// public static void main(String[] args)
259
// {
260
// try
261
// {
262
// String str = "0";
263
// Object o = null;
264
// str = "0";
265
// o = parse(str, String.class);
266
// System.out.println("value:" + str + " type: " + o.getClass() + " value:#" + o + "#");
267
//
268
// str = "0";
269
// o = parse(str, int.class);
270
// System.out.println("value:" + str + " type: " + o.getClass() + " value:#" + o + "#");
271
// str = "0";
272
// o = parse(str, Integer.class);
273
// System.out.println("value:" + str + " type: " + o.getClass() + " value:#" + o + "#");
274
//
275
// str = "0,1,2";
276
// o = parse(str, int[].class);
277
// System.out.println("value:" + str + " type: " + o.getClass() + " value:#" + (int[]) o + "#");
278
// System.out.println("DATA:" + java.util.Arrays.toString((int[])o));
279
// // System.out.println("DATA:" + java.util.Arrays.deepToString( (int[]) o));
280
//
281
// str = "0";
282
// o = parse(str, byte.class);
283
// System.out.println("value:" + str + " type: " + o.getClass() + " value:#" + o + "#");
284
//
285
// str = "0";
286
// o = parse(str, HashMap.class);
287
// System.out.println("value:" + str + " type: " + o.getClass() + " value:#" + o + "#");
288
//// String str = "0"; Object o = parsePrimitiveString(help_option, type); System.out.println("value:" + str + " type: " + o.getClass() + " value:#" + o + "#");
289
// } catch (ParserException ex)
290
// {
291
// System.out.println("" +ex);
292
// }
293
//// String str = "0"; Object o = parsePrimitiveString(help_option, type); System.out.println("value:" + str + " type: " + o.getClass() + " value:#" + o + "#");
294
//
295
// }
296
297
}
298
299