diff --git a/src/android/kiwixreader.cpp b/src/android/kiwixreader.cpp index 3e7687947..5b542fa2b 100644 --- a/src/android/kiwixreader.cpp +++ b/src/android/kiwixreader.cpp @@ -277,6 +277,40 @@ JNIEXPORT jbyteArray JNICALL Java_org_kiwix_kiwixlib_JNIKiwixReader_getContentPa return data; } +JNIEXPORT jobject JNICALL +Java_org_kiwix_kiwixlib_JNIKiwixReadear_getDirectAccessInformation( + JNIEnv* env, jobject obj, jstring url) +{ + jclass classPair = env->FindClass("org/kiwix/kiwixlib/Pair"); + jmethodID midPairinit = env->GetMethodID(classPair, "", "(D)"); + jobject pair = env->NewObject(classPair, midPairinit); + setPairObjValue("", 0, pair, env); + + std::string cUrl = jni2c(url, env); + try { + zim::Article article; + READER->getArticleObjectByDecodedUrl(kiwix::urlDecode(cUrl), article); + if (! article.good()) { + return pair; + } + int loopCounter = 0; + while (article.isRedirect() && loopCounter++ < 42) { + article = article.getRedirectArticle(); + } + if (loopCounter == 42) { + return pair; + } + + auto part_info = article.getDirectAccessInformation(); + setPairObjValue(part_info.first, part_info.second, pair, env); + } catch (...) { + std::cerr << "Unable to locate direct access information for url " << cUrl + << std::endl; + + } + return pair; +} + JNIEXPORT jboolean JNICALL Java_org_kiwix_kiwixlib_JNIKiwixReader_searchSuggestions(JNIEnv* env, jobject obj, diff --git a/src/android/meson.build b/src/android/meson.build index be6aeab24..39ebe198a 100644 --- a/src/android/meson.build +++ b/src/android/meson.build @@ -7,7 +7,8 @@ kiwix_jni = custom_target('jni', 'org/kiwix/kiwixlib/JNIKiwixSearcher.java', 'org/kiwix/kiwixlib/JNIKiwixInt.java', 'org/kiwix/kiwixlib/JNIKiwixString.java', - 'org/kiwix/kiwixlib/JNIKiwixBool.java'], + 'org/kiwix/kiwixlib/JNIKiwixBool.java', + 'org/kiwix/kiwixlib/Pair.java'], output: ['org_kiwix_kiwixlib_JNIKiwix.h', 'org_kiwix_kiwixlib_JNIKiwixReader.h', 'org_kiwix_kiwixlib_JNIKiwixSearcher.h', diff --git a/src/android/org/kiwix/kiwixlib/JNIKiwixReader.java b/src/android/org/kiwix/kiwixlib/JNIKiwixReader.java index ffae39d0c..e204f9aba 100644 --- a/src/android/org/kiwix/kiwixlib/JNIKiwixReader.java +++ b/src/android/org/kiwix/kiwixlib/JNIKiwixReader.java @@ -23,6 +23,7 @@ package org.kiwix.kiwixlib; import org.kiwix.kiwixlib.JNIKiwixString; import org.kiwix.kiwixlib.JNIKiwixInt; import org.kiwix.kiwixlib.JNIKiwixSearcher; +import org.kiwix.kiwixlib.Pair; public class JNIKiwixReader { @@ -56,6 +57,24 @@ public class JNIKiwixReader int len, JNIKiwixInt size); + /** + * 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 `Pair` (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 Pair getDirectAccessInformation(String url); + public native boolean searchSuggestions(String prefix, int count); public native boolean getNextSuggestion(JNIKiwixString title); diff --git a/src/android/org/kiwix/kiwixlib/Pair.java b/src/android/org/kiwix/kiwixlib/Pair.java new file mode 100644 index 000000000..ef49e1b33 --- /dev/null +++ b/src/android/org/kiwix/kiwixlib/Pair.java @@ -0,0 +1,26 @@ +/* + * 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. + */ + +package org.kiwix.kiwixlib; + +public class Pair +{ + public String filename; + public int offset; +} diff --git a/src/android/utils.h b/src/android/utils.h index f61114730..3c164e353 100644 --- a/src/android/utils.h +++ b/src/android/utils.h @@ -137,4 +137,14 @@ inline void setBoolObjValue(const bool value, const jobject obj, JNIEnv* env) env->SetIntField(obj, objFid, c2jni(value)); } +inline void setPairObjValue(const std::string& filename, const int 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", "I"); + env->SetIntField(obj, offsetFid, offset); +} + #endif // _ANDROID_JNI_UTILS_H