mirror of
https://github.com/kiwix/java-libkiwix.git
synced 2025-08-03 02:56:06 -04:00
Add a basic wrapper around libzim.
This validate the build system has we now have a compiling wrapper around libzim.
This commit is contained in:
parent
98388aa4e4
commit
f9f64991cd
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
.gradle
|
||||
local.properties
|
||||
build
|
||||
lib/.cxx
|
||||
|
@ -59,7 +59,7 @@ android {
|
||||
}
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
path file('src/cpp/CMakeLists.txt')
|
||||
path file('src/main/cpp/CMakeLists.txt')
|
||||
version '3.18.1'
|
||||
}
|
||||
}
|
||||
@ -285,5 +285,5 @@ task checkCurrentJavaVersion() {
|
||||
|
||||
task generateHeaderFilesFromJavaWrapper(type: Exec) {
|
||||
workingDir "${projectDir}/src/main/java/org/kiwix/"
|
||||
commandLine 'bash', '-c', "javac -h ${buildDir}/include/javah_generated/ -d ${buildDir}/kiwixlib/ kiwixlib/Book.java kiwixlib/DirectAccessInfo.java kiwixlib/Filter.java kiwixlib/JNIICU.java kiwixlib/JNIKiwixBool.java kiwixlib/JNIKiwixException.java kiwixlib/JNIKiwixInt.java kiwixlib/JNIKiwixReader.java kiwixlib/JNIKiwixSearcher.java kiwixlib/JNIKiwixServer.java kiwixlib/JNIKiwixString.java kiwixlib/Library.java kiwixlib/Manager.java"
|
||||
commandLine 'bash', '-c', "javac -h ${buildDir}/include/javah_generated/ -d ${buildDir}/libzim/ libzim/Archive.java libzim/Blob.java libzim/Entry.java libzim/Item.java libzim/ZimFileFormatException.java"
|
||||
}
|
||||
|
53
lib/src/main/cpp/CMakeLists.txt
Normal file
53
lib/src/main/cpp/CMakeLists.txt
Normal file
@ -0,0 +1,53 @@
|
||||
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH)
|
||||
cmake_minimum_required(VERSION 3.18.1)
|
||||
|
||||
set(CMAKE_ANDROID_STL_TYPE llvm-libc++_static)
|
||||
|
||||
project("libzim_wrapper")
|
||||
|
||||
add_library(
|
||||
libzim_wrapper
|
||||
|
||||
SHARED
|
||||
common.cpp
|
||||
libzim/archive.cpp
|
||||
libzim/entry.cpp
|
||||
libzim/item.cpp
|
||||
libzim/blob.cpp
|
||||
)
|
||||
|
||||
find_library(libzim
|
||||
zim
|
||||
PATHS
|
||||
${BUILD_DIR}/jniLibs/${CMAKE_ANDROID_ARCH_ABI}/libzim)
|
||||
if (NOT libzim)
|
||||
message(FATAL_ERROR "libzim not found!")
|
||||
endif()
|
||||
add_library(libzim SHARED IMPORTED)
|
||||
|
||||
set_property(TARGET
|
||||
libzim
|
||||
PROPERTY
|
||||
IMPORTED_LOCATION
|
||||
${BUILD_DIR}/jniLibs/${CMAKE_ANDROID_ARCH_ABI}/libzim/libzim.so)
|
||||
|
||||
include_directories(
|
||||
${CMAKE_SOURCE_DIR}
|
||||
${BUILD_DIR}/include/libkiwix
|
||||
${BUILD_DIR}/include/libzim
|
||||
${BUILD_DIR}/include/javah_generated
|
||||
#${CMAKE_SOURCE_DIR}/include/utils
|
||||
)
|
||||
|
||||
find_library(
|
||||
log-lib
|
||||
log)
|
||||
|
||||
target_link_libraries(
|
||||
libzim_wrapper
|
||||
libzim
|
||||
|
||||
${log-lib}
|
||||
)
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include "utils.h"
|
||||
#include "book.h"
|
||||
#include <zim/archive.h>
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_kiwix_kiwixlib_Book_allocate(
|
||||
@ -46,7 +47,7 @@ METHOD(void, Book, update__Lorg_kiwix_kiwixlib_Book_2, jobject otherBook)
|
||||
|
||||
METHOD(void, Book, update__Lorg_kiwix_kiwixlib_JNIKiwixReader_2, jobject reader)
|
||||
{
|
||||
BOOK->update(**Handle<kiwix::Reader>::getHandle(env, reader));
|
||||
BOOK->update(**Handle<zim::Archive>::getHandle(env, reader));
|
||||
}
|
||||
|
||||
#define GETTER(retType, name) JNIEXPORT retType JNICALL \
|
||||
|
4
lib/src/main/cpp/common.cpp
Normal file
4
lib/src/main/cpp/common.cpp
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
#include <thread>
|
||||
|
||||
std::mutex globalLock;
|
232
lib/src/main/cpp/libzim/archive.cpp
Normal file
232
lib/src/main/cpp/libzim/archive.cpp
Normal file
@ -0,0 +1,232 @@
|
||||
/*
|
||||
* 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_libzim_Archive.h"
|
||||
|
||||
#include <utils.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include <zim/archive.h>
|
||||
#include <zim/item.h>
|
||||
|
||||
/* Kiwix Reader JNI functions */
|
||||
JNIEXPORT jlong JNICALL Java_org_kiwix_libzim_Archive_getNativeArchive(
|
||||
JNIEnv* env, jobject obj, jstring filename)
|
||||
{
|
||||
std::string cPath = TO_C(filename);
|
||||
|
||||
LOG("Attempting to create reader with: %s", cPath.c_str());
|
||||
Lock l;
|
||||
try {
|
||||
zim::Archive* reader = new zim::Archive(cPath);
|
||||
return reinterpret_cast<jlong>(new Handle<zim::Archive>(reader));
|
||||
} catch (std::exception& e) {
|
||||
LOG("Error opening ZIM file");
|
||||
LOG("%s", 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_libzim_Archive_getNativeArchiveByFD(
|
||||
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 {
|
||||
zim::Archive* reader = new zim::Archive(fd);
|
||||
return reinterpret_cast<jlong>(new Handle<zim::Archive>(reader));
|
||||
} catch (std::exception& e) {
|
||||
LOG("Error opening ZIM file");
|
||||
LOG("%s", e.what());
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
jclass exception = env->FindClass("java/lang/UnsupportedOperationException");
|
||||
env->ThrowNew(exception, "org.kiwix.libzim.Archive.getNativeArchiveByFD() is not supported under Windows");
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_org_kiwix_libzim_Archive_getNativeArchiveEmbedded(
|
||||
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 {
|
||||
zim::Archive* reader = new zim::Archive(fd, offset, size);
|
||||
return reinterpret_cast<jlong>(new Handle<zim::Archive>(reader));
|
||||
} catch (std::exception& e) {
|
||||
LOG("Error opening ZIM file");
|
||||
LOG("%s", e.what());
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
jclass exception = env->FindClass("java/lang/UnsupportedOperationException");
|
||||
env->ThrowNew(exception, "org.kiwix.libzim.Archive.getNativeArchiveEmbedded() is not supported under Windows");
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_kiwix_libzim_Archive_dispose(JNIEnv* env, jobject thisObj)
|
||||
{
|
||||
dispose<zim::Archive>(env, thisObj);
|
||||
}
|
||||
|
||||
#define THIS (Handle<zim::Archive>::getHandle(env, thisObj))
|
||||
#define GETTER(retType, name) JNIEXPORT retType JNICALL \
|
||||
Java_org_kiwix_libzim_Archive_##name (JNIEnv* env, jobject thisObj) \
|
||||
{ \
|
||||
return TO_JNI(THIS->name()); \
|
||||
}
|
||||
|
||||
|
||||
GETTER(jstring, getFilename)
|
||||
GETTER(jlong, getFilesize)
|
||||
GETTER(jint, getAllEntryCount)
|
||||
GETTER(jint, getEntryCount)
|
||||
GETTER(jint, getArticleCount)
|
||||
GETTER(jint, getMediaCount)
|
||||
|
||||
METHOD0(jstring, Archive, getUuid) {
|
||||
return TO_JNI(std::string(THIS->getUuid()));
|
||||
}
|
||||
|
||||
METHOD(jstring, Archive, getMetadata, jstring name) {
|
||||
return TO_JNI(THIS->getMetadata(TO_C(name)));
|
||||
}
|
||||
|
||||
METHOD(jobject, Archive, getMetadataItem, jstring name) {
|
||||
auto item = THIS->getMetadataItem(TO_C(name));
|
||||
auto obj = CREATE_WRAPPER("org/kiwix/libzim/Item", item);
|
||||
return obj;
|
||||
}
|
||||
|
||||
GETTER(jobjectArray, getMetadataKeys)
|
||||
|
||||
METHOD(jobject, Archive, getIllustrationItem, jint size) {
|
||||
auto item = THIS->getIllustrationItem(TO_C(size));
|
||||
auto obj = CREATE_WRAPPER("org/kiwix/libzim/Item", item);
|
||||
return obj;
|
||||
}
|
||||
|
||||
METHOD(jboolean, Archive, hasIllustration, jint size) {
|
||||
return TO_JNI(THIS->hasIllustration(TO_C(size)));
|
||||
}
|
||||
|
||||
GETTER(jlongArray, getIllustrationSizes)
|
||||
|
||||
METHOD(jobject, Archive, getEntryByPath, jlong index) {
|
||||
auto entry = THIS->getEntryByPath(TO_C(index));
|
||||
auto obj = CREATE_WRAPPER("org/kiwix/libzim/Entry", entry);
|
||||
return obj;
|
||||
}
|
||||
|
||||
METHOD(jobject, Archive, getEntryByPath, jstring path) {
|
||||
auto entry = THIS->getEntryByPath(TO_C(path));
|
||||
auto obj = CREATE_WRAPPER("org/kiwix/libzim/Entry", entry);
|
||||
return obj;
|
||||
}
|
||||
|
||||
METHOD(jobject, Archive, getEntryByTitle, jlong index) {
|
||||
auto entry = THIS->getEntryByTitle(TO_C(index));
|
||||
auto obj = CREATE_WRAPPER("org/kiwix/libzim/Entry", entry);
|
||||
return obj;
|
||||
}
|
||||
|
||||
METHOD(jobject, Archive, getEntryByTitle, jstring title) {
|
||||
auto entry = THIS->getEntryByTitle(TO_C(title));
|
||||
auto obj = CREATE_WRAPPER("org/kiwix/libzim/Entry", entry);
|
||||
return obj;
|
||||
}
|
||||
|
||||
METHOD(jobject, Archive, getEntryByClusterOrder, jlong index) {
|
||||
auto entry = THIS->getEntryByClusterOrder(TO_C(index));
|
||||
auto obj = CREATE_WRAPPER("org/kiwix/libzim/Entry", entry);
|
||||
return obj;
|
||||
}
|
||||
|
||||
METHOD0(jobject, Archive, getMainEntry) {
|
||||
auto entry = THIS->getMainEntry();
|
||||
auto obj = CREATE_WRAPPER("org/kiwix/libzim/Entry", entry);
|
||||
return obj;
|
||||
}
|
||||
|
||||
METHOD0(jobject, Archive, getRandomEntry) {
|
||||
auto entry = THIS->getRandomEntry();
|
||||
auto obj = CREATE_WRAPPER("org/kiwix/libzim/Entry", entry);
|
||||
return obj;
|
||||
}
|
||||
|
||||
METHOD(jboolean, Archive, hasEntryByPath, jstring path) {
|
||||
return TO_JNI(THIS->hasEntryByPath(TO_C(path)));
|
||||
}
|
||||
|
||||
METHOD(jboolean, Archive, hasEntryByTitle, jstring title) {
|
||||
return TO_JNI(THIS->hasEntryByPath(TO_C(title)));
|
||||
}
|
||||
|
||||
GETTER(jboolean, hasMainEntry)
|
||||
|
||||
METHOD(jboolean, Archive, hasIllustration, jlong size) {
|
||||
return TO_JNI(THIS->hasIllustration(TO_C(size)));
|
||||
}
|
||||
|
||||
GETTER(jboolean, hasFulltextIndex)
|
||||
GETTER(jboolean, hasTitleIndex)
|
||||
GETTER(jboolean, hasChecksum)
|
||||
GETTER(jstring, getChecksum)
|
||||
GETTER(jboolean, check)
|
||||
|
||||
GETTER(jboolean, isMultiPart)
|
||||
GETTER(jboolean, hasNewNamespaceScheme)
|
||||
|
||||
|
||||
|
47
lib/src/main/cpp/libzim/blob.cpp
Normal file
47
lib/src/main/cpp/libzim/blob.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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_libzim_Blob.h"
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <zim/blob.h>
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_kiwix_kiwixlib_libzim_Blob_dispose(JNIEnv* env, jobject thisObj)
|
||||
{
|
||||
dispose<zim::Blob>(env, thisObj);
|
||||
}
|
||||
|
||||
#define THIS (Handle<zim::Blob>::getHandle(env, thisObj))
|
||||
#define GETTER(retType, name) JNIEXPORT retType JNICALL \
|
||||
Java_org_kiwix_libzim_Blob__##name (JNIEnv* env, jobject thisObj) \
|
||||
{ \
|
||||
return TO_JNI(THIS->name()); \
|
||||
}
|
||||
|
||||
METHOD0(jstring, Blob, getData) {
|
||||
return TO_JNI(std::string(**THIS));
|
||||
}
|
||||
GETTER(jlong, size)
|
67
lib/src/main/cpp/libzim/entry.cpp
Normal file
67
lib/src/main/cpp/libzim/entry.cpp
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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_libzim_Entry.h"
|
||||
|
||||
#include <utils.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <zim/entry.h>
|
||||
#include <zim/item.h>
|
||||
|
||||
#define NATIVE_TYPE zim::Entry
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_kiwix_kiwixlib_libzim_Entry_dispose(JNIEnv* env, jobject thisObj)
|
||||
{
|
||||
dispose<zim::Entry>(env, thisObj);
|
||||
}
|
||||
|
||||
#define THIS (Handle<zim::Entry>::getHandle(env, thisObj))
|
||||
#define GETTER(retType, name) JNIEXPORT retType JNICALL \
|
||||
Java_org_kiwix_libzim_Entry__##name (JNIEnv* env, jobject thisObj) \
|
||||
{ \
|
||||
return TO_JNI(THIS->name()); \
|
||||
}
|
||||
|
||||
|
||||
GETTER(jboolean, isRedirect)
|
||||
GETTER(jstring, getTitle)
|
||||
GETTER(jstring, getPath)
|
||||
METHOD(jobject, Entry, getItem, jboolean follow) {
|
||||
auto item = THIS->getItem(TO_C(follow));
|
||||
auto obj = CREATE_WRAPPER("org/kiwix/libzim/Item", item);
|
||||
return obj;
|
||||
}
|
||||
|
||||
METHOD0(jobject, Entry, getRedirect) {
|
||||
auto item = THIS->getRedirect();
|
||||
auto obj = CREATE_WRAPPER("org/kiwix/libzim/Item", item);
|
||||
return obj;
|
||||
}
|
||||
|
||||
METHOD0(jobject, Entry, getRedirectEntry) {
|
||||
auto entry = THIS->getRedirectEntry();
|
||||
auto obj = CREATE_WRAPPER("org/kiwix/libzim/Entry", entry);
|
||||
return obj;
|
||||
}
|
54
lib/src/main/cpp/libzim/item.cpp
Normal file
54
lib/src/main/cpp/libzim/item.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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_libzim_Item.h"
|
||||
|
||||
#include <utils.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <zim/item.h>
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_kiwix_kiwixlib_libzim_Item_dispose(JNIEnv* env, jobject thisObj)
|
||||
{
|
||||
dispose<zim::Item>(env, thisObj);
|
||||
}
|
||||
|
||||
#define THIS (Handle<zim::Item>::getHandle(env, thisObj))
|
||||
#define GETTER(retType, name) JNIEXPORT retType JNICALL \
|
||||
Java_org_kiwix_libzim_Item__##name (JNIEnv* env, jobject thisObj) \
|
||||
{ \
|
||||
return TO_JNI(THIS->name()); \
|
||||
}
|
||||
|
||||
GETTER(jstring, getTitle)
|
||||
GETTER(jstring, getPath)
|
||||
GETTER(jstring, getMimetype)
|
||||
|
||||
METHOD0(jobject, Item, getData) {
|
||||
auto blob = THIS->getData();
|
||||
auto obj = CREATE_WRAPPER("org/kiwix/libzim/Blob", blob);
|
||||
return obj;
|
||||
}
|
||||
|
||||
GETTER(jlong, getSize)
|
@ -27,6 +27,7 @@
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <iostream>
|
||||
|
||||
#if __ANDROID__
|
||||
@ -68,11 +69,11 @@ void dispose(JNIEnv* env, jobject thisObj)
|
||||
}
|
||||
|
||||
#define METHOD0(retType, class, name) \
|
||||
JNIEXPORT retType JNICALL Java_org_kiwix_kiwixlib_##class##_##name( \
|
||||
JNIEXPORT retType JNICALL Java_org_kiwix_libzim_##class##_##name( \
|
||||
JNIEnv* env, jobject thisObj)
|
||||
|
||||
#define METHOD(retType, class, name, ...) \
|
||||
JNIEXPORT retType JNICALL Java_org_kiwix_kiwixlib_##class##_##name( \
|
||||
JNIEXPORT retType JNICALL Java_org_kiwix_libzim_##class##_##name( \
|
||||
JNIEnv* env, jobject thisObj, __VA_ARGS__)
|
||||
|
||||
inline jfieldID getHandleField(JNIEnv* env, jobject obj)
|
||||
@ -88,6 +89,9 @@ inline jobjectArray createArray(JNIEnv* env, size_t length, const std::string& t
|
||||
return env->NewObjectArray(length, c, NULL);
|
||||
}
|
||||
|
||||
|
||||
// A mixin class which will lock the globalLock when a instance is created
|
||||
// This avoid the cration of two instance inheriting from Lock in the same time.
|
||||
class Lock : public std::unique_lock<std::mutex>
|
||||
{
|
||||
public:
|
||||
@ -97,14 +101,19 @@ class Lock : public std::unique_lock<std::mutex>
|
||||
template <class T>
|
||||
class LockedHandle;
|
||||
|
||||
|
||||
/*
|
||||
* A handle to a shared_ptr<T>
|
||||
* Not usable by itself, you must get a LockedHandle to access the value.
|
||||
*/
|
||||
template <class T>
|
||||
class Handle
|
||||
{
|
||||
protected:
|
||||
T* h;
|
||||
std::shared_ptr<T> value;
|
||||
|
||||
public:
|
||||
Handle(T* h) : h(h){};
|
||||
Handle(T* v) : value(v){};
|
||||
|
||||
// No destructor. This must and will be handled by dispose method.
|
||||
|
||||
@ -118,34 +127,42 @@ class Handle
|
||||
{
|
||||
auto lHandle = getHandle(env, obj);
|
||||
auto handle = lHandle.h;
|
||||
delete handle->h;
|
||||
delete handle;
|
||||
}
|
||||
friend class LockedHandle<T>;
|
||||
};
|
||||
|
||||
/*
|
||||
* A locked handle.
|
||||
* Only one LockedHandle can exist at the same time.
|
||||
* As LockedHandle is the
|
||||
*/
|
||||
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; }
|
||||
T* operator->() { return h->value.get(); }
|
||||
T* operator*() { return h->value.get(); }
|
||||
operator bool() const { return (h->value); }
|
||||
operator T*() const { return h->value.get(); }
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Convert things to JAVA
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
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<int32_t>{ typedef jint type_t; };
|
||||
template<> struct JType<int64_t>{ 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>
|
||||
|
||||
template<typename T, typename U=T>
|
||||
inline typename JType<T>::type_t c2jni(const T& val, JNIEnv* env) {
|
||||
return static_cast<typename JType<T>::type_t>(val);
|
||||
}
|
||||
@ -159,6 +176,70 @@ inline jstring c2jni(const std::string& val, JNIEnv* env)
|
||||
return env->NewStringUTF(val.c_str());
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
struct JTypeArray {};
|
||||
template<> struct JTypeArray<bool>{
|
||||
typedef jbooleanArray type_t;
|
||||
static jbooleanArray createArray(JNIEnv* env, size_t length) {
|
||||
return env->NewBooleanArray(length);
|
||||
}
|
||||
static void setArray(JNIEnv* env, jbooleanArray array, const bool* data, size_t length) {
|
||||
env->SetBooleanArrayRegion(array, 0, length, reinterpret_cast<const jboolean*>(data));
|
||||
}
|
||||
};
|
||||
template<> struct JTypeArray<int32_t>{
|
||||
typedef jintArray type_t;
|
||||
static jintArray createArray(JNIEnv* env, size_t length) {
|
||||
return env->NewIntArray(length);
|
||||
}
|
||||
static void setArray(JNIEnv* env, jintArray array, const int32_t* data, size_t length) {
|
||||
env->SetIntArrayRegion(array, 0, length, data);
|
||||
}
|
||||
};
|
||||
template<> struct JTypeArray<int64_t>{
|
||||
typedef jlongArray type_t;
|
||||
static jlongArray createArray(JNIEnv* env, size_t length) {
|
||||
return env->NewLongArray(length);
|
||||
}
|
||||
static void setArray(JNIEnv* env, jlongArray array, const int64_t* data, size_t length) {
|
||||
env->SetLongArrayRegion(array, 0, length, data);
|
||||
}
|
||||
};
|
||||
template<> struct JTypeArray<uint64_t> {
|
||||
typedef jlongArray type_t;
|
||||
static jlongArray createArray(JNIEnv* env, size_t length) {
|
||||
return env->NewLongArray(length);
|
||||
}
|
||||
static void setArray(JNIEnv* env, jlongArray array, const uint64_t* data, size_t length) {
|
||||
env->SetLongArrayRegion(array, 0, length, reinterpret_cast<const jlong*>(data));
|
||||
}
|
||||
};
|
||||
template<> struct JTypeArray<uint32_t> {
|
||||
typedef jlongArray type_t;
|
||||
static jlongArray createArray(JNIEnv* env, size_t length) {
|
||||
return env->NewLongArray(length);
|
||||
}
|
||||
static void setArray(JNIEnv* env, jlongArray array, const uint32_t* data, size_t length) {
|
||||
std::vector<jlong> temp(data, data+length);
|
||||
env->SetLongArrayRegion(array, 0, length, temp.data());
|
||||
}
|
||||
};
|
||||
template<> struct JTypeArray<std::string>{
|
||||
typedef jobjectArray type_t;
|
||||
static jobjectArray createArray(JNIEnv* env, size_t length) {
|
||||
return ::createArray(env, length, "java/lang/String");
|
||||
}
|
||||
static void setArray(JNIEnv* env, jobjectArray array, const std::string* data, size_t length) {
|
||||
size_t index = 0;
|
||||
for(size_t index=0; index<length; index++) {
|
||||
auto jElem = c2jni(data[index], env);
|
||||
env->SetObjectArrayElement(array, index, jElem);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
template<>
|
||||
inline jobjectArray c2jni(const std::vector<std::string>& val, JNIEnv* env)
|
||||
{
|
||||
@ -169,8 +250,31 @@ inline jobjectArray c2jni(const std::vector<std::string>& val, JNIEnv* env)
|
||||
env->SetObjectArrayElement(array, index++, jElem);
|
||||
}
|
||||
return array;
|
||||
}*/
|
||||
|
||||
template<typename U>
|
||||
inline typename JTypeArray<U>::type_t c2jni(const std::vector<U>& val, JNIEnv* env)
|
||||
{
|
||||
auto array = JTypeArray<U>::createArray(env, val.size());
|
||||
JTypeArray<U>::setArray(env, array, val.data(), val.size());
|
||||
return array;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
inline typename JTypeArray<U>::type_t c2jni(const std::set<U>& val, JNIEnv* env)
|
||||
{
|
||||
std::vector<U> temp(val.begin(), val.end());
|
||||
return c2jni(temp, env);
|
||||
}
|
||||
|
||||
#define TO_JNI(VAL) c2jni(VAL, env)
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Convert things to C
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
template<typename T, typename U=T>
|
||||
struct CType { };
|
||||
|
||||
@ -215,6 +319,8 @@ inline typename CType<jobjectArray, U>::type_t jni2c(const jobjectArray& val, JN
|
||||
return v;
|
||||
}
|
||||
|
||||
#define TO_C(VAL) jni2c(VAL, env)
|
||||
|
||||
/* Method to deal with variable passed by reference */
|
||||
inline std::string getStringObjValue(const jobject obj, JNIEnv* env)
|
||||
{
|
||||
@ -256,4 +362,15 @@ inline void setDaiObjValue(const std::string& filename, const long offset,
|
||||
env->SetLongField(obj, offsetFid, offset);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline jobject createWrapper(const char* className, T && nativeObj, JNIEnv* env) {
|
||||
jclass objClass = env->FindClass(className);
|
||||
jmethodID initMethod = env->GetMethodID(objClass, "<init>", "(J)V");
|
||||
jlong nativeHandle = reinterpret_cast<jlong>(new Handle<T>(new T(std::forward<T>(nativeObj))));
|
||||
jobject object = env->NewObject(objClass, initMethod, nativeHandle);
|
||||
return object;
|
||||
}
|
||||
|
||||
#define CREATE_WRAPPER(CLASSNAME, OBJ) createWrapper(CLASSNAME, std::move(OBJ), env)
|
||||
|
||||
#endif // _ANDROID_JNI_UTILS_H
|
||||
|
107
lib/src/main/java/org/kiwix/libzim/Archive.java
Normal file
107
lib/src/main/java/org/kiwix/libzim/Archive.java
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.libzim;
|
||||
|
||||
import org.kiwix.libzim.ZimFileFormatException;
|
||||
import org.kiwix.libzim.Entry;
|
||||
import org.kiwix.libzim.Item;
|
||||
import java.io.FileDescriptor;
|
||||
|
||||
public class Archive
|
||||
{
|
||||
|
||||
public Archive(String filename) throws ZimFileFormatException
|
||||
{
|
||||
nativeHandle = getNativeArchive(filename);
|
||||
if (nativeHandle == 0) {
|
||||
throw new ZimFileFormatException("Cannot open zimfile "+filename);
|
||||
}
|
||||
}
|
||||
|
||||
public Archive(FileDescriptor fd) throws ZimFileFormatException
|
||||
{
|
||||
nativeHandle = getNativeArchiveByFD(fd);
|
||||
if (nativeHandle == 0) {
|
||||
throw new ZimFileFormatException("Cannot open zimfile by fd "+fd.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public Archive(FileDescriptor fd, long offset, long size)
|
||||
throws ZimFileFormatException
|
||||
{
|
||||
nativeHandle = getNativeArchiveEmbedded(fd, offset, size);
|
||||
if (nativeHandle == 0) {
|
||||
throw new ZimFileFormatException(String.format("Cannot open embedded zimfile (fd=%s, offset=%d, size=%d)", fd, offset, size));
|
||||
}
|
||||
}
|
||||
|
||||
public native String getFilename();
|
||||
public native long getFilesize();
|
||||
public native int getAllEntryCount();
|
||||
public native int getEntryCount();
|
||||
public native int getArticleCount();
|
||||
public native int getMediaCount();
|
||||
public native String getUuid();
|
||||
public native String getMetadata(String name);
|
||||
public native Item getMetadataItem(String name);
|
||||
public native String[] getMetadataKeys();
|
||||
|
||||
public native Item getIllustrationItem(int size);
|
||||
public native boolean hasIllustration(int size);
|
||||
public native long[] getIllustrationSizes();
|
||||
|
||||
public native Entry getEntryByPath(String path);
|
||||
public native Entry getEntryByPath(int index);
|
||||
public native boolean hasEntryByPath(String path);
|
||||
|
||||
public native Entry getEntryByTitle(String title);
|
||||
public native Entry getEntryByTitle(int index);
|
||||
public native boolean hasEntryByTitle(String title);
|
||||
|
||||
public native Entry getEntryByClusterOrder(int index);
|
||||
|
||||
public native Entry getMainEntry();
|
||||
public native boolean hasMainEntry();
|
||||
|
||||
public native Entry getRandomEntry();
|
||||
|
||||
public native boolean hasFulltextIndex();
|
||||
public native boolean hasTitleIndex();
|
||||
|
||||
public native boolean hasChecksum();
|
||||
public native String getChecksum();
|
||||
public native boolean check();
|
||||
|
||||
public native boolean isMultiPart();
|
||||
public native boolean hasNewNamespaceScheme();
|
||||
|
||||
|
||||
private native long getNativeArchive(String filename);
|
||||
private native long getNativeArchiveByFD(FileDescriptor fd);
|
||||
private native long getNativeArchiveEmbedded(FileDescriptor fd, long offset, long size);
|
||||
|
||||
|
||||
///--------- The wrapper thing
|
||||
// To delete our native wrapper
|
||||
public native void dispose();
|
||||
|
||||
// A pointer (as a long) to a native Handle
|
||||
private long nativeHandle;
|
||||
}
|
41
lib/src/main/java/org/kiwix/libzim/Blob.java
Normal file
41
lib/src/main/java/org/kiwix/libzim/Blob.java
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.libzim;
|
||||
|
||||
import org.kiwix.libzim.Blob;
|
||||
|
||||
public class Blob
|
||||
{
|
||||
private Blob(long handle) {nativeHandle = handle;}
|
||||
|
||||
public native String getData();
|
||||
public native long size();
|
||||
|
||||
protected void finalize() {
|
||||
dispose();
|
||||
}
|
||||
|
||||
///--------- The wrapper thing
|
||||
// To delete our native wrapper
|
||||
public native void dispose();
|
||||
|
||||
// A pointer (as a long) to a native Handle
|
||||
private long nativeHandle;
|
||||
}
|
46
lib/src/main/java/org/kiwix/libzim/Entry.java
Normal file
46
lib/src/main/java/org/kiwix/libzim/Entry.java
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.libzim;
|
||||
|
||||
import org.kiwix.libzim.Item;
|
||||
|
||||
public class Entry
|
||||
{
|
||||
private Entry(long handle) {nativeHandle = handle;}
|
||||
|
||||
public native boolean isRedirect();
|
||||
public native String getTitle();
|
||||
public native String getPath();
|
||||
|
||||
public native Item getItem(boolean follow);
|
||||
public native Item getRedirect();
|
||||
public native Entry getRedirectEntry();
|
||||
|
||||
protected void finalize() {
|
||||
dispose();
|
||||
}
|
||||
|
||||
///--------- The wrapper thing
|
||||
// To delete our native wrapper
|
||||
private native void dispose();
|
||||
|
||||
// A pointer (as a long) to a native Handle
|
||||
private long nativeHandle;
|
||||
}
|
45
lib/src/main/java/org/kiwix/libzim/Item.java
Normal file
45
lib/src/main/java/org/kiwix/libzim/Item.java
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.libzim;
|
||||
|
||||
import org.kiwix.libzim.Blob;
|
||||
|
||||
public class Item
|
||||
{
|
||||
private Item(long handle) {nativeHandle = handle;}
|
||||
|
||||
public native String getTitle();
|
||||
public native String getPath();
|
||||
public native String getMimeType();
|
||||
|
||||
public native Blob getData();
|
||||
public native long getSize();
|
||||
|
||||
protected void finalize() {
|
||||
dispose();
|
||||
}
|
||||
|
||||
///--------- The wrapper thing
|
||||
// To delete our native wrapper
|
||||
private native void dispose();
|
||||
|
||||
// A pointer (as a long) to a native Handle
|
||||
private long nativeHandle;
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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.libzim;
|
||||
|
||||
public class ZimFileFormatException extends Exception
|
||||
{
|
||||
public ZimFileFormatException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user