diff --git a/android-kiwix-lib-publisher/kiwixLibAndroid/src/main/AndroidManifest.xml b/android-kiwix-lib-publisher/kiwixLibAndroid/src/main/AndroidManifest.xml index b32776b..e9b809a 100644 --- a/android-kiwix-lib-publisher/kiwixLibAndroid/src/main/AndroidManifest.xml +++ b/android-kiwix-lib-publisher/kiwixLibAndroid/src/main/AndroidManifest.xml @@ -1,5 +1,5 @@ + package="org.kiwix.kiwixlib"> + + + + + + diff --git a/src/wrapper/java/book.cpp b/src/wrapper/java/book.cpp new file mode 100644 index 0000000..b76492c --- /dev/null +++ b/src/wrapper/java/book.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2020 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 "org_kiwix_kiwixlib_Book.h" + +#include "utils.h" +#include "book.h" + +JNIEXPORT void JNICALL +Java_org_kiwix_kiwixlib_Book_allocate( + JNIEnv* env, jobject thisObj) +{ + allocate(env, thisObj); +} + +JNIEXPORT void JNICALL +Java_org_kiwix_kiwixlib_Book_dispose(JNIEnv* env, jobject thisObj) +{ + dispose(env, thisObj); +} + +#define BOOK (getPtr(env, thisObj)) + +#define GETTER(retType, name) JNIEXPORT retType JNICALL \ +Java_org_kiwix_kiwixlib_Book_##name (JNIEnv* env, jobject thisObj) \ +{ \ + auto cRet = BOOK->name(); \ + retType ret = c2jni(cRet, env); \ + return ret; \ +} + +GETTER(jstring, getId) +GETTER(jstring, getPath) +GETTER(jboolean, isPathValid) +GETTER(jstring, getTitle) +GETTER(jstring, getDescription) +GETTER(jstring, getLanguage) +GETTER(jstring, getCreator) +GETTER(jstring, getPublisher) +GETTER(jstring, getDate) +GETTER(jstring, getUrl) +GETTER(jstring, getName) +GETTER(jstring, getTags) +GETTER(jlong, getArticleCount) +GETTER(jlong, getMediaCount) +GETTER(jlong, getSize) +GETTER(jstring, getFavicon) +GETTER(jstring, getFaviconUrl) +GETTER(jstring, getFaviconMimeType) + +#undef GETTER diff --git a/src/wrapper/java/filter.cpp b/src/wrapper/java/filter.cpp new file mode 100644 index 0000000..09c0734 --- /dev/null +++ b/src/wrapper/java/filter.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2019-2020 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 "org_kiwix_kiwixlib_Filter.h" + +#include "library.h" +#include "utils.h" + +/* Kiwix Reader JNI functions */ +METHOD0(void, Filter, allocate) { + allocate(env, thisObj); +} + +METHOD0(void, Filter, dispose) { + dispose(env, thisObj); +} + +#define FILTER (getPtr(env, thisObj)) + +#define FORWARD(name, args_type) \ +METHOD(jobject, Filter, name, args_type value) { \ + FILTER->name(jni2c(value, env)); \ + return thisObj; \ +} + +#define FORWARDA(name, args_type) \ +METHOD(jobject, Filter, name, jobjectArray value) { \ + FILTER->name(jni2c(value, env)); \ + return thisObj; \ +} + + + +FORWARD(local, jboolean) +FORWARD(remote, jboolean) +FORWARD(valid, jboolean) +FORWARDA(acceptTags, jstring) +FORWARDA(rejectTags, jstring) +FORWARD(lang, jstring) +FORWARD(publisher, jstring) +FORWARD(creator, jstring) +FORWARD(maxSize, jlong) +FORWARD(query, jstring) + + diff --git a/src/wrapper/java/kiwixicu.cpp b/src/wrapper/java/kiwixicu.cpp new file mode 100644 index 0000000..0c604eb --- /dev/null +++ b/src/wrapper/java/kiwixicu.cpp @@ -0,0 +1,48 @@ +/* + * 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 "org_kiwix_kiwixlib_JNIICU.h" + +#include +#include + +#include "unicode/putil.h" + +#include "utils.h" + +#if __ANDROID__ +pthread_mutex_t globalLock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER; +#else +pthread_mutex_t globalLock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; +#endif + +JNIEXPORT void JNICALL Java_org_kiwix_kiwixlib_JNIICU_setDataDirectory( + JNIEnv* env, jclass kclass, jstring dirStr) +{ + std::string cPath = jni2c(dirStr, env); + + Lock l; + try { + u_setDataDirectory(cPath.c_str()); + } catch (...) { + std::cerr << "Unable to set data directory " << cPath << std::endl; + } +} diff --git a/src/wrapper/java/kiwixreader.cpp b/src/wrapper/java/kiwixreader.cpp new file mode 100644 index 0000000..7bc61eb --- /dev/null +++ b/src/wrapper/java/kiwixreader.cpp @@ -0,0 +1,473 @@ +/* + * 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_kiwixlib_JNIKiwixReader.h" + +#include "tools/base64.h" +#include "reader.h" +#include "utils.h" + +/* Kiwix Reader JNI functions */ +JNIEXPORT jlong JNICALL Java_org_kiwix_kiwixlib_JNIKiwixReader_getNativeReader( + JNIEnv* env, jobject obj, jstring filename) +{ + std::string cPath = jni2c(filename, env); + + LOG("Attempting to create reader with: %s", cPath.c_str()); + Lock l; + try { + kiwix::Reader* reader = new kiwix::Reader(cPath); + return reinterpret_cast(new Handle(reader)); + } catch (std::exception& e) { + LOG("Error opening ZIM file"); + LOG(e.what()); + return 0; + } +} + +JNIEXPORT void JNICALL +Java_org_kiwix_kiwixlib_JNIKiwixReader_dispose(JNIEnv* env, jobject obj) +{ + Handle::dispose(env, obj); +} + +#define READER (Handle::getHandle(env, obj)) + +/* Kiwix library functions */ +JNIEXPORT jstring JNICALL +Java_org_kiwix_kiwixlib_JNIKiwixReader_getMainPage(JNIEnv* env, jobject obj) +{ + jstring url; + + try { + std::string cUrl = READER->getMainPage().getPath(); + url = c2jni(cUrl, env); + } catch (std::exception& e) { + LOG("Unable to get ZIM main page"); + LOG(e.what()); + url = NULL; + } + return url; +} + +JNIEXPORT jstring JNICALL +Java_org_kiwix_kiwixlib_JNIKiwixReader_getId(JNIEnv* env, jobject obj) +{ + jstring id; + + try { + std::string cId = READER->getId(); + id = c2jni(cId, env); + } catch (std::exception& e) { + LOG("Unable to get ZIM id"); + LOG(e.what()); + id = NULL; + } + + return id; +} + +JNIEXPORT jint JNICALL +Java_org_kiwix_kiwixlib_JNIKiwixReader_getFileSize(JNIEnv* env, jobject obj) +{ + jint size = 0; + + try { + int cSize = READER->getFileSize(); + size = c2jni(cSize, env); + } catch (std::exception& e) { + LOG("Unable to get ZIM file size"); + LOG(e.what()); + } + + return size; +} + +JNIEXPORT jstring JNICALL +Java_org_kiwix_kiwixlib_JNIKiwixReader_getCreator(JNIEnv* env, jobject obj) +{ + jstring creator; + + try { + std::string cCreator = READER->getCreator(); + creator = c2jni(cCreator, env); + } catch (std::exception& e) { + LOG("Unable to get ZIM creator"); + LOG(e.what()); + creator = NULL; + } + + return creator; +} + +JNIEXPORT jstring JNICALL +Java_org_kiwix_kiwixlib_JNIKiwixReader_getPublisher(JNIEnv* env, jobject obj) +{ + jstring publisher; + + try { + std::string cPublisher = READER->getPublisher(); + publisher = c2jni(cPublisher, env); + } catch (std::exception& e) { + LOG("Unable to get ZIM publish"); + LOG(e.what()); + publisher = NULL; + } + return publisher; +} + +JNIEXPORT jstring JNICALL +Java_org_kiwix_kiwixlib_JNIKiwixReader_getName(JNIEnv* env, jobject obj) +{ + jstring name; + + try { + std::string cName = READER->getName(); + name = c2jni(cName, env); + } catch (std::exception& e) { + LOG("Unable to get ZIM name"); + LOG(e.what()); + name = NULL; + } + return name; +} + +JNIEXPORT jstring JNICALL +Java_org_kiwix_kiwixlib_JNIKiwixReader_getFavicon(JNIEnv* env, jobject obj) +{ + jstring favicon; + + try { + std::string cContent; + std::string cMime; + READER->getFavicon(cContent, cMime); + favicon = c2jni( + base64_encode(cContent), + env); + } catch (std::exception& e) { + LOG("Unable to get ZIM favicon"); + LOG(e.what()); + favicon = NULL; + } + return favicon; +} + +JNIEXPORT jstring JNICALL +Java_org_kiwix_kiwixlib_JNIKiwixReader_getDate(JNIEnv* env, jobject obj) +{ + jstring date; + + try { + std::string cDate = READER->getDate(); + date = c2jni(cDate, env); + } catch (std::exception& e) { + LOG("Unable to get ZIM date"); + LOG(e.what()); + date = NULL; + } + return date; +} + +JNIEXPORT jstring JNICALL +Java_org_kiwix_kiwixlib_JNIKiwixReader_getLanguage(JNIEnv* env, jobject obj) +{ + jstring language; + + try { + std::string cLanguage = READER->getLanguage(); + language = c2jni(cLanguage, env); + } catch (std::exception& e) { + LOG("Unable to get ZIM language"); + LOG(e.what()); + language = NULL; + } + + return language; +} + +JNIEXPORT jstring JNICALL Java_org_kiwix_kiwixlib_JNIKiwixReader_getMimeType( + JNIEnv* env, jobject obj, jstring url) +{ + jstring mimeType; + + std::string cUrl = jni2c(url, env); + try { + auto entry = READER->getEntryFromEncodedPath(cUrl); + auto cMimeType = entry.getMimetype(); + mimeType = c2jni(cMimeType, env); + } catch (std::exception& e) { + LOG("Unable to get mime-type for url: %s", cUrl.c_str()); + LOG(e.what()); + mimeType = NULL; + } + return mimeType; +} + +JNIEXPORT jstring JNICALL Java_org_kiwix_kiwixlib_JNIKiwixReader_checkUrl( + JNIEnv* env, jobject obj, jstring url) +{ + jstring finalUrl; + std::string cUrl = jni2c(url, env); + try { + auto entry = READER->getEntryFromEncodedPath(cUrl); + entry = entry.getFinalEntry(); + finalUrl = c2jni(entry.getPath(), env); + } catch (std::exception& e) { + finalUrl = c2jni(std::string(), env); + } + return finalUrl; +} + +JNIEXPORT jbyteArray JNICALL Java_org_kiwix_kiwixlib_JNIKiwixReader_getContent( + JNIEnv* env, jobject obj, jobject url, jobject titleObj, jobject mimeTypeObj, jobject sizeObj) +{ + /* Default values */ + setStringObjValue("", titleObj, env); + setStringObjValue("", mimeTypeObj, env); + setIntObjValue(0, sizeObj, env); + jbyteArray data = env->NewByteArray(0); + + /* Retrieve the content */ + std::string cUrl = getStringObjValue(url, env); + unsigned int cSize = 0; + + try { + auto entry = READER->getEntryFromEncodedPath(cUrl); + bool isRedirect = entry.isRedirect(); + entry = entry.getFinalEntry(); + cSize = entry.getSize(); + setIntObjValue(cSize, sizeObj, env); + setStringObjValue(entry.getMimetype(), mimeTypeObj, env); + setStringObjValue(entry.getTitle(), titleObj, env); + if (isRedirect) { + setStringObjValue(entry.getPath(), url, env); + } else { + data = env->NewByteArray(cSize); + env->SetByteArrayRegion( + data, 0, cSize, reinterpret_cast(entry.getBlob().data())); + } + } catch (std::exception& e) { + LOG("Unable to get content for url: %s", cUrl.c_str()); + LOG(e.what()); + } + + return data; +} + +JNIEXPORT jbyteArray JNICALL Java_org_kiwix_kiwixlib_JNIKiwixReader_getContentPart( + JNIEnv* env, jobject obj, jstring url, jint offset, jint len, jobject sizeObj) +{ + jbyteArray data = env->NewByteArray(0); + setIntObjValue(0, sizeObj, env); + + /* Default values */ + /* Retrieve the content */ + std::string cUrl = jni2c(url, env); + unsigned int cOffset = jni2c(offset, env); + unsigned int cLen = jni2c(len, env); + try { + auto entry = READER->getEntryFromEncodedPath(cUrl); + entry = entry.getFinalEntry(); + + if (cLen == 0) { + setIntObjValue(entry.getSize(), sizeObj, env); + } else if (cOffset+cLen < entry.getSize()) { + auto blob = entry.getBlob(cOffset, cLen); + data = env->NewByteArray(cLen); + env->SetByteArrayRegion( + data, 0, cLen, reinterpret_cast(blob.data())); + setIntObjValue(cLen, sizeObj, env); + } + } catch (std::exception& e) { + LOG("Unable to get partial content for url: %s (%u : %u)", cUrl.c_str(), cOffset, cLen); + LOG(e.what()); + } + return data; +} + +JNIEXPORT jobject JNICALL +Java_org_kiwix_kiwixlib_JNIKiwixReader_getDirectAccessInformation( + JNIEnv* env, jobject obj, jstring url) +{ + jclass classPair = env->FindClass("org/kiwix/kiwixlib/Pair"); + jmethodID midPairinit = env->GetMethodID(classPair, "", "()V"); + jobject pair = env->NewObject(classPair, midPairinit); + setPairObjValue("", 0, pair, env); + + std::string cUrl = jni2c(url, env); + try { + auto entry = READER->getEntryFromEncodedPath(cUrl); + entry = entry.getFinalEntry(); + auto part_info = entry.getDirectAccessInfo(); + setPairObjValue(part_info.first, part_info.second, pair, env); + } catch (std::exception& e) { + LOG("Unable to get direct access info for url: %s", cUrl.c_str()); + LOG(e.what()); + } + return pair; +} + +JNIEXPORT jboolean JNICALL +Java_org_kiwix_kiwixlib_JNIKiwixReader_searchSuggestions(JNIEnv* env, + jobject obj, + jstring prefix, + jint count) +{ + jboolean retVal = JNI_FALSE; + std::string cPrefix = jni2c(prefix, env); + unsigned int cCount = jni2c(count, env); + + try { + if (READER->searchSuggestionsSmart(cPrefix, cCount)) { + retVal = JNI_TRUE; + } + } catch (std::exception& e) { + LOG("Unable to get search results for pattern: %s", cPrefix.c_str()); + LOG(e.what()); + } + + return retVal; +} + +JNIEXPORT jboolean JNICALL +Java_org_kiwix_kiwixlib_JNIKiwixReader_getNextSuggestion(JNIEnv* env, + jobject obj, + jobject titleObj, + jobject urlObj) +{ + jboolean retVal = JNI_FALSE; + std::string cTitle; + std::string cUrl; + + try { + if (READER->getNextSuggestion(cTitle, cUrl)) { + setStringObjValue(cTitle, titleObj, env); + setStringObjValue(cUrl, urlObj, env); + retVal = JNI_TRUE; + } + } catch (std::exception& e) { + LOG("Unable to get next suggestion"); + LOG(e.what()); + } + + return retVal; +} + +JNIEXPORT jboolean JNICALL +Java_org_kiwix_kiwixlib_JNIKiwixReader_getPageUrlFromTitle(JNIEnv* env, + jobject obj, + jstring title, + jobject urlObj) +{ + std::string cTitle = jni2c(title, env); + + try { + auto entry = READER->getEntryFromTitle(cTitle); + entry = entry.getFinalEntry(); + setStringObjValue(entry.getPath(), urlObj, env); + return JNI_TRUE; + } catch (std::exception& e) { + LOG("Unable to get url for title %s: ", cTitle.c_str()); + LOG(e.what()); + } + + return JNI_FALSE; +} + +JNIEXPORT jstring JNICALL Java_org_kiwix_kiwixlib_JNIKiwixReader_getTitle( + JNIEnv* env, jobject obj) +{ + jstring title; + + try { + std::string cTitle = READER->getTitle(); + title = c2jni(cTitle, env); + } catch (std::exception& e) { + LOG("Unable to get zim title"); + LOG(e.what()); + title = NULL; + } + return title; +} + +JNIEXPORT jstring JNICALL +Java_org_kiwix_kiwixlib_JNIKiwixReader_getDescription(JNIEnv* env, jobject obj) +{ + jstring description; + + try { + std::string cDescription = READER->getDescription(); + description = c2jni(cDescription, env); + } catch (std::exception& e) { + LOG("Unable to get zim description"); + LOG(e.what()); + description = NULL; + } + return description; +} + +JNIEXPORT jint JNICALL +Java_org_kiwix_kiwixlib_JNIKiwixReader_getArticleCount(JNIEnv* env, jobject obj) +{ + jint articleCount = 0; + try { + auto cArticleCount = READER->getArticleCount(); + articleCount = c2jni(cArticleCount, env); + } catch (std::exception& e) { + LOG("Unable to get article count."); + LOG(e.what()); + } + return articleCount; +} + +JNIEXPORT jint JNICALL +Java_org_kiwix_kiwixlib_JNIKiwixReader_getMediaCount(JNIEnv* env, jobject obj) +{ + jint mediaCount = 0; + try { + auto cMediaCount = READER->getMediaCount(); + mediaCount = c2jni(cMediaCount, env); + } catch (std::exception& e) { + LOG("Unable to get media count."); + LOG(e.what()); + } + return mediaCount; +} + + +JNIEXPORT jboolean JNICALL Java_org_kiwix_kiwixlib_JNIKiwixReader_getRandomPage( + JNIEnv* env, jobject obj, jobject urlObj) +{ + jboolean retVal = JNI_FALSE; + std::string cUrl; + + try { + std::string cUrl = READER->getRandomPage().getPath(); + setStringObjValue(cUrl, urlObj, env); + retVal = JNI_TRUE; + } catch (std::exception& e) { + LOG("Unable to get random page"); + LOG(e.what()); + } + return retVal; +} diff --git a/src/wrapper/java/kiwixsearcher.cpp b/src/wrapper/java/kiwixsearcher.cpp new file mode 100644 index 0000000..de5f078 --- /dev/null +++ b/src/wrapper/java/kiwixsearcher.cpp @@ -0,0 +1,124 @@ +/* + * 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 "org_kiwix_kiwixlib_JNIKiwixSearcher.h" +#include "org_kiwix_kiwixlib_JNIKiwixSearcher_Result.h" + +#include "reader.h" +#include "searcher.h" +#include "utils.h" + +#define SEARCHER (Handle::getHandle(env, obj)) +#define RESULT (Handle::getHandle(env, obj)) + + +JNIEXPORT void JNICALL +Java_org_kiwix_kiwixlib_JNIKiwixSearcher_dispose(JNIEnv* env, jobject obj) +{ + Handle::dispose(env, obj); +} + +/* Kiwix Reader JNI functions */ +JNIEXPORT jlong JNICALL +Java_org_kiwix_kiwixlib_JNIKiwixSearcher_getNativeHandle(JNIEnv* env, + jobject obj) +{ + kiwix::Searcher* searcher = new kiwix::Searcher(); + return reinterpret_cast(new Handle(searcher)); +} + +/* Kiwix library functions */ +JNIEXPORT void JNICALL Java_org_kiwix_kiwixlib_JNIKiwixSearcher_addReader( + JNIEnv* env, jobject obj, jobject reader) +{ + auto searcher = SEARCHER; + + searcher->add_reader(*(Handle::getHandle(env, reader))); +} + +JNIEXPORT void JNICALL Java_org_kiwix_kiwixlib_JNIKiwixSearcher_search( + JNIEnv* env, jobject obj, jstring query, jint count) +{ + std::string cquery = jni2c(query, env); + unsigned int ccount = jni2c(count, env); + + SEARCHER->search(cquery, 0, ccount); +} + +JNIEXPORT jobject JNICALL +Java_org_kiwix_kiwixlib_JNIKiwixSearcher_getNextResult(JNIEnv* env, + jobject obj) +{ + jobject result = nullptr; + + kiwix::Result* cresult = SEARCHER->getNextResult(); + if (cresult != nullptr) { + jclass resultclass + = env->FindClass("org/kiwix/kiwixlib/JNIKiwixSearcher$Result"); + jmethodID ctor = env->GetMethodID( + resultclass, "", "(Lorg/kiwix/kiwixlib/JNIKiwixSearcher;JLorg/kiwix/kiwixlib/JNIKiwixSearcher;)V"); + result = env->NewObject(resultclass, ctor, obj, reinterpret_cast(new Handle(cresult)), obj); + } + return result; +} + +JNIEXPORT void JNICALL Java_org_kiwix_kiwixlib_JNIKiwixSearcher_00024Result_dispose( + JNIEnv* env, jobject obj) +{ + Handle::dispose(env, obj); +} + +JNIEXPORT jstring JNICALL +Java_org_kiwix_kiwixlib_JNIKiwixSearcher_00024Result_getUrl(JNIEnv* env, + jobject obj) +{ + try { + return c2jni(RESULT->get_url(), env); + } catch (...) { + return nullptr; + } +} + +JNIEXPORT jstring JNICALL +Java_org_kiwix_kiwixlib_JNIKiwixSearcher_00024Result_getTitle(JNIEnv* env, + jobject obj) +{ + try { + return c2jni(RESULT->get_title(), env); + } catch (...) { + return nullptr; + } +} + +JNIEXPORT jstring JNICALL +Java_org_kiwix_kiwixlib_JNIKiwixSearcher_00024Result_getSnippet(JNIEnv* env, + jobject obj) +{ + return c2jni(RESULT->get_snippet(), env); +} + +JNIEXPORT jstring JNICALL +Java_org_kiwix_kiwixlib_JNIKiwixSearcher_00024Result_getContent(JNIEnv* env, + jobject obj) +{ + return c2jni(RESULT->get_content(), env); +} diff --git a/src/wrapper/java/kiwixserver.cpp b/src/wrapper/java/kiwixserver.cpp new file mode 100644 index 0000000..7242c4c --- /dev/null +++ b/src/wrapper/java/kiwixserver.cpp @@ -0,0 +1,98 @@ +/* + * 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_kiwixlib_JNIKiwixServer.h" + +#include "tools/base64.h" +#include "server.h" +#include "utils.h" + +/* Kiwix Reader JNI functions */ +JNIEXPORT jlong JNICALL Java_org_kiwix_kiwixlib_JNIKiwixServer_getNativeServer( + JNIEnv* env, jobject obj, jobject jLibrary) +{ + LOG("Attempting to create server"); + Lock l; + try { + auto library = getPtr(env, jLibrary); + kiwix::Server* server = new kiwix::Server(library); + return reinterpret_cast(new Handle(server)); + } catch (std::exception& e) { + LOG("Error creating the server"); + LOG(e.what()); + return 0; + } +} + +JNIEXPORT void JNICALL +Java_org_kiwix_kiwixlib_JNIKiwixServer_dispose(JNIEnv* env, jobject obj) +{ + Handle::dispose(env, obj); +} + +#define SERVER (Handle::getHandle(env, obj)) + +/* Kiwix library functions */ +JNIEXPORT void JNICALL +Java_org_kiwix_kiwixlib_JNIKiwixServer_setRoot(JNIEnv* env, jobject obj, jstring jRoot) +{ + std::string root = jni2c(jRoot, env); + SERVER->setRoot(root); +} + +JNIEXPORT void JNICALL +Java_org_kiwix_kiwixlib_JNIKiwixServer_setAddress(JNIEnv* env, jobject obj, jstring jAddress) +{ + std::string address = jni2c(jAddress, env); + SERVER->setAddress(address); +} + +JNIEXPORT void JNICALL +Java_org_kiwix_kiwixlib_JNIKiwixServer_setPort(JNIEnv* env, jobject obj, int port) +{ + SERVER->setPort(port); +} + +JNIEXPORT void JNICALL +Java_org_kiwix_kiwixlib_JNIKiwixServer_setNbThreads(JNIEnv* env, jobject obj, int threads) +{ + SERVER->setNbThreads(threads); +} + +JNIEXPORT void JNICALL +Java_org_kiwix_kiwixlib_JNIKiwixServer_setTaskbar(JNIEnv* env, jobject obj, jboolean withTaskbar, jboolean withLibraryButton) +{ + SERVER->setTaskbar(withTaskbar, withLibraryButton); +} + +JNIEXPORT jboolean JNICALL +Java_org_kiwix_kiwixlib_JNIKiwixServer_start(JNIEnv* env, jobject obj) +{ + return SERVER->start(); +} + +JNIEXPORT void JNICALL +Java_org_kiwix_kiwixlib_JNIKiwixServer_stop(JNIEnv* env, jobject obj) +{ + SERVER->stop(); +} diff --git a/src/wrapper/java/library.cpp b/src/wrapper/java/library.cpp new file mode 100644 index 0000000..f2a0846 --- /dev/null +++ b/src/wrapper/java/library.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2019-2020 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 "org_kiwix_kiwixlib_Library.h" + +#include "library.h" +#include "reader.h" +#include "utils.h" + +/* Kiwix Reader JNI functions */ +JNIEXPORT void JNICALL +Java_org_kiwix_kiwixlib_Library_allocate( + JNIEnv* env, jobject thisObj) +{ + allocate(env, thisObj); +} + +JNIEXPORT void JNICALL +Java_org_kiwix_kiwixlib_Library_dispose(JNIEnv* env, jobject thisObj) +{ + dispose(env, thisObj); +} + +#define LIBRARY (getPtr(env, thisObj)) + +/* Kiwix library functions */ +JNIEXPORT jboolean JNICALL +Java_org_kiwix_kiwixlib_Library_addBook( + JNIEnv* env, jobject thisObj, jstring path) +{ + auto cPath = jni2c(path, env); + + try { + kiwix::Reader reader(cPath); + kiwix::Book book; + book.update(reader); + return LIBRARY->addBook(book); + } catch (std::exception& e) { + LOG("Unable to add the book"); + LOG(e.what()); } + return false; +} + +METHOD(jobject, Library, getBookById, jstring id) { + auto cId = jni2c(id, env); + auto cBook = new kiwix::Book(LIBRARY->getBookById(cId)); + jclass cls = env->FindClass("org/kiwix/kiwixlib/Book"); + jmethodID constructorId = env->GetMethodID(cls, "", "()V"); + jobject book = env->NewObject(cls, constructorId); + setPtr(env, book, cBook); + return book; +} + +METHOD(jint, Library, getBookCount, jboolean localBooks, jboolean remoteBooks) { + return LIBRARY->getBookCount(localBooks, remoteBooks); +} + +METHOD0(jobjectArray, Library, getBooksIds) { + return c2jni(LIBRARY->getBooksIds(), env); +} + +METHOD(jobjectArray, Library, filter, jobject filterObj) { + auto filter = getPtr(env, filterObj); + return c2jni(LIBRARY->filter(*filter), env); +} + +METHOD0(jobjectArray, Library, getBooksLanguages) { + return c2jni(LIBRARY->getBooksLanguages(), env); +} + +METHOD0(jobjectArray, Library, getBooksCreators) { + return c2jni(LIBRARY->getBooksCreators(), env); +} + +METHOD0(jobjectArray, Library, getBooksPublisher) { + return c2jni(LIBRARY->getBooksPublishers(), env); +} + diff --git a/src/wrapper/java/manager.cpp b/src/wrapper/java/manager.cpp new file mode 100644 index 0000000..b2e94d9 --- /dev/null +++ b/src/wrapper/java/manager.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2020 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_kiwixlib_Manager.h" + +#include "manager.h" +#include "utils.h" + + +JNIEXPORT void JNICALL +Java_org_kiwix_kiwixlib_Manager_allocate( + JNIEnv* env, jobject thisObj, jobject libraryObj) +{ + auto lib = getPtr(env, libraryObj); + allocate(env, thisObj, lib); +} + +JNIEXPORT void JNICALL +Java_org_kiwix_kiwixlib_Manager_dispose(JNIEnv* env, jobject thisObj) +{ + dispose(env, thisObj); +} + +#define MANAGER (getPtr(env, thisObj)) + +/* Kiwix manager functions */ +JNIEXPORT jboolean JNICALL +Java_org_kiwix_kiwixlib_Manager_readFile( + JNIEnv* env, jobject thisObj, jstring path) +{ + auto cPath = jni2c(path, env); + + try { + return MANAGER->readFile(cPath); + } catch (std::exception& e) { + LOG("Unable to get readFile"); + LOG(e.what()); + } + return false; +} + +JNIEXPORT jboolean JNICALL +Java_org_kiwix_kiwixlib_Manager_readXml( + JNIEnv* env, jobject thisObj, jstring content, jstring libraryPath) +{ + auto cContent = jni2c(content, env); + auto cPath = jni2c(libraryPath, env); + + try { + return MANAGER->readXml(cContent, false, cPath); + } catch (std::exception& e) { + LOG("Unable to get ZIM id"); + LOG(e.what()); + } + + return false; +} + +JNIEXPORT jboolean JNICALL +Java_org_kiwix_kiwixlib_Manager_readOpds( + JNIEnv* env, jobject thisObj, jstring content, jstring urlHost) +{ + auto cContent = jni2c(content, env); + auto cUrl = jni2c(urlHost, env); + + try { + return MANAGER->readOpds(cContent, cUrl); + } catch (std::exception& e) { + LOG("Unable to get ZIM id"); + LOG(e.what()); + } + + return false; +} + +JNIEXPORT jboolean JNICALL +Java_org_kiwix_kiwixlib_Manager_readBookmarkFile( + JNIEnv* env, jobject thisObj, jstring path) +{ + auto cPath = jni2c(path, env); + + try { + return MANAGER->readBookmarkFile(cPath); + } catch (std::exception& e) { + LOG("Unable to get ZIM id"); + LOG(e.what()); + } + + return false; +} + +JNIEXPORT jstring JNICALL +Java_org_kiwix_kiwixlib_Manager_addBookFromPath( + JNIEnv* env, jobject thisObj, + jstring pathToOpen, jstring pathToSave, jstring url, jboolean checkMetaData) +{ + auto cPathToOpen = jni2c(pathToOpen, env); + auto cPathToSave = jni2c(pathToSave, env); + auto cUrl = jni2c(url, env); + jstring id = NULL; + + try { + auto cId = MANAGER->addBookFromPathAndGetId(cPathToOpen, cPathToSave, cUrl, checkMetaData); + if ( !cId.empty() ) { + id = c2jni(cId, env); + } + } catch (std::exception& e) { + LOG("Unable to get ZIM file size"); + LOG(e.what()); + } + + return id; +} diff --git a/src/wrapper/java/meson.build b/src/wrapper/java/meson.build new file mode 100644 index 0000000..0341730 --- /dev/null +++ b/src/wrapper/java/meson.build @@ -0,0 +1,55 @@ + +java_sources = files([ + 'org/kiwix/kiwixlib/JNIICU.java', + 'org/kiwix/kiwixlib/Book.java', + 'org/kiwix/kiwixlib/JNIKiwixReader.java', + 'org/kiwix/kiwixlib/Library.java', + 'org/kiwix/kiwixlib/Manager.java', + 'org/kiwix/kiwixlib/Filter.java', + 'org/kiwix/kiwixlib/JNIKiwixSearcher.java', + 'org/kiwix/kiwixlib/JNIKiwixServer.java', + 'org/kiwix/kiwixlib/JNIKiwixInt.java', + 'org/kiwix/kiwixlib/JNIKiwixString.java', + 'org/kiwix/kiwixlib/JNIKiwixBool.java', + 'org/kiwix/kiwixlib/JNIKiwixException.java', + 'org/kiwix/kiwixlib/Pair.java' +]) + +kiwix_jni = custom_target('jni', + input: java_sources, + output: ['org_kiwix_kiwixlib_JNIKiwix.h', + 'org_kiwix_kiwixlib_Book.h', + 'org_kiwix_kiwixlib_JNIKiwixReader.h', + 'org_kiwix_kiwixlib_Library.h', + 'org_kiwix_kiwixlib_Manager.h', + 'org_kiwix_kiwixlib_Filter.h', + 'org_kiwix_kiwixlib_JNIKiwixServer.h', + 'org_kiwix_kiwixlib_JNIKiwixSearcher.h', + 'org_kiwix_kiwixlib_JNIKiwixSearcher_Result.h'], + command:['javac', '-d', '@OUTDIR@', '-h', '@OUTDIR@', '@INPUT@'] +) + +jni_sources = files([ + 'kiwixicu.cpp', + 'book.cpp', + 'kiwixreader.cpp', + 'library.cpp', + 'manager.cpp', + 'filter.cpp', + 'kiwixsearcher.cpp', + 'kiwixserver.cpp', +]) + +kiwix_sources += jni_sources + [kiwix_jni] + +if 'java' in wrapper + kiwix_jar = jar('kiwixlib', java_sources) + #junit_jar = files('org/kiwix/testing/junit-4.13.jar') + #test_jar = jar('testing', 'org/kiwix/testing/test.java', + # link_with: [kiwix_jar, junit_jar]) + #test('javatest', test_jar) +endif + +install_subdir('org', install_dir: 'kiwix-lib/java', exclude_directories: ['kiwix/testing']) +install_subdir('res', install_dir: 'kiwix-lib') +install_data('AndroidManifest.xml', install_dir: 'kiwix-lib') diff --git a/src/wrapper/java/org/kiwix/kiwixlib/Book.java b/src/wrapper/java/org/kiwix/kiwixlib/Book.java new file mode 100644 index 0000000..06b72e1 --- /dev/null +++ b/src/wrapper/java/org/kiwix/kiwixlib/Book.java @@ -0,0 +1,35 @@ + +package org.kiwix.kiwixlib; + +public class Book +{ + public Book() { allocate(); } + + @Override + protected void finalize() { dispose(); } + + public native String getId(); + public native String getPath(); + public native boolean isPathValid(); + public native String getTitle(); + public native String getDescription(); + public native String getLanguage(); + public native String getCreator(); + public native String getPublisher(); + public native String getDate(); + public native String getUrl(); + public native String getName(); + public native String getTags(); + + public native long getArticleCount(); + public native long getMediaCount(); + public native long getSize(); + + public native String getFavicon(); + public native String getFaviconUrl(); + public native String getFaviconMimeType(); + + private native void allocate(); + private native void dispose(); + private long nativeHandle; +} diff --git a/src/wrapper/java/org/kiwix/kiwixlib/Filter.java b/src/wrapper/java/org/kiwix/kiwixlib/Filter.java new file mode 100644 index 0000000..bf9e719 --- /dev/null +++ b/src/wrapper/java/org/kiwix/kiwixlib/Filter.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2019-2020 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. + */ + +package org.kiwix.kiwixlib; + +public class Filter +{ + + public native Filter local(boolean accept); + public native Filter remote(boolean accept); + public native Filter valid(boolean accept); + public native Filter acceptTags(String[] tags); + public native Filter rejectTags(String[] tags); + public native Filter lang(String lang); + public native Filter publisher(String publisher); + public native Filter creator(String creator); + 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; +} diff --git a/src/wrapper/java/org/kiwix/kiwixlib/JNIICU.java b/src/wrapper/java/org/kiwix/kiwixlib/JNIICU.java new file mode 100644 index 0000000..db8ba6e --- /dev/null +++ b/src/wrapper/java/org/kiwix/kiwixlib/JNIICU.java @@ -0,0 +1,26 @@ +/* + * 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. + */ + +package org.kiwix.kiwixlib; + +public class JNIICU +{ + static public native void setDataDirectory(String icuDataDir); +} diff --git a/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwix.java b/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwix.java new file mode 100644 index 0000000..57e148b --- /dev/null +++ b/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwix.java @@ -0,0 +1,36 @@ +/* + * 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. + */ + +package org.kiwix.kiwixlib; + +import android.content.Context; +import com.getkeepsafe.relinker.ReLinker; +import org.kiwix.kiwixlib.JNIICU; + +public class JNIKiwix +{ + public JNIKiwix(final Context context){ + ReLinker.loadLibrary(context, "kiwix"); + } + + public void setDataDirectory(String icuDataDir) { + JNIICU.setDataDirectory(icuDataDir); + } +} diff --git a/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixBool.java b/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixBool.java new file mode 100644 index 0000000..74563d3 --- /dev/null +++ b/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixBool.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2013 Emmanuel Engelhart + * + * 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. + */ + +package org.kiwix.kiwixlib; + +public class JNIKiwixBool +{ + public boolean value; +} diff --git a/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixException.java b/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixException.java new file mode 100644 index 0000000..dd0e214 --- /dev/null +++ b/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixException.java @@ -0,0 +1,27 @@ +/* + * 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. + */ + +package org.kiwix.kiwixlib; + +public class JNIKiwixException extends Exception +{ + public JNIKiwixException(String message) { + super(message); + } +} diff --git a/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixInt.java b/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixInt.java new file mode 100644 index 0000000..a66c937 --- /dev/null +++ b/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixInt.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2013 Emmanuel Engelhart + * + * 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. + */ + +package org.kiwix.kiwixlib; + +public class JNIKiwixInt +{ + public int value; +} diff --git a/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixReader.java b/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixReader.java new file mode 100644 index 0000000..0da29ed --- /dev/null +++ b/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixReader.java @@ -0,0 +1,151 @@ +/* + * 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. + */ + +package org.kiwix.kiwixlib; + +import org.kiwix.kiwixlib.JNIKiwixException; +import org.kiwix.kiwixlib.JNIKiwixString; +import org.kiwix.kiwixlib.JNIKiwixInt; +import org.kiwix.kiwixlib.JNIKiwixSearcher; +import org.kiwix.kiwixlib.Pair; + +public class JNIKiwixReader +{ + public native String getMainPage(); + + public native String getTitle(); + + public native String getId(); + + public native String getLanguage(); + + public native String getMimeType(String url); + + /** + * Check if a url exists and is a redirect or not. + * + * Return an empty string if the url doesn't exist in the reader. + * Return the url of the "final" entry. + * - equal to the input url if the entry is not a redirection. + * - different if the url is a redirection (and the webview should redirect to it). + */ + public native String checkUrl(String url); + + /** + * Get the content of a article. + * + * Return a byte array of the content of the article. + * Set the title, mimeType to the title and mimeType of the article. + * Set the size to the size of the returned array. + * + * If the entry doesn't exist : + * - return a empty byte array + * - set all arguments (except url) to empty/0. + * If the entry exist but is a redirection : + * - return an empty byte array + * - set all arguments (including url) to information of the targeted article. + */ + public native byte[] getContent(JNIKiwixString url, + JNIKiwixString title, + JNIKiwixString mimeType, + JNIKiwixInt size); + + /** + * getContentPart. + * + * Get only a part of the content of the article. + * Return a byte array of `len` size starting from offset `offset`. + * Set `size` to the number of bytes read + * (`len` if everything is ok, 0 in case of error). + * If `len` == 0, no bytes are read but `size` is set to the total size of the + * article. + */ + public native byte[] getContentPart(String url, + int offest, + int len, + JNIKiwixInt size); + + /** + * getDirectAccessInformation. + * + * Return information giving where the content is located in the zim file. + * + * Some contents (binary content) are stored uncompressed in the zim file. + * Knowing this information, it could be interesting to directly open + * the zim file (or zim part) and directly read the content from it (and so + * bypassing the libzim). + * + * Return a `Pair` (filename, offset) where the content is located. + * + * If the content cannot be directly accessed (content is compressed or zim + * file is cut in the middle of the content), the filename is an empty string + * and offset is zero. + */ + public native Pair getDirectAccessInformation(String url); + + public native boolean searchSuggestions(String prefix, int count); + + public native boolean getNextSuggestion(JNIKiwixString title, JNIKiwixString url); + + public native boolean getPageUrlFromTitle(String title, JNIKiwixString url); + + public native String getDescription(); + + public native String getDate(); + + public native String getFavicon(); + + public native String getCreator(); + + public native String getPublisher(); + + public native String getName(); + + public native int getFileSize(); + + public native int getArticleCount(); + + public native int getMediaCount(); + + public native boolean getRandomPage(JNIKiwixString url); + + public JNIKiwixSearcher search(String query, int count) + { + JNIKiwixSearcher searcher = new JNIKiwixSearcher(); + searcher.addKiwixReader(this); + searcher.search(query, count); + return searcher; + } + + public JNIKiwixReader(String filename) throws JNIKiwixException + { + nativeHandle = getNativeReader(filename); + if (nativeHandle == 0) { + throw new JNIKiwixException("Cannot open zimfile "+filename); + } + } + public JNIKiwixReader() { + + } + public native void dispose(); + + private native long getNativeReader(String filename); + private long nativeHandle; +} diff --git a/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixSearcher.java b/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixSearcher.java new file mode 100644 index 0000000..30d7afb --- /dev/null +++ b/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixSearcher.java @@ -0,0 +1,67 @@ +/* + * 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. + */ + + +package org.kiwix.kiwixlib; + +import org.kiwix.kiwixlib.JNIKiwixReader; +import java.util.Vector; + +public class JNIKiwixSearcher +{ + public class Result + { + private long nativeHandle; + private JNIKiwixSearcher searcher; + public Result(long handle, JNIKiwixSearcher _searcher) + { + nativeHandle = handle; + searcher = _searcher; + } + public native String getUrl(); + public native String getTitle(); + public native String getContent(); + public native String getSnippet(); + public native void dispose(); + } + + public JNIKiwixSearcher() + { + nativeHandle = getNativeHandle(); + usedReaders = new Vector(); + } + public native void dispose(); + + private native long getNativeHandle(); + private long nativeHandle; + private Vector usedReaders; + + public native void addReader(JNIKiwixReader reader); + public void addKiwixReader(JNIKiwixReader reader) + { + addReader(reader); + usedReaders.addElement(reader); + }; + + public native void search(String query, int count); + + public native Result getNextResult(); + public native boolean hasMoreResult(); +} diff --git a/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixServer.java b/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixServer.java new file mode 100644 index 0000000..578e2f4 --- /dev/null +++ b/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixServer.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2019 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. + */ + +package org.kiwix.kiwixlib; + +import org.kiwix.kiwixlib.JNIKiwixException; +import org.kiwix.kiwixlib.Library; + +public class JNIKiwixServer +{ + public native void setRoot(String root); + + public native void setAddress(String address); + + public native void setPort(int port); + + public native void setNbThreads(int nbTreads); + + public native void setTaskbar(boolean withTaskBar, boolean witLibraryButton); + + public native boolean start(); + + public native void stop(); + + public JNIKiwixServer(Library library) + { + nativeHandle = getNativeServer(library); + } + + private native long getNativeServer(Library library); + private long nativeHandle; +} diff --git a/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixString.java b/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixString.java new file mode 100644 index 0000000..601fb9d --- /dev/null +++ b/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixString.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2013 Emmanuel Engelhart + * + * 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. + */ + +package org.kiwix.kiwixlib; + +public class JNIKiwixString +{ + public String value; + + public JNIKiwixString(String value) { + this.value = value; + } + + public JNIKiwixString() { + this(""); + } + + public String getValue() { + return value; + } +} diff --git a/src/wrapper/java/org/kiwix/kiwixlib/Library.java b/src/wrapper/java/org/kiwix/kiwixlib/Library.java new file mode 100644 index 0000000..68aa7d2 --- /dev/null +++ b/src/wrapper/java/org/kiwix/kiwixlib/Library.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2019-2020 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. + */ + +package org.kiwix.kiwixlib; + +import org.kiwix.kiwixlib.Book; +import org.kiwix.kiwixlib.JNIKiwixException; + +public class Library +{ + public native boolean addBook(String path) throws JNIKiwixException; + + public native Book getBookById(String id); + public native int getBookCount(boolean localBooks, boolean remoteBooks); + + public native String[] getBooksIds(); + public native String[] filter(Filter filter); + + public native String[] getBooksLanguages(); + public native String[] getBooksCreators(); + public native String[] getBooksPublishers(); + + public Library() + { + allocate(); + } + + @Override + protected void finalize() { dispose(); } + private native void allocate(); + private native void dispose(); + private long nativeHandle; +} diff --git a/src/wrapper/java/org/kiwix/kiwixlib/Manager.java b/src/wrapper/java/org/kiwix/kiwixlib/Manager.java new file mode 100644 index 0000000..2772ca9 --- /dev/null +++ b/src/wrapper/java/org/kiwix/kiwixlib/Manager.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2020 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. + */ + +package org.kiwix.kiwixlib; + +import org.kiwix.kiwixlib.Library; + +public class Manager +{ + /** + * Read a `library.xml` file and add books in the library. + * + * @param path The (utf8) path to the `library.xml` file. + * @return True if the file has been properly parsed. + */ + public native boolean readFile(String path); + + /** + * Load a library content stored in a string (at `library.xml` format). + * + * @param content The content corresponding of the library xml. + * @param libraryPath The library path (used to resolve relative paths) + * @return True if the content has been properly parsed. + */ + public native boolean readXml(String content, String libraryPath); + + /** + * Load a library content stored in a string (at OPDS stream format) + * + * @param content the content of the OPDS stream. + * @param urlHost the url of the stream (used to resolve relative url) + * @return True if the content has been properly parsed. + */ + public native boolean readOpds(String content, String urlHost); + + /** + * Load a bookmark file + * + * @param path The path of the file to read. + * @return True if the content has been properly parsed + */ + public native boolean readBookmarkFile(String path); + + /** + * Add a book to the library. + * + * @param pathToOpen The path of the zim file to add. + * @param pathToSave The path to store in the library in place of + * pathToOpen. + * @param url The url of the book to store in the library + * (useful for kiiwix-serve catalog) + * @param checkMetaData Tell if we check metadata before adding a book to the + * library. + * @return The id of te book if the book has been added to the library. + * Empty string if not. + */ + public native String addBookFromPath(String pathToOpen, + String pathToSave, + String url, + boolean checkMetaData); + + public Manager(Library library) { + allocate(library); + _library = library; + } + + private Library _library; + + @Override + protected void finalize() { dispose(); } + private native void allocate(Library library); + private native void dispose(); + private long nativeHandle; +} diff --git a/src/wrapper/java/org/kiwix/kiwixlib/Pair.java b/src/wrapper/java/org/kiwix/kiwixlib/Pair.java new file mode 100644 index 0000000..ef49e1b --- /dev/null +++ b/src/wrapper/java/org/kiwix/kiwixlib/Pair.java @@ -0,0 +1,26 @@ +/* + * 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. + */ + +package org.kiwix.kiwixlib; + +public class Pair +{ + public String filename; + public int offset; +} diff --git a/src/wrapper/java/org/kiwix/testing/compile_test.sh b/src/wrapper/java/org/kiwix/testing/compile_test.sh new file mode 100755 index 0000000..a985699 --- /dev/null +++ b/src/wrapper/java/org/kiwix/testing/compile_test.sh @@ -0,0 +1,26 @@ +#!/usr/bin/bash + +# This script compile the unit test to test the java wrapper. +# This is not integrated in meson because ... this is not so easy. + + +KIWIX_LIB_JAR=$1 +if [ -z $KIWIX_LIB_JAR ] +then + echo "You must give the path to the kiwixlib.jar as first argument" + exit 1 +fi + +KIWIX_LIB_DIR=$2 +if [ -z $KIWIX_LIB_DIR ] +then + echo "You must give the path to directory containing libkiwix.so as second argument" + exit 1 +fi +TEST_SOURCE_DIR=$(dirname $(readlink -f $0)) + + +javac -g -d . -s . -cp $TEST_SOURCE_DIR/junit-4.13.jar:$KIWIX_LIB_JAR $TEST_SOURCE_DIR/test.java + +java -Djava.library.path=$KIWIX_LIB_DIR -cp $TEST_SOURCE_DIR/junit-4.13.jar:$TEST_SOURCE_DIR/hamcrest-core-1.3.jar:$KIWIX_LIB_JAR:. org.junit.runner.JUnitCore test + diff --git a/src/wrapper/java/org/kiwix/testing/hamcrest-core-1.3.jar b/src/wrapper/java/org/kiwix/testing/hamcrest-core-1.3.jar new file mode 100644 index 0000000..9d5fe16 Binary files /dev/null and b/src/wrapper/java/org/kiwix/testing/hamcrest-core-1.3.jar differ diff --git a/src/wrapper/java/org/kiwix/testing/junit-4.13.jar b/src/wrapper/java/org/kiwix/testing/junit-4.13.jar new file mode 100644 index 0000000..acc3c43 Binary files /dev/null and b/src/wrapper/java/org/kiwix/testing/junit-4.13.jar differ diff --git a/src/wrapper/java/org/kiwix/testing/test.java b/src/wrapper/java/org/kiwix/testing/test.java new file mode 100644 index 0000000..671b0b4 --- /dev/null +++ b/src/wrapper/java/org/kiwix/testing/test.java @@ -0,0 +1,53 @@ + +import java.io.*; +import java.util.*; +import org.junit.Test; +import static org.junit.Assert.*; +import org.kiwix.kiwixlib.*; + +public class test { +static { + System.loadLibrary("kiwix"); +} + +private static String getCatalogContent() +throws IOException +{ + BufferedReader reader = new BufferedReader(new FileReader("catalog.xml")); + String line; + StringBuilder sb = new StringBuilder(); + while ((line = reader.readLine()) != null) + { + sb.append(line + "\n"); + } + reader.close(); + return sb.toString(); +} + +@Test +public void testSome() +throws IOException +{ + Library lib = new Library(); + Manager manager = new Manager(lib); + String content = getCatalogContent(); + manager.readOpds(content, "https://library.kiwix.org"); + assertEquals(lib.getBookCount(true, true), 10); + String[] bookIds = lib.getBooksIds(); + assertEquals(bookIds.length, 10); + Book book = lib.getBookById(bookIds[0]); + assertEquals(book.getTitle(), "Wikisource"); + assertEquals(book.getTags(), "wikisource;_category:wikisource;_pictures:no;_videos:no;_details:yes;_ftindex:yes"); + assertEquals(book.getFaviconUrl(), "https://library.kiwix.org/meta?name=favicon&content=wikisource_fr_all_nopic_2020-01"); + assertEquals(book.getUrl(), "http://download.kiwix.org/zim/wikisource/wikisource_fr_all_nopic_2020-01.zim.meta4"); +} + +static +public void main(String[] args) { + Library lib = new Library(); + lib.getBookCount(true, true); +} + + + +} diff --git a/src/wrapper/java/res/values/strings.xml b/src/wrapper/java/res/values/strings.xml new file mode 100644 index 0000000..8386572 --- /dev/null +++ b/src/wrapper/java/res/values/strings.xml @@ -0,0 +1,3 @@ + + Kiwix Lib + diff --git a/src/wrapper/java/utils.h b/src/wrapper/java/utils.h new file mode 100644 index 0000000..7fa32a1 --- /dev/null +++ b/src/wrapper/java/utils.h @@ -0,0 +1,271 @@ +/* + * 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. + */ + + +#ifndef _ANDROID_JNI_UTILS_H +#define _ANDROID_JNI_UTILS_H + +#include + +#include +#include +#include +#include + +#if __ANDROID__ + #include + #define LOG(...) __android_log_print(ANDROID_LOG_ERROR, "kiwix", __VA_ARGS__) +#else + #define LOG(...) +#endif + +extern pthread_mutex_t globalLock; + +template +void setPtr(JNIEnv* env, jobject thisObj, T* ptr) +{ + jclass thisClass = env->GetObjectClass(thisObj); + jfieldID fieldId = env->GetFieldID(thisClass, "nativeHandle", "J"); + env->SetLongField(thisObj, fieldId, reinterpret_cast(ptr)); +} + +template +void allocate(JNIEnv* env, jobject thisObj, Args && ...args) +{ + T* ptr = new T(std::forward(args)...); + setPtr(env, thisObj, ptr); +} + +template +T* getPtr(JNIEnv* env, jobject thisObj) +{ + jclass thisClass = env->GetObjectClass(thisObj); + jfieldID fidNumber = env->GetFieldID(thisClass, "nativeHandle", "J"); + return reinterpret_cast(env->GetLongField(thisObj, fidNumber)); +} + +template +void dispose(JNIEnv* env, jobject thisObj) +{ + delete getPtr(env, thisObj); +} + +#define METHOD0(retType, class, name) \ +JNIEXPORT retType JNICALL Java_org_kiwix_kiwixlib_##class##_##name( \ + JNIEnv* env, jobject thisObj) + +#define METHOD(retType, class, name, ...) \ +JNIEXPORT retType JNICALL Java_org_kiwix_kiwixlib_##class##_##name( \ + JNIEnv* env, jobject thisObj, __VA_ARGS__) + +inline jfieldID getHandleField(JNIEnv* env, jobject obj) +{ + jclass c = env->GetObjectClass(obj); + // J is the type signature for long: + return env->GetFieldID(c, "nativeHandle", "J"); +} + +inline jobjectArray createArray(JNIEnv* env, size_t length, const std::string& type_sig) +{ + jclass c = env->FindClass(type_sig.c_str()); + return env->NewObjectArray(length, c, NULL); +} + +class Lock +{ + protected: + pthread_mutex_t* lock; + + public: + Lock() : lock(&globalLock) { pthread_mutex_lock(lock); } + Lock(const Lock&) = delete; + Lock& operator=(const Lock&) = delete; + Lock(Lock&& other) : lock(&globalLock) { other.lock = nullptr; } + virtual ~Lock() + { + if (lock) { + pthread_mutex_unlock(lock); + } + } +}; + +template +class LockedHandle; + +template +class Handle +{ + protected: + T* h; + + public: + Handle(T* h) : h(h){}; + + // No destructor. This must and will be handled by dispose method. + + static LockedHandle getHandle(JNIEnv* env, jobject obj) + { + jlong handle = env->GetLongField(obj, getHandleField(env, obj)); + return LockedHandle(reinterpret_cast*>(handle)); + } + + static void dispose(JNIEnv* env, jobject obj) + { + auto lHandle = getHandle(env, obj); + auto handle = lHandle.h; + delete handle->h; + delete handle; + } + friend class LockedHandle; +}; + +template +struct LockedHandle : public Lock { + Handle* h; + LockedHandle(Handle* h) : h(h) {} + T* operator->() { return h->h; } + T* operator*() { return h->h; } + operator bool() const { return (h->h != nullptr); } + operator T*() const { return h->h; } +}; + +template +struct JType { }; + +template<> struct JType{ typedef jboolean type_t; }; +template<> struct JType{ typedef jint type_t; }; +template<> struct JType{ typedef jlong type_t; }; +template<> struct JType { typedef jlong type_t; }; +template<> struct JType { typedef jlong type_t; }; +template<> struct JType{ typedef jstring type_t; }; +template<> struct JType>{ typedef jobjectArray type_t; }; + +template +inline typename JType::type_t c2jni(const T& val, JNIEnv* env) { + return static_cast::type_t>(val); +} + +template<> +inline jboolean c2jni(const bool& val, JNIEnv* env) { return val ? JNI_TRUE : JNI_FALSE; } + +template<> +inline jstring c2jni(const std::string& val, JNIEnv* env) +{ + return env->NewStringUTF(val.c_str()); +} + +template<> +inline jobjectArray c2jni(const std::vector& val, JNIEnv* env) +{ + auto array = createArray(env, val.size(), "java/lang/String"); + size_t index = 0; + for (auto& elem: val) { + auto jElem = c2jni(elem, env); + env->SetObjectArrayElement(array, index++, jElem); + } + return array; +} + +template +struct CType { }; + +template<> struct CType{ typedef bool type_t; }; +template<> struct CType{ typedef int type_t; }; +template<> struct CType{ typedef long type_t; }; +template<> struct CType{ typedef std::string type_t; }; + +template +struct CType{ typedef std::vector::type_t> type_t; }; + +/* jni2c type conversion functions */ +template +inline typename CType::type_t jni2c(const T& val, JNIEnv* env) { + return static_cast::type_t>(val); +} + +template<> +inline bool jni2c(const jboolean& val, JNIEnv* env) { return val == JNI_TRUE; } + +template<> +inline std::string jni2c(const jstring& val, JNIEnv* env) +{ + const char* chars = env->GetStringUTFChars(val, 0); + std::string ret(chars); + env->ReleaseStringUTFChars(val, chars); + return ret; +} + +template +inline typename CType::type_t jni2c(const jobjectArray& val, JNIEnv* env) +{ + jsize length = env->GetArrayLength(val); + typename CType::type_t v(length); + + int i; + for (i = 0; i < length; i++) { + U obj = (U) env->GetObjectArrayElement(val, i); + auto cobj = jni2c(obj, env); + v.push_back(cobj); + } + return v; +} + +/* Method to deal with variable passed by reference */ +inline std::string getStringObjValue(const jobject obj, JNIEnv* env) +{ + jclass objClass = env->GetObjectClass(obj); + jfieldID objFid = env->GetFieldID(objClass, "value", "Ljava/lang/String;"); + jstring jstr = (jstring)env->GetObjectField(obj, objFid); + return jni2c(jstr, env); +} +inline void setStringObjValue(const std::string& value, + const jobject obj, + JNIEnv* env) +{ + jclass objClass = env->GetObjectClass(obj); + jfieldID objFid = env->GetFieldID(objClass, "value", "Ljava/lang/String;"); + env->SetObjectField(obj, objFid, c2jni(value, env)); +} + +inline void setIntObjValue(const int value, const jobject obj, JNIEnv* env) +{ + jclass objClass = env->GetObjectClass(obj); + jfieldID objFid = env->GetFieldID(objClass, "value", "I"); + env->SetIntField(obj, objFid, value); +} + +inline void setBoolObjValue(const bool value, const jobject obj, JNIEnv* env) +{ + jclass objClass = env->GetObjectClass(obj); + jfieldID objFid = env->GetFieldID(objClass, "value", "Z"); + env->SetIntField(obj, objFid, c2jni(value, env)); +} + +inline void setPairObjValue(const std::string& filename, const int offset, + const jobject obj, JNIEnv* env) +{ + jclass objClass = env->GetObjectClass(obj); + jfieldID filenameFid = env->GetFieldID(objClass, "filename", "Ljava/lang/String;"); + env->SetObjectField(obj, filenameFid, c2jni(filename, env)); + jfieldID offsetFid = env->GetFieldID(objClass, "offset", "I"); + env->SetIntField(obj, offsetFid, offset); +} + +#endif // _ANDROID_JNI_UTILS_H