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:
Matthieu Gautier 2022-12-20 14:18:36 +01:00
parent 98388aa4e4
commit f9f64991cd
15 changed files with 858 additions and 16 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
.gradle
local.properties
build
lib/.cxx

View File

@ -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"
}

View 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}
)

View File

@ -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 \

View File

@ -0,0 +1,4 @@
#include <thread>
std::mutex globalLock;

View 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)

View 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)

View 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;
}

View 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)

View File

@ -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

View 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;
}

View 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;
}

View 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;
}

View 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;
}

View File

@ -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);
}
}