From 45a5bae8b2f9110283ea859e2494b1e45d09f828 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <99822064+revonateB0T@users.noreply.github.com>
Date: Tue, 5 Nov 2024 17:39:03 +0800
Subject: [PATCH] Group rust ffi code (#1893)
* Group rust ffi code
Signed-off-by: Dude so hot
* Fix
Signed-off-by: Dude so hot
* Fix
Signed-off-by: Dude so hot
* Refine
Signed-off-by: Dude so hot
---------
Signed-off-by: Dude so hot
Co-authored-by: Dude so hot
---
app/src/main/cpp/CMakeLists.txt | 4 +-
app/src/main/rust/Cargo.toml | 10 +-
app/src/main/rust/src/ffi.rs | 3 +
app/src/main/rust/src/ffi/android.rs | 55 +++++++
.../src/{img/copy_ahb.rs => ffi/android_o.rs} | 5 +-
app/src/main/rust/src/ffi/jvm.rs | 143 ++++++++++++++++++
app/src/main/rust/src/img.rs | 5 +-
app/src/main/rust/src/img/border.rs | 21 +--
app/src/main/rust/src/img/qr_code.rs | 17 +--
app/src/main/rust/src/lib.rs | 114 +-------------
app/src/main/rust/src/parser.rs | 10 +-
app/src/main/rust/src/parser/config.rs | 23 +--
app/src/main/rust/src/parser/fav.rs | 20 +--
app/src/main/rust/src/parser/home.rs | 21 +--
app/src/main/rust/src/parser/list.rs | 16 +-
app/src/main/rust/src/parser/torrent.rs | 20 +--
16 files changed, 246 insertions(+), 241 deletions(-)
create mode 100644 app/src/main/rust/src/ffi.rs
create mode 100644 app/src/main/rust/src/ffi/android.rs
rename app/src/main/rust/src/{img/copy_ahb.rs => ffi/android_o.rs} (92%)
create mode 100644 app/src/main/rust/src/ffi/jvm.rs
diff --git a/app/src/main/cpp/CMakeLists.txt b/app/src/main/cpp/CMakeLists.txt
index df0a894e4..392a04320 100644
--- a/app/src/main/cpp/CMakeLists.txt
+++ b/app/src/main/cpp/CMakeLists.txt
@@ -111,7 +111,9 @@ FetchContent_MakeAvailable(Corrosion)
corrosion_import_crate(MANIFEST_PATH ../rust/Cargo.toml LOCKED)
corrosion_add_target_local_rustflags(ehviewer_rust "-Clink-args=-Wl,-z,max-page-size=16384")
if (ANDROID_NATIVE_API_LEVEL GREATER_EQUAL 26)
- corrosion_set_features(ehviewer_rust FEATURES api-level-26)
+ corrosion_set_features(ehviewer_rust FEATURES android-26)
+else ()
+ corrosion_set_features(ehviewer_rust FEATURES android)
endif ()
# Build and link our app's native lib
diff --git a/app/src/main/rust/Cargo.toml b/app/src/main/rust/Cargo.toml
index 026965063..4ecf040ae 100644
--- a/app/src/main/rust/Cargo.toml
+++ b/app/src/main/rust/Cargo.toml
@@ -7,12 +7,14 @@ edition = "2021"
crate-type = ["cdylib"]
[features]
-api-level-26 = ["ndk/api-level-26"]
+jvm = ["dep:jni", "dep:jni_fn"]
+android = ["dep:ndk", "jvm", "ndk/bitmap"]
+android-26 = ["android", "ndk/api-level-26"]
[dependencies]
regex-lite = "0.1"
-jni = "0.21"
-jni_fn = "0.1"
+jni = { version = "0.21", optional = true }
+jni_fn = { version = "0.1", optional = true }
quick-xml = { default-features = false, version = "0.37" }
tl = "0.7"
log = "0.4"
@@ -22,7 +24,7 @@ serde = { version = "1.0", features = ["derive"] }
anyhow = "1.0"
image = { default-features = false, version = "0.25" }
rxing = { default-features = false, version = "0.6" }
-ndk = { version = "0.9", features = ["bitmap"] }
+ndk = { version = "0.9", optional = true }
[profile.release]
panic = "abort"
diff --git a/app/src/main/rust/src/ffi.rs b/app/src/main/rust/src/ffi.rs
new file mode 100644
index 000000000..a0de50146
--- /dev/null
+++ b/app/src/main/rust/src/ffi.rs
@@ -0,0 +1,3 @@
+mod android;
+mod android_o;
+mod jvm;
diff --git a/app/src/main/rust/src/ffi/android.rs b/app/src/main/rust/src/ffi/android.rs
new file mode 100644
index 000000000..e54709ac9
--- /dev/null
+++ b/app/src/main/rust/src/ffi/android.rs
@@ -0,0 +1,55 @@
+#![cfg(feature = "android")]
+
+use super::jvm::jni_throwing;
+use crate::img::border::detect_border;
+use crate::img::qr_code::detect_image_ad;
+use anyhow::{Context, Result};
+use image::{ImageBuffer, Rgba};
+use jni::objects::JClass;
+use jni::sys::jboolean;
+use jni::sys::{jintArray, jobject};
+use jni::JNIEnv;
+use jni_fn::jni_fn;
+use ndk::bitmap::Bitmap;
+use std::ptr::slice_from_raw_parts;
+
+#[no_mangle]
+#[allow(non_snake_case)]
+#[jni_fn("com.hippo.ehviewer.image.ImageKt")]
+pub fn detectBorder(mut env: JNIEnv, _class: JClass, object: jobject) -> jintArray {
+ jni_throwing(&mut env, |env| {
+ let slice = with_bitmap_content(env, object, |img| Ok(detect_border(&img)))?;
+ let array = env.new_int_array(4)?;
+ env.set_int_array_region(&array, 0, &slice.context("Image too small!")?)?;
+ Ok(array.into_raw())
+ })
+}
+
+#[no_mangle]
+#[allow(non_snake_case)]
+#[jni_fn("com.hippo.ehviewer.image.ImageKt")]
+pub fn hasQrCode(mut env: JNIEnv, _class: JClass, object: jobject) -> jboolean {
+ jni_throwing(&mut env, |env| {
+ with_bitmap_content(env, object, |image| Ok(detect_image_ad(image) as jboolean))
+ })
+}
+
+pub fn with_bitmap_content(env: &mut JNIEnv, bitmap: jobject, f: F) -> Result
+where
+ F: FnOnce(ImageBuffer, &[u8]>) -> Result,
+{
+ // SAFETY: kotlin caller must ensure bitmap is valid.
+ let handle = unsafe { Bitmap::from_jni(env.get_raw(), bitmap) };
+
+ let info = handle.info()?;
+ let (width, height) = (info.width(), info.height());
+ let ptr = handle.lock_pixels()? as *const u8;
+
+ // SAFETY: maybe unsafe if bitmap buffer not RGBA8888 format.
+ let buffer = unsafe { &*slice_from_raw_parts(ptr, (width * height * 4) as usize) };
+
+ let image = ImageBuffer::from_raw(width, height, buffer);
+ let result = image.context("Image buffer not RGBA8888!!!").and_then(f);
+ handle.unlock_pixels()?;
+ result
+}
diff --git a/app/src/main/rust/src/img/copy_ahb.rs b/app/src/main/rust/src/ffi/android_o.rs
similarity index 92%
rename from app/src/main/rust/src/img/copy_ahb.rs
rename to app/src/main/rust/src/ffi/android_o.rs
index 9b85f0c48..4ab3dee2a 100644
--- a/app/src/main/rust/src/img/copy_ahb.rs
+++ b/app/src/main/rust/src/ffi/android_o.rs
@@ -1,6 +1,7 @@
-#![cfg(feature = "api-level-26")]
+#![cfg(feature = "android-26")]
-use crate::{jni_throwing, with_bitmap_content};
+use super::android::with_bitmap_content;
+use super::jvm::jni_throwing;
use anyhow::Context;
use image::{GenericImage, GenericImageView, ImageBuffer};
use jni::objects::JClass;
diff --git a/app/src/main/rust/src/ffi/jvm.rs b/app/src/main/rust/src/ffi/jvm.rs
new file mode 100644
index 000000000..b7193a90b
--- /dev/null
+++ b/app/src/main/rust/src/ffi/jvm.rs
@@ -0,0 +1,143 @@
+#![cfg(feature = "jvm")]
+
+use crate::parser::config::parse_fav_cat;
+use crate::parser::fav::parse_fav;
+use crate::parser::home::parse_limit;
+use crate::parser::list::parse_info_list;
+use crate::parser::torrent::parse_torrent_list;
+use crate::EhError;
+use android_logger::Config;
+use anyhow::{ensure, Context, Result};
+use jni::objects::{JByteBuffer, JClass};
+use jni::sys::{jboolean, jint, jobject, JNI_VERSION_1_6};
+use jni::{JNIEnv, JavaVM};
+use jni_fn::jni_fn;
+use log::LevelFilter;
+use serde::Serialize;
+use std::ffi::c_void;
+use std::io::Cursor;
+use std::ptr::slice_from_raw_parts_mut;
+use std::str::from_utf8_unchecked;
+use tl::{ParserOptions, VDom};
+
+#[no_mangle]
+#[allow(non_snake_case)]
+#[jni_fn("com.hippo.ehviewer.client.parser.FavoritesParserKt")]
+pub fn parseFav(mut env: JNIEnv, _class: JClass, input: JByteBuffer, limit: jint) -> jint {
+ parse_marshal_inplace(&mut env, input, limit, |dom, html| {
+ parse_fav(dom, dom.parser(), html)
+ })
+}
+
+#[no_mangle]
+#[allow(non_snake_case)]
+#[jni_fn("com.hippo.ehviewer.client.parser.HomeParserKt")]
+pub fn parseLimit(mut env: JNIEnv, _class: JClass, input: JByteBuffer, limit: jint) -> jint {
+ parse_marshal_inplace(&mut env, input, limit, |dom, _| {
+ parse_limit(dom, dom.parser()).context("Can't parse Limit")
+ })
+}
+
+#[no_mangle]
+#[allow(non_snake_case)]
+#[jni_fn("com.hippo.ehviewer.client.parser.GalleryListParserKt")]
+pub fn parseGalleryInfoList(mut env: JNIEnv, _: JClass, buffer: JByteBuffer, limit: jint) -> jint {
+ parse_marshal_inplace(&mut env, buffer, limit, |dom, str| {
+ parse_info_list(dom, dom.parser(), str)
+ })
+}
+
+#[no_mangle]
+#[allow(non_snake_case)]
+#[jni_fn("com.hippo.ehviewer.client.parser.TorrentParserKt")]
+pub fn parseTorrent(mut env: JNIEnv, _class: JClass, buffer: JByteBuffer, limit: jint) -> jint {
+ parse_marshal_inplace(&mut env, buffer, limit, |dom, _| {
+ parse_torrent_list(dom, dom.parser())
+ })
+}
+
+#[no_mangle]
+#[allow(non_snake_case)]
+#[jni_fn("com.hippo.ehviewer.client.parser.UserConfigParser")]
+pub fn parseFavCat(mut env: JNIEnv, _class: JClass, buffer: JByteBuffer, limit: jint) -> jint {
+ parse_marshal_inplace(&mut env, buffer, limit, |_, body| Ok(parse_fav_cat(body)))
+}
+
+fn deref_mut_direct_bytebuffer<'local>(
+ env: &JNIEnv,
+ buffer: JByteBuffer<'local>,
+) -> Result<&'local mut [u8]> {
+ let ptr = env.get_direct_buffer_address(&buffer)?;
+ let cap = env.get_direct_buffer_capacity(&buffer)?;
+
+ // SAFETY: jni contract, buffer must alive through native call.
+ Ok(unsafe { &mut *slice_from_raw_parts_mut(ptr, cap) })
+}
+
+pub trait ThrowingHasDefault {
+ fn default() -> Self;
+}
+
+impl ThrowingHasDefault for jboolean {
+ fn default() -> Self {
+ 0 as jboolean
+ }
+}
+
+impl ThrowingHasDefault for jobject {
+ fn default() -> Self {
+ 0 as jobject
+ }
+}
+
+impl ThrowingHasDefault for i32 {
+ fn default() -> Self {
+ 0
+ }
+}
+
+impl ThrowingHasDefault for () {
+ fn default() -> Self {}
+}
+
+pub fn jni_throwing(env: &mut JNIEnv, f: F) -> R
+where
+ F: FnOnce(&mut JNIEnv) -> Result,
+ R: ThrowingHasDefault,
+{
+ match f(env) {
+ Ok(value) => value,
+ Err(err) => {
+ let msg = format!("{err}");
+ env.throw_new("java/lang/RuntimeException", msg).ok();
+ R::default()
+ }
+ }
+}
+
+pub fn parse_marshal_inplace(env: &mut JNIEnv, str: JByteBuffer, limit: jint, f: F) -> i32
+where
+ F: Fn(&VDom, &str) -> Result,
+ R: Serialize,
+{
+ jni_throwing(env, |env| {
+ let buffer = deref_mut_direct_bytebuffer(env, str)?;
+ let value = {
+ // SAFETY: ktor client ensure html content is valid utf-8.
+ let html = unsafe { from_utf8_unchecked(&buffer[..limit as usize]) };
+
+ let dom = tl::parse(html, ParserOptions::default())?;
+ ensure!(dom.version().is_some(), EhError::Error(html.to_string()));
+ f(&dom, html)?
+ };
+ let mut cursor = Cursor::new(buffer);
+ serde_cbor::to_writer(&mut cursor, &value)?;
+ Ok(cursor.position() as i32)
+ })
+}
+
+#[no_mangle]
+pub extern "system" fn JNI_OnLoad(_: JavaVM, _: *mut c_void) -> jint {
+ android_logger::init_once(Config::default().with_max_level(LevelFilter::Debug));
+ JNI_VERSION_1_6
+}
diff --git a/app/src/main/rust/src/img.rs b/app/src/main/rust/src/img.rs
index aca9e08ae..9a2fb15ea 100644
--- a/app/src/main/rust/src/img.rs
+++ b/app/src/main/rust/src/img.rs
@@ -1,3 +1,2 @@
-mod border;
-mod copy_ahb;
-mod qr_code;
+pub mod border;
+pub mod qr_code;
diff --git a/app/src/main/rust/src/img/border.rs b/app/src/main/rust/src/img/border.rs
index a7e7fbb35..8e0ad68c1 100644
--- a/app/src/main/rust/src/img/border.rs
+++ b/app/src/main/rust/src/img/border.rs
@@ -1,10 +1,4 @@
-use crate::{jni_throwing, with_bitmap_content};
-use anyhow::Context;
use image::{ImageBuffer, Luma, Pixel, Rgba};
-use jni::objects::JClass;
-use jni::sys::{jintArray, jobject};
-use jni::JNIEnv;
-use jni_fn::jni_fn;
/** A line will be considered as having content if 0.25% of it is filled. */
static FILLED_RATIO_LIMIT: f32 = 0.0025;
@@ -72,7 +66,8 @@ fn detect_border_lines<'pixel>(
}
}
-fn detect_border(image: &ImageBuffer, &[u8]>) -> Option<[i32; 4]> {
+#[allow(dead_code)]
+pub fn detect_border(image: &ImageBuffer, &[u8]>) -> Option<[i32; 4]> {
let (w, h) = image.dimensions();
let top = detect_border_lines(image.rows(), w);
let bottom = detect_border_lines(image.rows().rev(), w);
@@ -81,15 +76,3 @@ fn detect_border(image: &ImageBuffer, &[u8]>) -> Option<[i32; 4]> {
let right = detect_border_lines(iter.rev(), h);
Some([left, top, w as i32 - right, h as i32 - bottom])
}
-
-#[no_mangle]
-#[allow(non_snake_case)]
-#[jni_fn("com.hippo.ehviewer.image.ImageKt")]
-pub fn detectBorder(mut env: JNIEnv, _class: JClass, object: jobject) -> jintArray {
- jni_throwing(&mut env, |env| {
- let slice = with_bitmap_content(env, object, |img| Ok(detect_border(&img)))?;
- let array = env.new_int_array(4)?;
- env.set_int_array_region(&array, 0, &slice.context("Image too small!")?)?;
- Ok(array.into_raw())
- })
-}
diff --git a/app/src/main/rust/src/img/qr_code.rs b/app/src/main/rust/src/img/qr_code.rs
index e23c3b108..1e2e324ed 100644
--- a/app/src/main/rust/src/img/qr_code.rs
+++ b/app/src/main/rust/src/img/qr_code.rs
@@ -1,16 +1,12 @@
-use crate::{jni_throwing, with_bitmap_content};
use image::{ImageBuffer, Rgba};
-use jni::objects::JClass;
-use jni::sys::{jboolean, jobject};
-use jni::JNIEnv;
-use jni_fn::jni_fn;
use rxing::common::HybridBinarizer;
use rxing::qrcode::detector::FinderPatternFinder;
use rxing::{BinaryBitmap, DecodingHintDictionary, Point, RGBLuminanceSource};
use std::f32::consts::FRAC_1_SQRT_2;
use std::ptr::slice_from_raw_parts;
-fn detect_image_ad(image: ImageBuffer, &[u8]>) -> bool {
+#[allow(dead_code)]
+pub fn detect_image_ad(image: ImageBuffer, &[u8]>) -> bool {
let (width, height) = (image.width() as usize, image.height() as usize);
let buffer = image.into_raw();
let pixels = unsafe { &*slice_from_raw_parts(buffer.as_ptr() as *const u32, buffer.len()) };
@@ -30,12 +26,3 @@ fn detect_image_ad(image: ImageBuffer, &[u8]>) -> bool {
Err(_) => false,
}
}
-
-#[no_mangle]
-#[allow(non_snake_case)]
-#[jni_fn("com.hippo.ehviewer.image.ImageKt")]
-pub fn hasQrCode(mut env: JNIEnv, _class: JClass, object: jobject) -> jboolean {
- jni_throwing(&mut env, |env| {
- with_bitmap_content(env, object, |image| Ok(detect_image_ad(image) as jboolean))
- })
-}
diff --git a/app/src/main/rust/src/lib.rs b/app/src/main/rust/src/lib.rs
index f800314a1..98d56e621 100644
--- a/app/src/main/rust/src/lib.rs
+++ b/app/src/main/rust/src/lib.rs
@@ -1,21 +1,8 @@
+mod ffi;
mod img;
mod parser;
-use android_logger::Config;
-use anyhow::{ensure, Context, Result};
-use image::{ImageBuffer, Rgba};
-use jni::objects::JByteBuffer;
-use jni::sys::{jboolean, jint, jobject, JavaVM, JNI_VERSION_1_6};
-use jni::JNIEnv;
-use log::LevelFilter;
-use ndk::bitmap::Bitmap;
-use serde::Serialize;
-use std::ffi::c_void;
use std::fmt::{Debug, Display, Formatter};
-use std::io::Cursor;
-use std::ptr::{slice_from_raw_parts, slice_from_raw_parts_mut};
-use std::str::from_utf8_unchecked;
-use tl::ParserOptions;
use tl::{Bytes, Node, NodeHandle, Parser, VDom};
#[macro_export]
@@ -58,43 +45,6 @@ where
handle.get(parser)
}
-fn deref_mut_direct_bytebuffer<'local>(
- env: &JNIEnv,
- buffer: JByteBuffer<'local>,
-) -> Result<&'local mut [u8]> {
- let ptr = env.get_direct_buffer_address(&buffer)?;
- let cap = env.get_direct_buffer_capacity(&buffer)?;
-
- // SAFETY: jni contract, buffer must alive through native call.
- Ok(unsafe { &mut *slice_from_raw_parts_mut(ptr, cap) })
-}
-
-trait ThrowingHasDefault {
- fn default() -> Self;
-}
-
-impl ThrowingHasDefault for jboolean {
- fn default() -> Self {
- 0 as jboolean
- }
-}
-
-impl ThrowingHasDefault for jobject {
- fn default() -> Self {
- 0 as jobject
- }
-}
-
-impl ThrowingHasDefault for i32 {
- fn default() -> Self {
- 0
- }
-}
-
-impl ThrowingHasDefault for () {
- fn default() -> Self {}
-}
-
#[derive(Debug)]
enum EhError {
NoHits,
@@ -115,42 +65,6 @@ impl Display for EhError {
}
}
-fn jni_throwing(env: &mut JNIEnv, f: F) -> R
-where
- F: FnOnce(&mut JNIEnv) -> Result,
- R: ThrowingHasDefault,
-{
- match f(env) {
- Ok(value) => value,
- Err(err) => {
- let msg = format!("{err}");
- env.throw_new("java/lang/RuntimeException", msg).ok();
- R::default()
- }
- }
-}
-
-fn parse_marshal_inplace(env: &mut JNIEnv, str: JByteBuffer, limit: jint, f: F) -> i32
-where
- F: Fn(&VDom, &str) -> Result,
- R: Serialize,
-{
- jni_throwing(env, |env| {
- let buffer = deref_mut_direct_bytebuffer(env, str)?;
- let value = {
- // SAFETY: ktor client ensure html content is valid utf-8.
- let html = unsafe { from_utf8_unchecked(&buffer[..limit as usize]) };
-
- let dom = tl::parse(html, ParserOptions::default())?;
- ensure!(dom.version().is_some(), EhError::Error(html.to_string()));
- f(&dom, html)?
- };
- let mut cursor = Cursor::new(buffer);
- serde_cbor::to_writer(&mut cursor, &value)?;
- Ok(cursor.position() as i32)
- })
-}
-
fn get_node_handle_attr<'a>(
node: &NodeHandle,
parser: &'a Parser,
@@ -173,29 +87,3 @@ fn query_childs_first_match_attr<'a>(
let mut iter = node.as_tag()?.query_selector(parser, &selector)?;
get_node_handle_attr(&iter.next()?, parser, attr)
}
-
-fn with_bitmap_content(env: &mut JNIEnv, bitmap: jobject, f: F) -> Result
-where
- F: FnOnce(ImageBuffer, &[u8]>) -> Result,
-{
- // SAFETY: kotlin caller must ensure bitmap is valid.
- let handle = unsafe { Bitmap::from_jni(env.get_raw(), bitmap) };
-
- let info = handle.info()?;
- let (width, height) = (info.width(), info.height());
- let ptr = handle.lock_pixels()? as *const u8;
-
- // SAFETY: maybe unsafe if bitmap buffer not RGBA8888 format.
- let buffer = unsafe { &*slice_from_raw_parts(ptr, (width * height * 4) as usize) };
-
- let image = ImageBuffer::from_raw(width, height, buffer);
- let result = image.context("Image buffer not RGBA8888!!!").and_then(f);
- handle.unlock_pixels()?;
- result
-}
-
-#[no_mangle]
-pub extern "system" fn JNI_OnLoad(_: JavaVM, _: *mut c_void) -> jint {
- android_logger::init_once(Config::default().with_max_level(LevelFilter::Debug));
- JNI_VERSION_1_6
-}
diff --git a/app/src/main/rust/src/parser.rs b/app/src/main/rust/src/parser.rs
index b1188dc1d..05fb27d87 100644
--- a/app/src/main/rust/src/parser.rs
+++ b/app/src/main/rust/src/parser.rs
@@ -1,5 +1,5 @@
-mod config;
-mod fav;
-mod home;
-mod list;
-mod torrent;
+pub mod config;
+pub mod fav;
+pub mod home;
+pub mod list;
+pub mod torrent;
diff --git a/app/src/main/rust/src/parser/config.rs b/app/src/main/rust/src/parser/config.rs
index 640c1454f..a2118ad5b 100644
--- a/app/src/main/rust/src/parser/config.rs
+++ b/app/src/main/rust/src/parser/config.rs
@@ -1,19 +1,10 @@
-use crate::{parse_marshal_inplace, regex};
-use jni::objects::{JByteBuffer, JClass};
-use jni::sys::jint;
-use jni::JNIEnv;
-use jni_fn::jni_fn;
+use crate::regex;
use quick_xml::escape::unescape;
-#[no_mangle]
-#[allow(non_snake_case)]
-#[jni_fn("com.hippo.ehviewer.client.parser.UserConfigParser")]
-pub fn parseFavCat(mut env: JNIEnv, _class: JClass, buffer: JByteBuffer, limit: jint) -> jint {
- parse_marshal_inplace(&mut env, buffer, limit, |_, body| {
- let cat = regex!(">();
- Ok(cat)
- })
+#[allow(dead_code)]
+pub fn parse_fav_cat(html: &str) -> Vec {
+ regex!(",
countArray: Vec,
galleryListResult: GalleryListResult,
}
-fn parse_fav(dom: &VDom, parser: &Parser, html: &str) -> Result {
+#[allow(dead_code)]
+pub fn parse_fav(dom: &VDom, parser: &Parser, html: &str) -> Result {
if html.contains("This page requires you to log on.
") {
bail!(EhError::NeedLogin)
}
@@ -53,12 +50,3 @@ fn parse_fav(dom: &VDom, parser: &Parser, html: &str) -> Result {
bail!("Illegal fav cat count!")
}
}
-
-#[no_mangle]
-#[allow(non_snake_case)]
-#[jni_fn("com.hippo.ehviewer.client.parser.FavoritesParserKt")]
-pub fn parseFav(mut env: JNIEnv, _class: JClass, input: JByteBuffer, limit: jint) -> jint {
- parse_marshal_inplace(&mut env, input, limit, |dom, html| {
- parse_fav(dom, dom.parser(), html)
- })
-}
diff --git a/app/src/main/rust/src/parser/home.rs b/app/src/main/rust/src/parser/home.rs
index 568782726..ff2d41e43 100644
--- a/app/src/main/rust/src/parser/home.rs
+++ b/app/src/main/rust/src/parser/home.rs
@@ -1,22 +1,18 @@
-use crate::{get_vdom_first_element_by_class_name, parse_marshal_inplace};
-use anyhow::Context;
-use jni::objects::{JByteBuffer, JClass};
-use jni::sys::jint;
-use jni::JNIEnv;
-use jni_fn::jni_fn;
+use crate::get_vdom_first_element_by_class_name;
use serde::Serialize;
use tl::Parser;
use tl::VDom;
#[allow(non_snake_case)]
#[derive(Serialize)]
-struct Limits {
+pub struct Limits {
current: i32,
maximum: i32,
resetCost: i32,
}
-fn parse_limit(dom: &VDom, parser: &Parser) -> Option {
+#[allow(dead_code)]
+pub fn parse_limit(dom: &VDom, parser: &Parser) -> Option {
let limit_box = get_vdom_first_element_by_class_name(dom, "homebox")?.as_tag()?;
let vec = limit_box
.query_selector(parser, "strong")?
@@ -46,12 +42,3 @@ fn parse_limit(dom: &VDom, parser: &Parser) -> Option {
_ => None,
}
}
-
-#[no_mangle]
-#[allow(non_snake_case)]
-#[jni_fn("com.hippo.ehviewer.client.parser.HomeParserKt")]
-pub fn parseLimit(mut env: JNIEnv, _class: JClass, input: JByteBuffer, limit: jint) -> jint {
- parse_marshal_inplace(&mut env, input, limit, |dom, _| {
- parse_limit(dom, dom.parser()).context("Can't parse Limit")
- })
-}
diff --git a/app/src/main/rust/src/parser/list.rs b/app/src/main/rust/src/parser/list.rs
index 2da10d6e5..0af6f9282 100644
--- a/app/src/main/rust/src/parser/list.rs
+++ b/app/src/main/rust/src/parser/list.rs
@@ -1,13 +1,9 @@
+use crate::EhError;
use crate::{get_element_by_id, get_vdom_first_element_by_class_name};
use crate::{get_first_element_by_class_name, query_childs_first_match_attr};
use crate::{get_node_attr, get_node_handle_attr, regex};
-use crate::{parse_marshal_inplace, EhError};
use crate::{EHGT_PREFIX, EX_PREFIX};
use anyhow::{bail, Context, Result};
-use jni::objects::{JByteBuffer, JClass};
-use jni::sys::jint;
-use jni::JNIEnv;
-use jni_fn::jni_fn;
use quick_xml::escape::unescape;
use serde::Serialize;
use std::borrow::Cow;
@@ -197,6 +193,7 @@ fn parse_gallery_info(node: &Node, parser: &Parser) -> Option {
})
}
+#[allow(dead_code)]
pub fn parse_info_list(dom: &VDom, parser: &Parser, str: &str) -> Result {
if str.contains("You do not have any watched tags") {
bail!(EhError::NoWatched)
@@ -241,12 +238,3 @@ pub fn parse_info_list(dom: &VDom, parser: &Parser, str: &str) -> Result jint {
- parse_marshal_inplace(&mut env, buffer, limit, |dom, str| {
- parse_info_list(dom, dom.parser(), str)
- })
-}
diff --git a/app/src/main/rust/src/parser/torrent.rs b/app/src/main/rust/src/parser/torrent.rs
index 76beb57e7..d69849e50 100644
--- a/app/src/main/rust/src/parser/torrent.rs
+++ b/app/src/main/rust/src/parser/torrent.rs
@@ -1,15 +1,11 @@
-use crate::{parse_marshal_inplace, regex};
+use crate::regex;
use anyhow::{Context, Result};
-use jni::objects::{JByteBuffer, JClass};
-use jni::sys::jint;
-use jni::JNIEnv;
-use jni_fn::jni_fn;
use quick_xml::escape::unescape;
use serde::Serialize;
use tl::{Parser, VDom};
#[derive(Serialize)]
-struct Torrent {
+pub struct Torrent {
outdated: bool,
posted: String,
size: String,
@@ -21,7 +17,8 @@ struct Torrent {
name: String,
}
-fn parse_torrent_list(dom: &VDom, parser: &Parser) -> Result> {
+#[allow(dead_code)]
+pub fn parse_torrent_list(dom: &VDom, parser: &Parser) -> Result> {
let list = dom.query_selector("table").context("No Table")?.filter_map(|e| {
let html = e.get(parser)?.inner_html(parser);
if html.contains("Expunged") {
@@ -44,12 +41,3 @@ fn parse_torrent_list(dom: &VDom, parser: &Parser) -> Result> {
}).collect::>();
Ok(list)
}
-
-#[no_mangle]
-#[allow(non_snake_case)]
-#[jni_fn("com.hippo.ehviewer.client.parser.TorrentParserKt")]
-pub fn parseTorrent(mut env: JNIEnv, _class: JClass, buffer: JByteBuffer, limit: jint) -> jint {
- parse_marshal_inplace(&mut env, buffer, limit, |dom, _| {
- parse_torrent_list(dom, dom.parser())
- })
-}