// Copyright (c) 2011-present, Facebook, Inc. All rights reserved. // This source code is licensed under both the GPLv2 (found in the // COPYING file in the root directory) and Apache 2.0 License // (found in the LICENSE.Apache file in the root directory). // // This file implements the "bridge" between Java and C++ for // rocksdb::Slice. #include #include #include #include #include "include/org_rocksdb_AbstractSlice.h" #include "include/org_rocksdb_DirectSlice.h" #include "include/org_rocksdb_Slice.h" #include "rocksdb/slice.h" #include "rocksjni/portal.h" // /* * Class: org_rocksdb_Slice * Method: createNewSlice0 * Signature: ([BI)J */ jlong Java_org_rocksdb_Slice_createNewSlice0(JNIEnv* env, jclass /*jcls*/, jbyteArray data, jint offset) { const jsize dataSize = env->GetArrayLength(data); const int len = dataSize - offset; // NOTE: buf will be deleted in the Java_org_rocksdb_Slice_disposeInternalBuf // method jbyte* buf = new jbyte[len]; env->GetByteArrayRegion(data, offset, len, buf); if (env->ExceptionCheck()) { // exception thrown: ArrayIndexOutOfBoundsException return 0; } const auto* slice = new rocksdb::Slice((const char*)buf, len); return reinterpret_cast(slice); } /* * Class: org_rocksdb_Slice * Method: createNewSlice1 * Signature: ([B)J */ jlong Java_org_rocksdb_Slice_createNewSlice1(JNIEnv* env, jclass /*jcls*/, jbyteArray data) { jbyte* ptrData = env->GetByteArrayElements(data, nullptr); if (ptrData == nullptr) { // exception thrown: OutOfMemoryError return 0; } const int len = env->GetArrayLength(data) + 1; // NOTE: buf will be deleted in the Java_org_rocksdb_Slice_disposeInternalBuf // method char* buf = new char[len]; memcpy(buf, ptrData, len - 1); buf[len - 1] = '\0'; const auto* slice = new rocksdb::Slice(buf, len - 1); env->ReleaseByteArrayElements(data, ptrData, JNI_ABORT); return reinterpret_cast(slice); } /* * Class: org_rocksdb_Slice * Method: data0 * Signature: (J)[B */ jbyteArray Java_org_rocksdb_Slice_data0(JNIEnv* env, jobject /*jobj*/, jlong handle) { const auto* slice = reinterpret_cast(handle); const jsize len = static_cast(slice->size()); const jbyteArray data = env->NewByteArray(len); if (data == nullptr) { // exception thrown: OutOfMemoryError return nullptr; } env->SetByteArrayRegion( data, 0, len, const_cast(reinterpret_cast(slice->data()))); if (env->ExceptionCheck()) { // exception thrown: ArrayIndexOutOfBoundsException env->DeleteLocalRef(data); return nullptr; } return data; } /* * Class: org_rocksdb_Slice * Method: clear0 * Signature: (JZJ)V */ void Java_org_rocksdb_Slice_clear0(JNIEnv* /*env*/, jobject /*jobj*/, jlong handle, jboolean shouldRelease, jlong internalBufferOffset) { auto* slice = reinterpret_cast(handle); if (shouldRelease == JNI_TRUE) { const char* buf = slice->data_ - internalBufferOffset; delete[] buf; } slice->clear(); } /* * Class: org_rocksdb_Slice * Method: removePrefix0 * Signature: (JI)V */ void Java_org_rocksdb_Slice_removePrefix0(JNIEnv* /*env*/, jobject /*jobj*/, jlong handle, jint length) { auto* slice = reinterpret_cast(handle); slice->remove_prefix(length); } /* * Class: org_rocksdb_Slice * Method: disposeInternalBuf * Signature: (JJ)V */ void Java_org_rocksdb_Slice_disposeInternalBuf(JNIEnv* /*env*/, jobject /*jobj*/, jlong handle, jlong internalBufferOffset) { const auto* slice = reinterpret_cast(handle); const char* buf = slice->data_ - internalBufferOffset; delete[] buf; } // // (data_addr); const auto* slice = new rocksdb::Slice(ptrData, length); return reinterpret_cast(slice); } /* * Class: org_rocksdb_DirectSlice * Method: createNewDirectSlice1 * Signature: (Ljava/nio/ByteBuffer;)J */ jlong Java_org_rocksdb_DirectSlice_createNewDirectSlice1(JNIEnv* env, jclass /*jcls*/, jobject data) { void* data_addr = env->GetDirectBufferAddress(data); if (data_addr == nullptr) { // error: memory region is undefined, given object is not a direct // java.nio.Buffer, or JNI access to direct buffers is not supported by JVM rocksdb::IllegalArgumentExceptionJni::ThrowNew( env, rocksdb::Status::InvalidArgument("Could not access DirectBuffer")); return 0; } const auto* ptrData = reinterpret_cast(data_addr); const auto* slice = new rocksdb::Slice(ptrData); return reinterpret_cast(slice); } /* * Class: org_rocksdb_DirectSlice * Method: data0 * Signature: (J)Ljava/lang/Object; */ jobject Java_org_rocksdb_DirectSlice_data0(JNIEnv* env, jobject /*jobj*/, jlong handle) { const auto* slice = reinterpret_cast(handle); return env->NewDirectByteBuffer(const_cast(slice->data()), slice->size()); } /* * Class: org_rocksdb_DirectSlice * Method: get0 * Signature: (JI)B */ jbyte Java_org_rocksdb_DirectSlice_get0(JNIEnv* /*env*/, jobject /*jobj*/, jlong handle, jint offset) { const auto* slice = reinterpret_cast(handle); return (*slice)[offset]; } /* * Class: org_rocksdb_DirectSlice * Method: clear0 * Signature: (JZJ)V */ void Java_org_rocksdb_DirectSlice_clear0(JNIEnv* /*env*/, jobject /*jobj*/, jlong handle, jboolean shouldRelease, jlong internalBufferOffset) { auto* slice = reinterpret_cast(handle); if (shouldRelease == JNI_TRUE) { const char* buf = slice->data_ - internalBufferOffset; delete[] buf; } slice->clear(); } /* * Class: org_rocksdb_DirectSlice * Method: removePrefix0 * Signature: (JI)V */ void Java_org_rocksdb_DirectSlice_removePrefix0(JNIEnv* /*env*/, jobject /*jobj*/, jlong handle, jint length) { auto* slice = reinterpret_cast(handle); slice->remove_prefix(length); } /* * Class: org_rocksdb_DirectSlice * Method: disposeInternalBuf * Signature: (JJ)V */ void Java_org_rocksdb_DirectSlice_disposeInternalBuf( JNIEnv* /*env*/, jobject /*jobj*/, jlong handle, jlong internalBufferOffset) { const auto* slice = reinterpret_cast(handle); const char* buf = slice->data_ - internalBufferOffset; delete[] buf; } //