Merge pull request #781 from kiwix/no_wrapper

This commit is contained in:
Matthieu Gautier 2022-06-09 14:23:04 +02:00 committed by GitHub
commit 62306373be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 7 additions and 2550 deletions

View File

@ -5,22 +5,13 @@ project('libkiwix', 'cpp',
compiler = meson.get_compiler('cpp')
wrapper = get_option('wrapper')
static_deps = wrapper.contains('android') or wrapper.contains('java') or get_option('default_library') == 'static'
if wrapper.contains('android')
extra_libs = ['-llog']
else
extra_libs = []
endif
if wrapper.contains('java')
add_languages('java')
endif
static_deps = get_option('static-linkage') or get_option('default_library') == 'static'
# See https://github.com/kiwix/libkiwix/issues/371
if ['arm', 'mips', 'm68k', 'ppc', 'sh4'].contains(host_machine.cpu_family())
extra_libs += '-latomic'
extra_libs = ['-latomic']
else
extra_libs = []
endif
if (compiler.get_id() == 'gcc' and build_machine.system() == 'linux') or host_machine.system() == 'freebsd'

View File

@ -1,4 +1,4 @@
option('wrapper', type:'array', choices:['java', 'android'], value:[],
description: 'The wrapper to generate.')
option('static-linkage', type : 'boolean', value : false,
description : 'Link statically with the dependencies.')
option('doc', type : 'boolean', value : false,
description : 'Build the documentations.')

View File

@ -41,15 +41,7 @@ else
kiwix_sources += 'subprocess_unix.cpp'
endif
if wrapper.contains('android')
install_dir = 'kiwix-lib/jniLibs/' + meson.get_cross_property('android_abi')
else
install_dir = get_option('libdir')
endif
if wrapper.contains('android') or wrapper.contains('java')
subdir('wrapper/java')
endif
install_dir = get_option('libdir')
config_h = configure_file(output : 'kiwix_config.h',
configuration : conf,

View File

@ -1,13 +0,0 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="kiwix.org.kiwixlib"
>
<application android:allowBackup="true"
android:label="@string/app_name"
android:supportsRtl="true"
>
</application>
</manifest>

View File

@ -1,88 +0,0 @@
/*
* Copyright (C) 2020 Matthieu Gautier <mgautier@kymeria.fr>
*
* 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 <jni.h>
#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<kiwix::Book>(env, thisObj);
}
JNIEXPORT void JNICALL
Java_org_kiwix_kiwixlib_Book_dispose(JNIEnv* env, jobject thisObj)
{
dispose<kiwix::Book>(env, thisObj);
}
#define BOOK (getPtr<kiwix::Book>(env, thisObj))
METHOD(void, Book, update__Lorg_kiwix_kiwixlib_Book_2, jobject otherBook)
{
BOOK->update(*getPtr<kiwix::Book>(env, otherBook));
}
METHOD(void, Book, update__Lorg_kiwix_kiwixlib_JNIKiwixReader_2, jobject reader)
{
BOOK->update(**Handle<kiwix::Reader>::getHandle(env, reader));
}
#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, getFlavour)
GETTER(jstring, getCategory)
GETTER(jstring, getTags)
GETTER(jlong, getArticleCount)
GETTER(jlong, getMediaCount)
GETTER(jlong, getSize)
GETTER(jstring, getFavicon)
GETTER(jstring, getFaviconUrl)
GETTER(jstring, getFaviconMimeType)
METHOD(jstring, Book, getTagStr, jstring tagName) try {
auto cRet = BOOK->getTagStr(jni2c(tagName, env));
return c2jni(cRet, env);
} catch(...) {
return c2jni<std::string>("", env);
}
#undef GETTER

View File

@ -1,63 +0,0 @@
/*
* Copyright (C) 2019-2020 Matthieu Gautier <mgautier@kymeria.fr>
*
* 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 <jni.h>
#include "org_kiwix_kiwixlib_Filter.h"
#include "library.h"
#include "utils.h"
/* Kiwix Reader JNI functions */
METHOD0(void, Filter, allocate) {
allocate<kiwix::Filter>(env, thisObj);
}
METHOD0(void, Filter, dispose) {
dispose<kiwix::Library>(env, thisObj);
}
#define FILTER (getPtr<kiwix::Filter>(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<args_type>(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)

View File

@ -1,44 +0,0 @@
/*
* Copyright (C) 2013 Emmanuel Engelhart <kelson@kiwix.org>
* Copyright (C) 2017 Matthieu Gautier <mgautier@kymeria.fr>
*
* 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 <jni.h>
#include "org_kiwix_kiwixlib_JNIICU.h"
#include <iostream>
#include <string>
#include "unicode/putil.h"
#include "utils.h"
std::mutex globalLock;
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;
}
}

View File

@ -1,561 +0,0 @@
/*
* Copyright (C) 2013 Emmanuel Engelhart <kelson@kiwix.org>
* Copyright (C) 2017 Matthieu Gautier <mgautier@kymeria.fr>
*
* 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 <jni.h>
#include <exception>
#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<jlong>(new Handle<kiwix::Reader>(reader));
} catch (std::exception& e) {
LOG("Error opening ZIM file");
LOG(e.what());
return 0;
}
}
namespace
{
int jni2fd(const jobject& fdObj, JNIEnv* env)
{
jclass class_fdesc = env->FindClass("java/io/FileDescriptor");
jfieldID field_fd = env->GetFieldID(class_fdesc, "fd", "I");
if ( field_fd == NULL )
{
env->ExceptionClear();
// Under Android the (private) 'fd' field of java.io.FileDescriptor has been
// renamed to 'descriptor'. See, for example,
// https://android.googlesource.com/platform/libcore/+/refs/tags/android-8.1.0_r1/ojluni/src/main/java/java/io/FileDescriptor.java#55
field_fd = env->GetFieldID(class_fdesc, "descriptor", "I");
}
return env->GetIntField(fdObj, field_fd);
}
} // unnamed namespace
JNIEXPORT jlong JNICALL Java_org_kiwix_kiwixlib_JNIKiwixReader_getNativeReaderByFD(
JNIEnv* env, jobject obj, jobject fdObj)
{
#ifndef _WIN32
int fd = jni2fd(fdObj, env);
LOG("Attempting to create reader with fd: %d", fd);
Lock l;
try {
kiwix::Reader* reader = new kiwix::Reader(fd);
return reinterpret_cast<jlong>(new Handle<kiwix::Reader>(reader));
} catch (std::exception& e) {
LOG("Error opening ZIM file");
LOG(e.what());
return 0;
}
#else
jclass exception = env->FindClass("java/lang/UnsupportedOperationException");
env->ThrowNew(exception, "org.kiwix.kiwixlib.JNIKiwixReader.getNativeReaderByFD() is not supported under Windows");
return 0;
#endif
}
JNIEXPORT jlong JNICALL Java_org_kiwix_kiwixlib_JNIKiwixReader_getNativeReaderEmbedded(
JNIEnv* env, jobject obj, jobject fdObj, jlong offset, jlong size)
{
#ifndef _WIN32
int fd = jni2fd(fdObj, env);
LOG("Attempting to create reader with fd: %d", fd);
Lock l;
try {
kiwix::Reader* reader = new kiwix::Reader(fd, offset, size);
return reinterpret_cast<jlong>(new Handle<kiwix::Reader>(reader));
} catch (std::exception& e) {
LOG("Error opening ZIM file");
LOG(e.what());
return 0;
}
#else
jclass exception = env->FindClass("java/lang/UnsupportedOperationException");
env->ThrowNew(exception, "org.kiwix.kiwixlib.JNIKiwixReader.getNativeReaderEmbedded() is not supported under Windows");
return 0;
#endif
}
JNIEXPORT void JNICALL
Java_org_kiwix_kiwixlib_JNIKiwixReader_dispose(JNIEnv* env, jobject obj)
{
Handle<kiwix::Reader>::dispose(env, obj);
}
#define READER (Handle<kiwix::Reader>::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<const jbyte*>(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<const jbyte*>(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 jlong JNICALL
Java_org_kiwix_kiwixlib_JNIKiwixReader_getArticleSize(
JNIEnv* env, jobject obj, jstring url)
{
std::string cUrl = jni2c(url, env);
try {
auto entry = READER->getEntryFromEncodedPath(cUrl);
entry = entry.getFinalEntry();
return c2jni(entry.getSize(), env);
} catch(std::exception& e) {
LOG("Unable to get size for url : %s", cUrl.c_str());
LOG(e.what());
}
return c2jni(0, env);
}
JNIEXPORT jobject JNICALL
Java_org_kiwix_kiwixlib_JNIKiwixReader_getDirectAccessInformation(
JNIEnv* env, jobject obj, jstring url)
{
jclass daiClass = env->FindClass("org/kiwix/kiwixlib/DirectAccessInfo");
jmethodID daiInitMethod = env->GetMethodID(daiClass, "<init>", "()V");
jobject dai = env->NewObject(daiClass, daiInitMethod);
setDaiObjValue("", 0, dai, env);
std::string cUrl = jni2c(url, env);
try {
auto entry = READER->getEntryFromEncodedPath(cUrl);
entry = entry.getFinalEntry();
auto part_info = entry.getDirectAccessInfo();
setDaiObjValue(part_info.first, part_info.second, dai, env);
} catch (std::exception& e) {
LOG("Unable to get direct access info for url: %s", cUrl.c_str());
LOG(e.what());
}
return dai;
}
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 {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
if (READER->searchSuggestionsSmart(cPrefix, cCount)) {
retVal = JNI_TRUE;
}
#pragma GCC diagnostic pop
} 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 {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
if (READER->getNextSuggestion(cTitle, cUrl)) {
setStringObjValue(cTitle, titleObj, env);
setStringObjValue(cUrl, urlObj, env);
retVal = JNI_TRUE;
}
#pragma GCC diagnostic pop
} 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;
}

View File

@ -1,123 +0,0 @@
/*
* Copyright (C) 2013 Emmanuel Engelhart <kelson@kiwix.org>
* Copyright (C) 2017 Matthieu Gautier <mgautier@kymeria.fr>
*
* 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 "org_kiwix_kiwixlib_JNIKiwixSearcher.h"
#include "org_kiwix_kiwixlib_JNIKiwixSearcher_Result.h"
#include "reader.h"
#include "searcher.h"
#include "utils.h"
#define SEARCHER (Handle<kiwix::Searcher>::getHandle(env, obj))
#define RESULT (Handle<kiwix::Result>::getHandle(env, obj))
JNIEXPORT void JNICALL
Java_org_kiwix_kiwixlib_JNIKiwixSearcher_dispose(JNIEnv* env, jobject obj)
{
Handle<kiwix::Searcher>::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<jlong>(new Handle<kiwix::Searcher>(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<kiwix::Reader>::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, "<init>", "(Lorg/kiwix/kiwixlib/JNIKiwixSearcher;JLorg/kiwix/kiwixlib/JNIKiwixSearcher;)V");
result = env->NewObject(resultclass, ctor, obj, reinterpret_cast<jlong>(new Handle<kiwix::Result>(cresult)), obj);
}
return result;
}
JNIEXPORT void JNICALL Java_org_kiwix_kiwixlib_JNIKiwixSearcher_00024Result_dispose(
JNIEnv* env, jobject obj)
{
Handle<kiwix::Result>::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);
}

View File

@ -1,103 +0,0 @@
/*
* Copyright (C) 2013 Emmanuel Engelhart <kelson@kiwix.org>
* Copyright (C) 2017 Matthieu Gautier <mgautier@kymeria.fr>
*
* 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 <jni.h>
#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<kiwix::Library>(env, jLibrary);
kiwix::Server* server = new kiwix::Server(library);
return reinterpret_cast<jlong>(new Handle<kiwix::Server>(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<kiwix::Server>::dispose(env, obj);
}
#define SERVER (Handle<kiwix::Server>::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 void JNICALL
Java_org_kiwix_kiwixlib_JNIKiwixServer_setBlockExternalLinks(JNIEnv* env, jobject obj, jboolean blockExternalLinks)
{
SERVER->setBlockExternalLinks(blockExternalLinks);
}
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();
}

View File

@ -1,96 +0,0 @@
/*
* Copyright (C) 2019-2020 Matthieu Gautier <mgautier@kymeria.fr>
*
* 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 <jni.h>
#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<kiwix::Library>(env, thisObj);
}
JNIEXPORT void JNICALL
Java_org_kiwix_kiwixlib_Library_dispose(JNIEnv* env, jobject thisObj)
{
dispose<kiwix::Library>(env, thisObj);
}
#define LIBRARY (getPtr<kiwix::Library>(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, "<init>", "()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<kiwix::Filter>(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);
}

View File

@ -1,131 +0,0 @@
/*
* Copyright (C) 2020 Matthieu Gautier <mgautier@kymeria.fr>
*
* 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 <jni.h>
#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<kiwix::Library>(env, libraryObj);
allocate<kiwix::Manager>(env, thisObj, lib);
}
JNIEXPORT void JNICALL
Java_org_kiwix_kiwixlib_Manager_dispose(JNIEnv* env, jobject thisObj)
{
dispose<kiwix::Manager>(env, thisObj);
}
#define MANAGER (getPtr<kiwix::Manager>(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;
}

View File

@ -1,55 +0,0 @@
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/DirectAccessInfo.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')

View File

@ -1,48 +0,0 @@
package org.kiwix.kiwixlib;
public class Book
{
public Book() { allocate(); }
public native void update(Book book);
public native void update(JNIKiwixReader reader);
@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 getFlavour();
public native String getCategory();
public native String getTags();
/**
* Return the value associated to the tag tagName
*
* @param tagName the tag name to search for.
* @return The value of the tag. If the tag is not found, return empty string.
*/
public native String getTagStr(String tagName);
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;
}

View File

@ -1,26 +0,0 @@
/*
* Copyright (C) 2017 Matthieu Gautier <mgautier@kymeria.fr>
*
* 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 DirectAccessInfo
{
public String filename;
public long offset;
}

View File

@ -1,44 +0,0 @@
/*
* Copyright (C) 2019-2020 Matthieu Gautier <mgautier@kymeria.fr>
*
* 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;
}

View File

@ -1,26 +0,0 @@
/*
* Copyright (C) 2013 Emmanuel Engelhart <kelson@kiwix.org>
* Copyright (C) 2017 Matthieu Gautier <mgautier@kymeria.fr>
*
* 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);
}

View File

@ -1,36 +0,0 @@
/*
* Copyright (C) 2013 Emmanuel Engelhart <kelson@kiwix.org>
* Copyright (C) 2017 Matthieu Gautier <mgautier@kymeria.fr>
*
* 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);
}
}

View File

@ -1,25 +0,0 @@
/*
* Copyright (C) 2013 Emmanuel Engelhart <kelson@kiwix.org>
*
* 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;
}

View File

@ -1,27 +0,0 @@
/*
* Copyright (C) 2017 Matthieu Gautier <mgautier@kymeria.org>
*
* 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);
}
}

View File

@ -1,25 +0,0 @@
/*
* Copyright (C) 2013 Emmanuel Engelhart <kelson@kiwix.org>
*
* 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;
}

View File

@ -1,182 +0,0 @@
/*
* Copyright (C) 2013 Emmanuel Engelhart <kelson@kiwix.org>
* Copyright (C) 2017 Matthieu Gautier <mgautier@kymeria.fr>
*
* 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.DirectAccessInfo;
import java.io.FileDescriptor;
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);
/**
*
* Get the size of an article.
*
* @param url The url of the article.
* @return The size of the final (redirections are resolved) article (in byte).
* Return 0 if the article is not found.
*/
public native long getArticleSize(String url);
/**
* 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 `DirectAccessInfo` (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 DirectAccessInfo 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(FileDescriptor fd) throws JNIKiwixException
{
nativeHandle = getNativeReaderByFD(fd);
if (nativeHandle == 0) {
throw new JNIKiwixException("Cannot open zimfile by fd "+fd.toString());
}
}
public JNIKiwixReader(FileDescriptor fd, long offset, long size)
throws JNIKiwixException
{
nativeHandle = getNativeReaderEmbedded(fd, offset, size);
if (nativeHandle == 0) {
throw new JNIKiwixException(String.format("Cannot open embedded zimfile (fd=%s, offset=%d, size=%d)", fd, offset, size));
}
}
public JNIKiwixReader() {
}
public native void dispose();
private native long getNativeReader(String filename);
private native long getNativeReaderByFD(FileDescriptor fd);
private native long getNativeReaderEmbedded(FileDescriptor fd, long offset, long size);
private long nativeHandle;
}

View File

@ -1,67 +0,0 @@
/*
* Copyright (C) 2013 Emmanuel Engelhart <kelson@kiwix.org>
* Copyright (C) 2017 Matthieu Gautier <mgautier@kymeria.fr>
*
* 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();
}

View File

@ -1,50 +0,0 @@
/*
* Copyright (C) 2019 Matthieu Gautier <mgautier@kymeria.fr>
*
* 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 void setBlockExternalLinks(boolean blockExternalLinks);
public native boolean start();
public native void stop();
public JNIKiwixServer(Library library)
{
nativeHandle = getNativeServer(library);
}
private native long getNativeServer(Library library);
private long nativeHandle;
}

View File

@ -1,37 +0,0 @@
/*
* Copyright (C) 2013 Emmanuel Engelhart <kelson@kiwix.org>
*
* 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;
}
}

View File

@ -1,49 +0,0 @@
/*
* Copyright (C) 2019-2020 Matthieu Gautier <mgautier@kymeria.fr>
*
* 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;
}

View File

@ -1,90 +0,0 @@
/*
* Copyright (C) 2020 Matthieu Gautier <mgautier@kymeria.fr>
*
* 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;
}

View File

@ -1,19 +0,0 @@
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:opds="http://opds-spec.org/2010/catalog">
<id>00000000-0000-0000-0000-000000000000</id>
<entry>
<title>Test ZIM file</title>
<id>urn:uuid:86c91e51-55bf-8882-464e-072aca37a3e8</id>
<icon>/meta?name=favicon&amp;content=small</icon>
<updated>2020-11-27:00::00:Z</updated>
<language>en</language>
<summary>This is a ZIM file used in libzim unit-tests</summary>
<tags>unit;test</tags>
<link type="text/html" href="/small" />
<author>
<name>Kiwix</name>
</author>
<link rel="http://opds-spec.org/acquisition/open-access" type="application/x-zim" href="http://localhost/small.zim" length="78982" />
<link rel="http://opds-spec.org/image/thumbnail" type="image/png" href="/meta?name=favicon&amp;content=small" />
</entry>
</feed>

View File

@ -1,37 +0,0 @@
#!/usr/bin/bash
# This script compiles and runs the unit test to test the java wrapper.
# This is not integrated in meson because ... this is not so easy.
die()
{
echo >&2 "!!! ERROR: $*"
exit 1
}
KIWIX_LIB_JAR=$1
if [ -z $KIWIX_LIB_JAR ]
then
die "You must give the path to the kiwixlib.jar as first argument"
fi
KIWIX_LIB_DIR=$2
if [ -z $KIWIX_LIB_DIR ]
then
die "You must give the path to directory containing libkiwix.so as second argument"
fi
KIWIX_LIB_JAR=$(readlink -f "$KIWIX_LIB_JAR")
KIWIX_LIB_DIR=$(readlink -f "$KIWIX_LIB_DIR")
TEST_SOURCE_DIR=$(dirname "$(readlink -f $0)")
cd "$TEST_SOURCE_DIR"
javac -g -d . -s . -cp "junit-4.13.jar:$KIWIX_LIB_JAR" test.java \
|| die "Compilation failed"
java -Djava.library.path="$KIWIX_LIB_DIR" \
-cp "junit-4.13.jar:hamcrest-core-1.3.jar:$KIWIX_LIB_JAR:." \
org.junit.runner.JUnitCore test \
|| die "Unit test failed"

View File

@ -1,28 +0,0 @@
#!/usr/bin/env bash
die()
{
echo >&2 "!!! ERROR: $*"
exit 1
}
cd "$(dirname "$0")"
rm -f small.zim
zimwriterfs --withoutFTIndex \
-w main.html \
-f favicon.png \
-l en \
-t "Test ZIM file" \
-d "N/A" \
-c "N/A" \
-p "N/A" \
small_zimfile_data \
small.zim \
&& echo 'small.zim was successfully created' \
|| die 'Failed to create small.zim'
printf "BEGINZIM" > small.zim.embedded \
&& cat small.zim >> small.zim.embedded \
&& printf "ENDZIM" >> small.zim.embedded \
&& echo 'small.zim.embedded was successfully created' \
|| die 'Failed to create small.zim.embedded'

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -1,11 +0,0 @@
<html>
<head>
<meta charset="UTF-8">
<title>Test ZIM file</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
Test ZIM file
</body>
</html>

View File

@ -1,160 +0,0 @@
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 byte[] getFileContent(String path)
throws IOException
{
File file = new File(path);
DataInputStream in = new DataInputStream(
new BufferedInputStream(
new FileInputStream(file)));
byte[] data = new byte[(int)file.length()];
in.read(data);
return data;
}
private static byte[] getFileContentPartial(String path, int offset, int size)
throws IOException
{
File file = new File(path);
DataInputStream in = new DataInputStream(
new BufferedInputStream(
new FileInputStream(file)));
byte[] data = new byte[size];
in.skipBytes(offset);
in.read(data, 0, size);
return data;
}
private static String getTextFileContent(String path)
throws IOException
{
return new String(getFileContent(path));
}
@Test
public void testReader()
throws JNIKiwixException, IOException
{
JNIKiwixReader reader = new JNIKiwixReader("small.zim");
assertEquals("Test ZIM file", reader.getTitle());
assertEquals(45, reader.getFileSize()); // The file size is in KiB
assertEquals("A/main.html", reader.getMainPage());
String s = getTextFileContent("small_zimfile_data/main.html");
byte[] c = reader.getContent(new JNIKiwixString("A/main.html"),
new JNIKiwixString(),
new JNIKiwixString(),
new JNIKiwixInt());
assertEquals(s, new String(c));
byte[] faviconData = getFileContent("small_zimfile_data/favicon.png");
assertEquals(faviconData.length, reader.getArticleSize("I/favicon.png"));
c = reader.getContent(new JNIKiwixString("I/favicon.png"),
new JNIKiwixString(),
new JNIKiwixString(),
new JNIKiwixInt());
assertTrue(Arrays.equals(faviconData, c));
DirectAccessInfo dai = reader.getDirectAccessInformation("I/favicon.png");
assertNotEquals("", dai.filename);
c = getFileContentPartial(dai.filename, (int)dai.offset, faviconData.length);
assertTrue(Arrays.equals(faviconData, c));
}
@Test
public void testReaderByFd()
throws JNIKiwixException, IOException
{
FileInputStream fis = new FileInputStream("small.zim");
JNIKiwixReader reader = new JNIKiwixReader(fis.getFD());
assertEquals("Test ZIM file", reader.getTitle());
assertEquals(45, reader.getFileSize()); // The file size is in KiB
assertEquals("A/main.html", reader.getMainPage());
String s = getTextFileContent("small_zimfile_data/main.html");
byte[] c = reader.getContent(new JNIKiwixString("A/main.html"),
new JNIKiwixString(),
new JNIKiwixString(),
new JNIKiwixInt());
assertEquals(s, new String(c));
byte[] faviconData = getFileContent("small_zimfile_data/favicon.png");
assertEquals(faviconData.length, reader.getArticleSize("I/favicon.png"));
c = reader.getContent(new JNIKiwixString("I/favicon.png"),
new JNIKiwixString(),
new JNIKiwixString(),
new JNIKiwixInt());
assertTrue(Arrays.equals(faviconData, c));
DirectAccessInfo dai = reader.getDirectAccessInformation("I/favicon.png");
assertNotEquals("", dai.filename);
c = getFileContentPartial(dai.filename, (int)dai.offset, faviconData.length);
assertTrue(Arrays.equals(faviconData, c));
}
@Test
public void testReaderWithAnEmbeddedArchive()
throws JNIKiwixException, IOException
{
File plainArchive = new File("small.zim");
FileInputStream fis = new FileInputStream("small.zim.embedded");
JNIKiwixReader reader = new JNIKiwixReader(fis.getFD(), 8, plainArchive.length());
assertEquals("Test ZIM file", reader.getTitle());
assertEquals(45, reader.getFileSize()); // The file size is in KiB
assertEquals("A/main.html", reader.getMainPage());
String s = getTextFileContent("small_zimfile_data/main.html");
byte[] c = reader.getContent(new JNIKiwixString("A/main.html"),
new JNIKiwixString(),
new JNIKiwixString(),
new JNIKiwixInt());
assertEquals(s, new String(c));
byte[] faviconData = getFileContent("small_zimfile_data/favicon.png");
assertEquals(faviconData.length, reader.getArticleSize("I/favicon.png"));
c = reader.getContent(new JNIKiwixString("I/favicon.png"),
new JNIKiwixString(),
new JNIKiwixString(),
new JNIKiwixInt());
assertTrue(Arrays.equals(faviconData, c));
DirectAccessInfo dai = reader.getDirectAccessInformation("I/favicon.png");
assertNotEquals("", dai.filename);
c = getFileContentPartial(dai.filename, (int)dai.offset, faviconData.length);
assertTrue(Arrays.equals(faviconData, c));
}
@Test
public void testLibrary()
throws IOException
{
Library lib = new Library();
Manager manager = new Manager(lib);
String content = getTextFileContent("catalog.xml");
manager.readOpds(content, "http://localhost");
assertEquals(lib.getBookCount(true, true), 1);
String[] bookIds = lib.getBooksIds();
assertEquals(bookIds.length, 1);
Book book = lib.getBookById(bookIds[0]);
assertEquals(book.getTitle(), "Test ZIM file");
assertEquals(book.getTags(), "unit;test");
assertEquals(book.getFaviconUrl(), "http://localhost/meta?name=favicon&content=small");
assertEquals(book.getUrl(), "http://localhost/small.zim");
}
static
public void main(String[] args) {
Library lib = new Library();
lib.getBookCount(true, true);
}
}

View File

@ -1,3 +0,0 @@
<resources>
<string name="app_name">Kiwix Lib</string>
</resources>

View File

@ -1,259 +0,0 @@
/*
* Copyright (C) 2013 Emmanuel Engelhart <kelson@kiwix.org>
* Copyright (C) 2017 Matthieu Gautier <mgautier@kymeria.fr>
*
* 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 <jni.h>
#include <mutex>
#include <string>
#include <vector>
#include <iostream>
#if __ANDROID__
#include <android/log.h>
#define LOG(...) __android_log_print(ANDROID_LOG_ERROR, "kiwix", __VA_ARGS__)
#else
#define LOG(...)
#endif
extern std::mutex globalLock;
template<typename T>
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<jlong>(ptr));
}
template<typename T, typename ...Args>
void allocate(JNIEnv* env, jobject thisObj, Args && ...args)
{
T* ptr = new T(std::forward<Args>(args)...);
setPtr(env, thisObj, ptr);
}
template<typename T>
T* getPtr(JNIEnv* env, jobject thisObj)
{
jclass thisClass = env->GetObjectClass(thisObj);
jfieldID fidNumber = env->GetFieldID(thisClass, "nativeHandle", "J");
return reinterpret_cast<T*>(env->GetLongField(thisObj, fidNumber));
}
template<typename T>
void dispose(JNIEnv* env, jobject thisObj)
{
delete getPtr<T>(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 : public std::unique_lock<std::mutex>
{
public:
Lock() : std::unique_lock<std::mutex>(globalLock) { }
};
template <class T>
class LockedHandle;
template <class T>
class Handle
{
protected:
T* h;
public:
Handle(T* h) : h(h){};
// No destructor. This must and will be handled by dispose method.
static LockedHandle<T> getHandle(JNIEnv* env, jobject obj)
{
jlong handle = env->GetLongField(obj, getHandleField(env, obj));
return LockedHandle<T>(reinterpret_cast<Handle<T>*>(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<T>;
};
template <class T>
struct LockedHandle : public Lock {
Handle<T>* h;
LockedHandle(Handle<T>* 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<typename T>
struct JType { };
template<> struct JType<bool>{ typedef jboolean type_t; };
template<> struct JType<int>{ typedef jint type_t; };
template<> struct JType<long>{ typedef jlong type_t; };
template<> struct JType<uint64_t> { typedef jlong type_t; };
template<> struct JType<uint32_t> { typedef jlong type_t; };
template<> struct JType<std::string>{ typedef jstring type_t; };
template<> struct JType<std::vector<std::string>>{ typedef jobjectArray type_t; };
template<typename T>
inline typename JType<T>::type_t c2jni(const T& val, JNIEnv* env) {
return static_cast<typename JType<T>::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<std::string>& 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<typename T, typename U=T>
struct CType { };
template<> struct CType<jboolean>{ typedef bool type_t; };
template<> struct CType<jint>{ typedef int type_t; };
template<> struct CType<jlong>{ typedef long type_t; };
template<> struct CType<jstring>{ typedef std::string type_t; };
template<typename U>
struct CType<jobjectArray, U>{ typedef std::vector<typename CType<U>::type_t> type_t; };
/* jni2c type conversion functions */
template<typename T, typename U=T>
inline typename CType<T>::type_t jni2c(const T& val, JNIEnv* env) {
return static_cast<typename CType<T>::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<typename U>
inline typename CType<jobjectArray, U>::type_t jni2c(const jobjectArray& val, JNIEnv* env)
{
jsize length = env->GetArrayLength(val);
typename CType<jobjectArray, U>::type_t v(length);
int i;
for (i = 0; i < length; i++) {
U obj = (U) env->GetObjectArrayElement(val, i);
auto cobj = jni2c<U>(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 setDaiObjValue(const std::string& filename, const long 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", "J");
env->SetLongField(obj, offsetFid, offset);
}
#endif // _ANDROID_JNI_UTILS_H