diff --git a/include/reader.h b/include/reader.h index d36e44da9..263617c9d 100644 --- a/include/reader.h +++ b/include/reader.h @@ -55,7 +55,8 @@ class Reader * unsplitted path as if the file were not splitted * (.zim extesion). */ - Reader(const string zimFilePath); + explicit Reader(const string zimFilePath); + explicit Reader(int fd); ~Reader() = default; /** diff --git a/src/reader.cpp b/src/reader.cpp index 173dbbb93..51bdaf28d 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -86,6 +86,15 @@ Reader::Reader(const string zimFilePath) srand(time(nullptr)); } +Reader::Reader(int fd) + : zimArchive(new zim::Archive(fd)), + zimFilePath("") +{ + + /* initialize random seed: */ + srand(time(nullptr)); +} + zim::Archive* Reader::getZimArchive() const { return zimArchive.get(); diff --git a/src/wrapper/java/kiwixreader.cpp b/src/wrapper/java/kiwixreader.cpp index e55d54f8d..e62eb3084 100644 --- a/src/wrapper/java/kiwixreader.cpp +++ b/src/wrapper/java/kiwixreader.cpp @@ -45,6 +45,35 @@ JNIEXPORT jlong JNICALL Java_org_kiwix_kiwixlib_JNIKiwixReader_getNativeReader( } } +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"); + return env->GetIntField(fdObj, field_fd); +} + +} // unnamed namespace + +JNIEXPORT jlong JNICALL Java_org_kiwix_kiwixlib_JNIKiwixReader_getNativeReaderByFD( + JNIEnv* env, jobject obj, jobject fdObj) +{ + int fd = jni2fd(fdObj, env); + + LOG("Attempting to create reader with fd: %d", fd); + Lock l; + try { + kiwix::Reader* reader = new kiwix::Reader(fd); + return reinterpret_cast(new Handle(reader)); + } catch (std::exception& e) { + LOG("Error opening ZIM file"); + LOG(e.what()); + return 0; + } +} + JNIEXPORT void JNICALL Java_org_kiwix_kiwixlib_JNIKiwixReader_dispose(JNIEnv* env, jobject obj) { diff --git a/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixReader.java b/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixReader.java index f94c3dc6f..fe5e39e6c 100644 --- a/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixReader.java +++ b/src/wrapper/java/org/kiwix/kiwixlib/JNIKiwixReader.java @@ -25,6 +25,7 @@ import org.kiwix.kiwixlib.JNIKiwixString; import org.kiwix.kiwixlib.JNIKiwixInt; import org.kiwix.kiwixlib.JNIKiwixSearcher; import org.kiwix.kiwixlib.Pair; +import java.io.FileDescriptor; public class JNIKiwixReader { @@ -151,11 +152,21 @@ public class JNIKiwixReader throw new JNIKiwixException("Cannot open zimfile "+filename); } } + + public JNIKiwixReader(FileDescriptor fd) throws JNIKiwixException + { + nativeHandle = getNativeReaderByFD(fd); + if (nativeHandle == 0) { + throw new JNIKiwixException("Cannot open zimfile by fd "+fd.toString()); + } + } + public JNIKiwixReader() { } public native void dispose(); private native long getNativeReader(String filename); + private native long getNativeReaderByFD(FileDescriptor fd); private long nativeHandle; } diff --git a/src/wrapper/java/org/kiwix/testing/test.java b/src/wrapper/java/org/kiwix/testing/test.java index cc0879fda..c0eb7f044 100644 --- a/src/wrapper/java/org/kiwix/testing/test.java +++ b/src/wrapper/java/org/kiwix/testing/test.java @@ -41,6 +41,24 @@ throws JNIKiwixException, IOException } +@Test +public void testReaderByFd() +throws JNIKiwixException, IOException +{ + FileInputStream fis = new FileInputStream("small.zim"); + JNIKiwixReader reader = new JNIKiwixReader(fis.getFD()); + assertEquals("Test ZIM file", reader.getTitle()); + assertEquals(45, reader.getFileSize()); // The file size is in KiB + assertEquals("A/main.html", reader.getMainPage()); + String s = getFileContent("small_zimfile_data/main.html"); + byte[] c = reader.getContent(new JNIKiwixString("A/main.html"), + new JNIKiwixString(), + new JNIKiwixString(), + new JNIKiwixInt()); + assertEquals(s, new String(c)); + +} + @Test public void testLibrary() throws IOException