From 4aa8eeedfb1c5232d8cb6c863874faf40cbfc60e Mon Sep 17 00:00:00 2001 From: Matthieu Gautier Date: Tue, 17 Jan 2023 16:37:42 +0100 Subject: [PATCH] Wrap `Archive::iterByFoo` and `Archive::findByFoo` --- lib/src/main/cpp/CMakeLists.txt | 1 + lib/src/main/cpp/libzim/archive.cpp | 60 ++++++++++ lib/src/main/cpp/libzim/entry_iterator.cpp | 111 ++++++++++++++++++ .../main/java/org/kiwix/libzim/Archive.java | 7 ++ .../java/org/kiwix/libzim/EntryIterator.java | 44 +++++++ 5 files changed, 223 insertions(+) create mode 100644 lib/src/main/cpp/libzim/entry_iterator.cpp create mode 100644 lib/src/main/java/org/kiwix/libzim/EntryIterator.java diff --git a/lib/src/main/cpp/CMakeLists.txt b/lib/src/main/cpp/CMakeLists.txt index 9e87b1d..db24255 100644 --- a/lib/src/main/cpp/CMakeLists.txt +++ b/lib/src/main/cpp/CMakeLists.txt @@ -13,6 +13,7 @@ add_library( common.cpp libzim/archive.cpp libzim/entry.cpp + libzim/entry_iterator.cpp libzim/item.cpp libzim/blob.cpp libzim/searcher.cpp diff --git a/lib/src/main/cpp/libzim/archive.cpp b/lib/src/main/cpp/libzim/archive.cpp index c6a4763..4a93f53 100644 --- a/lib/src/main/cpp/libzim/archive.cpp +++ b/lib/src/main/cpp/libzim/archive.cpp @@ -223,5 +223,65 @@ GETTER(jboolean, check) GETTER(jboolean, isMultiPart) GETTER(jboolean, hasNewNamespaceScheme) +#define ITER_BY_PATH 0 +#define ITER_BY_TITLE 1 +#define ITER_EFFICIENT 2 +METHOD0(jobject, Archive, iterByPath) { + auto range = THIS->iterByPath(); + jclass objClass = env->FindClass("org/kiwix/libzim/EntryIterator"); + jmethodID initMethod = env->GetMethodID(objClass, "", "(I)V"); + jobject obj = env->NewObject(objClass, initMethod, ITER_BY_PATH); + SET_HANDLE(zim::Archive::iterator, obj, range.begin()); + auto end_ptr = std::make_shared>(range.end()); + setPtr(env, obj, std::move(end_ptr), "nativeHandleEnd"); + return obj; +} +METHOD0(jobject, Archive, iterByTitle) { + auto range = THIS->iterByTitle(); + jclass objClass = env->FindClass("org/kiwix/libzim/EntryIterator"); + jmethodID initMethod = env->GetMethodID(objClass, "", "(I)V"); + jobject obj = env->NewObject(objClass, initMethod, ITER_BY_TITLE); + SET_HANDLE(zim::Archive::iterator, obj, range.begin()); + + auto end_ptr = std::make_shared>(range.end()); + setPtr(env, obj, std::move(end_ptr), "nativeHandleEnd"); + return obj; +} + +METHOD0(jobject, Archive, iterEfficient) { + auto range = THIS->iterEfficient(); + jclass objClass = env->FindClass("org/kiwix/libzim/EntryIterator"); + jmethodID initMethod = env->GetMethodID(objClass, "", "(I)V"); + jobject obj = env->NewObject(objClass, initMethod, ITER_EFFICIENT); + SET_HANDLE(zim::Archive::iterator, obj, range.begin()); + + auto end_ptr = std::make_shared>(range.end()); + setPtr(env, obj, std::move(end_ptr), "nativeHandleEnd"); + return obj; +} + +METHOD(jobject, Archive, findByPath, jstring path) { + auto range = THIS->findByPath(TO_C(path)); + jclass objClass = env->FindClass("org/kiwix/libzim/EntryIterator"); + jmethodID initMethod = env->GetMethodID(objClass, "", "(I)V"); + jobject obj = env->NewObject(objClass, initMethod, ITER_BY_PATH); + SET_HANDLE(zim::Archive::iterator, obj, range.begin()); + + auto end_ptr = std::make_shared>(range.end()); + setPtr(env, obj, std::move(end_ptr), "nativeHandleEnd"); + return obj; +} + +METHOD(jobject, Archive, findByTitle, jstring title) { + auto range = THIS->findByTitle(TO_C(title)); + jclass objClass = env->FindClass("org/kiwix/libzim/EntryIterator"); + jmethodID initMethod = env->GetMethodID(objClass, "", "(I)V"); + jobject obj = env->NewObject(objClass, initMethod, ITER_BY_TITLE); + SET_HANDLE(zim::Archive::iterator, obj, range.begin()); + + auto end_ptr = std::make_shared>(range.end()); + setPtr(env, obj, std::move(end_ptr), "nativeHandleEnd"); + return obj; +} diff --git a/lib/src/main/cpp/libzim/entry_iterator.cpp b/lib/src/main/cpp/libzim/entry_iterator.cpp new file mode 100644 index 0000000..88a904e --- /dev/null +++ b/lib/src/main/cpp/libzim/entry_iterator.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2013 Emmanuel Engelhart + * Copyright (C) 2017 Matthieu Gautier + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include +#include +#include "org_kiwix_libzim_EntryIterator.h" + +#include + +#include + +#include +#include + +#define PATH_NATIVE_TYPE zim::Archive::iterator +#define TITLE_NATIVE_TYPE zim::Archive::iterator +#define EFFICIENT_NATIVE_TYPE zim::Archive::iterator + +inline int get_order(JNIEnv* env, jobject thisObj) { + jclass thisClass = env->GetObjectClass(thisObj); + jfieldID fieldId = env->GetFieldID(thisClass, "order", "I"); + return TO_C(env->GetIntField(thisObj, fieldId)); +} + +JNIEXPORT void JNICALL +Java_org_kiwix_kiwixlib_libzim_EntryIterotar_dispose(JNIEnv* env, jobject thisObj) +{ + // Delete end iterator + switch (get_order(env, thisObj)) { + case 0: + dispose(env, thisObj, "nativeHandleEnd"); + dispose(env, thisObj); + break; + case 1: + dispose(env, thisObj, "nativeHandleEnd"); + dispose(env, thisObj); + break; + case 2: + dispose(env, thisObj, "nativeHandleEnd"); + dispose(env, thisObj); + break; + } +} + + +METHOD0(jboolean, EntryIterator, hasNext) { + switch (get_order(env, thisObj)) { + case 0: { + PATH_NATIVE_TYPE next(*GET_PTR(PATH_NATIVE_TYPE)); + next++; + auto end = getPtr(env, thisObj, "nativeHandleEnd"); + return next == *end; + } + case 1: { + TITLE_NATIVE_TYPE next(*GET_PTR(TITLE_NATIVE_TYPE)); + next++; + auto end = getPtr(env, thisObj, "nativeHandleEnd"); + return next == *end; + } + case 2: { + EFFICIENT_NATIVE_TYPE next(*GET_PTR(EFFICIENT_NATIVE_TYPE)); + next++; + auto end = getPtr(env, thisObj, "nativeHandleEnd"); + return next == *end; + } + } +} + +METHOD0(jobject, EntryIterator, next) { + switch (get_order(env, thisObj)) { + case 0: { + (*GET_PTR(PATH_NATIVE_TYPE))++; + zim::Entry entry = **GET_PTR(PATH_NATIVE_TYPE); + auto obj = NEW_OBJECT("org/kiwix/libzim/Entry"); + SET_HANDLE(zim::Entry, obj, entry); + return obj; + } + case 1: { + (*GET_PTR(TITLE_NATIVE_TYPE))++; + zim::Entry entry = **GET_PTR(TITLE_NATIVE_TYPE); + auto obj = NEW_OBJECT("org/kiwix/libzim/Entry"); + SET_HANDLE(zim::Entry, obj, entry); + return obj; + } + case 2: { + (*GET_PTR(EFFICIENT_NATIVE_TYPE))++; + zim::Entry entry = **GET_PTR(EFFICIENT_NATIVE_TYPE); + auto obj = NEW_OBJECT("org/kiwix/libzim/Entry"); + SET_HANDLE(zim::Entry, obj, entry); + return obj; + } + } +} + diff --git a/lib/src/main/java/org/kiwix/libzim/Archive.java b/lib/src/main/java/org/kiwix/libzim/Archive.java index a663c65..86d4129 100644 --- a/lib/src/main/java/org/kiwix/libzim/Archive.java +++ b/lib/src/main/java/org/kiwix/libzim/Archive.java @@ -22,6 +22,7 @@ package org.kiwix.libzim; import org.kiwix.libzim.ZimFileFormatException; import org.kiwix.libzim.Entry; import org.kiwix.libzim.Item; +import org.kiwix.libzim.EntryIterator; import java.io.FileDescriptor; public class Archive @@ -92,6 +93,12 @@ public class Archive public native boolean isMultiPart(); public native boolean hasNewNamespaceScheme(); + public native EntryIterator iterByPath(); + public native EntryIterator iterByTitle(); + public native EntryIterator iterEfficient(); + public native EntryIterator findByPath(String path); + public native EntryIterator findByTitle(String path); + private native void setNativeArchive(String filename); private native void setNativeArchiveByFD(FileDescriptor fd); diff --git a/lib/src/main/java/org/kiwix/libzim/EntryIterator.java b/lib/src/main/java/org/kiwix/libzim/EntryIterator.java new file mode 100644 index 0000000..56aa6e3 --- /dev/null +++ b/lib/src/main/java/org/kiwix/libzim/EntryIterator.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2022 Matthieu Gautier + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +package org.kiwix.libzim; + +import java.util.Iterator; + +public class EntryIterator implements Iterator +{ + private EntryIterator(int order) { + this.order = order; + } + public native boolean hasNext(); + public native Entry next(); + +///--------- The wrapper thing + // To delete our native wrapper + public native void dispose(); + + // A marker of the order used for this iterator + private int order; + + // A pointer (as a long) to a native Handle + private long nativeHandle; + + // A pointer (as a long) to the native end + private long nativeHandleEnd; +}