/** * @(#) CFuncDeclaration.java */ import java.lang.System; import java.lang.String; import java.util.Vector; /** * The function-declaration holder ! * * @see CFuncVariable * @version 1.00, 12. Novemeber 1999 * @author Sven Goethel * */ public class CFuncDeclaration implements Cloneable { public boolean isValid; public CFuncVariable funcSpec; public Vector argList; public static final String jniFuncPrefixStd= "Java_" ; public static final String jniFuncArgPrefix="JNIEnv *env, jobject obj"; public static final int FUNC_ERROR = 0; public static final int FUNC_OK = 1; public static final int FUNC_TYPE_MISSING = 2; public static final int FUNC_NAME_MISSING = 3; public static final int FUNC_LASTARG_INCOMPLETE = 4; public CFuncDeclaration() { isValid = true; funcSpec = null; argList = new Vector(); } protected Object clone() throws CloneNotSupportedException { int i; CFuncDeclaration nobj = new CFuncDeclaration(); nobj.isValid=isValid; try { nobj.funcSpec=(CFuncVariable)funcSpec.clone(); } catch (Exception ex) {} for(i=0; i0) { if(which==n || which<0) { cfvar.typeJava=customType; cfvar.isVoid=isNewTypeVoid; } if(which==n) break; /* job done - leave loop */ n++; } } return tmp; } protected String args2JNIStrList() { String res = new String(); CFuncVariable cfvar; int i,j; for (i=0; i0) n++; } return n; } protected String getFuncArgsSignature() { String res = new String(); CFuncVariable cfvar; int i,j; res += "__"; for (i=0; i type[] */ if(cfvar.typeJava.equals("boolean")) res+="Z"; else if(cfvar.typeJava.equals("byte")) res+="B"; else if(cfvar.typeJava.equals("char")) res+="C"; else if(cfvar.typeJava.equals("short")) res+="S"; else if(cfvar.typeJava.equals("int")) res+="I"; else if(cfvar.typeJava.equals("long")) res+="J"; else if(cfvar.typeJava.equals("float")) res+="F"; else if(cfvar.typeJava.equals("double")) res+="D"; else if(cfvar.typeJava.equals("String")) res+="Ljava_lang_String_2"; } return res; } protected String __toJniJavaCode(boolean isFinal) { String res = new String(); if(funcSpec.arrayNumber>0) { System.err.println("ERROR: Pointer As Function-ReturnType is not supported yet !"); System.err.println("Function: "+funcSpec); return ""; } if(isFinal) res += "\tpublic final native "; else res += "\tpublic native "; res += funcSpec.getJavaTypeString() + " " + funcSpec.identifier + " (\n"; res += args2JavaStrList(); res += "\t) ;\n"; return res; } public String toJniJavaCode(boolean isFinal) { int numberOfVoidPointerArgs = getNumberOfVoidPointerArgs(); if(numberOfVoidPointerArgs==0) { return __toJniJavaCode(isFinal); } CFuncDeclaration tmp = null; String res = new String(); tmp=getChangedVoidPtr2CustomPtrClone("byte", -1); if(tmp!=null) res+=tmp.__toJniJavaCode(isFinal); tmp=getChangedVoidPtr2CustomPtrClone("short", -1); if(tmp!=null) res+=tmp.__toJniJavaCode(isFinal); tmp=getChangedVoidPtr2CustomPtrClone("int", -1); if(tmp!=null) res+=tmp.__toJniJavaCode(isFinal); tmp=getChangedVoidPtr2CustomPtrClone("float", -1); if(tmp!=null) res+=tmp.__toJniJavaCode(isFinal); tmp=getChangedVoidPtr2CustomPtrClone("double", -1); if(tmp!=null) res+=tmp.__toJniJavaCode(isFinal); tmp=getChangedVoidPtr2CustomPtrClone("boolean", -1); if(tmp!=null) res+=tmp.__toJniJavaCode(isFinal); tmp=getChangedVoidPtr2CustomPtrClone("long", -1); if(tmp!=null) res+=tmp.__toJniJavaCode(isFinal); return res; } protected String __toJniCCode(String clazzName, int exportMode, int modifier, boolean overloaded) { String res = new String(); CFuncVariable cfvar; int i; if(funcSpec.arrayNumber>0) { System.err.println("ERROR: Pointer As Function-ReturnType is not supported yet !"); System.err.println("Function: "+funcSpec); return ""; } res += "\tJNIEXPORT " + funcSpec.getJNITypeString() + " JNICALL\n" ; res += "\t" + jniFuncPrefixStd+clazzName+"_"+funcSpec.identifier; if(overloaded) res += getFuncArgsSignature(); res += " (\n"; res += "\t\t"+jniFuncArgPrefix; res += args2JNIStrList(); res += ")\n"; res += "\t{\n"; if(exportMode==C2J.EXPORT_JNI_C_DYN) { // // Add the global static OpenGL function pointer // res += "\t\tstatic "+funcSpec.getJNITypeString()+ " (CALLBACK *__func_ptr__)("+argsType2CStrList()+") = NULL;\n"; } // // Add the return variable // if(funcSpec.typeJava.equals("void")==false) { res += "\t\t"+funcSpec.getJNITypeString()+" ret;\n\n"; } String jniCMethodBaseType; // // Adding the JNI access Methods // for Arrays ... // THE VARABLE DEFINITIONS // for (i=0; i0 ) { jniCMethodBaseType = cfvar.getJniCMethodBaseType(); if( !cfvar.isConst || (modifier&C2J.MODIFIER_JNI_COPY_CHECK)>0 ) res += "\t\tjboolean isCopiedArray" +i+ " = JNI_FALSE;\n"; res += "\t\t" + "j" + cfvar.typeJava + " *ptr" + i + " = NULL;\n"; if( (modifier&C2J.MODIFIER_JNI_COPY_CHECK )>0 ) { // // JAU COPY Warning, if copy is used !!! // res += "\t\tstatic int isWarned"+i+" = 0;\n"; } } } res += "\n" ; if(exportMode==C2J.EXPORT_JNI_C_DYN) { // // Add the global static OpenGL function pointer assignment // res += "\t\tif(__func_ptr__==NULL) {\n"; res += "\t\t\t__func_ptr__ = ("+ funcSpec.getJNITypeString()+" (CALLBACK *)("+ argsType2CStrList()+"))\n"+ "\t\t\t\tgetGLProcAddressHelper(\"" +funcSpec.identifier+"\", NULL, 1, 0);\n"; res += "\t\t\tif(__func_ptr__==NULL)\n"; if(funcSpec.typeC.equals("void")==false) res += "\t\t\t\treturn 0;\n"; else res += "\t\t\t\treturn;\n"; res += "\t\t}\n"; } // // Adding the JNI access Methods // for Arrays ... // THE ARGUMENT ACCESS // for (i=0; i0 ) { jniCMethodBaseType = cfvar.getJniCMethodBaseType(); res += "\t\tif("+cfvar.identifier+"!=NULL)\n"; res += "\t\t{\n"; if ( (modifier&C2J.MODIFIER_JNI_CRITICAL_ARRAY)>0 ) { if( !cfvar.isConst || (modifier&C2J.MODIFIER_JNI_COPY_CHECK)>0 ) { res += "\t\t\t" + "ptr" + i + " = " + "(j" + cfvar.typeJava + " *) " + "(*env)->GetPrimitiveArrayCritical" + "(env, " + cfvar.identifier + ", " + "&isCopiedArray"+i+");\n"; } else { res += "\t\t\t" + "ptr" + i + " = " + "(j" + cfvar.typeJava + " *) " + "(*env)->GetPrimitiveArrayCritical" + "(env, " + cfvar.identifier + ", 0);\n"; } } else { if( !cfvar.isConst || (modifier&C2J.MODIFIER_JNI_COPY_CHECK)>0 ) { res += "\t\t\t" + "ptr" + i + " = " + "(*env)->Get" + jniCMethodBaseType + "ArrayElements(env, " + cfvar.identifier + ", " + "&isCopiedArray"+i+");\n"; } else { res += "\t\t\t" + "ptr" + i + " = " + "(*env)->Get" + jniCMethodBaseType + "ArrayElements(env, " + cfvar.identifier + ", 0);\n"; } } if( (modifier&C2J.MODIFIER_JNI_COPY_CHECK)>0 ) { // // JAU COPY Warning, if copy is used !!! // res += "\t\t\tif( isCopiedArray"+i+" == JNI_TRUE && isWarned"+i+"==0 ) {\n"; res += "\t\t\t\tisWarned"+i+"=1;\n"; res += "\t\t\t\tprintf(\"COPY by "+funcSpec.identifier+" arg: "+cfvar.identifier+"\");\n"; res += "\t\t\t}\n"; } res += "\t\t}\n"; } } // // Add the return variable assignment, incl. casting ! // if(funcSpec.typeC.equals("void")==false) { res += "\t\tret = ("+funcSpec.getJNITypeString()+") "; } else res += "\t\t"; // // Add the native function call ! // if(exportMode==C2J.EXPORT_JNI_C) res += funcSpec.identifier + " (\n"; else res += "__func_ptr__ (\n"; for (i=0; i0 ) res += "ptr"+i; else res += cfvar.identifier; if(i0 ) { jniCMethodBaseType = cfvar.getJniCMethodBaseType(); res += "\t\tif("+cfvar.identifier+"!=NULL)\n"; res += "\t\t{\n"; if ( (modifier&C2J.MODIFIER_JNI_CRITICAL_ARRAY)>0 ) { if( !cfvar.isConst ) { // // Free the memory, or the pinning lock. // A copy is needed, // if the Get*Array method used // the copy method ! // res += "\t\t\t(*env)->ReleasePrimitiveArrayCritical" + "(env, "+ cfvar.identifier + ", ptr" + i + ", " +"(isCopiedArray"+i+" == JNI_TRUE)?0:JNI_ABORT" +");\n"; } else { // // Just free the memory, or the pinning lock. // No copy needed, // because of the const data type ! // res += "\t\t\t(*env)->ReleasePrimitiveArrayCritical" + "(env, "+ cfvar.identifier + ", ptr" + i + ", JNI_ABORT);\n"; } } else { if( !cfvar.isConst ) { // // Free the memory, or the pinning lock. // A copy is needed, // if the Get*Array method used // the copy method ! // res += "\t\t\t(*env)->Release" + jniCMethodBaseType+ "ArrayElements(env, "+ cfvar.identifier + ", ptr" + i + ", " +"(isCopiedArray"+i+" == JNI_TRUE)?0:JNI_ABORT" +");\n"; } else { // // Just free the memory, or the pinning lock. // No copy needed, // because of the const data type ! // res += "\t\t\t(*env)->Release" + jniCMethodBaseType+ "ArrayElements(env, "+ cfvar.identifier + ", ptr" + i + ", JNI_ABORT);\n"; } } res += "\t\t}\n"; } } // // Let's give the baby to the caller ... // if(funcSpec.typeJava.equals("void")==false) res += "\t\treturn ret;\n"; res += "\t}\n"; return res; } public String toJniCCode(String clazzName, int exportMode, int modifier) { int numberOfVoidPointerArgs = getNumberOfVoidPointerArgs(); if(numberOfVoidPointerArgs==0) { return __toJniCCode(clazzName, exportMode, modifier, false); } CFuncDeclaration tmp = null; String res = new String(); tmp=getChangedVoidPtr2CustomPtrClone("byte", -1); if(tmp!=null) res+=tmp.__toJniCCode(clazzName, exportMode, modifier, true); tmp=getChangedVoidPtr2CustomPtrClone("short", -1); if(tmp!=null) res+=tmp.__toJniCCode(clazzName, exportMode, modifier, true); tmp=getChangedVoidPtr2CustomPtrClone("int", -1); if(tmp!=null) res+=tmp.__toJniCCode(clazzName, exportMode, modifier, true); tmp=getChangedVoidPtr2CustomPtrClone("float", -1); if(tmp!=null) res+=tmp.__toJniCCode(clazzName, exportMode, modifier, true); tmp=getChangedVoidPtr2CustomPtrClone("double", -1); if(tmp!=null) res+=tmp.__toJniCCode(clazzName, exportMode, modifier, true); tmp=getChangedVoidPtr2CustomPtrClone("boolean", -1); if(tmp!=null) res+=tmp.__toJniCCode(clazzName, exportMode, modifier, true); tmp=getChangedVoidPtr2CustomPtrClone("long", -1); if(tmp!=null) res+=tmp.__toJniCCode(clazzName, exportMode, modifier, true); return res; } protected String __toMsJDirectCode(String dllname) { String res = new String(); CFuncVariable cfvar; int i; if(funcSpec.arrayNumber>0) { System.err.println("ERROR: Pointer As Function-ReturnType is not supported yet !"); System.err.println("Function: "+funcSpec); return ""; } // // Use The JDirect security tag to make security calls easy ! // This one grants access to all MSJVM's >= // "Microsoft (R) VM for Java, 5.0 Release 5.0.0.3186" // without signing the applet !!! // // Making the mapping from the "static native" wrapper function // to the corresponding native function // res += "\t/**\n"; res += "\t * @dll.import(\""+dllname+"\",entrypoint=\""+ funcSpec.identifier+"\")\n"; res += "\t */\n"; // // adding the "static native" wrapper function // res += "\tprivate static native "; res += funcSpec.getJavaTypeString() + " __" + funcSpec.identifier + " (\n"; res += args2JavaStrList(); res += "\t) ;\n"; // // adding our GL4Java glue to the // "static native" wrapper function // res += "\tpublic final "; res += funcSpec.getJavaTypeString() + " " + funcSpec.identifier + " (\n"; res += args2JavaStrList(); res += "\t)\n"; res += "\t{\n"; res += "\t\t"; if(funcSpec.typeJava.equals("void")==false) res += "return "; res += "__"+funcSpec.identifier+"(\n"; for (i=0; i