+ if ty_info.c_ty == "jbyteArray":
+ ret_conv = ("jbyteArray " + arr_name + "_arr = (*_env)->NewByteArray(_env, " + arr_len + ");\n" + "(*_env)->SetByteArrayRegion(_env, " + arr_name + "_arr, 0, " + arr_len + ", ", "")
+ arg_conv_cleanup = None
+ if not arr_len.isdigit():
+ arg_conv = ty_info.rust_obj + " " + arr_name + "_ref;\n"
+ arg_conv = arg_conv + arr_name + "_ref." + arr_len + " = (*_env)->GetArrayLength (_env, " + arr_name + ");\n"
+ if (not ty_info.is_ptr or not holds_ref) and ty_info.rust_obj != "LDKu8slice":
+ arg_conv = arg_conv + arr_name + "_ref." + ty_info.arr_access + " = MALLOC(" + arr_name + "_ref." + arr_len + ", \"" + ty_info.rust_obj + " Bytes\");\n"
+ arg_conv = arg_conv + "(*_env)->GetByteArrayRegion(_env, " + arr_name + ", 0, " + arr_name + "_ref." + arr_len + ", " + arr_name + "_ref." + ty_info.arr_access + ");"
+ else:
+ arg_conv = arg_conv + arr_name + "_ref." + ty_info.arr_access + " = (*_env)->GetByteArrayElements (_env, " + arr_name + ", NULL);"
+ arg_conv_cleanup = "(*_env)->ReleaseByteArrayElements(_env, " + arr_name + ", (int8_t*)" + arr_name + "_ref." + ty_info.arr_access + ", 0);"
+ if ty_info.rust_obj == "LDKTransaction":
+ arg_conv = arg_conv + "\n" + arr_name + "_ref.data_is_owned = " + str(holds_ref).lower() + ";"
+ ret_conv = (ty_info.rust_obj + " " + arr_name + "_var = ", "")
+ ret_conv = (ret_conv[0], ";\njbyteArray " + arr_name + "_arr = (*_env)->NewByteArray(_env, " + arr_name + "_var." + arr_len + ");\n")
+ ret_conv = (ret_conv[0], ret_conv[1] + "(*_env)->SetByteArrayRegion(_env, " + arr_name + "_arr, 0, " + arr_name + "_var." + arr_len + ", " + arr_name + "_var." + ty_info.arr_access + ");")
+ if not holds_ref and ty_info.rust_obj != "LDKu8slice":
+ ret_conv = (ret_conv[0], ret_conv[1] + "\n" + ty_info.rust_obj.replace("LDK", "") + "_free(" + arr_name + "_var);")
+ elif ty_info.rust_obj is not None:
+ arg_conv = ty_info.rust_obj + " " + arr_name + "_ref;\n"
+ arg_conv = arg_conv + "CHECK((*_env)->GetArrayLength (_env, " + arr_name + ") == " + arr_len + ");\n"
+ arg_conv = arg_conv + "(*_env)->GetByteArrayRegion (_env, " + arr_name + ", 0, " + arr_len + ", " + arr_name + "_ref." + ty_info.arr_access + ");"
+ ret_conv = (ret_conv[0], "." + ty_info.arr_access + ");")
+ else:
+ arg_conv = "unsigned char " + arr_name + "_arr[" + arr_len + "];\n"
+ arg_conv = arg_conv + "CHECK((*_env)->GetArrayLength (_env, " + arr_name + ") == " + arr_len + ");\n"
+ arg_conv = arg_conv + "(*_env)->GetByteArrayRegion (_env, " + arr_name + ", 0, " + arr_len + ", " + arr_name + "_arr);\n" + "unsigned char (*" + arr_name + "_ref)[" + arr_len + "] = &" + arr_name + "_arr;"
+ ret_conv = (ret_conv[0] + "*", ");")
+ return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
+ arg_conv = arg_conv, arg_conv_name = arr_name + "_ref", arg_conv_cleanup = arg_conv_cleanup,
+ ret_conv = ret_conv, ret_conv_name = arr_name + "_arr", to_hu_conv = None, to_hu_conv_name = None, from_hu_conv = None)
+ else:
+ assert not arr_len.isdigit() # fixed length arrays not implemented
+ assert ty_info.java_ty[len(ty_info.java_ty) - 2:] == "[]"
+ conv_name = "arr_conv_" + str(len(ty_info.java_hu_ty))
+ idxc = chr(ord('a') + (len(ty_info.java_hu_ty) % 26))
+ ty_info.subty.var_name = conv_name
+ if ty_info.is_ptr or holds_ref:
+ ty_info.subty.requires_clone = False
+ subty = map_type_with_info(ty_info.subty, False, None, is_free, holds_ref)
+ if arr_name == "":
+ arr_name = "arg"
+ arg_conv = ty_info.rust_obj + " " + arr_name + "_constr;\n"
+ arg_conv = arg_conv + arr_name + "_constr." + arr_len + " = (*_env)->GetArrayLength (_env, " + arr_name + ");\n"
+ arg_conv = arg_conv + "if (" + arr_name + "_constr." + arr_len + " > 0)\n"
+ if subty.rust_obj is None:
+ szof = subty.c_ty
+ else:
+ szof = subty.rust_obj
+ arg_conv = arg_conv + "\t" + arr_name + "_constr." + ty_info.arr_access + " = MALLOC(" + arr_name + "_constr." + arr_len + " * sizeof(" + szof + "), \"" + ty_info.rust_obj + " Elements\");\n"
+ arg_conv = arg_conv + "else\n"
+ arg_conv = arg_conv + "\t" + arr_name + "_constr." + ty_info.arr_access + " = NULL;\n"
+ if not ty_info.java_ty[:len(ty_info.java_ty) - 2].endswith("[]"):
+ arg_conv = arg_conv + ty_info.java_ty.strip("[]") + "* " + arr_name + "_vals = (*_env)->Get" + ty_info.subty.java_ty.title() + "ArrayElements (_env, " + arr_name + ", NULL);\n"
+ arg_conv = arg_conv + "for (size_t " + idxc + " = 0; " + idxc + " < " + arr_name + "_constr." + arr_len + "; " + idxc + "++) {\n"
+ if not ty_info.java_ty[:len(ty_info.java_ty) - 2].endswith("[]"):
+ arg_conv = arg_conv + "\t" + ty_info.java_ty.strip("[]") + " " + conv_name + " = " + arr_name + "_vals[" + idxc + "];"
+ if subty.arg_conv is not None:
+ arg_conv = arg_conv + "\n\t" + subty.arg_conv.replace("\n", "\n\t")
+ else:
+ arg_conv = arg_conv + "\tjobject " + conv_name + " = (*_env)->GetObjectArrayElement(_env, " + arr_name + ", " + idxc + ");\n"
+ arg_conv = arg_conv + "\t" + subty.arg_conv.replace("\n", "\n\t")
+ arg_conv = arg_conv + "\n\t" + arr_name + "_constr." + ty_info.arr_access + "[" + idxc + "] = " + subty.arg_conv_name + ";\n}"
+ if not ty_info.java_ty[:len(ty_info.java_ty) - 2].endswith("[]"):
+ arg_conv = arg_conv + "\n(*_env)->Release" + ty_info.java_ty.strip("[]").title() + "ArrayElements (_env, " + arr_name + ", " + arr_name + "_vals, 0);"
+ if ty_info.is_ptr:
+ arg_conv_name = "&" + arr_name + "_constr"
+ else:
+ arg_conv_name = arr_name + "_constr"
+ arg_conv_cleanup = None
+ if ty_info.is_ptr:
+ arg_conv_cleanup = "FREE(" + arr_name + "_constr." + ty_info.arr_access + ");"
+
+ if arr_name == "arg":
+ arr_name = "ret"
+ ret_conv = (ty_info.rust_obj + " " + arr_name + "_var = ", "")
+ if subty.ret_conv is None:
+ ret_conv = ("DUMMY", "DUMMY")
+ elif not ty_info.java_ty[:len(ty_info.java_ty) - 2].endswith("[]"):
+ ret_conv = (ret_conv[0], ";\n" + ty_info.c_ty + " " + arr_name + "_arr = (*_env)->New" + ty_info.java_ty.strip("[]").title() + "Array(_env, " + arr_name + "_var." + arr_len + ");\n")
+ ret_conv = (ret_conv[0], ret_conv[1] + subty.c_ty + " *" + arr_name + "_arr_ptr = (*_env)->GetPrimitiveArrayCritical(_env, " + arr_name + "_arr, NULL);\n")
+ ret_conv = (ret_conv[0], ret_conv[1] + "for (size_t " + idxc + " = 0; " + idxc + " < " + arr_name + "_var." + arr_len + "; " + idxc + "++) {\n")
+ ret_conv = (ret_conv[0], ret_conv[1] + "\t" + subty.ret_conv[0].replace("\n", "\n\t"))
+ ret_conv = (ret_conv[0], ret_conv[1] + arr_name + "_var." + ty_info.arr_access + "[" + idxc + "]" + subty.ret_conv[1].replace("\n", "\n\t"))
+ ret_conv = (ret_conv[0], ret_conv[1] + "\n\t" + arr_name + "_arr_ptr[" + idxc + "] = " + subty.ret_conv_name + ";\n")
+ ret_conv = (ret_conv[0], ret_conv[1] + "}\n(*_env)->ReleasePrimitiveArrayCritical(_env, " + arr_name + "_arr, " + arr_name + "_arr_ptr, 0);")
+ else:
+ assert ty_info.java_fn_ty_arg.startswith("[")
+ clz_var = ty_info.java_fn_ty_arg[1:].replace("[", "arr_of_")
+ c_array_class_caches.add(clz_var)
+ ret_conv = (ret_conv[0], ";\n" + ty_info.c_ty + " " + arr_name + "_arr = (*_env)->NewObjectArray(_env, " + arr_name + "_var." + arr_len + ", " + clz_var + "_clz, NULL);\n")
+ ret_conv = (ret_conv[0], ret_conv[1] + "for (size_t " + idxc + " = 0; " + idxc + " < " + arr_name + "_var." + arr_len + "; " + idxc + "++) {\n")
+ ret_conv = (ret_conv[0], ret_conv[1] + "\t" + subty.ret_conv[0].replace("\n", "\n\t"))
+ ret_conv = (ret_conv[0], ret_conv[1] + arr_name + "_var." + ty_info.arr_access + "[" + idxc + "]" + subty.ret_conv[1].replace("\n", "\n\t"))
+ ret_conv = (ret_conv[0], ret_conv[1] + "\n\t(*_env)->SetObjectArrayElement(_env, " + arr_name + "_arr, " + idxc + ", " + subty.ret_conv_name + ");\n")
+ ret_conv = (ret_conv[0], ret_conv[1] + "}")
+ if not holds_ref:
+ # Note that we don't drop the full vec here - we're passing ownership to java (or have cloned) or free'd by now!
+ ret_conv = (ret_conv[0], ret_conv[1] + "\nFREE(" + arr_name + "_var." + ty_info.arr_access + ");")
+
+ to_hu_conv = None
+ to_hu_conv_name = None
+ if subty.to_hu_conv is not None:
+ to_hu_conv = ty_info.java_hu_ty + " " + conv_name + "_arr = new " + ty_info.subty.java_hu_ty.split("<")[0] + "[" + arr_name + ".length];\n"
+ to_hu_conv = to_hu_conv + "for (int " + idxc + " = 0; " + idxc + " < " + arr_name + ".length; " + idxc + "++) {\n"
+ to_hu_conv = to_hu_conv + "\t" + subty.java_ty + " " + conv_name + " = " + arr_name + "[" + idxc + "];\n"
+ to_hu_conv = to_hu_conv + "\t" + subty.to_hu_conv.replace("\n", "\n\t") + "\n"
+ to_hu_conv = to_hu_conv + "\t" + conv_name + "_arr[" + idxc + "] = " + subty.to_hu_conv_name + ";\n}"
+ to_hu_conv_name = conv_name + "_arr"
+ from_hu_conv = None
+ if subty.from_hu_conv is not None:
+ if subty.java_ty == "long" and subty.java_hu_ty != "long":
+ from_hu_conv = ("Arrays.stream(" + arr_name + ").mapToLong(" + conv_name + " -> " + subty.from_hu_conv[0] + ").toArray()", "/* TODO 2 " + subty.java_hu_ty + " */")
+ elif subty.java_ty == "long":
+ from_hu_conv = ("Arrays.stream(" + arr_name + ").map(" + conv_name + " -> " + subty.from_hu_conv[0] + ").toArray()", "/* TODO 2 " + subty.java_hu_ty + " */")
+ else:
+ from_hu_conv = ("(" + ty_info.java_ty + ")Arrays.stream(" + arr_name + ").map(" + conv_name + " -> " + subty.from_hu_conv[0] + ").toArray()", "/* TODO 2 " + subty.java_hu_ty + " */")
+
+ return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
+ arg_conv = arg_conv, arg_conv_name = arg_conv_name, arg_conv_cleanup = arg_conv_cleanup,
+ ret_conv = ret_conv, ret_conv_name = arr_name + "_arr", to_hu_conv = to_hu_conv, to_hu_conv_name = to_hu_conv_name, from_hu_conv = from_hu_conv)
+ elif ty_info.java_ty == "String":
+ if ty_info.arr_access is None:
+ return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
+ arg_conv = None, arg_conv_name = None, arg_conv_cleanup = None,
+ ret_conv = ("jstring " + ty_info.var_name + "_conv = (*_env)->NewStringUTF(_env, ", ");"), ret_conv_name = ty_info.var_name + "_conv",
+ to_hu_conv = None, to_hu_conv_name = None, from_hu_conv = None)
+ else:
+ return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
+ arg_conv = None, arg_conv_name = None, arg_conv_cleanup = None,
+ ret_conv = ("LDKStr " + ty_info.var_name + "_str = ",
+ ";\nchar* " + ty_info.var_name + "_buf = MALLOC(" + ty_info.var_name + "_str." + ty_info.arr_len + " + 1, \"str conv buf\");\n" +
+ "memcpy(" + ty_info.var_name + "_buf, " + ty_info.var_name + "_str." + ty_info.arr_access + ", " + ty_info.var_name + "_str." + ty_info.arr_len + ");\n" +
+ ty_info.var_name + "_buf[" + ty_info.var_name + "_str." + ty_info.arr_len + "] = 0;\n" +
+ "jstring " + ty_info.var_name + "_conv = (*_env)->NewStringUTF(_env, " + ty_info.var_name + "_str." + ty_info.arr_access + ");\n" +
+ "FREE(" + ty_info.var_name + "_buf);"),
+ ret_conv_name = ty_info.var_name + "_conv", to_hu_conv = None, to_hu_conv_name = None, from_hu_conv = None)
+ elif ty_info.var_name == "" and not print_void:
+ # We don't have a parameter name, and want one, just call it arg