Skip to content

Commit d6ac65d

Browse files
committed
Add a basic wrapper around libzim.
This validate the build system has we now have a compiling wrapper around libzim.
1 parent c4b582c commit d6ac65d

File tree

15 files changed

+858
-16
lines changed

15 files changed

+858
-16
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
.gradle
22
local.properties
33
build
4+
lib/.cxx

lib/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ android {
5959
}
6060
externalNativeBuild {
6161
cmake {
62-
path file('src/cpp/CMakeLists.txt')
62+
path file('src/main/cpp/CMakeLists.txt')
6363
version '3.18.1'
6464
}
6565
}
@@ -285,5 +285,5 @@ task checkCurrentJavaVersion() {
285285

286286
task generateHeaderFilesFromJavaWrapper(type: Exec) {
287287
workingDir "${projectDir}/src/main/java/org/kiwix/"
288-
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"
288+
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"
289289
}

lib/src/main/cpp/CMakeLists.txt

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
2+
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH)
3+
cmake_minimum_required(VERSION 3.18.1)
4+
5+
set(CMAKE_ANDROID_STL_TYPE llvm-libc++_static)
6+
7+
project("libzim_wrapper")
8+
9+
add_library(
10+
libzim_wrapper
11+
12+
SHARED
13+
common.cpp
14+
libzim/archive.cpp
15+
libzim/entry.cpp
16+
libzim/item.cpp
17+
libzim/blob.cpp
18+
)
19+
20+
find_library(libzim
21+
zim
22+
PATHS
23+
${BUILD_DIR}/jniLibs/${CMAKE_ANDROID_ARCH_ABI}/libzim)
24+
if (NOT libzim)
25+
message(FATAL_ERROR "libzim not found!")
26+
endif()
27+
add_library(libzim SHARED IMPORTED)
28+
29+
set_property(TARGET
30+
libzim
31+
PROPERTY
32+
IMPORTED_LOCATION
33+
${BUILD_DIR}/jniLibs/${CMAKE_ANDROID_ARCH_ABI}/libzim/libzim.so)
34+
35+
include_directories(
36+
${CMAKE_SOURCE_DIR}
37+
${BUILD_DIR}/include/libkiwix
38+
${BUILD_DIR}/include/libzim
39+
${BUILD_DIR}/include/javah_generated
40+
#${CMAKE_SOURCE_DIR}/include/utils
41+
)
42+
43+
find_library(
44+
log-lib
45+
log)
46+
47+
target_link_libraries(
48+
libzim_wrapper
49+
libzim
50+
51+
${log-lib}
52+
)
53+

lib/src/main/cpp/book.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
#include "utils.h"
2525
#include "book.h"
26+
#include <zim/archive.h>
2627

