GlueGen v2.6.0-rc-20250712
GlueGen, Native Binding Generator for Java™ (public API).
JavaType.java
Go to the documentation of this file.
1/**
2 * Copyright (c) 2010-2023 JogAmp Community. All rights reserved.
3 * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * - Redistribution of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * - Redistribution in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * Neither the name of Sun Microsystems, Inc. or the names of
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * This software is provided "AS IS," without a warranty of any kind. ALL
21 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
22 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
23 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
24 * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
25 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
26 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
27 * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
28 * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
29 * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
30 * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
31 * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
32 *
33 * You acknowledge that this software is not designed or intended for use
34 * in the design, construction, operation or maintenance of any nuclear
35 * facility.
36 *
37 * Sun gratefully acknowledges that this software was originally authored
38 * and developed by Kenneth Bradley Russell and Christopher John Kline.
39 */
40
41package com.jogamp.gluegen;
42
43import java.nio.*;
44import java.util.ArrayList;
45import java.util.List;
46
47import com.jogamp.gluegen.cgram.types.*;
48
49/**
50 * Describes a java-side representation of a type that is used to represent
51 * the same data on both the Java-side and C-side during a JNI operation. Also
52 * contains some utility methods for creating common types.
53 */
54public class JavaType {
55
56 /*
57 * Represents C arrays that will / can be represented
58 * with NIO buffers (resolved down to another JavaType later in processing)
59 */
60 private enum C_PTR {
61 VOID, CHAR, SHORT, INT32, INT64, FLOAT, DOUBLE;
62 }
63
64 /** Pascal string argument index tuple for length and value. */
65public static class PascalStringElem {
66 public final int lengthIdx;
67 public final int valueIdx;
68
69 PascalStringElem(final int lenIdx, final int valIdx) {
70 lengthIdx = lenIdx;
71 valueIdx = valIdx;
72 }
73
74 public static final List<Integer> pushValueIndex(final List<PascalStringElem> source, List<Integer> indices) {
75 if( null == indices ) {
76 indices = new ArrayList<Integer>(2);
77 }
78 for(final PascalStringElem p : source) {
79 indices.add(p.valueIdx);
80 }
81 return indices;
82 }
83 public static final List<Integer> pushLengthIndex(final List<PascalStringElem> source) {
84 final List<Integer> lengths = new ArrayList<Integer>(2);
85 for(final PascalStringElem p : source) {
86 lengths.add(p.lengthIdx);
87 }
88 return lengths;
89 }
90
91 public static PascalStringElem getByValueIdx(final List<PascalStringElem> pascals, final int valueIdx) {
92 if( null != pascals ) {
93 for(final PascalStringElem p : pascals) {
94 if( valueIdx == p.valueIdx ) {
95 return p;
96 }
97 }
98 }
99 return null;
100 }
101 public static PascalStringElem getByLengthIdx(final List<PascalStringElem> pascals, final int lengthIdx) {
102 if( null != pascals ) {
103 for(final PascalStringElem p : pascals) {
104 if( lengthIdx == p.lengthIdx ) {
105 return p;
106 }
107 }
108 }
109 return null;
110 }
111
112 @Override
113 public String toString() {
114 return "PascalStr[lenIdx "+lengthIdx+", valIdx "+valueIdx+"]";
115 }
116}
117
118private final Class<?> clazz; // Primitive types and other types representable as Class objects
119 private final String clazzName; // Future (not yet generated or existing) Class objects (existing at runtime)
120 private final String structName; // Types we're generating glue code for (i.e., C structs)
121 private final Type elementType; // Element type if this JavaType represents a C array
122 private final C_PTR primitivePointerType;
123 private final boolean opaqued;
125
126 private static JavaType objectType;
127 private static JavaType nioBufferType;
128 private static JavaType nioByteBufferType;
129 private static JavaType nioShortBufferType;
130 private static JavaType nioIntBufferType;
131 private static JavaType nioLongBufferType;
132 private static JavaType nioPointerBufferType;
133 private static JavaType nioFloatBufferType;
134 private static JavaType nioDoubleBufferType;
135 private static JavaType nioByteBufferArrayType;
136
137 @Override
138 public boolean equals(final Object arg) {
139 if ((arg == null) || (!(arg instanceof JavaType))) {
140 return false;
141 }
142 final JavaType t = (JavaType) arg;
143 return this == t ||
144 ( t.clazz == clazz &&
145 ( ( clazzName == null ? t.clazzName == null : clazzName.equals(t.clazzName) ) ||
146 ( clazzName != null && t.clazzName != null && clazzName.equals(t.clazzName) )
147 ) &&
148 ( ( structName == null ? t.structName == null : structName.equals(t.structName) ) ||
149 ( structName != null && t.structName != null && structName.equals(t.structName) )
150 ) &&
151 ( elementType == t.elementType ||
152 ( elementType != null && t.elementType != null && elementType.equals(t.elementType) )
153 ) &&
154 primitivePointerType == t.primitivePointerType
155 );
156 }
157
158 @Override
159 public int hashCode() {
160 if (clazz != null) {
161 return clazz.hashCode();
162 }
163 if (clazzName != null) {
164 return clazzName.hashCode();
165 }
166 if (structName != null) {
167 return structName.hashCode();
168 }
169 if (elementType != null) {
170 return elementType.hashCode();
171 }
172 if (primitivePointerType != null) {
173 return primitivePointerType.hashCode();
174 }
175 return 0;
176 }
177
179 return new JavaType(elementType);
180 }
182 return elementType;
183 }
184
185 /** Creates a JavaType corresponding to the given opaque Java type. This
186 can be used to represent arrays of primitive values or Strings;
187 the emitters understand how to perform proper conversion from
188 the corresponding C type. */
189 public static JavaType createForOpaqueClass(final Class<?> clazz) {
190 return new JavaType(clazz, true, null);
191 }
192
193 /** Creates a JavaType corresponding to the given Java type. This
194 can be used to represent arrays of primitive values or Strings;
195 the emitters understand how to perform proper conversion from
196 the corresponding C type. */
197 public static JavaType createForClass(final Class<?> clazz) {
198 return new JavaType(clazz, false, null);
199 }
200 public static JavaType createForStringClass(final Class<?> clazz, final PascalStringElem pascalStrElem) {
201 return new JavaType(clazz, false, pascalStrElem);
202 }
203
204 /**
205 * Creates a JavaType corresponding to the given named Java class,
206 * not necessarily existing yet.
207 */
208 public static JavaType createForNamedClass(final String name) {
209 return new JavaType(name, null);
210 }
211
212 /** Creates a JavaType corresponding to the specified C CompoundType
213 name; for example, if "Foo" is supplied, then this JavaType
214 represents a "Foo *" by way of a StructAccessor. */
215 public static JavaType createForCStruct(final String name) {
216 return new JavaType(null, name);
217 }
218
219 /** Creates a JavaType corresponding to an array of the given
220 element type. This is used to represent arrays of "Foo **" which
221 should be mapped to Foo[] in Java. */
222 public static JavaType createForCArray(final Type elementType) {
223 return new JavaType(elementType);
224 }
225
227 return new JavaType(C_PTR.VOID);
228 }
229
231 return new JavaType(C_PTR.CHAR);
232 }
233
235 return new JavaType(C_PTR.SHORT);
236 }
237
239 return new JavaType(C_PTR.INT32);
240 }
241
243 return new JavaType(C_PTR.INT64);
244 }
245
247 return new JavaType(C_PTR.FLOAT);
248 }
249
251 return new JavaType(C_PTR.DOUBLE);
252 }
253
254 public static JavaType createForJNIEnv() {
255 return createForCStruct("JNIEnv");
256 }
257
258 public static JavaType forObjectClass() {
259 if (objectType == null) {
260 objectType = createForClass(java.lang.Object.class);
261 }
262 return objectType;
263 }
264
265 public static JavaType forNIOBufferClass() {
266 if (nioBufferType == null) {
267 nioBufferType = createForClass(java.nio.Buffer.class);
268 }
269 return nioBufferType;
270 }
271
273 if (nioByteBufferType == null) {
274 nioByteBufferType = createForClass(java.nio.ByteBuffer.class);
275 }
276 return nioByteBufferType;
277 }
278
280 if (nioShortBufferType == null) {
281 nioShortBufferType = createForClass(java.nio.ShortBuffer.class);
282 }
283 return nioShortBufferType;
284 }
285
287 if (nioIntBufferType == null) {
288 nioIntBufferType = createForClass(java.nio.IntBuffer.class);
289 }
290 return nioIntBufferType;
291 }
292
294 if (nioLongBufferType == null) {
295 nioLongBufferType = createForClass(java.nio.LongBuffer.class);
296 }
297 return nioLongBufferType;
298 }
299
301 if(nioPointerBufferType == null)
302 nioPointerBufferType = createForClass(com.jogamp.common.nio.PointerBuffer.class);
303 return nioPointerBufferType;
304 }
305
307 if (nioFloatBufferType == null) {
308 nioFloatBufferType = createForClass(java.nio.FloatBuffer.class);
309 }
310 return nioFloatBufferType;
311 }
312
314 if (nioDoubleBufferType == null) {
315 nioDoubleBufferType = createForClass(java.nio.DoubleBuffer.class);
316 }
317 return nioDoubleBufferType;
318 }
319
321 if (nioByteBufferArrayType == null) {
322 final ByteBuffer[] tmp = new ByteBuffer[0];
323 nioByteBufferArrayType = createForClass(tmp.getClass());
324 }
325 return nioByteBufferArrayType;
326 }
327
328 /**
329 * Returns the Java Class corresponding to this type. Returns null if this
330 * object corresponds to a C primitive array type.
331 */
332 public Class<?> getJavaClass() {
333 return clazz;
334 }
335
336 /**
337 * Returns the Java type name corresponding to this type.
338 */
339 public String getName() {
340 return getName(null);
341 }
342
343 public String getName(final JavaConfiguration cfg) {
344 if (clazz != null) {
345 if (clazz.isArray()) {
346 return arrayName(clazz);
347 }
348 return clazz.getName();
349 }
350 if( clazzName != null ) {
351 return (null != cfg ? (cfg.packageForStruct(clazzName) + ".") : "") + clazzName;
352 }
353 if (elementType != null) {
354 return elementType.getName();
355 }
356 return (null != cfg ? (cfg.packageForStruct(clazzName) + ".") : "") + structName;
357 }
358
359 /**
360 * Returns the descriptor (internal type signature) corresponding to this type.
361 */
362 public String getDescriptor() {
363 return getDescriptor(null);
364 }
365 public String getDescriptor(final JavaConfiguration cfg) {
366 if (clazz != null) {
367 return descriptor(clazz);
368 }
369 if( null != clazzName ) {
370 return descriptor((null != cfg ? (cfg.packageForStruct(clazzName) + ".") : "") + clazzName);
371 }
372 if( null != structName ) {
373 return descriptor((null != cfg ? (cfg.packageForStruct(structName) + ".") : "") + structName);
374 }
375 if (elementType != null) {
376 if(elementType.getName()==null) {
377 throw new RuntimeException("elementType.name is null: "+getDebugString());
378 }
379 return "[" + descriptor(elementType.getName());
380 }
381 return "ANON_NIO";
382 }
383
384 /**
385 * Returns the native (JNI) method-name descriptor corresponding to this type,
386 * i.e. replacing chars {@link #getDescriptor()} as follows
387 * <ul>
388 * <li>`_` -> `_1`</li>
389 * <li>`/` -> `_`</li>
390 * <li>`;` -> `_2`</li>
391 * <li>`[` -> `_3`</li>
392 * </ul>
393 * @see JNI Spec 2, Chapter 2, Resolving Native Method Names
394 * @see #toJNIMethodDescriptor(String)
395 */
396 public String getJNIMethodDesciptor() {
398 }
399
400 /**
401 * Appends the descriptor (internal type signature) corresponding to the given Class<?> c.
402 * @param buf the StringBuilder sink
403 * @param c the Class<?> to append the descriptor for
404 * @param useTrueType if true, use the actual Class<?> name for non primitives, otherwise java.lang.Object will be used (flattened)
405 * @return the given StringBuilder sink for chaining
406 */
407 public static StringBuilder appendDescriptor(final StringBuilder buf, final Class<?> c, final boolean useTrueType) {
408 if (c.isPrimitive()) {
409 if (c == Boolean.TYPE) buf.append("Z");
410 else if (c == Byte.TYPE) buf.append("B");
411 else if (c == Character.TYPE) buf.append("C");
412 else if (c == Short.TYPE) buf.append("S");
413 else if (c == Integer.TYPE) buf.append("I");
414 else if (c == Long.TYPE) buf.append("J");
415 else if (c == Float.TYPE) buf.append("F");
416 else if (c == Double.TYPE) buf.append("D");
417 else throw new RuntimeException("Illegal primitive type \"" + c.getName() + "\"");
418 } else {
419 // Arrays and NIO Buffers are always passed down as java.lang.Object.
420 // The only arrays that show up as true arrays in the signature
421 // are the synthetic byte offset arrays created when passing
422 // down arrays of direct Buffers. Compound type wrappers are
423 // passed down as ByteBuffers (no good reason, just to avoid
424 // accidental conflation) so we mangle them differently.
425 if (useTrueType) {
426 if (c.isArray()) {
427 buf.append("[");
428 final Class<?> componentType = c.getComponentType();
429 // Handle arrays of compound type wrappers differently for
430 // convenience of the Java-level glue code generation
431 appendDescriptor(buf, componentType,
432 (componentType == java.nio.ByteBuffer.class));
433 } else {
434 buf.append("L");
435 buf.append(c.getName().replace('.', '/'));
436 buf.append(";");
437 }
438 } else {
439 if (c.isArray()) {
440 buf.append("[");
441 appendDescriptor(buf, c.getComponentType(), false);
442 } else if (c == java.lang.String.class) {
443 buf.append("L");
444 buf.append(c.getName().replace('.', '/'));
445 buf.append(";");
446 } else {
447 buf.append("Ljava/lang/Object;");
448 }
449 }
450 }
451 return buf;
452 }
453
454 /**
455 * Appends the native (JNI) method-name descriptor corresponding to the given Class<?> c,
456 * i.e. replacing chars {@link #appendDescriptor(StringBuilder, Class, boolean)} as follows
457 * <ul>
458 * <li>`_` -> `_1`</li>
459 * <li>`/` -> `_`</li>
460 * <li>`;` -> `_2`</li>
461 * <li>`[` -> `_3`</li>
462 * </ul>
463 * Only the newly appended segment to the StringBuilder sink will be converted to (JNI) method-name using {@link #toJNIMethodDescriptor(StringBuilder, int)}.
464 * @param buf the StringBuilder sink
465 * @param c the Class<?> to append the descriptor for
466 * @param useTrueType if true, use the actual Class<?> name for non primitives, otherwise java.lang.Object will be used (flattened)
467 * @return the given StringBuilder sink for chaining
468 * @see JNI Spec 2, Chapter 2, Resolving Native Method Names
469 * @see #toJNIMethodDescriptor(StringBuilder)
470 */
471 public static StringBuilder appendJNIDescriptor(final StringBuilder res, final Class<?> c, final boolean useTrueType) {
472 final int start = res.length();
473 return toJNIMethodDescriptor( appendDescriptor(res, c, useTrueType), start );
474 }
475
476 /**
477 * Converts the assumed descriptor (internal type signature) to a native (JNI) method-name descriptor,
478 * i.e. replacing chars {@link #getDescriptor()} as follows
479 * <ul>
480 * <li>`_` -> `_1`</li>
481 * <li>`/` -> `_`</li>
482 * <li>`;` -> `_2`</li>
483 * <li>`[` -> `_3`</li>
484 * </ul>
485 * @param descriptor the char sequence holding the original descriptor
486 * @see JNI Spec 2, Chapter 2, Resolving Native Method Names
487 */
488 public static String toJNIMethodDescriptor(final String descriptor) {
489 return descriptor.replace("_", "_1")
490 .replace("/", "_")
491 .replace(";", "_2")
492 .replace("[", "_3");
493 }
494
495 /**
496 * Converts the assumed descriptor (internal type signature) to a native (JNI) method-name descriptor,
497 * i.e. replacing chars {@link #getDescriptor()} as follows
498 * <ul>
499 * <li>`_` -> `_1`</li>
500 * <li>`/` -> `_`</li>
501 * <li>`;` -> `_2`</li>
502 * <li>`[` -> `_3`</li>
503 * </ul>
504 * @param descriptor the char buffer holding the original descriptor
505 * @param start start position of the segment to convert, use 0 if whole buffr shall be converted
506 * @return returns passed descriptor buffer for chaining
507 * @see JNI Spec 2, Chapter 2, Resolving Native Method Names
508 */
509 public static StringBuilder toJNIMethodDescriptor(final StringBuilder descriptor, final int start) {
510 replace(descriptor, start, "_", "_1");
511 replace(descriptor, start, "/", "_");
512 replace(descriptor, start, ";", "_2");
513 replace(descriptor, start, "[", "_3");
514 return descriptor;
515 }
516 private static StringBuilder replace(final StringBuilder buf, int start, final String target, final String replacement) {
517 start = buf.indexOf(target, start);
518 while( 0 <= start ) {
519 buf.replace(start, start + target.length(), replacement);
520 start = buf.indexOf(target, start + replacement.length());
521 }
522 return buf;
523 }
524
525 /** Returns the String corresponding to the JNI type for this type,
526 or NULL if it can't be represented (i.e., it's a boxing class
527 that we need to call getBuffer() on.) */
528 public String jniTypeName() {
529 if (isCompoundTypeWrapper()) {
530 // These are sent down as Buffers (e.g., jobject)
531 return "jobject";
532 }
533
535 // These are returned as arrays of ByteBuffers (e.g., jobjectArray)
536 return "jobjectArray /* of ByteBuffer */";
537 }
538
539 if ( clazzName != null ) {
540 return "jobject";
541 }
542
543 if (clazz == null) {
544 return null;
545 }
546
547 if (isVoid()) {
548 return "void";
549 }
550
551 if (isPrimitive()) {
552 return "j" + clazz.getName();
553 }
554
555 if (isPrimitiveArray() || isNIOBuffer()) {
556 // We now pass primitive arrays and buffers uniformly down to native code as java.lang.Object.
557 return "jobject";
558 }
559
560 if (isArray()) {
561 if (isStringArray()) {
562 return "jobjectArray /*elements are String*/";
563 }
564
565 final Class<?> elementType = clazz.getComponentType();
566
567 if (isNIOBufferArray()) {
568 return "jobjectArray /*elements are " + elementType.getName() + "*/";
569 }
570
571 if (elementType.isArray()) {
572 // Type is array-of-arrays-of-something
573
574 if (elementType.getComponentType().isPrimitive()) {
575 // Type is an array-of-arrays-of-primitive
576 return "jobjectArray /* elements are " + elementType.getComponentType() + "[]*/";
577 //return "jobjectArray";
578 } else {
579 throw new RuntimeException("Multi-dimensional arrays of types that are not primitives or Strings are not supported.");
580 }
581 }
582
583 // Some unusual type that we don't handle
584 throw new RuntimeException("Unexpected and unsupported array type: \"" + this + "\"");
585 }
586
587 if (isString()) {
588 return "jstring";
589 }
590
591 return "jobject";
592 }
593
594 public boolean isOpaqued() { return opaqued; }
595
596 public boolean isNIOBuffer() {
597 return clazz != null && ( java.nio.Buffer.class.isAssignableFrom(clazz) ||
598 com.jogamp.common.nio.NativeBuffer.class.isAssignableFrom(clazz)) ;
599 }
600
601 public boolean isNIOByteBuffer() {
602 return (clazz == java.nio.ByteBuffer.class);
603 }
604
605 public boolean isNIOByteBufferArray() {
606 return (this == nioByteBufferArrayType);
607 }
608
609 public boolean isNIOBufferArray() {
610 return (isArray() && (java.nio.Buffer.class.isAssignableFrom(clazz.getComponentType())));
611 }
612
613 public boolean isNIOLongBuffer() {
614 return (clazz == java.nio.LongBuffer.class);
615 }
616
617 public boolean isNIOPointerBuffer() {
618 return (clazz == com.jogamp.common.nio.PointerBuffer.class);
619 }
620
621 public boolean isString() {
622 return (clazz == java.lang.String.class);
623 }
624
625 public boolean isPascalStrElem() { return null != pascalStrElem; }
626
627 public boolean isPascalStr() { return isPascalStrElem() && isString() ; }
628
629 public boolean isPascalLen() { return isPascalStrElem() && !isString() ; }
630
631 public boolean isArray() {
632 return ((clazz != null) && clazz.isArray());
633 }
634
635 public boolean isFloatArray() {
636 return (clazz != null && clazz.isArray() && clazz.getComponentType() == Float.TYPE);
637 }
638
639 public boolean isDoubleArray() {
640 return (clazz != null && clazz.isArray() && clazz.getComponentType() == Double.TYPE);
641 }
642
643 public boolean isByteArray() {
644 return (clazz != null && clazz.isArray() && clazz.getComponentType() == Byte.TYPE);
645 }
646
647 public boolean isIntArray() {
648 return (clazz != null && clazz.isArray() && clazz.getComponentType() == Integer.TYPE);
649 }
650
651 public boolean isShortArray() {
652 return (clazz != null && clazz.isArray() && clazz.getComponentType() == Short.TYPE);
653 }
654
655 public boolean isLongArray() {
656 return (clazz != null && clazz.isArray() && clazz.getComponentType() == Long.TYPE);
657 }
658
659 public boolean isStringArray() {
660 return (clazz != null && clazz.isArray() && clazz.getComponentType() == java.lang.String.class);
661 }
662
663 public boolean isPascalStrArray() { return isPascalStrElem() && isStringArray() ; }
664
665 public boolean isPrimitive() {
666 return ((clazz != null) && !isArray() && clazz.isPrimitive() && (clazz != Void.TYPE));
667 }
668
669 public boolean isPrimitiveArray() {
670 return (isArray() && (clazz.getComponentType().isPrimitive()));
671 }
672
673 public boolean isShort() {
674 return (clazz == Short.TYPE);
675 }
676
677 public boolean isFloat() {
678 return (clazz == Float.TYPE);
679 }
680
681 public boolean isDouble() {
682 return (clazz == Double.TYPE);
683 }
684
685 public boolean isByte() {
686 return (clazz == Byte.TYPE);
687 }
688
689 public boolean isLong() {
690 return (clazz == Long.TYPE);
691 }
692
693 public boolean isInt() {
694 return (clazz == Integer.TYPE);
695 }
696
697 public boolean isVoid() {
698 return (clazz == Void.TYPE);
699 }
700
701 public boolean isNamedClass() {
702 return clazzName != null;
703 }
704
705 public boolean isCompoundTypeWrapper() {
706 return structName != null && !isJNIEnv();
707 }
708
710 return elementType != null;
711 }
712
713
714 public boolean isCPrimitivePointerType() {
715 return primitivePointerType != null;
716 }
717
718 public boolean isCVoidPointerType() {
719 return C_PTR.VOID.equals(primitivePointerType);
720 }
721
722 public boolean isCCharPointerType() {
723 return C_PTR.CHAR.equals(primitivePointerType);
724 }
725
726 public boolean isCShortPointerType() {
727 return C_PTR.SHORT.equals(primitivePointerType);
728 }
729
730 public boolean isCInt32PointerType() {
731 return C_PTR.INT32.equals(primitivePointerType);
732 }
733
734 public boolean isCInt64PointerType() {
735 return C_PTR.INT64.equals(primitivePointerType);
736 }
737
738 public boolean isCFloatPointerType() {
739 return C_PTR.FLOAT.equals(primitivePointerType);
740 }
741
742 public boolean isCDoublePointerType() {
743 return C_PTR.DOUBLE.equals(primitivePointerType);
744 }
745
746 public boolean isJNIEnv() {
747 return "JNIEnv".equals(structName);
748 }
749
750 @Override
751 public Object clone() {
752 return new JavaType(primitivePointerType, clazz, clazzName, structName, elementType, pascalStrElem);
753 }
754
755 @Override
756 public String toString() {
757 return getName();
758 }
759
760 //----------------------------------------------------------------------
761 // Internals only below this point
762 //
763
764 private void append(final StringBuilder sb, final String val, final boolean prepComma) {
765 if( prepComma ) {
766 sb.append(", ");
767 }
768 sb.append(val);
769 }
770 public final StringBuilder getSignature(StringBuilder sb) {
771 if( null == sb ) {
772 sb = new StringBuilder();
773 }
774 boolean prepComma = false;
775 {
776 final String javaTypeName = getName();
777 if( null != javaTypeName ) {
778 append(sb, javaTypeName, false);
779 } else {
780 append(sb, "ANON", false);
781 }
782 }
783 if( null != clazz ) {
784 append(sb, "clazz = "+clazz.getName(), prepComma); prepComma=true;
785 }
786 if( null != clazzName ) {
787 append(sb, "clazzName = "+clazzName, prepComma); prepComma=true;
788 }
789 if( null != structName ) {
790 append(sb, "struct = "+structName, prepComma); prepComma=true;
791 }
792 if( null != elementType ) {
793 append(sb, "elementType = "+elementType, prepComma); prepComma=true;
794 }
795 if( null != primitivePointerType ) {
796 append(sb, "primitivePointerType = "+primitivePointerType, prepComma); prepComma=true;
797 }
798 append(sb, "is[", prepComma); prepComma=false;
799 {
800 if( isOpaqued() ) {
801 append(sb, "opaque", prepComma); prepComma=true;
802 }
803 if( isPascalStrElem() ) {
804 sb.append("pascal ");
805 }
806 if( isString() ) {
807 append(sb, "string", prepComma); prepComma=true;
808 }
809 if( isStringArray() ) {
810 append(sb, "stringArray", prepComma); prepComma=true;
811 } else if( isArray() ) {
812 append(sb, "array", prepComma); prepComma=true;
813 }
815 append(sb, "compoundArray", prepComma); prepComma=true;
816 }
817 if( isCompoundTypeWrapper() ) {
818 append(sb, "compound", prepComma); prepComma=true;
819 }
820 if( isPrimitive() ) {
821 append(sb, "primitive", prepComma); prepComma=true;
822 }
823 if( isPrimitiveArray() ) {
824 append(sb, "primitiveArray", prepComma); prepComma=true;
825 }
826 if( isNIOBuffer() ) {
827 append(sb, "nioBuffer", prepComma); prepComma=true;
828 }
829 if( isNIOBufferArray() ) {
830 append(sb, "nioBufferArray", prepComma); prepComma=true;
831 }
833 append(sb, "C-Primitive-Pointer", prepComma); prepComma=true;
834 }
835 }
836 append(sb, "], descriptor '"+getDescriptor()+"'", false); prepComma=true;
837 return sb;
838 }
839
840 // For debugging
841 public String getDebugString() {
842 final StringBuilder sb = new StringBuilder();
843 sb.append("JType[");
844 getSignature(sb);
845 sb.append("]");
846 return sb.toString();
847 }
848
849 /**
850 * Constructs a representation for a type corresponding to the given Class
851 * argument.
852 */
853 private JavaType(final Class<?> clazz, final boolean opaqued, final PascalStringElem pascalStrElem) {
854 if( null == clazz ) {
855 throw new IllegalArgumentException("null clazz passed");
856 }
857 this.primitivePointerType = null;
858 this.clazz = clazz;
859 this.clazzName = null;
860 this.structName = null;
861 this.elementType = null;
862 this.opaqued = opaqued;
863 this.pascalStrElem = pascalStrElem;
864 }
865
866 /** Constructs a type representing a either a named clazz or a named C struct.*/
867 private JavaType(final String clazzName, final String structName) {
868 if( null != clazzName && null != structName ) {
869 throw new IllegalArgumentException("Both clazzName and structName set");
870 }
871 if( null != clazzName ) {
872 this.clazzName = clazzName;
873 this.structName = null;
874 } else if( null != structName ) {
875 this.clazzName = null;
876 this.structName = structName;
877 } else {
878 throw new IllegalArgumentException("Neither clazzName nor structName set");
879 }
880 this.primitivePointerType = null;
881 this.clazz = null;
882 this.elementType = null;
883 this.opaqued = false;
884 this.pascalStrElem = null;
885 }
886
887 /** Constructs a type representing a pointer to a C primitive
888 (integer, floating-point, or void pointer) type. */
889 private JavaType(final C_PTR primitivePointerType) {
890 if( null == primitivePointerType ) {
891 throw new IllegalArgumentException("null primitivePointerType passed");
892 }
893 this.primitivePointerType = primitivePointerType;
894 this.clazz = null;
895 this.clazzName = null;
896 this.structName = null;
897 this.elementType = null;
898 this.opaqued = false;
899 this.pascalStrElem = null;
900 }
901
902 /** Constructs a type representing an array of C pointers. */
903 private JavaType(final Type elementType) {
904 if( null == elementType ) {
905 throw new IllegalArgumentException("null elementType passed");
906 }
907 this.primitivePointerType = null;
908 this.clazz = null;
909 this.clazzName = null;
910 this.structName = null;
911 this.elementType = elementType;
912 this.opaqued = false;
913 this.pascalStrElem = null;
914 }
915
916 /** clone only */
917 private JavaType(final C_PTR primitivePointerType, final Class<?> clazz, final String clazzName, final String structName, final Type elementType,
918 final PascalStringElem pascalStrElem)
919 {
920 this.primitivePointerType = primitivePointerType;
921 this.clazz = clazz;
922 this.clazzName = clazzName;
923 this.structName = structName;
924 this.elementType = elementType;
925 this.opaqued = false;
926 this.pascalStrElem = pascalStrElem;
927 }
928 /** Copy ctor */
929 public JavaType(final JavaType o) {
930 this(o.primitivePointerType, o.clazz, o.clazzName, o.structName, o.elementType, o.pascalStrElem);
931 }
932 /** Copy ctor w/ pascalString variant override */
934 this(o.primitivePointerType, o.clazz, o.clazzName, o.structName, o.elementType, pascalStrElem);
935 }
936
937 private static String arrayName(Class<?> clazz) {
938 final StringBuilder buf = new StringBuilder();
939 int arrayCount = 0;
940 while (clazz.isArray()) {
941 ++arrayCount;
942 clazz = clazz.getComponentType();
943 }
944 buf.append(clazz.getName());
945 while (--arrayCount >= 0) {
946 buf.append("[]");
947 }
948 return buf.toString();
949 }
950
951 private static String arrayDescriptor(Class<?> clazz) {
952 final StringBuilder buf = new StringBuilder();
953 while (clazz.isArray()) {
954 buf.append("[");
955 clazz = clazz.getComponentType();
956 }
957 buf.append(descriptor(clazz));
958 return buf.toString();
959 }
960
961 private static String descriptor(final Class<?> clazz) {
962 if (clazz.isPrimitive()) {
963 if (clazz == Boolean.TYPE) return "Z";
964 if (clazz == Byte.TYPE) return "B";
965 if (clazz == Double.TYPE) return "D";
966 if (clazz == Float.TYPE) return "F";
967 if (clazz == Integer.TYPE) return "I";
968 if (clazz == Long.TYPE) return "J";
969 if (clazz == Short.TYPE) return "S";
970 if (clazz == Void.TYPE) return "V";
971 throw new RuntimeException("Unexpected primitive type " + clazz.getName());
972 }
973 if (clazz.isArray()) {
974 return arrayDescriptor(clazz);
975 }
976 return descriptor(clazz.getName());
977 }
978
979 private static String descriptor(final String clazzName) {
980 return "L" + clazzName.replace('.', '/') + ";";
981 }
982}
Parses and provides access to the contents of .cfg files for the JavaEmitter.
String packageForStruct(final String structName)
Returns the package into which to place the glue code for accessing the specified struct.
Pascal string argument index tuple for length and value.
Definition: JavaType.java:65
static final List< Integer > pushValueIndex(final List< PascalStringElem > source, List< Integer > indices)
Definition: JavaType.java:74
static PascalStringElem getByLengthIdx(final List< PascalStringElem > pascals, final int lengthIdx)
Definition: JavaType.java:101
static final List< Integer > pushLengthIndex(final List< PascalStringElem > source)
Definition: JavaType.java:83
static PascalStringElem getByValueIdx(final List< PascalStringElem > pascals, final int valueIdx)
Definition: JavaType.java:91
Describes a java-side representation of a type that is used to represent the same data on both the Ja...
Definition: JavaType.java:54
static StringBuilder appendDescriptor(final StringBuilder buf, final Class<?> c, final boolean useTrueType)
Appends the descriptor (internal type signature) corresponding to the given Class<?...
Definition: JavaType.java:407
static JavaType forNIOBufferClass()
Definition: JavaType.java:265
static JavaType forNIOByteBufferArrayClass()
Definition: JavaType.java:320
static StringBuilder appendJNIDescriptor(final StringBuilder res, final Class<?> c, final boolean useTrueType)
Appends the native (JNI) method-name descriptor corresponding to the given Class<?...
Definition: JavaType.java:471
boolean equals(final Object arg)
Definition: JavaType.java:138
static JavaType forNIOByteBufferClass()
Definition: JavaType.java:272
String getName()
Returns the Java type name corresponding to this type.
Definition: JavaType.java:339
static StringBuilder toJNIMethodDescriptor(final StringBuilder descriptor, final int start)
Converts the assumed descriptor (internal type signature) to a native (JNI) method-name descriptor,...
Definition: JavaType.java:509
static JavaType createForCStruct(final String name)
Creates a JavaType corresponding to the specified C CompoundType name; for example,...
Definition: JavaType.java:215
static JavaType forNIODoubleBufferClass()
Definition: JavaType.java:313
static JavaType forNIOShortBufferClass()
Definition: JavaType.java:279
static JavaType createForCShortPointer()
Definition: JavaType.java:234
static JavaType createForNamedClass(final String name)
Creates a JavaType corresponding to the given named Java class, not necessarily existing yet.
Definition: JavaType.java:208
static JavaType createForCCharPointer()
Definition: JavaType.java:230
String getJNIMethodDesciptor()
Returns the native (JNI) method-name descriptor corresponding to this type, i.e.
Definition: JavaType.java:396
static JavaType createForCVoidPointer()
Definition: JavaType.java:226
static JavaType createForCArray(final Type elementType)
Creates a JavaType corresponding to an array of the given element type.
Definition: JavaType.java:222
static JavaType createForJNIEnv()
Definition: JavaType.java:254
JavaType(final JavaType o)
Copy ctor.
Definition: JavaType.java:929
static JavaType forNIOLongBufferClass()
Definition: JavaType.java:293
final PascalStringElem pascalStrElem
Definition: JavaType.java:124
static JavaType forNIOFloatBufferClass()
Definition: JavaType.java:306
static JavaType createForCInt32Pointer()
Definition: JavaType.java:238
static JavaType createForClass(final Class<?> clazz)
Creates a JavaType corresponding to the given Java type.
Definition: JavaType.java:197
JavaType(final JavaType o, final PascalStringElem pascalStrElem)
Copy ctor w/ pascalString variant override.
Definition: JavaType.java:933
static JavaType forObjectClass()
Definition: JavaType.java:258
static JavaType createForOpaqueClass(final Class<?> clazz)
Creates a JavaType corresponding to the given opaque Java type.
Definition: JavaType.java:189
String jniTypeName()
Returns the String corresponding to the JNI type for this type, or NULL if it can't be represented (i...
Definition: JavaType.java:528
static JavaType createForCInt64Pointer()
Definition: JavaType.java:242
static JavaType forNIOIntBufferClass()
Definition: JavaType.java:286
static JavaType createForStringClass(final Class<?> clazz, final PascalStringElem pascalStrElem)
Definition: JavaType.java:200
String getDescriptor()
Returns the descriptor (internal type signature) corresponding to this type.
Definition: JavaType.java:362
boolean isArrayOfCompoundTypeWrappers()
Definition: JavaType.java:709
static String toJNIMethodDescriptor(final String descriptor)
Converts the assumed descriptor (internal type signature) to a native (JNI) method-name descriptor,...
Definition: JavaType.java:488
static JavaType createForCDoublePointer()
Definition: JavaType.java:250
static JavaType createForCFloatPointer()
Definition: JavaType.java:246
String getDescriptor(final JavaConfiguration cfg)
Definition: JavaType.java:365
String getName(final JavaConfiguration cfg)
Definition: JavaType.java:343
static JavaType forNIOPointerBufferClass()
Definition: JavaType.java:300
Class<?> getJavaClass()
Returns the Java Class corresponding to this type.
Definition: JavaType.java:332
final StringBuilder getSignature(StringBuilder sb)
Definition: JavaType.java:770
final int hashCode()
Hashcode for Types.
Definition: Type.java:446
final String getName()
Returns the name of this type.
Definition: Type.java:142
final boolean equals(final Object arg)
Equality test for Types inclusive its given name.
Definition: Type.java:468