From eb54a7ede43d9275f10db6fce1472256550da0eb Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Wed, 2 Mar 2011 04:49:12 +0000 Subject: [PATCH] java: Fix generated functions that return RHashtable. Creating a HashMap directly from JNI is possible but very tedious (see: http://java.sun.com/docs/books/jni/html/fldmeth.html#26254) Instead we use the existing code to return hashes from JNI as plain String[], then add some code in the Java wrapper to convert these to HashMap. --- generator/generator_java.ml | 45 ++++++++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/generator/generator_java.ml b/generator/generator_java.ml index 90ae263..dedf962 100644 --- a/generator/generator_java.ml +++ b/generator/generator_java.ml @@ -142,11 +142,25 @@ public class GuestFS { pr " if (g == 0)\n"; pr " throw new LibGuestFSException (\"%s: handle is closed\");\n" name; - pr " "; - if ret <> RErr then pr "return "; - pr "_%s " name; - generate_java_call_args ~handle:"g" style; - pr ";\n"; + (match ret with + | RErr -> + pr " _%s " name; + generate_java_call_args ~handle:"g" style; + pr ";\n" + | RHashtable _ -> + pr " String[] r = _%s " name; + generate_java_call_args ~handle:"g" style; + pr ";\n"; + pr "\n"; + pr " HashMap rhash = new HashMap ();\n"; + pr " for (int i = 0; i < r.length; i += 2)\n"; + pr " rhash.put (r[i], r[i+1]);\n"; + pr " return rhash;\n" + | _ -> + pr " return _%s " name; + generate_java_call_args ~handle:"g" style; + pr ";\n" + ); pr " }\n"; pr " "; generate_java_prototype ~privat:true ~native:true name style; @@ -184,7 +198,11 @@ and generate_java_prototype ?(public=false) ?(privat=false) ?(native=false) | RStructList (_, typ) -> let name = java_name_of_struct typ in pr "%s[] " name; - | RHashtable _ -> pr "Map "; + | RHashtable _ -> + if not native then + pr "Map " + else + pr "String[] "; ); if native then pr "_%s " name else pr "%s " name; @@ -367,7 +385,8 @@ Java_com_redhat_et_libguestfs_GuestFS__1close | RString _ -> pr " jstring jr;\n"; pr " char *r;\n"; "NULL", "NULL" - | RStringList _ -> + | RStringList _ + | RHashtable _ -> pr " jobjectArray jr;\n"; pr " int r_len;\n"; pr " jclass cl;\n"; @@ -384,7 +403,6 @@ Java_com_redhat_et_libguestfs_GuestFS__1close pr " jfieldID fl;\n"; pr " jobject jfl;\n"; pr " struct guestfs_%s_list *r;\n" typ; "NULL", "NULL" - | RHashtable _ -> pr " char **r;\n"; "NULL", "NULL" | RBufferOut _ -> pr " jstring jr;\n"; pr " char *r;\n"; @@ -417,10 +435,10 @@ Java_com_redhat_et_libguestfs_GuestFS__1close let needs_i = (match ret with - | RStringList _ | RStructList _ -> true + | RStringList _ | RStructList _ | RHashtable _ -> true | RErr | RBool _ | RInt _ | RInt64 _ | RConstString _ | RConstOptString _ - | RString _ | RBufferOut _ | RStruct _ | RHashtable _ -> false) || + | RString _ | RBufferOut _ | RStruct _ -> false) || List.exists (function | StringList _ -> true | DeviceList _ -> true @@ -527,7 +545,8 @@ Java_com_redhat_et_libguestfs_GuestFS__1close pr " jr = (*env)->NewStringUTF (env, r);\n"; pr " free (r);\n"; pr " return jr;\n" - | RStringList _ -> + | RStringList _ + | RHashtable _ -> pr " for (r_len = 0; r[r_len] != NULL; ++r_len) ;\n"; pr " cl = (*env)->FindClass (env, \"java/lang/String\");\n"; pr " jstr = (*env)->NewStringUTF (env, \"\");\n"; @@ -547,10 +566,6 @@ Java_com_redhat_et_libguestfs_GuestFS__1close let jtyp = java_name_of_struct typ in let cols = cols_of_struct typ in generate_java_struct_list_return typ jtyp cols - | RHashtable _ -> - (* XXX *) - pr " throw_exception (env, \"%s: internal error: please let us know how to make a Java HashMap from JNI bindings!\");\n" name; - pr " return NULL;\n" | RBufferOut _ -> pr " jr = (*env)->NewStringUTF (env, r); /* XXX size */\n"; pr " free (r);\n"; -- 1.8.3.1