2728
JNIEXPORT void JNICALL
2829
Java_org_kiwix_kiwixlib_Book_allocate(
@@ -46,7 +47,7 @@ METHOD(void, Book, update__Lorg_kiwix_kiwixlib_Book_2, jobject otherBook)
4647

4748
METHOD(void, Book, update__Lorg_kiwix_kiwixlib_JNIKiwixReader_2, jobject reader)
4849
{
49-
BOOK->update(**Handle<kiwix::Reader>::getHandle(env, reader));
50+
BOOK->update(**Handle<zim::Archive>::getHandle(env, reader));
5051
}
5152

5253
#define GETTER(retType, name) JNIEXPORT retType JNICALL \

lib/src/main/cpp/common.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
#include <thread>
3+
4+
std::mutex globalLock;
Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
/*
2+
* Copyright (C) 2013 Emmanuel Engelhart <kelson@kiwix.org>
3+
* Copyright (C) 2017 Matthieu Gautier <mgautier@kymeria.fr>
4+
*
5+
* This program is free software; you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation; either version 3 of the License, or
8+
* any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18+
* MA 02110-1301, USA.
19+
*/
20+
21+
#include <jni.h>
22+
#include <exception>
23+
#include "org_kiwix_libzim_Archive.h"
24+
25+
#include <utils.h>
26+
27+
#include <iostream>
28+
#include <string>
29+
30+
#include <zim/archive.h>
31+
#include <zim/item.h>
32+
33+
/* Kiwix Reader JNI functions */
34+
JNIEXPORT jlong JNICALL Java_org_kiwix_libzim_Archive_getNativeArchive(
35+
JNIEnv* env, jobject obj, jstring filename)
36+
{
37+
std::string cPath = TO_C(filename);
38+
39+
LOG("Attempting to create reader with: %s", cPath.c_str());
40+
Lock l;
41+
try {
42+
zim::Archive* reader = new zim::Archive(cPath);
43+
return reinterpret_cast<jlong>(new Handle<zim::Archive>(reader));
44+
} catch (std::exception& e) {
45+
LOG("Error opening ZIM file");
46+
LOG("%s", e.what());
47+
return 0;
48+
}
49+
}
50+
51+
namespace
52+
{
53+
54+
int jni2fd(const jobject& fdObj, JNIEnv* env)
55+
{
56+
jclass class_fdesc = env->FindClass("java/io/FileDescriptor");
57+
jfieldID field_fd = env->GetFieldID(class_fdesc, "fd", "I");
58+
if ( field_fd == NULL )
59+
{
60+
env->ExceptionClear();
61+
// Under Android the (private) 'fd' field of java.io.FileDescriptor has been
62+
// renamed to 'descriptor'. See, for example,
63+
// https://android.googlesource.com/platform/libcore/+/refs/tags/android-8.1.0_r1/ojluni/src/main/java/java/io/FileDescriptor.java#55
64+
field_fd = env->GetFieldID(class_fdesc, "descriptor", "I");
65+
}
66+
return env->GetIntField(fdObj, field_fd);
67+
}
68+
69+
} // unnamed namespace
70+
71+
JNIEXPORT jlong JNICALL Java_org_kiwix_libzim_Archive_getNativeArchiveByFD(
72+
JNIEnv* env, jobject obj, jobject fdObj)
73+
{
74+
#ifndef _WIN32
75+
int fd = jni2fd(fdObj, env);
76+
77+
LOG("Attempting to create reader with fd: %d", fd);
78+
Lock l;
79+
try {
80+
zim::Archive* reader = new zim::Archive(fd);
81+
return reinterpret_cast<jlong>(new Handle<zim::Archive>(reader));
82+
} catch (std::exception& e) {
83+
LOG("Error opening ZIM file");
84+
LOG("%s", e.what());
85+
return 0;
86+
}
87+
#else
88+
jclass exception = env->FindClass("java/lang/UnsupportedOperationException");
89+
env->ThrowNew(exception, "org.kiwix.libzim.Archive.getNativeArchiveByFD() is not supported under Windows");
90+
return 0;
91+
#endif
92+
}
93+
94+
JNIEXPORT jlong JNICALL Java_org_kiwix_libzim_Archive_getNativeArchiveEmbedded(
95+
JNIEnv* env, jobject obj, jobject fdObj, jlong offset, jlong size)
96+
{
97+
#ifndef _WIN32
98+
int fd = jni2fd(fdObj, env);
99+
100+
LOG("Attempting to create reader with fd: %d", fd);
101+
Lock l;
102+
try {
103+
zim::Archive* reader = new zim::Archive(fd, offset, size);
104+
return reinterpret_cast<jlong>(new Handle<zim::Archive>(reader));
105+
} catch (std::exception& e) {
106+
LOG("Error opening ZIM file");
107+
LOG("%s", e.what());
108+
return 0;
109+
}
110+
#else
111+
jclass exception = env->FindClass("java/lang/UnsupportedOperationException");
112+
env->ThrowNew(exception, "org.kiwix.libzim.Archive.getNativeArchiveEmbedded() is not supported under Windows");
113+
return 0;
114+
#endif
115+
}
116+
117+
JNIEXPORT void JNICALL
118+
Java_org_kiwix_libzim_Archive_dispose(JNIEnv* env, jobject thisObj)
119+
{
120+
dispose<zim::Archive>(env, thisObj);
121+
}
122+
123+
#define THIS (Handle<zim::Archive>::getHandle(env, thisObj))
124+
#define GETTER(retType, name) JNIEXPORT retType JNICALL \
125+
Java_org_kiwix_libzim_Archive_##name (JNIEnv* env, jobject thisObj) \
126+
{ \
127+
return TO_JNI(THIS->name()); \
128+
}
129+
130+
131+
GETTER(jstring, getFilename)
132+
GETTER(jlong, getFilesize)
133+
GETTER(jint, getAllEntryCount)
134+
GETTER(jint, getEntryCount)
135+
GETTER(jint, getArticleCount)
136+
GETTER(jint, getMediaCount)
137+
138+
METHOD0(jstring, Archive, getUuid) {
139+
return TO_JNI(std::string(THIS->getUuid()));
140+
}
141+
142+
METHOD(jstring, Archive, getMetadata, jstring name) {
143+
return TO_JNI(THIS->getMetadata(TO_C(name)));
144+
}
145+
146+
METHOD(jobject, Archive, getMetadataItem, jstring name) {
147+
auto item = THIS->getMetadataItem(TO_C(name));
148+
auto obj = CREATE_WRAPPER("org/kiwix/libzim/Item", item);
149+
return obj;
150+
}
151+
152+
GETTER(jobjectArray, getMetadataKeys)
153+
154+
METHOD(jobject, Archive, getIllustrationItem, jint size) {
155+
auto item = THIS->getIllustrationItem(TO_C(size));
156+
auto obj = CREATE_WRAPPER("org/kiwix/libzim/Item", item);
157+
return obj;
158+
}
159+
160+
METHOD(jboolean, Archive, hasIllustration, jint size) {
161+
return TO_JNI(THIS->hasIllustration(TO_C(size)));
162+
}
163+
164+
GETTER(jlongArray, getIllustrationSizes)
165+
166+
METHOD(jobject, Archive, getEntryByPath, jlong index) {
167+
auto entry = THIS->getEntryByPath(TO_C(index));
168+
auto obj = CREATE_WRAPPER("org/kiwix/libzim/Entry", entry);
169+
return obj;
170+
}
171+
172+
METHOD(jobject, Archive, getEntryByPath, jstring path) {
173+
auto entry = THIS->getEntryByPath(TO_C(path));
174+
auto obj = CREATE_WRAPPER("org/kiwix/libzim/Entry", entry);
175+
return obj;
176+
}
177+
178+
METHOD(jobject, Archive, getEntryByTitle, jlong index) {
179+
auto entry = THIS->getEntryByTitle(TO_C(index));
180+
auto obj = CREATE_WRAPPER("org/kiwix/libzim/Entry", entry);
181+
return obj;
182+
}
183+
184+
METHOD(jobject, Archive, getEntryByTitle, jstring title) {
185+
auto entry = THIS->getEntryByTitle(TO_C(title));
186+
auto obj = CREATE_WRAPPER("org/kiwix/libzim/Entry", entry);
187+
return obj;
188+
}
189+
190+
METHOD(jobject, Archive, getEntryByClusterOrder, jlong index) {
191+
auto entry = THIS->getEntryByClusterOrder(TO_C(index));
192+
auto obj = CREATE_WRAPPER("org/kiwix/libzim/Entry", entry);
193+
return obj;
194+
}
195+
196+
METHOD0(jobject, Archive, getMainEntry) {
197+
auto entry = THIS->getMainEntry();
198+
auto obj = CREATE_WRAPPER("org/kiwix/libzim/Entry", entry);
199+
return obj;
200+
}
201+
202+
METHOD0(jobject, Archive, getRandomEntry) {
203+
auto entry = THIS->getRandomEntry();
204+
auto obj = CREATE_WRAPPER("org/kiwix/libzim/Entry", entry);
205+
return obj;
206+
}
207+
208+
METHOD(jboolean, Archive, hasEntryByPath, jstring path) {
209+
return TO_JNI(THIS->hasEntryByPath(TO_C(path)));
210+
}
211+
212+
METHOD(jboolean, Archive, hasEntryByTitle, jstring title) {
213+
return TO_JNI(THIS->hasEntryByPath(TO_C(title)));
214+
}
215+
216+
GETTER(jboolean, hasMainEntry)
217+
218+
METHOD(jboolean, Archive, hasIllustration, jlong size) {
219+
return TO_JNI(THIS->hasIllustration(TO_C(size)));
220+
}
221+
222+
GETTER(jboolean, hasFulltextIndex)
223+
GETTER(jboolean, hasTitleIndex)
224+
GETTER(jboolean, hasChecksum)
225+
GETTER(jstring, getChecksum)
226+
GETTER(jboolean, check)
227+
228+
GETTER(jboolean, isMultiPart)
229+
GETTER(jboolean, hasNewNamespaceScheme)
230+
231+
232+

lib/src/main/cpp/libzim/blob.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright (C) 2013 Emmanuel Engelhart <kelson@kiwix.org>
3+
* Copyright (C) 2017 Matthieu Gautier <mgautier@kymeria.fr>
4+
*
5+
* This program is free software; you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation; either version 3 of the License, or
8+
* any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18+
* MA 02110-1301, USA.
19+
*/
20+
21+
#include <jni.h>
22+
#include <exception>
23+
#include "org_kiwix_libzim_Blob.h"
24+
25+
#include "utils.h"
26+
27+
#include <string>
28+
29+
#include <zim/blob.h>
30+
31+
JNIEXPORT void JNICALL
32+
Java_org_kiwix_kiwixlib_libzim_Blob_dispose(JNIEnv* env, jobject thisObj)
33+
{
34+
dispose<zim::Blob>(env, thisObj);
35+
}
36+
37+
#define THIS (Handle<zim::Blob>::getHandle(env, thisObj))
38+
#define GETTER(retType, name) JNIEXPORT retType JNICALL \
39+
Java_org_kiwix_libzim_Blob__##name (JNIEnv* env, jobject thisObj) \
40+
{ \
41+
return TO_JNI(THIS->name()); \
42+
}
43+
44+
METHOD0(jstring, Blob, getData) {
45+
return TO_JNI(std::string(**THIS));
46+
}
47+
GETTER(jlong, size)

0 commit comments

Comments
 (0)