1 /******************************************************************************* 2 * Copyright 2011 See AUTHORS file. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 ******************************************************************************/ 16 17 package com.badlogic.gdx.jnigen.parsing; 18 19 import java.util.ArrayList; 20 21 public interface JavaMethodParser { parse(String classFile)22 public ArrayList<JavaSegment> parse (String classFile) throws Exception; 23 24 public interface JavaSegment { getStartIndex()25 public int getStartIndex (); 26 getEndIndex()27 public int getEndIndex (); 28 } 29 30 public class JniSection implements JavaSegment { 31 private String nativeCode; 32 private final int startIndex; 33 private final int endIndex; 34 JniSection(String nativeCode, int startIndex, int endIndex)35 public JniSection (String nativeCode, int startIndex, int endIndex) { 36 this.nativeCode = nativeCode; 37 this.startIndex = startIndex; 38 this.endIndex = endIndex; 39 } 40 getNativeCode()41 public String getNativeCode () { 42 return nativeCode; 43 } 44 setNativeCode(String nativeCode)45 public void setNativeCode (String nativeCode) { 46 this.nativeCode = nativeCode; 47 } 48 getStartIndex()49 public int getStartIndex () { 50 return startIndex; 51 } 52 getEndIndex()53 public int getEndIndex () { 54 return endIndex; 55 } 56 57 @Override toString()58 public String toString () { 59 return "JniSection [nativeCode=" + nativeCode + ", startIndex=" + startIndex + ", endIndex=" + endIndex + "]"; 60 } 61 } 62 63 public enum ArgumentType { 64 Boolean("jboolean"), Byte("jbyte"), Char("jchar"), Short("jshort"), Integer("jint"), Long("jlong"), Float("jfloat"), Double( 65 "jdouble"), Buffer("jobject"), ByteBuffer("jobject"), CharBuffer("jobject"), ShortBuffer("jobject"), IntBuffer("jobject"), LongBuffer( 66 "jobject"), FloatBuffer("jobject"), DoubleBuffer("jobject"), BooleanArray("jbooleanArray"), ByteArray("jbyteArray"), CharArray( 67 "jcharArray"), ShortArray("jshortArray"), IntegerArray("jintArray"), LongArray("jlongArray"), FloatArray("jfloatArray"), DoubleArray( 68 "jdoubleArray"), String("jstring"), Object("jobject"), ObjectArray("jobjectArray"); 69 70 private final String jniType; 71 ArgumentType(String jniType)72 ArgumentType (String jniType) { 73 this.jniType = jniType; 74 } 75 isPrimitiveArray()76 public boolean isPrimitiveArray () { 77 return toString().endsWith("Array") && this != ObjectArray; 78 } 79 isBuffer()80 public boolean isBuffer () { 81 return toString().endsWith("Buffer"); 82 } 83 isObject()84 public boolean isObject () { 85 return toString().equals("Object") || this == ObjectArray; 86 } 87 isString()88 public boolean isString () { 89 return toString().equals("String"); 90 } 91 isPlainOldDataType()92 public boolean isPlainOldDataType () { 93 return !isString() && !isPrimitiveArray() && !isBuffer() && !isObject(); 94 } 95 getBufferCType()96 public String getBufferCType () { 97 if (!this.isBuffer()) throw new RuntimeException("ArgumentType " + this + " is not a Buffer!"); 98 if (this == Buffer) return "unsigned char*"; 99 if (this == ByteBuffer) return "char*"; 100 if (this == CharBuffer) return "unsigned short*"; 101 if (this == ShortBuffer) return "short*"; 102 if (this == IntBuffer) return "int*"; 103 if (this == LongBuffer) return "long long*"; 104 if (this == FloatBuffer) return "float*"; 105 if (this == DoubleBuffer) return "double*"; 106 throw new RuntimeException("Unknown Buffer type " + this); 107 } 108 getArrayCType()109 public String getArrayCType () { 110 if (!this.isPrimitiveArray()) throw new RuntimeException("ArgumentType " + this + " is not an Array!"); 111 if (this == BooleanArray) return "bool*"; 112 if (this == ByteArray) return "char*"; 113 if (this == CharArray) return "unsigned short*"; 114 if (this == ShortArray) return "short*"; 115 if (this == IntegerArray) return "int*"; 116 if (this == LongArray) return "long long*"; 117 if (this == FloatArray) return "float*"; 118 if (this == DoubleArray) return "double*"; 119 throw new RuntimeException("Unknown Array type " + this); 120 } 121 getJniType()122 public String getJniType () { 123 return jniType; 124 } 125 } 126 127 public static class Argument { 128 final ArgumentType type; 129 private final String name; 130 Argument(ArgumentType type, String name)131 public Argument (ArgumentType type, String name) { 132 this.type = type; 133 this.name = name; 134 } 135 getType()136 public ArgumentType getType () { 137 return type; 138 } 139 getName()140 public String getName () { 141 return name; 142 } 143 144 @Override toString()145 public String toString () { 146 return "Argument [type=" + type + ", name=" + name + "]"; 147 } 148 } 149 150 /** @author mzechner */ 151 public static class JavaMethod implements JavaSegment { 152 private final String className; 153 private final String name; 154 private final boolean isStatic; 155 private boolean isManual; 156 private final String returnType; 157 private String nativeCode; 158 private final ArrayList<Argument> arguments; 159 private final boolean hasDisposableArgument; 160 private final int startIndex; 161 private final int endIndex; 162 JavaMethod(String className, String name, boolean isStatic, String returnType, String nativeCode, ArrayList<Argument> arguments, int startIndex, int endIndex)163 public JavaMethod (String className, String name, boolean isStatic, String returnType, String nativeCode, 164 ArrayList<Argument> arguments, int startIndex, int endIndex) { 165 this.className = className; 166 this.name = name; 167 this.isStatic = isStatic; 168 this.returnType = returnType; 169 this.nativeCode = nativeCode; 170 this.arguments = arguments; 171 this.startIndex = startIndex; 172 this.endIndex = endIndex; 173 for (Argument arg : arguments) { 174 if (arg.type.isPrimitiveArray() || arg.type.isBuffer() || arg.type.isString()) { 175 hasDisposableArgument = true; 176 return; 177 } 178 } 179 hasDisposableArgument = false; 180 } 181 getName()182 public String getName () { 183 return name; 184 } 185 isStatic()186 public boolean isStatic () { 187 return isStatic; 188 } 189 setManual(boolean isManual)190 public void setManual (boolean isManual) { 191 this.isManual = isManual; 192 } 193 isManual()194 public boolean isManual () { 195 return this.isManual; 196 } 197 getReturnType()198 public String getReturnType () { 199 return returnType; 200 } 201 getNativeCode()202 public String getNativeCode () { 203 return nativeCode; 204 } 205 setNativeCode(String nativeCode)206 public void setNativeCode (String nativeCode) { 207 this.nativeCode = nativeCode; 208 } 209 getArguments()210 public ArrayList<Argument> getArguments () { 211 return arguments; 212 } 213 hasDisposableArgument()214 public boolean hasDisposableArgument () { 215 return hasDisposableArgument; 216 } 217 218 @Override getStartIndex()219 public int getStartIndex () { 220 return startIndex; 221 } 222 223 @Override getEndIndex()224 public int getEndIndex () { 225 return endIndex; 226 } 227 getClassName()228 public CharSequence getClassName () { 229 return className; 230 } 231 232 @Override toString()233 public String toString () { 234 return "JavaMethod [className=" + className + ", name=" + name + ", isStatic=" + isStatic + ", returnType=" + returnType 235 + ", nativeCode=" + nativeCode + ", arguments=" + arguments + ", hasDisposableArgument=" + hasDisposableArgument 236 + ", startIndex=" + startIndex + ", endIndex=" + endIndex + "]"; 237 } 238 } 239 } 240