diff --git a/lib/build.gradle b/lib/build.gradle index f4b5115..7d3ae13 100644 --- a/lib/build.gradle +++ b/lib/build.gradle @@ -26,11 +26,11 @@ ext { apply from: 'publish.gradle' android { - compileSdk 32 + compileSdk 33 defaultConfig { - minSdk 21 + minSdk 33 targetSdk 32 versionCode 1 versionName "1.0" @@ -285,7 +285,7 @@ task checkCurrentJavaVersion() { task generateHeaderFilesFromJavaWrapper(type: Exec) { workingDir "${projectDir}/src/main/java/org/kiwix/" - commandLine 'bash', '-c', "javac -h ${buildDir}/include/javah_generated/ -d ${buildDir}/libzim/ ${getLibzimFiles()} ${getLibkiwixFiles()}" + commandLine 'bash', '-c', "javac -h ${buildDir}/include/javah_generated/ -d ${buildDir}/libzim/ *.java ${getLibzimFiles()} ${getLibkiwixFiles()}" } String getLibkiwixFiles() { diff --git a/lib/src/main/cpp/CMakeLists.txt b/lib/src/main/cpp/CMakeLists.txt index f768ff2..977eba0 100644 --- a/lib/src/main/cpp/CMakeLists.txt +++ b/lib/src/main/cpp/CMakeLists.txt @@ -10,6 +10,7 @@ add_library( zim_wrapper SHARED + wrapper.cpp libzim/archive.cpp libzim/entry.cpp libzim/entry_iterator.cpp @@ -45,6 +46,7 @@ add_library( kiwix_wrapper SHARED + wrapper.cpp libkiwix/book.cpp libkiwix/filter.cpp libkiwix/kiwixicu.cpp diff --git a/lib/src/main/cpp/libkiwix/book.cpp b/lib/src/main/cpp/libkiwix/book.cpp index 81ec03b..9470eb4 100644 --- a/lib/src/main/cpp/libkiwix/book.cpp +++ b/lib/src/main/cpp/libkiwix/book.cpp @@ -29,13 +29,11 @@ #define TYPENAME libkiwix_Book #include -METHOD0(void, allocate) +METHOD0(jobject, getNativeBook) { - SET_PTR(std::make_shared()); + return NEW_RESOURCE(std::make_shared()); } -DISPOSE - METHOD(void, update__Lorg_kiwix_libkiwix_Book_2, jobject otherBook) { THIS->update(*getPtr(env, otherBook)); @@ -93,12 +91,12 @@ METHOD0(jobjectArray, getIllustrations) { jobjectArray retArray = createArray(env, illustrations.size(), "org/kiwix/libkiwix/Illustration"); size_t index = 0; for (auto illu: illustrations) { - auto wrapper = BUILD_WRAPPER("org/kiwix/libkiwx/Illustration", illu); + auto wrapper = BUILD_WRAPPER(illu); env->SetObjectArrayElement(retArray, index++, wrapper); } return retArray; } METHOD(jobject, getIllustration, jint size) { - return BUILD_WRAPPER("org/kiwix/libkiwix/Illustration", THIS->getIllustration(TO_C(size))); + return BUILD_WRAPPER(THIS->getIllustration(TO_C(size))); } diff --git a/lib/src/main/cpp/libkiwix/bookmark.cpp b/lib/src/main/cpp/libkiwix/bookmark.cpp index f14300c..ae14f6a 100644 --- a/lib/src/main/cpp/libkiwix/bookmark.cpp +++ b/lib/src/main/cpp/libkiwix/bookmark.cpp @@ -26,15 +26,13 @@ #define NATIVE_TYPE kiwix::Bookmark #define TYPENAME libkiwix_Bookmark -#include +#include "macros.h" -METHOD0(void, setNativeBookmark) +METHOD0(jobject, buildNativeBookmark) { - SET_PTR(std::make_shared()); + return NEW_RESOURCE(std::make_shared()); } -DISPOSE - GETTER(jstring, getBookId) GETTER(jstring, getBookTitle) diff --git a/lib/src/main/cpp/libkiwix/filter.cpp b/lib/src/main/cpp/libkiwix/filter.cpp index 4e4a5f3..294059d 100644 --- a/lib/src/main/cpp/libkiwix/filter.cpp +++ b/lib/src/main/cpp/libkiwix/filter.cpp @@ -28,15 +28,11 @@ #define TYPENAME libkiwix_Filter #include "macros.h" - - /* Kiwix Reader JNI functions */ -METHOD0(void, allocate) { - SET_PTR(std::make_shared()); +METHOD0(jobject, getNativeFilter) { + return NEW_RESOURCE(std::make_shared()); } -DISPOSE - #define FORWARD(name, args_type) \ METHOD(jobject, name, args_type value) { \ THIS->name(jni2c(value, env)); \ diff --git a/lib/src/main/cpp/libkiwix/kiwixserver.cpp b/lib/src/main/cpp/libkiwix/kiwixserver.cpp index 289e203..cd626c4 100644 --- a/lib/src/main/cpp/libkiwix/kiwixserver.cpp +++ b/lib/src/main/cpp/libkiwix/kiwixserver.cpp @@ -32,21 +32,14 @@ /* Kiwix Reader JNI functions */ -METHOD(void, setNativeServer, jobject jLibrary) +METHOD(jobject, buildNativeServer, jobject jLibrary) { LOG("Attempting to create server"); - try { - auto library = getPtr(env, jLibrary); - SET_PTR(std::make_shared(library.get())); - } catch (std::exception& e) { - LOG("Error creating the server"); - LOG("%s", e.what()); - } + auto library = getPtr(env, jLibrary); + return NEW_RESOURCE(std::make_shared(library.get())); } -DISPOSE - /* Kiwix library functions */ METHOD(void, setRoot, jstring root) { diff --git a/lib/src/main/cpp/libkiwix/library.cpp b/lib/src/main/cpp/libkiwix/library.cpp index e27e60d..9c4bdb9 100644 --- a/lib/src/main/cpp/libkiwix/library.cpp +++ b/lib/src/main/cpp/libkiwix/library.cpp @@ -29,12 +29,11 @@ #include "macros.h" /* Kiwix Reader JNI functions */ -METHOD0(void, setNativeHandler) +METHOD0(jobject, buildNativeLibrary) { - SET_PTR(std::make_shared()); + return NEW_RESOURCE(std::make_shared()); } -DISPOSE /* Kiwix library functions */ METHOD(jboolean, addBook, jobject book) @@ -50,11 +49,11 @@ METHOD(jboolean, addBook, jobject book) } METHOD(jobject, getBookById, jstring id) { - return BUILD_WRAPPER("org/kiwix/libkiwix/Book", THIS->getBookById(TO_C(id))); + return BUILD_WRAPPER(THIS->getBookById(TO_C(id))); } METHOD(jobject, getArchiveById, jstring id) { - return BUILD_WRAPPER("org/kiwix/libzim/Archive", THIS->getArchiveById(TO_C(id))); + return BUILD_WRAPPER(THIS->getArchiveById(TO_C(id))); } METHOD(jboolean, removeBookById, jstring id) { @@ -98,7 +97,7 @@ METHOD(jobjectArray, getBookmarks, jboolean onlyValidBookmarks) { jobjectArray retArray = createArray(env, bookmarks.size(), "org/kiwix/libkiwix/Bookmark"); size_t index = 0; for (auto bookmark: bookmarks) { - auto wrapper = BUILD_WRAPPER("org/kiwix/libkiwx/Bookmark", bookmark); + auto wrapper = BUILD_WRAPPER(bookmark); env->SetObjectArrayElement(retArray, index++, wrapper); } return retArray; diff --git a/lib/src/main/cpp/libkiwix/manager.cpp b/lib/src/main/cpp/libkiwix/manager.cpp index cc9a9bd..e0d36fe 100644 --- a/lib/src/main/cpp/libkiwix/manager.cpp +++ b/lib/src/main/cpp/libkiwix/manager.cpp @@ -28,14 +28,12 @@ #define TYPENAME libkiwix_Manager #include -METHOD(void, allocate, jobject libraryObj) +METHOD(jobject, buildNativeManager, jobject libraryObj) { auto lib = getPtr(env, libraryObj); - SET_PTR(std::make_shared(lib.get())); + return NEW_RESOURCE(std::make_shared(lib.get())); } -DISPOSE - /* Kiwix manager functions */ METHOD(jboolean, readFile, jstring path) { diff --git a/lib/src/main/cpp/libzim/archive.cpp b/lib/src/main/cpp/libzim/archive.cpp index 3392977..2545cf0 100644 --- a/lib/src/main/cpp/libzim/archive.cpp +++ b/lib/src/main/cpp/libzim/archive.cpp @@ -36,18 +36,13 @@ #include /* Kiwix Reader JNI functions */ -METHOD(void, setNativeArchive, jstring filename) +METHOD(jobject, buildNativeArchive, jstring filename) { std::string cPath = TO_C(filename); LOG("Attempting to create reader with: %s", cPath.c_str()); - try { - auto archive = std::make_shared(cPath); - SET_PTR(archive); - } catch (std::exception& e) { - LOG("Error opening ZIM file"); - LOG("%s", e.what()); - } + auto archive = std::make_shared(cPath); + return NEW_RESOURCE(archive); } namespace @@ -70,7 +65,7 @@ int jni2fd(const jobject& fdObj, JNIEnv* env) } // unnamed namespace -JNIEXPORT void JNICALL Java_org_kiwix_libzim_Archive_setNativeArchiveByFD( +JNIEXPORT jobject JNICALL Java_org_kiwix_libzim_Archive_buildNativeArchiveByFD( JNIEnv* env, jobject thisObj, jobject fdObj) { #ifndef _WIN32 @@ -79,18 +74,16 @@ JNIEXPORT void JNICALL Java_org_kiwix_libzim_Archive_setNativeArchiveByFD( LOG("Attempting to create reader with fd: %d", fd); try { auto archive = std::make_shared(fd); - SET_PTR(archive); - } catch (std::exception& e) { - LOG("Error opening ZIM file"); - LOG("%s", e.what()); - } + return NEW_RESOURCE(archive); + } CATCH("Error opening ZIM file") #else jclass exception = env->FindClass("java/lang/UnsupportedOperationException"); env->ThrowNew(exception, "org.kiwix.libzim.Archive.setNativeArchiveByFD() is not supported under Windows"); #endif + return nullptr; } -JNIEXPORT void JNICALL Java_org_kiwix_libzim_Archive_setNativeArchiveEmbedded( +JNIEXPORT jobject JNICALL Java_org_kiwix_libzim_Archive_buildNativeArchiveEmbedded( JNIEnv* env, jobject thisObj, jobject fdObj, jlong offset, jlong size) { #ifndef _WIN32 @@ -99,19 +92,15 @@ JNIEXPORT void JNICALL Java_org_kiwix_libzim_Archive_setNativeArchiveEmbedded( LOG("Attempting to create reader with fd: %d", fd); try { auto archive = std::make_shared(fd, offset, size); - SET_PTR(archive); - } catch (std::exception& e) { - LOG("Error opening ZIM file"); - LOG("%s", e.what()); - } + return NEW_RESOURCE(archive); + } CATCH("Error opening ZIM file") #else jclass exception = env->FindClass("java/lang/UnsupportedOperationException"); env->ThrowNew(exception, "org.kiwix.libzim.Archive.setNativeArchiveEmbedded() is not supported under Windows"); #endif + return nullptr; } -DISPOSE - GETTER(jstring, getFilename) GETTER(jlong, getFilesize) GETTER(jint, getAllEntryCount) @@ -128,13 +117,13 @@ METHOD(jstring, getMetadata, jstring name) { } METHOD(jobject, getMetadataItem, jstring name) { - return BUILD_WRAPPER("org/kiwix/libzim/Item", THIS->getMetadataItem(TO_C(name))); + return BUILD_WRAPPER(THIS->getMetadataItem(TO_C(name))); } GETTER(jobjectArray, getMetadataKeys) METHOD(jobject, getIllustrationItem, jint size) { - return BUILD_WRAPPER("org/kiwix/libzim/Item", THIS->getIllustrationItem(TO_C(size))); + return BUILD_WRAPPER(THIS->getIllustrationItem(TO_C(size))); } METHOD(jboolean, hasIllustration, jint size) { @@ -144,11 +133,11 @@ METHOD(jboolean, hasIllustration, jint size) { GETTER(jlongArray, getIllustrationSizes) METHOD(jobject, getEntryByPath__Ljava_lang_String_2, jstring path) { - return BUILD_WRAPPER("org/kiwix/libzim/Entry", THIS->getEntryByPath(TO_C(path))); + return BUILD_WRAPPER(THIS->getEntryByPath(TO_C(path))); } METHOD(jobject, getEntryByPath__I, jint index) { - return BUILD_WRAPPER("org/kiwix/libzim/Entry", THIS->getEntryByPath(TO_C(index))); + return BUILD_WRAPPER(THIS->getEntryByPath(TO_C(index))); } METHOD(jboolean, hasEntryByPath, jstring path) { @@ -156,11 +145,11 @@ METHOD(jboolean, hasEntryByPath, jstring path) { } METHOD(jobject, getEntryByTitle__Ljava_lang_String_2, jstring title) { - return BUILD_WRAPPER("org/kiwix/libzim/Entry", THIS->getEntryByTitle(TO_C(title))); + return BUILD_WRAPPER(THIS->getEntryByTitle(TO_C(title))); } METHOD(jobject, getEntryByTitle__I, jint index) { - return BUILD_WRAPPER("org/kiwix/libzim/Entry", THIS->getEntryByTitle(TO_C(index))); + return BUILD_WRAPPER(THIS->getEntryByTitle(TO_C(index))); } METHOD(jboolean, hasEntryByTitle, jstring title) { @@ -168,17 +157,17 @@ METHOD(jboolean, hasEntryByTitle, jstring title) { } METHOD(jobject, getEntryByClusterOrder, jint index) { - return BUILD_WRAPPER("org/kiwix/libzim/Entry", THIS->getEntryByClusterOrder(TO_C(index))); + return BUILD_WRAPPER(THIS->getEntryByClusterOrder(TO_C(index))); } METHOD0(jobject, getMainEntry) { - return BUILD_WRAPPER("org/kiwix/libzim/Entry", THIS->getMainEntry()); + return BUILD_WRAPPER(THIS->getMainEntry()); } GETTER(jboolean, hasMainEntry) METHOD0(jobject, getRandomEntry) { - return BUILD_WRAPPER("org/kiwix/libzim/Entry", THIS->getRandomEntry()); + return BUILD_WRAPPER(THIS->getRandomEntry()); } GETTER(jboolean, hasFulltextIndex) @@ -192,62 +181,57 @@ GETTER(jboolean, hasNewNamespaceScheme) #define ITER_BY_PATH 0 #define ITER_BY_TITLE 1 #define ITER_EFFICIENT 2 + + +// No use of the macro BUILD_WRAPPER as `EntryIterator` takes a integer(I) to +// track the order. So the signature of the constructor is not the same. +// The same way, as we are building a iterator, it has two nativeHandle (for begin and end). METHOD0(jobject, iterByPath) { auto range = THIS->iterByPath(); - jclass objClass = env->FindClass("org/kiwix/libzim/EntryIterator"); - jmethodID initMethod = env->GetMethodID(objClass, "", "(I)V"); - jobject obj = env->NewObject(objClass, initMethod, ITER_BY_PATH); - SET_HANDLE(zim::Archive::iterator, obj, range.begin()); + auto beginIter = NEW_RESOURCE(range.begin()); + auto endIter = NEW_RESOURCE(range.end()); - auto end_ptr = std::make_shared>(range.end()); - setPtr(env, obj, std::move(end_ptr), "nativeHandleEnd"); - return obj; + jclass wrapperClass = env->FindClass("org/kiwix/libzim/EntryIterator"); + jmethodID initMethod = env->GetMethodID(wrapperClass, "", "(org/kiwix/Wrapper/Resource;org/kiwix/Wrapper/Resource)V"); + return env->NewObject(wrapperClass, initMethod, beginIter, endIter); } METHOD0(jobject, iterByTitle) { auto range = THIS->iterByTitle(); - jclass objClass = env->FindClass("org/kiwix/libzim/EntryIterator"); - jmethodID initMethod = env->GetMethodID(objClass, "", "(I)V"); - jobject obj = env->NewObject(objClass, initMethod, ITER_BY_TITLE); - SET_HANDLE(zim::Archive::iterator, obj, range.begin()); + auto beginIter = NEW_RESOURCE(range.begin()); + auto endIter = NEW_RESOURCE(range.end()); - auto end_ptr = std::make_shared>(range.end()); - setPtr(env, obj, std::move(end_ptr), "nativeHandleEnd"); - return obj; + jclass wrapperClass = env->FindClass("org/kiwix/libzim/EntryIterator"); + jmethodID initMethod = env->GetMethodID(wrapperClass, "", "(org/kiwix/Wrapper/Resource;org/kiwix/Wrapper/Resource)V"); + return env->NewObject(wrapperClass, initMethod, beginIter, endIter); } METHOD0(jobject, iterEfficient) { auto range = THIS->iterEfficient(); - jclass objClass = env->FindClass("org/kiwix/libzim/EntryIterator"); - jmethodID initMethod = env->GetMethodID(objClass, "", "(I)V"); - jobject obj = env->NewObject(objClass, initMethod, ITER_EFFICIENT); - SET_HANDLE(zim::Archive::iterator, obj, range.begin()); + auto beginIter = NEW_RESOURCE(range.begin()); + auto endIter = NEW_RESOURCE(range.end()); - auto end_ptr = std::make_shared>(range.end()); - setPtr(env, obj, std::move(end_ptr), "nativeHandleEnd"); - return obj; + jclass wrapperClass = env->FindClass("org/kiwix/libzim/EntryIterator"); + jmethodID initMethod = env->GetMethodID(wrapperClass, "", "(org/kiwix/Wrapper/Resource;org/kiwix/Wrapper/Resource)V"); + return env->NewObject(wrapperClass, initMethod, beginIter, endIter); } METHOD(jobject, findByPath, jstring path) { auto range = THIS->findByPath(TO_C(path)); - jclass objClass = env->FindClass("org/kiwix/libzim/EntryIterator"); - jmethodID initMethod = env->GetMethodID(objClass, "", "(I)V"); - jobject obj = env->NewObject(objClass, initMethod, ITER_BY_PATH); - SET_HANDLE(zim::Archive::iterator, obj, range.begin()); + auto beginIter = NEW_RESOURCE(range.begin()); + auto endIter = NEW_RESOURCE(range.end()); - auto end_ptr = std::make_shared>(range.end()); - setPtr(env, obj, std::move(end_ptr), "nativeHandleEnd"); - return obj; + jclass wrapperClass = env->FindClass("org/kiwix/libzim/EntryIterator"); + jmethodID initMethod = env->GetMethodID(wrapperClass, "", "(org/kiwix/Wrapper/Resource;org/kiwix/Wrapper/Resource)V"); + return env->NewObject(wrapperClass, initMethod, beginIter, endIter); } METHOD(jobject, findByTitle, jstring title) { auto range = THIS->findByTitle(TO_C(title)); - jclass objClass = env->FindClass("org/kiwix/libzim/EntryIterator"); - jmethodID initMethod = env->GetMethodID(objClass, "", "(I)V"); - jobject obj = env->NewObject(objClass, initMethod, ITER_BY_TITLE); - SET_HANDLE(zim::Archive::iterator, obj, range.begin()); - - auto end_ptr = std::make_shared>(range.end()); - setPtr(env, obj, std::move(end_ptr), "nativeHandleEnd"); - return obj; + auto beginIter = NEW_RESOURCE(range.begin()); + auto endIter = NEW_RESOURCE(range.end()); + + jclass wrapperClass = env->FindClass("org/kiwix/libzim/EntryIterator"); + jmethodID initMethod = env->GetMethodID(wrapperClass, "", "(org/kiwix/Wrapper/Resource;org/kiwix/Wrapper/Resource)V"); + return env->NewObject(wrapperClass, initMethod, beginIter, endIter); } diff --git a/lib/src/main/cpp/libzim/blob.cpp b/lib/src/main/cpp/libzim/blob.cpp index a197e11..4eee23d 100644 --- a/lib/src/main/cpp/libzim/blob.cpp +++ b/lib/src/main/cpp/libzim/blob.cpp @@ -33,8 +33,6 @@ #define TYPENAME libzim_Blob #include -DISPOSE - METHOD0(jstring, getData) { return TO_JNI(std::string(*THIS)); } diff --git a/lib/src/main/cpp/libzim/entry.cpp b/lib/src/main/cpp/libzim/entry.cpp index 2652e25..56022e3 100644 --- a/lib/src/main/cpp/libzim/entry.cpp +++ b/lib/src/main/cpp/libzim/entry.cpp @@ -34,20 +34,17 @@ #define TYPENAME libzim_Entry #include - -DISPOSE - GETTER(jboolean, isRedirect) GETTER(jstring, getTitle) GETTER(jstring, getPath) METHOD(jobject, getItem, jboolean follow) { - return BUILD_WRAPPER("org/kiwix/libzim/Item", THIS->getItem(TO_C(follow))); + return BUILD_WRAPPER(THIS->getItem(TO_C(follow))); } METHOD0(jobject, getRedirect) { - return BUILD_WRAPPER("org/kiwix/libzim/Item", THIS->getRedirect()); + return BUILD_WRAPPER(THIS->getRedirect()); } METHOD0(jobject, getRedirectEntry) { - return BUILD_WRAPPER("org/kiwix/libzim/Entry", THIS->getRedirectEntry()); + return BUILD_WRAPPER(THIS->getRedirectEntry()); } diff --git a/lib/src/main/cpp/libzim/entry_iterator.cpp b/lib/src/main/cpp/libzim/entry_iterator.cpp index 9f19d56..72fcc9f 100644 --- a/lib/src/main/cpp/libzim/entry_iterator.cpp +++ b/lib/src/main/cpp/libzim/entry_iterator.cpp @@ -43,44 +43,24 @@ inline int get_order(JNIEnv* env, jobject thisObj) { return TO_C(env->GetIntField(thisObj, fieldId)); } -METHOD0(void, dispose) -{ - // Delete end iterator - switch (get_order(env, thisObj)) { - case 0: - dispose(env, thisObj, "nativeHandleEnd"); - dispose(env, thisObj); - break; - case 1: - dispose(env, thisObj, "nativeHandleEnd"); - dispose(env, thisObj); - break; - case 2: - dispose(env, thisObj, "nativeHandleEnd"); - dispose(env, thisObj); - break; - } -} - - METHOD0(jboolean, hasNext) { switch (get_order(env, thisObj)) { case 0: { - PATH_NATIVE_TYPE next(*GET_PTR(PATH_NATIVE_TYPE)); + PATH_NATIVE_TYPE next(*getPtr(env, thisObj, "nativeResourceBegin")); next++; - auto end = getPtr(env, thisObj, "nativeHandleEnd"); + auto end = getPtr(env, thisObj, "nativeResourceEnd"); return next == *end; } case 1: { - TITLE_NATIVE_TYPE next(*GET_PTR(TITLE_NATIVE_TYPE)); + TITLE_NATIVE_TYPE next(*getPtr(env, thisObj, "nativeResourceBegin")); next++; - auto end = getPtr(env, thisObj, "nativeHandleEnd"); + auto end = getPtr(env, thisObj, "nativeResourceEnd"); return next == *end; } case 2: { - EFFICIENT_NATIVE_TYPE next(*GET_PTR(EFFICIENT_NATIVE_TYPE)); + EFFICIENT_NATIVE_TYPE next(*getPtr(env, thisObj, "nativeResourceBegin")); next++; - auto end = getPtr(env, thisObj, "nativeHandleEnd"); + auto end = getPtr(env, thisObj, "nativeResourceEnd"); return next == *end; } default: @@ -92,19 +72,19 @@ METHOD0(jboolean, hasNext) { METHOD0(jobject, next) { switch (get_order(env, thisObj)) { case 0: { - (*GET_PTR(PATH_NATIVE_TYPE))++; - zim::Entry entry = **GET_PTR(PATH_NATIVE_TYPE); - return BUILD_WRAPPER("org/kiwix/libzim/Entry", entry); + (*getPtr(env, thisObj, "nativeResourceBegin"))++; + zim::Entry entry = **getPtr(env, thisObj, "nativeResourceBegin"); + return BUILD_WRAPPER(entry); } case 1: { - (*GET_PTR(TITLE_NATIVE_TYPE))++; - zim::Entry entry = **GET_PTR(TITLE_NATIVE_TYPE); - return BUILD_WRAPPER("org/kiwix/libzim/Entry", entry); + (*getPtr(env, thisObj, "nativeResourceBegin"))++; + zim::Entry entry = **getPtr(env, thisObj, "nativeResourceBegin"); + return BUILD_WRAPPER(entry); } case 2: { - (*GET_PTR(EFFICIENT_NATIVE_TYPE))++; - zim::Entry entry = **GET_PTR(EFFICIENT_NATIVE_TYPE); - return BUILD_WRAPPER("org/kiwix/libzim/Entry", entry); + (*getPtr(env, thisObj, "nativeResourceBegin"))++; + zim::Entry entry = **getPtr(env, thisObj, "nativeResourceBegin"); + return BUILD_WRAPPER(entry); } default: // unreachable!() diff --git a/lib/src/main/cpp/libzim/item.cpp b/lib/src/main/cpp/libzim/item.cpp index 500797f..c8da5d1 100644 --- a/lib/src/main/cpp/libzim/item.cpp +++ b/lib/src/main/cpp/libzim/item.cpp @@ -33,21 +33,20 @@ #define TYPENAME libzim_Item #include -DISPOSE - GETTER(jstring, getTitle) GETTER(jstring, getPath) GETTER(jstring, getMimetype) METHOD0(jobject, getData) { - return BUILD_WRAPPER("org/kiwix/libzim/Blob", THIS->getData()); + return BUILD_WRAPPER(THIS->getData()); } GETTER(jlong, getSize) METHOD0(jobject, getDirectAccessInformation) { - jobject directObjInfo = newObject("org/kiwix/libzim/DirectAccessInfo", env); + //return BUILD_WRAPPER(THIS->getDirectAccessInformation()); + jobject directObjInfo = NEW_OBJECT("org/kiwix/libzim/DirectAccessInfo"); setDaiObjValue("", 0, directObjInfo, env); auto cDirectObjInfo = THIS->getDirectAccessInformation(); diff --git a/lib/src/main/cpp/libzim/query.cpp b/lib/src/main/cpp/libzim/query.cpp index 6117b4d..2804772 100644 --- a/lib/src/main/cpp/libzim/query.cpp +++ b/lib/src/main/cpp/libzim/query.cpp @@ -33,20 +33,11 @@ #define TYPENAME libzim_Query #include -METHOD(void, setNativeQuery, jstring query) +METHOD(jobject, buildNativeQuery, jstring query) { - auto cQuery = TO_C(query); - try { - auto query = std::make_shared(cQuery); - SET_PTR(query); - } catch (std::exception& e) { - LOG("Cannot create query"); - LOG("%s", e.what()); - } + return NEW_RESOURCE(std::make_shared(TO_C(query))); } -DISPOSE - METHOD(jobject, setQuery, jstring query) { THIS->setQuery(TO_C(query)); return thisObj; diff --git a/lib/src/main/cpp/libzim/search.cpp b/lib/src/main/cpp/libzim/search.cpp index 763bb2c..29777c9 100644 --- a/lib/src/main/cpp/libzim/search.cpp +++ b/lib/src/main/cpp/libzim/search.cpp @@ -33,17 +33,14 @@ #define TYPENAME libzim_Search #include -DISPOSE - METHOD(jobject, getResults, jint start, jint maxResults) { auto results = THIS->getResults(TO_C(start), TO_C(maxResults)); - auto obj = NEW_OBJECT("ork/kiwix/libzim/SearchIterator"); - SET_HANDLE(zim::SearchIterator, obj, results.begin()); + auto beginResource = NEW_RESOURCE(results.begin()); + auto endResource = NEW_RESOURCE(results.end()); - // We have to set the nativeHandleEnd but no macro ease our work here. - auto end_ptr = std::make_shared(results.end()); - setPtr(env, obj, std::move(end_ptr), "nativeHandleEnd"); - return obj; + jclass wrapperClass = env->FindClass("org/kiwix/libzim/SearchIterator"); + jmethodID initMethod = env->GetMethodID(wrapperClass, "", "(org/kiwix/Wrapper/Resource;org/kiwix/Wrapper/Resource)V"); + return env->NewObject(wrapperClass, initMethod, beginResource, endResource); } GETTER(jlong, getEstimatedMatches) diff --git a/lib/src/main/cpp/libzim/search_iterator.cpp b/lib/src/main/cpp/libzim/search_iterator.cpp index 6c04c7d..d0c064f 100644 --- a/lib/src/main/cpp/libzim/search_iterator.cpp +++ b/lib/src/main/cpp/libzim/search_iterator.cpp @@ -35,14 +35,6 @@ #include -// We cannot use the default macro to implement `dispose` as we need to delete the end handle -METHOD0(void, dispose) -{ - // Delete end iterator - dispose(env, thisObj, "nativeHandleEnd"); - dispose(env, thisObj); -} - GETTER(jstring, getPath) GETTER(jstring, getTitle) @@ -59,13 +51,13 @@ METHOD0(jstring, getZimId) { METHOD0(jboolean, hasNext) { zim::SearchIterator next(*THIS); next++; - auto end = getPtr(env, thisObj, "nativeHandleEnd"); + auto end = getPtr(env, thisObj, "nativeResourceEnd"); return next == *end; } METHOD0(jobject, next) { (*THIS)++; zim::Entry entry = **THIS; - return BUILD_WRAPPER("org/kiwix/libzim/Entry", entry); + return BUILD_WRAPPER(entry); } diff --git a/lib/src/main/cpp/libzim/searcher.cpp b/lib/src/main/cpp/libzim/searcher.cpp index 9810ba2..f6dd609 100644 --- a/lib/src/main/cpp/libzim/searcher.cpp +++ b/lib/src/main/cpp/libzim/searcher.cpp @@ -33,19 +33,14 @@ #define TYPENAME libzim_Searcher #include -METHOD(void, setNativeSearcher, jobject archive) +METHOD(jobject, buildNativeSearcher, jobject archive) { auto cArchive = getPtr(env, archive); - try { - auto searcher = std::make_shared(*cArchive); - SET_PTR(searcher); - } catch (std::exception& e) { - LOG("Cannot create searcher"); - LOG("%s", e.what()); - } + auto searcher = std::make_shared(*cArchive); + return NEW_RESOURCE(searcher); } -METHOD(void, setNativeSearcherMulti, jobjectArray archives) +METHOD(jobject, buildNativeSearcherMulti, jobjectArray archives) { std::vector cArchives; jsize nbArchives = env->GetArrayLength(archives); @@ -54,17 +49,10 @@ METHOD(void, setNativeSearcherMulti, jobjectArray archives) auto cArchive = getPtr(env, archive); cArchives.push_back(*cArchive); } - try { - auto searcher = std::make_shared(cArchives); - SET_PTR(searcher); - } catch (std::exception& e) { - LOG("Cannot create searcher"); - LOG("%s", e.what()); - } + auto searcher = std::make_shared(cArchives); + return NEW_RESOURCE(searcher); } -DISPOSE - METHOD(jobject, addArchive, jobject archive) { auto cArchive = getPtr(env, archive); THIS->addArchive(*cArchive); @@ -73,7 +61,7 @@ METHOD(jobject, addArchive, jobject archive) { METHOD(jobject, search, jobject query) { auto cQuery = getPtr(env, query); - return BUILD_WRAPPER("org/kiwix/libzim/Search", THIS->search(*cQuery)); + return BUILD_WRAPPER(THIS->search(*cQuery)); } METHOD(void, setVerbose, jboolean verbose) { diff --git a/lib/src/main/cpp/libzim/suggestion_item.cpp b/lib/src/main/cpp/libzim/suggestion_item.cpp index 35b1c4f..e550c7f 100644 --- a/lib/src/main/cpp/libzim/suggestion_item.cpp +++ b/lib/src/main/cpp/libzim/suggestion_item.cpp @@ -33,8 +33,6 @@ #define TYPENAME libzim_SuggestionItem #include -DISPOSE - GETTER(jstring, getTitle) GETTER(jstring, getPath) GETTER(jstring, getSnippet) diff --git a/lib/src/main/cpp/libzim/suggestion_iterator.cpp b/lib/src/main/cpp/libzim/suggestion_iterator.cpp index 5181ae1..a5334c6 100644 --- a/lib/src/main/cpp/libzim/suggestion_iterator.cpp +++ b/lib/src/main/cpp/libzim/suggestion_iterator.cpp @@ -33,24 +33,16 @@ #define TYPENAME libzim_SuggestionIterator #include -// We cannot use the default macro to implement `dispose` as we need to delete the end handle -METHOD0(void, dispose) -{ - // Delete end iterator - dispose(env, thisObj, "nativeHandleEnd"); - dispose(env, thisObj); -} - METHOD0(jboolean, hasNext) { NATIVE_TYPE next(*THIS); next++; - auto end = getPtr(env, thisObj, "nativeHandleEnd"); + auto end = getPtr(env, thisObj, "nativeResourceEnd"); return next == *end; } METHOD0(jobject, next) { (*THIS)++; zim::SuggestionItem item = **THIS; - return BUILD_WRAPPER("org/kiwix/libzim/SuggestionItem", item); + return BUILD_WRAPPER(item); } diff --git a/lib/src/main/cpp/libzim/suggestion_search.cpp b/lib/src/main/cpp/libzim/suggestion_search.cpp index 26fa783..66f121e 100644 --- a/lib/src/main/cpp/libzim/suggestion_search.cpp +++ b/lib/src/main/cpp/libzim/suggestion_search.cpp @@ -33,17 +33,14 @@ #define TYPENAME libzim_SuggestionSearch #include -DISPOSE - METHOD(jobject, getResults, jint start, jint maxResults) { auto results = THIS->getResults(TO_C(start), TO_C(maxResults)); - auto obj = NEW_OBJECT("ork/kiwix/libzim/SuggestionIterator"); - SET_HANDLE(zim::SuggestionIterator, obj, results.begin()); + auto beginResource = NEW_RESOURCE(results.begin()); + auto endResource = NEW_RESOURCE(results.end()); - // We have to set the nativeHandleEnd but no macro ease our work here. - auto end_ptr = std::make_shared(results.end()); - setPtr(env, obj, std::move(end_ptr), "nativeHandleEnd"); - return obj; + jclass wrapperClass = env->FindClass("org/kiwix/libzim/SuggestionIterator"); + jmethodID initMethod = env->GetMethodID(wrapperClass, "", "(org/kiwix/Wrapper/Resource;org/kiwix/Wrapper/Resource)V"); + return env->NewObject(wrapperClass, initMethod, beginResource, endResource); } GETTER(jlong, getEstimatedMatches) diff --git a/lib/src/main/cpp/libzim/suggestion_searcher.cpp b/lib/src/main/cpp/libzim/suggestion_searcher.cpp index 792447e..6949a1f 100644 --- a/lib/src/main/cpp/libzim/suggestion_searcher.cpp +++ b/lib/src/main/cpp/libzim/suggestion_searcher.cpp @@ -33,22 +33,16 @@ #include -METHOD(void, setNativeSearcher, jobject archive) +METHOD(jobject, buildNativeSearcher, jobject archive) { auto cArchive = getPtr(env, archive); - try { - auto searcher = std::make_shared(*cArchive); - SET_PTR(searcher); - } catch (std::exception& e) { - LOG("Cannot create searcher"); - LOG("%s", e.what()); - } + auto searcher = std::make_shared(*cArchive); + return NEW_RESOURCE(searcher); } -DISPOSE - METHOD(jobject, suggest, jstring query) { - return BUILD_WRAPPER("org/kiwix/libzim/SuggestionSearch", THIS->suggest(TO_C(query))); + //return BUILD_WRAPPER("org/kiwix/libzim/SuggestionSearch", THIS->suggest(TO_C(query))); + return BUILD_WRAPPER(std::make_shared(THIS->suggest(TO_C(query)))); } METHOD(void, setVerbose, jboolean verbose) { diff --git a/lib/src/main/cpp/macros.h b/lib/src/main/cpp/macros.h index bef647b..aea88e8 100644 --- a/lib/src/main/cpp/macros.h +++ b/lib/src/main/cpp/macros.h @@ -38,5 +38,3 @@ JNIEXPORT retType JNICALL BUILD_METHOD(TYPENAME ,name) ( \ #define GETTER(retType, name) METHOD0(retType, name) { \ return TO_JNI(THIS->name()); \ } - -#define DISPOSE METHOD0(void, dispose) { dispose(env, thisObj); } diff --git a/lib/src/main/cpp/utils.h b/lib/src/main/cpp/utils.h index 00529dd..39ed39b 100644 --- a/lib/src/main/cpp/utils.h +++ b/lib/src/main/cpp/utils.h @@ -37,8 +37,325 @@ #define LOG(...) #endif +#include +#include + using std::shared_ptr; +namespace zim { + class Blob; + class Searcher; + class Query; + class Search; + class SearchIterator; + class SuggestionSearcher; + class SuggestionSearch; + class SuggestionIterator; + class SuggestionItem; + + class Entry; + class Item; +} + +namespace kiwix { + class Library; + class Bookmark; + class Filter; + class Manager; + class Server; +} + +enum class type_id :int { + Archive, + Iterator_path, + Iterator_title, + Iterator_efficient, + Blob, + Searcher, + Query, + Search, + SearchIterator, + SuggestionSearcher, + SuggestionSearch, + SuggestionIterator, + SuggestionItem, + Entry, + Item, + + Library, + Filter, + Manager, + Server, + Book, + Bookmark, + ConstBook, + Illustration, + ConstIllustration +}; + +template +struct WrappedType { }; + +template<> struct WrappedType{ + static constexpr const type_id ID = type_id::Archive; + static constexpr const char* CLASS_NAME = "org/kiwix/libzim/Archive"; +}; + +template<> struct WrappedType>{ + static constexpr const type_id ID = type_id::Iterator_path; + //static constexpr const char* CLASS_NAME = "org/kiwix/libzim/Archive"; +}; + +template<> struct WrappedType>{ + static constexpr const type_id ID = type_id::Iterator_title; + //static constexpr const char* CLASS_NAME = "org/kiwix/libzim/Archive"; +}; + +template<> struct WrappedType>{ + static constexpr const type_id ID = type_id::Iterator_efficient; + //static constexpr const char* CLASS_NAME = "org/kiwix/libzim/Archive"; +}; + +template<> struct WrappedType{ + static constexpr const type_id ID = type_id::Blob; + static constexpr const char* const CLASS_NAME = "org/kiwix/libzim/Blob"; +}; + +template<> struct WrappedType{ + static constexpr const type_id ID = type_id::Searcher; + static constexpr const char* const CLASS_NAME = "org/kiwix/libzim/Searcher"; +}; + + +template<> struct WrappedType{ + static constexpr const type_id ID = type_id::Search; + static constexpr const char* const CLASS_NAME = "org/kiwix/libzim/Search"; +}; + +template<> struct WrappedType{ + static constexpr const type_id ID = type_id::Query; + static constexpr const char* const CLASS_NAME = "org/kiwix/libzim/Query"; +}; + +template<> struct WrappedType{ + static constexpr const type_id ID = type_id::SearchIterator; + //static constexpr const char* const CLASS_NAME = "org/kiwix/libzim/Search"; +}; + +template<> struct WrappedType{ + static constexpr const type_id ID = type_id::SuggestionSearcher; + static constexpr const char* const CLASS_NAME = "org/kiwix/libzim/SuggestionSearcher"; +}; + +template<> struct WrappedType{ + static constexpr const type_id ID = type_id::SuggestionSearch; + static constexpr const char* const CLASS_NAME = "org/kiwix/libzim/SuggestionSearch"; +}; + +template<> struct WrappedType{ + static constexpr const type_id ID = type_id::SuggestionIterator; + //static constexpr const char* const CLASS_NAME = "org/kiwix/libzim/SuggestionIterator"; +}; + +template<> struct WrappedType{ + static constexpr const type_id ID = type_id::SuggestionItem; + static constexpr const char* const CLASS_NAME = "org/kiwix/libzim/SuggestionItem"; +}; + +template<> struct WrappedType{ + static constexpr const type_id ID = type_id::Entry; + static constexpr const char* const CLASS_NAME = "org/kiwix/libzim/Entry"; +}; + +template<> struct WrappedType{ + static constexpr const type_id ID = type_id::Item; + static constexpr const char* const CLASS_NAME = "org/kiwix/libzim/Item"; +}; + + +template<> struct WrappedType{ + static constexpr const type_id ID = type_id::Library; + static constexpr const char* const CLASS_NAME = "org/kiwix/libkiwix/Library"; +}; + +template<> struct WrappedType{ + static constexpr const type_id ID = type_id::Bookmark; + static constexpr const char* const CLASS_NAME = "org/kiwix/libkiwix/Bookmark"; +}; + + +template<> struct WrappedType{ + static constexpr const type_id ID = type_id::Filter; + static constexpr const char* const CLASS_NAME = "org/kiwix/libkiwix/Filter"; +}; + +template<> struct WrappedType{ + static constexpr const type_id ID = type_id::Manager; + static constexpr const char* const CLASS_NAME = "org/kiwix/libkiwix/Manager"; +}; + +template<> struct WrappedType{ + static constexpr const type_id ID = type_id::Server; + static constexpr const char* const CLASS_NAME = "org/kiwix/libkiwix/Server"; +}; + +template<> struct WrappedType{ + static constexpr const type_id ID = type_id::Book; + static constexpr const char* const CLASS_NAME = "org/kiwix/libkiwix/Book"; +}; + +template<> struct WrappedType{ + static constexpr const type_id ID = type_id::ConstBook; + static constexpr const char* const CLASS_NAME = "org/kiwix/libkiwix/Book"; +}; + +template<> struct WrappedType{ + static constexpr const type_id ID = type_id::Illustration; + static constexpr const char* const CLASS_NAME = "org/kiwix/libkiwix/Illustration"; +}; + + +template<> struct WrappedType{ + static constexpr const type_id ID = type_id::ConstIllustration; + static constexpr const char* const CLASS_NAME = "org/kiwix/libkiwix/Illustration"; +}; + + +inline jfieldID getHandleField(JNIEnv* env, jobject obj, const char* handleName) +{ + jclass c = env->GetObjectClass(obj); + // J is the type signature for long: + return env->GetFieldID(c, handleName, "J"); +} + + +template +inline jobject newResource(JNIEnv* env, T&& reference) { + auto ptr = std::make_shared::type>(std::move(reference)); + return newResource(env, std::move(ptr)); +} + +template +inline jobject newResource(JNIEnv* env, shared_ptr&& ptr) { + jclass wrapperClass = env->FindClass("org/kiwix/Wrapper/Resource"); + jmethodID initMethod = env->GetMethodID(wrapperClass, "", "(IL)V"); + // allocate a shared_ptr on the head + shared_ptr* handle = new shared_ptr(ptr); + jobject wrapper = env->NewObject(wrapperClass, initMethod, static_cast(WrappedType::ID), reinterpret_cast(handle)); + return wrapper; +} +#define NEW_RESOURCE(SHARED_PTR) newResource(env, std::move(SHARED_PTR)); + + +inline void deleteResource(JNIEnv* env, jobject resource) { + jclass resourceClass = env->GetObjectClass(resource); + + jfieldID handleFieldId = env->GetFieldID(resourceClass, "nativeHandle", "J"); + auto handle_ptr = env->GetLongField(resource, handleFieldId); + + // We now need to know the type of the handle. + jfieldID typeFieldId = env->GetFieldID(resourceClass, "classid", "I"); + auto type_id = static_cast(env->GetIntField(resource, typeFieldId)); + + switch (type_id) { + case type_id::Archive: + delete reinterpret_cast*>(handle_ptr); + break; + case type_id::Iterator_path: + delete reinterpret_cast>*>(handle_ptr); + break; + case type_id::Iterator_title: + delete reinterpret_cast>*>(handle_ptr); + break; + case type_id::Iterator_efficient: + delete reinterpret_cast>*>(handle_ptr); + break; + case type_id::Blob: + delete reinterpret_cast*>(handle_ptr); + break; + case type_id::Searcher: + delete reinterpret_cast*>(handle_ptr); + break; + case type_id::Query: + delete reinterpret_cast*>(handle_ptr); + break; + case type_id::Search: + delete reinterpret_cast*>(handle_ptr); + break; + case type_id::SearchIterator: + delete reinterpret_cast*>(handle_ptr); + break; + case type_id::SuggestionSearcher: + delete reinterpret_cast*>(handle_ptr); + break; + case type_id::SuggestionSearch: + delete reinterpret_cast*>(handle_ptr); + break; + case type_id::SuggestionIterator: + delete reinterpret_cast*>(handle_ptr); + break; + case type_id::SuggestionItem: + delete reinterpret_cast*>(handle_ptr); + break; + case type_id::Entry: + delete reinterpret_cast*>(handle_ptr); + break; + case type_id::Item: + delete reinterpret_cast*>(handle_ptr); + break; + + case type_id::Library: + delete reinterpret_cast*>(handle_ptr); + break; + case type_id::Bookmark: + delete reinterpret_cast*>(handle_ptr); + break; + case type_id::Filter: + delete reinterpret_cast*>(handle_ptr); + break; + case type_id::Manager: + delete reinterpret_cast*>(handle_ptr); + break; + case type_id::Server: + delete reinterpret_cast*>(handle_ptr); + break; + case type_id::Book: + delete reinterpret_cast*>(handle_ptr); + break; + case type_id::ConstBook: + delete reinterpret_cast*>(handle_ptr); + break; + case type_id::Illustration: + delete reinterpret_cast*>(handle_ptr); + break; + case type_id::ConstIllustration: + delete reinterpret_cast*>(handle_ptr); + break; + }; +} + +template +shared_ptr getPtr(JNIEnv* env, jobject thisObj, const char* resourceField = "nativeResource") +{ + jclass thisClass = env->GetObjectClass(thisObj); + jfieldID resourceFieldId = env->GetFieldID(thisClass, resourceField, "org/kiwix/Wrapper/Resource"); + jobject resource = env->GetObjectField(thisObj, resourceFieldId); + + // This may be Wrapper.Resource or IterWrapper.Resource + jclass resourceClass = env->GetObjectClass(resource); + jfieldID handleFieldId = env->GetFieldID(resourceClass, "nativeHandle", "J"); + auto handle_ptr = env->GetLongField(resource, handleFieldId); + + // Let's check that asked type is same that the one registered in the resource. + jfieldID typeFieldId = env->GetFieldID(resourceClass, "classid", "I"); + auto type_id = static_cast(env->GetIntField(resource, typeFieldId)); + assert(type_id == WrappedType::ID); + + auto handle = reinterpret_cast*>(handle_ptr); + return *handle; +} + + // Here is the wrapping structure. // All java class wrapping a `Native` instance must contain a pointer (cast as a long (J)) called "nativeHandle". // They also need a constructor taking no argument (or they can, but helper here cannot be used.) @@ -58,9 +375,8 @@ inline jobject newObject(const char* className, JNIEnv* env) { } #define NEW_OBJECT(CLASSNAME) newObject(CLASSNAME, env) - // Set the pointer to the wrapped object. -template +/*template inline void setPtr(JNIEnv* env, jobject thisObj, shared_ptr&& ptr, const char* handleName = "nativeHandle") { jclass thisClass = env->GetObjectClass(thisObj); @@ -71,19 +387,20 @@ inline void setPtr(JNIEnv* env, jobject thisObj, shared_ptr&& ptr, const char shared_ptr* handle = new shared_ptr(ptr); env->SetLongField(thisObj, fieldId, reinterpret_cast(handle)); } -#define SET_PTR(SHARED_PTR) setPtr(env, thisObj, std::move(SHARED_PTR)) +#define SET_PTR(SHARED_PTR) setPtr(env, thisObj, std::move(SHARED_PTR))*/ // This create a object and set it in the wrapper -template +/*template inline void setHandle(JNIEnv* env, jobject thisObj, Args && ...args) { auto ptr = std::make_shared(std::forward(args)...); setPtr(env, thisObj, std::move(ptr)); } -#define SET_HANDLE(NATIVE_TYPE, OBJ, VALUE) setHandle(env, OBJ, VALUE) +#define SET_HANDLE(NATIVE_TYPE, OBJ, VALUE) setHandle(env, OBJ, VALUE)*/ // Return a shared_ptr for the handle +/* template shared_ptr getPtr(JNIEnv* env, jobject thisObj, const char* handleName = "nativeHandle") { @@ -92,7 +409,7 @@ shared_ptr getPtr(JNIEnv* env, jobject thisObj, const char* handleName = "nat auto handle = reinterpret_cast*>(env->GetLongField(thisObj, fidNumber)); return *handle; } -#define GET_PTR(NATIVE_TYPE) getPtr(env, thisObj) +#define GET_PTR(NATIVE_TYPE) getPtr(env, thisObj)*/ // Delete the heap allocated handle template @@ -107,12 +424,6 @@ void dispose(JNIEnv* env, jobject thisObj, const char* handleName = "nativeHandl env->SetLongField(thisObj, fieldId, 0); } -inline jfieldID getHandleField(JNIEnv* env, jobject obj, const char* handleName) -{ - jclass c = env->GetObjectClass(obj); - // J is the type signature for long: - return env->GetFieldID(c, handleName, "J"); -} inline jobjectArray createArray(JNIEnv* env, size_t length, const std::string& type_sig) { @@ -120,15 +431,28 @@ inline jobjectArray createArray(JNIEnv* env, size_t length, const std::string& t return env->NewObjectArray(length, c, NULL); } + + template -inline jobject buildWrapper(JNIEnv* env, const char* class_name, T&& obj, const char* handleName = "nativeHandle") { - auto wrapper = newObject(class_name, env); - auto ptr = std::make_shared(std::move(obj)); - setPtr(env, wrapper, std::move(ptr)); - return wrapper; +inline jobject buildWrapper(JNIEnv* env, std::shared_ptr&& ptr) { + auto resource = newResource(env, std::move(ptr)); + jclass wrapperClass = env->FindClass(WrappedType::CLASS_NAME); + jmethodID initMethod = env->GetMethodID(wrapperClass, "", "(org/kiwix/Wrapper/Resource)V"); + return env->NewObject(wrapperClass, initMethod, resource); } -#define BUILD_WRAPPER(CLASSNAME, OBJ) buildWrapper(env, CLASSNAME, std::move(OBJ)) +template +inline jobject buildWrapper(JNIEnv* env, T&& obj) { + auto resource = newResource(env, std::move(obj)); + jclass wrapperClass = env->FindClass(WrappedType::CLASS_NAME); + jmethodID initMethod = env->GetMethodID(wrapperClass, "", "(org/kiwix/Wrapper/Resource)V"); + return env->NewObject(wrapperClass, initMethod, resource); +} +#define BUILD_WRAPPER(OBJ) buildWrapper(env, std::move(OBJ)) +#define CATCH(MESSAGE) catch (...) { \ + jclass exceptionClass = env->FindClass("java/lang/RuntimeException"); \ + env->ThrowNew(exceptionClass, MESSAGE); \ +} // --------------------------------------------------------------------------- diff --git a/lib/src/main/cpp/wrapper.cpp b/lib/src/main/cpp/wrapper.cpp new file mode 100644 index 0000000..af1599a --- /dev/null +++ b/lib/src/main/cpp/wrapper.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2013 Emmanuel Engelhart + * Copyright (C) 2017 Matthieu Gautier + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include +#include +#include "org_kiwix_Wrapper_Resource.h" +#include "org_kiwix_IterWrapper_Resource.h" + +#include + +#include + +#include + +#define CLASSNAME "org/kiwix/Wrapper" +#define TYPENAME libzim_Item +#include + +/* + * Class: org_kiwix_Wrapper_Resource + * Method: dispose + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_org_kiwix_Wrapper_00024Resource_dispose + (JNIEnv *env, jobject resource) { + deleteResource(env, resource); +} + + +/* + * Class: org_kiwix_IterWrapper_Resource + * Method: dispose + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_org_kiwix_IterWrapper_00024Resource_dispose + (JNIEnv *env , jobject resource) { + deleteResource(env, resource); +} diff --git a/lib/src/main/java/org/kiwix/IterWrapper.java b/lib/src/main/java/org/kiwix/IterWrapper.java new file mode 100644 index 0000000..9a9ea2b --- /dev/null +++ b/lib/src/main/java/org/kiwix/IterWrapper.java @@ -0,0 +1,46 @@ + +package org.kiwix; + +import java.lang.ref.Cleaner; + +public class IterWrapper implements AutoCloseable { + private static final Cleaner cleaner = Cleaner.create(); + protected static class Resource implements Runnable { + Resource(int classid, long nativeHandle) { + this.classid = classid; + this.nativeHandle = nativeHandle; + } + + public void run() { + dispose(); + } + // The pointer (as a long) to the native handle (the shared_ptr) + private long nativeHandle; + + // The name of the class. + // We need it to cast our pointer to the right type. + private int classid; + + // The native method wich will actually delete the cpp resource. + private native void dispose(); + } + + + private final Resource nativeResourceBegin; + private final Cleaner.Cleanable cleanableBegin; + + private final Resource nativeResourceEnd; + private final Cleaner.Cleanable cleanableEnd; + + public IterWrapper(Resource resourceBegin, Resource resourceEnd) { + this.nativeResourceBegin = resourceBegin; + this.cleanableBegin = cleaner.register(this, nativeResourceBegin); + this.nativeResourceEnd = resourceEnd; + this.cleanableEnd = cleaner.register(this, nativeResourceEnd); + } + + public void close() { + cleanableBegin.clean(); + cleanableEnd.clean(); + } +} diff --git a/lib/src/main/java/org/kiwix/Wrapper.java b/lib/src/main/java/org/kiwix/Wrapper.java new file mode 100644 index 0000000..22b2ce9 --- /dev/null +++ b/lib/src/main/java/org/kiwix/Wrapper.java @@ -0,0 +1,40 @@ + +package org.kiwix; + +import java.lang.ref.Cleaner; + +public class Wrapper implements AutoCloseable { + private static final Cleaner cleaner = Cleaner.create(); + protected static class Resource implements Runnable { + Resource(int classid, long nativeHandle) { + this.classid = classid; + this.nativeHandle = nativeHandle; + } + + public void run() { + dispose(); + } + // The pointer (as a long) to the native handle (the shared_ptr) + private long nativeHandle; + + // The name of the class. + // We need it to cast our pointer to the right type. + private int classid; + + // The native method wich will actually delete the cpp resource. + private native void dispose(); + } + + + private final Resource nativeResource; + private final Cleaner.Cleanable cleanable; + + public Wrapper(Resource resource) { + this.nativeResource = resource; + this.cleanable = cleaner.register(this, nativeResource); + } + + public void close() { + cleanable.clean(); + } +} diff --git a/lib/src/main/java/org/kiwix/libkiwix/Book.java b/lib/src/main/java/org/kiwix/libkiwix/Book.java index a7ddc88..ab6e0ff 100644 --- a/lib/src/main/java/org/kiwix/libkiwix/Book.java +++ b/lib/src/main/java/org/kiwix/libkiwix/Book.java @@ -3,19 +3,15 @@ import org.kiwix.libzim.Archive; import org.kiwix.libkiwix.Illustration; +import org.kiwix.Wrapper; -public class Book +public class Book extends Wrapper { - public Book() { allocate(); } - + public Book(Wrapper.Resource res) { super(res); } public native void update(Book book); public native void update(Archive archive); - - @Override - protected void finalize() { dispose(); } - public native String getId(); public native String getPath(); public native String getHumanReadableIdFromPath(); @@ -45,8 +41,4 @@ public class Book public native Illustration[] getIllustrations(); public native Illustration getIllustration(int size); - - private native void allocate(); - private native void dispose(); - private long nativeHandle; } diff --git a/lib/src/main/java/org/kiwix/libkiwix/Bookmark.java b/lib/src/main/java/org/kiwix/libkiwix/Bookmark.java index a6c1d4c..ccdacb2 100644 --- a/lib/src/main/java/org/kiwix/libkiwix/Bookmark.java +++ b/lib/src/main/java/org/kiwix/libkiwix/Bookmark.java @@ -19,10 +19,12 @@ package org.kiwix.libkiwix; -public class Bookmark +import org.kiwix.Wrapper; + +public class Bookmark extends Wrapper { public Bookmark() { - setNativeBookmark(); + super(buildNativeBookmark()); } public native void setBookId(String bookId); @@ -39,15 +41,6 @@ public Bookmark() { public native String getLanguage(); public native String getDate(); - @Override - protected void finalize() { dispose(); } - - -///--------- The wrapper thing - // To delete our native wrapper - public native void dispose(); - // A pointer (as a long) to a native Handle - private native void setNativeBookmark(); - private long nativeHandle; + private native static Wrapper.Resource buildNativeBookmark(); } diff --git a/lib/src/main/java/org/kiwix/libkiwix/Filter.java b/lib/src/main/java/org/kiwix/libkiwix/Filter.java index 458856d..d43a35e 100644 --- a/lib/src/main/java/org/kiwix/libkiwix/Filter.java +++ b/lib/src/main/java/org/kiwix/libkiwix/Filter.java @@ -19,8 +19,13 @@ package org.kiwix.libkiwix; -public class Filter +import org.kiwix.Wrapper; + +public class Filter extends Wrapper { + public Filter() { + super(getNativeFilter()); + } public native Filter local(boolean accept); public native Filter remote(boolean accept); @@ -33,12 +38,5 @@ public class Filter public native Filter maxSize(long size); public native Filter query(String query); - - public Filter() { allocate(); } - - @Override - protected void finalize() { dispose(); } - private native void allocate(); - private native void dispose(); - private long nativeHandle; + private native static Wrapper.Resource getNativeFilter(); } diff --git a/lib/src/main/java/org/kiwix/libkiwix/Illustration.java b/lib/src/main/java/org/kiwix/libkiwix/Illustration.java index 771a4e2..c369b87 100644 --- a/lib/src/main/java/org/kiwix/libkiwix/Illustration.java +++ b/lib/src/main/java/org/kiwix/libkiwix/Illustration.java @@ -1,7 +1,8 @@ package org.kiwix.libkiwix; +import org.kiwix.Wrapper; -public class Illustration +public class Illustration extends Wrapper { public native int width(); public native int height(); @@ -9,9 +10,7 @@ public class Illustration public native String url(); public native String getData(); - @Override - protected void finalize() { dispose(); } - private native void dispose(); - private long nativeHandle; + + private Illustration(Wrapper.Resource res) { super(res); } } diff --git a/lib/src/main/java/org/kiwix/libkiwix/Library.java b/lib/src/main/java/org/kiwix/libkiwix/Library.java index e9f4c47..9497b73 100644 --- a/lib/src/main/java/org/kiwix/libkiwix/Library.java +++ b/lib/src/main/java/org/kiwix/libkiwix/Library.java @@ -24,12 +24,13 @@ import org.kiwix.libkiwix.Book; import org.kiwix.libkiwix.JNIKiwixException; import org.kiwix.libkiwix.Bookmark; +import org.kiwix.Wrapper; -public class Library +public class Library extends Wrapper { public Library() { - setNativeHandler(); + super(buildNativeLibrary()); } public native boolean addBook(Book book) throws JNIKiwixException; @@ -58,9 +59,5 @@ public Library() public native boolean removeBookmark(String zimId, String url); public native Bookmark[] getBookmarks(boolean onlyValidBookmarks); - @Override - protected void finalize() { dispose(); } - private native void setNativeHandler(); - private native void dispose(); - private long nativeHandle; + private native static Wrapper.Resource buildNativeLibrary(); } diff --git a/lib/src/main/java/org/kiwix/libkiwix/Manager.java b/lib/src/main/java/org/kiwix/libkiwix/Manager.java index 5ddbc08..afbb83f 100644 --- a/lib/src/main/java/org/kiwix/libkiwix/Manager.java +++ b/lib/src/main/java/org/kiwix/libkiwix/Manager.java @@ -20,8 +20,9 @@ package org.kiwix.libkiwix; import org.kiwix.libkiwix.Library; +import org.kiwix.Wrapper; -public class Manager +public class Manager extends Wrapper { /** * Read a `library.xml` file and add books in the library. @@ -76,15 +77,11 @@ public native String addBookFromPath(String pathToOpen, boolean checkMetaData); public Manager(Library library) { - allocate(library); + super(buildNativeManager(library)); _library = library; } private Library _library; - @Override - protected void finalize() { dispose(); } - private native void allocate(Library library); - private native void dispose(); - private long nativeHandle; + private native static Wrapper.Resource buildNativeManager(Library library); } diff --git a/lib/src/main/java/org/kiwix/libkiwix/Server.java b/lib/src/main/java/org/kiwix/libkiwix/Server.java index b8b5a78..4dadb83 100644 --- a/lib/src/main/java/org/kiwix/libkiwix/Server.java +++ b/lib/src/main/java/org/kiwix/libkiwix/Server.java @@ -21,8 +21,9 @@ import org.kiwix.libkiwix.JNIKiwixException; import org.kiwix.libkiwix.Library; +import org.kiwix.Wrapper; -public class Server +public class Server extends Wrapper { public native void setRoot(String root); @@ -42,14 +43,8 @@ public class Server public Server(Library library) { - setNativeServer(library); + super(buildNativeServer(library)); } - @Override - protected void finalize() { dispose(); } - - - private native void setNativeServer(Library library); - private native void dispose(); - private long nativeHandle; + private native static Wrapper.Resource buildNativeServer(Library library); } diff --git a/lib/src/main/java/org/kiwix/libzim/Archive.java b/lib/src/main/java/org/kiwix/libzim/Archive.java index 735cc79..f88c61c 100644 --- a/lib/src/main/java/org/kiwix/libzim/Archive.java +++ b/lib/src/main/java/org/kiwix/libzim/Archive.java @@ -23,34 +23,26 @@ import org.kiwix.libzim.Entry; import org.kiwix.libzim.Item; import org.kiwix.libzim.EntryIterator; +import org.kiwix.Wrapper; import java.io.FileDescriptor; -public class Archive +public class Archive extends Wrapper { public Archive(String filename) throws ZimFileFormatException { - setNativeArchive(filename); - if (nativeHandle == 0) { - throw new ZimFileFormatException("Cannot open zimfile "+filename); - } + super(buildNativeArchive(filename)); } public Archive(FileDescriptor fd) throws ZimFileFormatException { - setNativeArchiveByFD(fd); - if (nativeHandle == 0) { - throw new ZimFileFormatException("Cannot open zimfile by fd "+fd.toString()); - } + super(buildNativeArchiveByFD(fd)); } public Archive(FileDescriptor fd, long offset, long size) throws ZimFileFormatException { - setNativeArchiveEmbedded(fd, offset, size); - if (nativeHandle == 0) { - throw new ZimFileFormatException(String.format("Cannot open embedded zimfile (fd=%s, offset=%d, size=%d)", fd, offset, size)); - } + super(buildNativeArchiveEmbedded(fd, offset, size)); } public native String getFilename(); @@ -100,18 +92,7 @@ public Archive(FileDescriptor fd, long offset, long size) public native EntryIterator findByTitle(String path); - private native void setNativeArchive(String filename); - private native void setNativeArchiveByFD(FileDescriptor fd); - private native void setNativeArchiveEmbedded(FileDescriptor fd, long offset, long size); - - @Override - protected void finalize() { dispose(); } - - -///--------- The wrapper thing - // To delete our native wrapper - public native void dispose(); - - // A pointer (as a long) to a native Handle - private long nativeHandle; + private native static Wrapper.Resource buildNativeArchive(String filename); + private native static Wrapper.Resource buildNativeArchiveByFD(FileDescriptor fd); + private native static Wrapper.Resource buildNativeArchiveEmbedded(FileDescriptor fd, long offset, long size); } diff --git a/lib/src/main/java/org/kiwix/libzim/Blob.java b/lib/src/main/java/org/kiwix/libzim/Blob.java index 93852f2..a8470eb 100644 --- a/lib/src/main/java/org/kiwix/libzim/Blob.java +++ b/lib/src/main/java/org/kiwix/libzim/Blob.java @@ -20,21 +20,13 @@ package org.kiwix.libzim; import org.kiwix.libzim.Blob; +import org.kiwix.Wrapper; -public class Blob +public class Blob extends Wrapper { + private Blob(Wrapper.Resource res) { + super(res); + } public native String getData(); public native long size(); - - - @Override - protected void finalize() { dispose(); } - - -///--------- The wrapper thing - // To delete our native wrapper - public native void dispose(); - - // A pointer (as a long) to a native Handle - private long nativeHandle; } diff --git a/lib/src/main/java/org/kiwix/libzim/Entry.java b/lib/src/main/java/org/kiwix/libzim/Entry.java index 052a9df..e3e2e1f 100644 --- a/lib/src/main/java/org/kiwix/libzim/Entry.java +++ b/lib/src/main/java/org/kiwix/libzim/Entry.java @@ -20,9 +20,13 @@ package org.kiwix.libzim; import org.kiwix.libzim.Item; +import org.kiwix.Wrapper; -public class Entry +public class Entry extends Wrapper { + private Entry(Wrapper.Resource res) { + super(res); + } public native boolean isRedirect(); public native String getTitle(); public native String getPath(); @@ -30,14 +34,4 @@ public class Entry public native Item getItem(boolean follow); public native Item getRedirect(); public native Entry getRedirectEntry(); - - @Override - protected void finalize() { dispose(); } - -///--------- The wrapper thing - // To delete our native wrapper - private native void dispose(); - - // A pointer (as a long) to a native Handle - private long nativeHandle; } diff --git a/lib/src/main/java/org/kiwix/libzim/EntryIterator.java b/lib/src/main/java/org/kiwix/libzim/EntryIterator.java index b072de1..7214cdc 100644 --- a/lib/src/main/java/org/kiwix/libzim/EntryIterator.java +++ b/lib/src/main/java/org/kiwix/libzim/EntryIterator.java @@ -20,29 +20,17 @@ package org.kiwix.libzim; import java.util.Iterator; +import org.kiwix.IterWrapper; -public class EntryIterator implements Iterator +public class EntryIterator extends IterWrapper implements Iterator { - private EntryIterator(int order) { + private EntryIterator(int order, Resource nativeResourceBegin, Resource nativeResourceEnd) { + super(nativeResourceBegin, nativeResourceEnd); this.order = order; } public native boolean hasNext(); public native Entry next(); - @Override - protected void finalize() { dispose(); } - - -///--------- The wrapper thing - // To delete our native wrapper - public native void dispose(); - // A marker of the order used for this iterator private int order; - - // A pointer (as a long) to a native Handle - private long nativeHandle; - - // A pointer (as a long) to the native end - private long nativeHandleEnd; } diff --git a/lib/src/main/java/org/kiwix/libzim/Item.java b/lib/src/main/java/org/kiwix/libzim/Item.java index 2b59b82..19f0ac4 100644 --- a/lib/src/main/java/org/kiwix/libzim/Item.java +++ b/lib/src/main/java/org/kiwix/libzim/Item.java @@ -21,9 +21,13 @@ import org.kiwix.libzim.Blob; import org.kiwix.libzim.DirectAccessInfo; +import org.kiwix.Wrapper; -public class Item +public class Item extends Wrapper { + private Item(Wrapper.Resource res) { + super(res); + } public native String getTitle(); public native String getPath(); public native String getMimetype(); @@ -32,14 +36,4 @@ public class Item public native long getSize(); public native DirectAccessInfo getDirectAccessInformation(); - - @Override - protected void finalize() { dispose(); } - -///--------- The wrapper thing - // To delete our native wrapper - private native void dispose(); - - // A pointer (as a long) to a native Handle - private long nativeHandle; } diff --git a/lib/src/main/java/org/kiwix/libzim/Query.java b/lib/src/main/java/org/kiwix/libzim/Query.java index 75599b5..ff117b1 100644 --- a/lib/src/main/java/org/kiwix/libzim/Query.java +++ b/lib/src/main/java/org/kiwix/libzim/Query.java @@ -19,24 +19,15 @@ package org.kiwix.libzim; -public class Query +import org.kiwix.Wrapper; + +public class Query extends Wrapper { public Query(String query) { - setNativeQuery(query); + super(buildNativeQuery(query)); } public native Query setQuery(String query); public native Query setGeorange(float latitude, float longitute, float distance); - - @Override - protected void finalize() { dispose(); } - - -///--------- The wrapper thing - // To delete our native wrapper - public native void dispose(); - - // A pointer (as a long) to a native Handle - private native long setNativeQuery(String query); - private long nativeHandle; + private native static Wrapper.Resource buildNativeQuery(String query); } diff --git a/lib/src/main/java/org/kiwix/libzim/Search.java b/lib/src/main/java/org/kiwix/libzim/Search.java index d078886..6f05906 100644 --- a/lib/src/main/java/org/kiwix/libzim/Search.java +++ b/lib/src/main/java/org/kiwix/libzim/Search.java @@ -20,20 +20,13 @@ package org.kiwix.libzim; import org.kiwix.libzim.SearchIterator; +import org.kiwix.Wrapper; -public class Search +public class Search extends Wrapper { + private Search(Wrapper.Resource res) { + super(res); + } public native SearchIterator getResults(int start, int maxResults); public native long getEstimatedMatches(); - - @Override - protected void finalize() { dispose(); } - - -///--------- The wrapper thing - // To delete our native wrapper - public native void dispose(); - - // A pointer (as a long) to a native Handle - private long nativeHandle; } diff --git a/lib/src/main/java/org/kiwix/libzim/SearchIterator.java b/lib/src/main/java/org/kiwix/libzim/SearchIterator.java index 0a73912..b84a3ff 100644 --- a/lib/src/main/java/org/kiwix/libzim/SearchIterator.java +++ b/lib/src/main/java/org/kiwix/libzim/SearchIterator.java @@ -35,18 +35,4 @@ public class SearchIterator implements Iterator public native boolean hasNext(); public native Entry next(); - - - @Override - protected void finalize() { dispose(); } - -///--------- The wrapper thing - // To delete our native wrapper - public native void dispose(); - - // A pointer (as a long) to a native Handle - private long nativeHandle; - - // A pointer (as a long) to the native end - private long nativeHandleEnd; } diff --git a/lib/src/main/java/org/kiwix/libzim/Searcher.java b/lib/src/main/java/org/kiwix/libzim/Searcher.java index cd3c4d6..33d973f 100644 --- a/lib/src/main/java/org/kiwix/libzim/Searcher.java +++ b/lib/src/main/java/org/kiwix/libzim/Searcher.java @@ -24,41 +24,25 @@ import org.kiwix.libzim.Search; import org.kiwix.libzim.Query; import java.io.FileDescriptor; +import org.kiwix.Wrapper; -public class Searcher +public class Searcher extends Wrapper { public Searcher(Archive archive) throws Exception { - setNativeSearcher(archive); - if (nativeHandle == 0) { - throw new Exception("Cannot create searcher"); - } + super(buildNativeSearcher(archive)); } public Searcher(Archive[] archives) throws Exception { - setNativeSearcherMulti(archives); - if (nativeHandle == 0) { - throw new Exception("Cannot create searcher"); - } + super(buildNativeSearcherMulti(archives)); } public native Searcher addArchive(Archive archive); public native Search search(Query query); public native void setVerbose(boolean verbose); - private native void setNativeSearcher(Archive archive); - private native void setNativeSearcherMulti(Archive[] archives); - - @Override - protected void finalize() { dispose(); } - - -///--------- The wrapper thing - // To delete our native wrapper - public native void dispose(); - - // A pointer (as a long) to a native Handle - private long nativeHandle; + private native static Wrapper.Resource buildNativeSearcher(Archive archive); + private native static Wrapper.Resource buildNativeSearcherMulti(Archive[] archives); } diff --git a/lib/src/main/java/org/kiwix/libzim/SuggestionItem.java b/lib/src/main/java/org/kiwix/libzim/SuggestionItem.java index 4021cd4..d7f1af1 100644 --- a/lib/src/main/java/org/kiwix/libzim/SuggestionItem.java +++ b/lib/src/main/java/org/kiwix/libzim/SuggestionItem.java @@ -18,21 +18,14 @@ */ package org.kiwix.libzim; +import org.kiwix.Wrapper; -public class SuggestionItem +public class SuggestionItem extends Wrapper { public native String getTitle(); public native String getPath(); public native String getSnippet(); public native boolean hasSnippet(); - @Override - protected void finalize() { dispose(); } - -///--------- The wrapper thing - // To delete our native wrapper - private native void dispose(); - - // A pointer (as a long) to a native Handle - private long nativeHandle; + private SuggestionItem(Wrapper.Resource res) { super(res); } } diff --git a/lib/src/main/java/org/kiwix/libzim/SuggestionIterator.java b/lib/src/main/java/org/kiwix/libzim/SuggestionIterator.java index 20d0298..8ed2e55 100644 --- a/lib/src/main/java/org/kiwix/libzim/SuggestionIterator.java +++ b/lib/src/main/java/org/kiwix/libzim/SuggestionIterator.java @@ -20,24 +20,13 @@ package org.kiwix.libzim; import org.kiwix.libzim.SuggestionItem; +import org.kiwix.IterWrapper; import java.util.Iterator; -public class SuggestionIterator implements Iterator +public class SuggestionIterator extends IterWrapper implements Iterator { public native boolean hasNext(); public native SuggestionItem next(); - @Override - protected void finalize() { dispose(); } - - -///--------- The wrapper thing - // To delete our native wrapper - public native void dispose(); - - // A pointer (as a long) to a native Handle - private long nativeHandle; - - // A pointer (as a long) to the native end - private long nativeHandleEnd; + private SuggestionIterator(IterWrapper.Resource begin, IterWrapper.Resource end) { super(begin, end); } } diff --git a/lib/src/main/java/org/kiwix/libzim/SuggestionSearch.java b/lib/src/main/java/org/kiwix/libzim/SuggestionSearch.java index 5d2976b..9a03991 100644 --- a/lib/src/main/java/org/kiwix/libzim/SuggestionSearch.java +++ b/lib/src/main/java/org/kiwix/libzim/SuggestionSearch.java @@ -20,20 +20,12 @@ package org.kiwix.libzim; import org.kiwix.libzim.SuggestionIterator; +import org.kiwix.Wrapper; -public class SuggestionSearch +public class SuggestionSearch extends Wrapper { public native SuggestionIterator getResults(int start, int maxResults); public native long getEstimatedMatches(); - - @Override - protected void finalize() { dispose(); } - -///--------- The wrapper thing - // To delete our native wrapper - public native void dispose(); - - // A pointer (as a long) to a native Handle - private long nativeHandle; + private SuggestionSearch(Wrapper.Resource res) { super(res); } } diff --git a/lib/src/main/java/org/kiwix/libzim/SuggestionSearcher.java b/lib/src/main/java/org/kiwix/libzim/SuggestionSearcher.java index c45961e..a103002 100644 --- a/lib/src/main/java/org/kiwix/libzim/SuggestionSearcher.java +++ b/lib/src/main/java/org/kiwix/libzim/SuggestionSearcher.java @@ -23,31 +23,18 @@ import org.kiwix.libzim.Archive; import org.kiwix.libzim.SuggestionSearch; import java.io.FileDescriptor; +import org.kiwix.Wrapper; -public class SuggestionSearcher +public class SuggestionSearcher extends Wrapper { public SuggestionSearcher(Archive archive) throws Exception { - setNativeSearcher(archive); - if (nativeHandle == 0) { - throw new Exception("Cannot create searcher"); - } + super(buildNativeSearcher(archive)); } public native SuggestionSearch suggest(String query); public native void setVerbose(boolean verbose); - private native void setNativeSearcher(Archive archive); - - - @Override - protected void finalize() { dispose(); } - -///--------- The wrapper thing - // To delete our native wrapper - public native void dispose(); - - // A pointer (as a long) to a native Handle - private long nativeHandle; + private native static Wrapper.Resource buildNativeSearcher(Archive archive); }