1 /** 2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 * SPDX-License-Identifier: Apache-2.0. 4 */ 5 6 #ifndef AWS_JNI_CRT_H 7 #define AWS_JNI_CRT_H 8 9 #include <aws/common/byte_buf.h> 10 #include <aws/common/common.h> 11 #include <aws/common/logging.h> 12 #include <aws/common/string.h> 13 14 #include <jni.h> 15 16 #define AWS_CRT_JAVA_PACKAGE_ID 9 17 18 enum aws_java_crt_log_subject { 19 AWS_LS_JAVA_CRT_GENERAL = AWS_LOG_SUBJECT_BEGIN_RANGE(AWS_CRT_JAVA_PACKAGE_ID), 20 AWS_LS_JAVA_CRT_RESOURCE, 21 AWS_LS_JAVA_CRT_S3, 22 AWS_LS_JAVA_ANDROID_KEYCHAIN, 23 24 AWS_LS_JAVA_CRT_LAST = AWS_LOG_SUBJECT_END_RANGE(AWS_CRT_JAVA_PACKAGE_ID), 25 }; 26 27 enum aws_java_crt_error { 28 AWS_ERROR_JAVA_CRT_JVM_DESTROYED = AWS_ERROR_ENUM_BEGIN_RANGE(AWS_CRT_JAVA_PACKAGE_ID), 29 AWS_ERROR_JAVA_CRT_JVM_OUT_OF_MEMORY, 30 31 AWS_ERROR_JAVA_CRT_END_RANGE = AWS_ERROR_ENUM_END_RANGE(AWS_CRT_JAVA_PACKAGE_ID), 32 }; 33 34 struct aws_allocator *aws_jni_get_allocator(void); 35 36 /******************************************************************************* 37 * aws_jni_throw_runtime_exception - throws a crt.CrtRuntimeException with the 38 * supplied message, sprintf formatted. Control WILL return from this function, 39 * so after calling it, make sure to clean up any native resources before exiting 40 * the calling JNIEXPORT function. 41 ******************************************************************************/ 42 void aws_jni_throw_runtime_exception(JNIEnv *env, const char *msg, ...); 43 44 /******************************************************************************* 45 * Throws java NullPointerException 46 ******************************************************************************/ 47 void aws_jni_throw_null_pointer_exception(JNIEnv *env, const char *msg, ...); 48 49 /******************************************************************************* 50 * Throws java IllegalArgumentException 51 ******************************************************************************/ 52 void aws_jni_throw_illegal_argument_exception(JNIEnv *env, const char *msg, ...); 53 54 /******************************************************************************* 55 * Checks whether or not an exception is pending on the stack and clears it. 56 * If an exception was pending, it is cleared. 57 * 58 * @return true if an exception was pending, false otherwise. If it returns true 59 * the pending exception was cleared. 60 ******************************************************************************/ 61 bool aws_jni_check_and_clear_exception(JNIEnv *env); 62 63 /******************************************************************************* 64 * Checks whether or not an exception is pending on the stack. 65 * If the exception is pending, deletes existing global reference of `out`, sets `out` to the new exception and clears 66 * it. 67 * 68 * @param env A pointer to the JNI environment, used to interact with the JVM. 69 * @param out A pointer to a jthrowable object. If an exception is pending, the function 70 * deletes any existing global reference pointed to by 'out', and sets 'out' 71 * to point to the new exception. Must not be NULL. 72 * 73 * @return true if an exception was pending and has been cleared; false otherwise. 74 * 75 ******************************************************************************/ 76 bool aws_jni_get_and_clear_exception(JNIEnv *env, jthrowable *out); 77 78 /******************************************************************************* 79 * Set a size_t based on a jlong. 80 * If conversion fails, a java IllegalArgumentException is thrown like 81 * "{errmsg_prefix} cannot be negative" and AWS_OP_ERR is returned. 82 ******************************************************************************/ 83 int aws_size_t_from_java(JNIEnv *env, size_t *out_size, jlong java_long, const char *errmsg_prefix); 84 85 /******************************************************************************* 86 * aws_java_byte_array_new - Creates a new Java byte[] 87 ******************************************************************************/ 88 jbyteArray aws_java_byte_array_new(JNIEnv *env, size_t size); 89 90 /******************************************************************************* 91 * aws_copy_java_byte_array_to_native_array - Copies from a Java byte[] to a Native byte array. 92 * Returns false if ArrayIndexOutOfBoundsException occurred. 93 ******************************************************************************/ 94 bool aws_copy_java_byte_array_to_native_array(JNIEnv *env, jbyteArray src, uint8_t *dst, size_t amount); 95 96 /******************************************************************************* 97 * aws_copy_java_byte_array_to_native_array - Copies from a Native byte array to a Java byte[] 98 * Returns false if ArrayIndexOutOfBoundsException occurred. 99 ******************************************************************************/ 100 bool aws_copy_native_array_to_java_byte_array(JNIEnv *env, jbyteArray dst, uint8_t *src, size_t amount); 101 102 /******************************************************************************* 103 * aws_jni_byte_array_from_cursor - Creates a jbyteArray from a aws_byte_cursor. 104 ******************************************************************************/ 105 jbyteArray aws_jni_byte_array_from_cursor(JNIEnv *env, const struct aws_byte_cursor *native_data); 106 107 /******************************************************************************* 108 * jni_byte_buffer_copy_from_cursor - Creates a Java ByteBuffer from a native aws_byte_cursor 109 ******************************************************************************/ 110 jobject aws_jni_byte_buffer_copy_from_cursor(JNIEnv *env, const struct aws_byte_cursor *native_data); 111 112 /******************************************************************************* 113 * aws_jni_string_from_cursor - Creates a Java String from a cursor. 114 * This function never returns NULL. It produces a fatal assertion if the allocator is out of memory. 115 ******************************************************************************/ 116 jstring aws_jni_string_from_cursor(JNIEnv *env, const struct aws_byte_cursor *native_data); 117 118 /******************************************************************************* 119 * aws_jni_string_from_cursor - Creates a Java String from a string. 120 * This function never returns NULL. It produces a fatal assertion if the allocator is out of memory. 121 ******************************************************************************/ 122 jstring aws_jni_string_from_string(JNIEnv *env, const struct aws_string *string); 123 124 /******************************************************************************* 125 * aws_jni_native_byte_buf_from_java_direct_byte_buf - Populates a aws_byte_buf from a Java DirectByteBuffer 126 ******************************************************************************/ 127 void aws_jni_native_byte_buf_from_java_direct_byte_buf(JNIEnv *env, jobject directBuf, struct aws_byte_buf *dst); 128 129 /******************************************************************************* 130 * aws_jni_direct_byte_buffer_from_raw_ptr - Creates a Java Direct ByteBuffer from raw pointer and length 131 ******************************************************************************/ 132 jobject aws_jni_direct_byte_buffer_from_raw_ptr(JNIEnv *env, const void *dst, size_t capacity); 133 134 /******************************************************************************* 135 * aws_jni_byte_buffer_get_position - Gets the Read/Write Position of a ByteBuffer 136 ******************************************************************************/ 137 int aws_jni_byte_buffer_get_position(JNIEnv *env, jobject java_byte_buffer); 138 139 /******************************************************************************* 140 * aws_jni_byte_buffer_set_position - Sets the Read/Write Position of a ByteBuffer 141 ******************************************************************************/ 142 void aws_jni_byte_buffer_set_position(JNIEnv *env, jobject jByteBuf, jint position); 143 144 /******************************************************************************* 145 * aws_jni_byte_buffer_set_limit - Sets the Read/Write Limit of a ByteBuffer 146 ******************************************************************************/ 147 void aws_jni_byte_buffer_set_limit(JNIEnv *env, jobject jByteBuf, jint limit); 148 149 /******************************************************************************* 150 * aws_jni_byte_cursor_from_jstring_acquire - Creates an aws_byte_cursor from the UTF-8 151 * characters extracted from the supplied jstring. The string value is null-terminated. 152 * The aws_byte_cursor MUST be given to aws_jni_byte_cursor_from jstring_release() when 153 * it's no longer needed, or it will leak. 154 * 155 * If there is an error, the returned aws_byte_cursor.ptr will be NULL and 156 * and a java exception is being thrown (OutOfMemoryError or NullPointerException) 157 ******************************************************************************/ 158 struct aws_byte_cursor aws_jni_byte_cursor_from_jstring_acquire(JNIEnv *env, jstring str); 159 160 /******************************************************************************** 161 * aws_jni_byte_cursor_from_jstring_release - Releases the string back to the JVM 162 ********************************************************************************/ 163 void aws_jni_byte_cursor_from_jstring_release(JNIEnv *env, jstring str, struct aws_byte_cursor cur); 164 165 /******************************************************************************* 166 * aws_jni_byte_cursor_from_jbyteArray_acquire - Creates an aws_byte_cursor from the 167 * bytes extracted from the supplied jbyteArray. 168 * The aws_byte_cursor MUST be given to aws_jni_byte_cursor_from jstring_release() when 169 * it's no longer needed, or it will leak. 170 * 171 * If there is an error, the returned aws_byte_cursor.ptr will be NULL and 172 * and a java exception is being thrown. 173 ******************************************************************************/ 174 struct aws_byte_cursor aws_jni_byte_cursor_from_jbyteArray_acquire(JNIEnv *env, jbyteArray str); 175 176 /******************************************************************************** 177 * aws_jni_byte_cursor_from_jbyteArray_release - Releases the array back to the JVM 178 ********************************************************************************/ 179 void aws_jni_byte_cursor_from_jbyteArray_release(JNIEnv *env, jbyteArray str, struct aws_byte_cursor cur); 180 181 /******************************************************************************* 182 * aws_jni_byte_cursor_from_direct_byte_buffer - Creates an aws_byte_cursor from the 183 * direct byte buffer. Note that the buffer is not reference pinned, so the cursor 184 * is only valid for the current JNI call 185 ******************************************************************************/ 186 struct aws_byte_cursor aws_jni_byte_cursor_from_direct_byte_buffer(JNIEnv *env, jobject byte_buffer); 187 188 /******************************************************************************* 189 * aws_jni_new_string_from_jstring - Creates a new aws_string from the UTF-8 190 * characters extracted from the supplied jstring. The string must be destroyed 191 * via aws_string_destroy or aws_string_destroy_secure 192 ******************************************************************************/ 193 struct aws_string *aws_jni_new_string_from_jstring(JNIEnv *env, jstring str); 194 195 /******************************************************************************* 196 * aws_jni_acquire_thread_env - Acquires the JNIEnv for the current thread from the VM, 197 * attaching the env if necessary. aws_jni_release_thread_env() must be called once 198 * the caller is through with the environment. 199 ******************************************************************************/ 200 JNIEnv *aws_jni_acquire_thread_env(JavaVM *jvm); 201 202 /******************************************************************************* 203 * aws_jni_release_thread_env - Releases an acquired JNIEnv for the current thread. Every successfully 204 * acquired JNIEnv must be released exactly once. Internally, all this does is release the reader 205 * lock on the set of valid JVMs. 206 ******************************************************************************/ 207 void aws_jni_release_thread_env(JavaVM *jvm, JNIEnv *env); 208 209 /******************************************************************************* 210 * aws_jni_new_crt_exception_from_error_code - Creates a new jobject from the aws 211 * error code, which is the type of software/amazon/awssdk/crt/CrtRuntimeException. 212 * Reference of the jobject needed to be cleaned up after use. 213 ******************************************************************************/ 214 jobject aws_jni_new_crt_exception_from_error_code(JNIEnv *env, int error_code); 215 216 #endif /* AWS_JNI_CRT_H */ 217