From c6919c39c6b0ef2086d41f92ee05a13d43ae7cbf Mon Sep 17 00:00:00 2001 From: tarsin Date: Wed, 14 Jun 2023 12:41:44 +0800 Subject: [PATCH] Move favParser to rust --- .../ehviewer/client/parser/FavoritesParser.kt | 26 +++-------- .../ehviewer/client/parser/HomeParser.kt | 2 +- app/src/main/rust/Cargo.toml | 2 + app/src/main/rust/src/lib.rs | 44 ++++++++++++++++--- 4 files changed, 45 insertions(+), 29 deletions(-) diff --git a/app/src/main/java/com/hippo/ehviewer/client/parser/FavoritesParser.kt b/app/src/main/java/com/hippo/ehviewer/client/parser/FavoritesParser.kt index f8ecae941..30486f552 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/parser/FavoritesParser.kt +++ b/app/src/main/java/com/hippo/ehviewer/client/parser/FavoritesParser.kt @@ -18,9 +18,6 @@ package com.hippo.ehviewer.client.parser import com.hippo.ehviewer.R import com.hippo.ehviewer.client.exception.EhException import com.hippo.ehviewer.client.exception.ParseException -import com.hippo.ehviewer.util.ExceptionUtils -import com.hippo.ehviewer.util.JsoupUtils -import org.jsoup.Jsoup import splitties.init.appCtx object FavoritesParser { @@ -29,24 +26,9 @@ object FavoritesParser { throw EhException(appCtx.getString(R.string.need_sign_in)) } val catArray = arrayOfNulls(10) - val countArray = IntArray(10) - val d = Jsoup.parse(body) - runCatching { - val ido = JsoupUtils.getElementByClass(d, "ido") - val fps = ido!!.getElementsByClass("fp") - // Last one is "fp fps" - check(fps.size == 11) - for (i in 0..9) { - val fp = fps[i] - countArray[i] = ParserUtils.parseInt(fp.child(0).text(), 0) - catArray[i] = ParserUtils.trim(fp.child(2).text()) - } - }.onFailure { - ExceptionUtils.throwIfFatal(it) - it.printStackTrace() - throw ParseException("Parse favorites error", body) - } - val result = GalleryListParser.parse(d, body) + val countArray = parseFav(body, catArray) + if (countArray.isEmpty()) throw ParseException("Parse favorites error", body) + val result = GalleryListParser.parse(body) return Result(catArray.requireNoNulls(), countArray, result) } @@ -60,3 +42,5 @@ object FavoritesParser { val galleryInfoList = galleryListResult.galleryInfoList } } + +private external fun parseFav(body: String, favCat: Array): IntArray diff --git a/app/src/main/java/com/hippo/ehviewer/client/parser/HomeParser.kt b/app/src/main/java/com/hippo/ehviewer/client/parser/HomeParser.kt index 705923b5a..f4fdb1098 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/parser/HomeParser.kt +++ b/app/src/main/java/com/hippo/ehviewer/client/parser/HomeParser.kt @@ -10,7 +10,7 @@ object HomeParser { fun parse(body: String): Limits { val value = parseLimit(body) - if (value[0] == -1) throw ParseException("Parse image limits error", body) + if (value.isEmpty()) throw ParseException("Parse image limits error", body) return Limits(value[0], value[1], value[2]) } diff --git a/app/src/main/rust/Cargo.toml b/app/src/main/rust/Cargo.toml index 596989200..52e8fee96 100644 --- a/app/src/main/rust/Cargo.toml +++ b/app/src/main/rust/Cargo.toml @@ -8,3 +8,5 @@ crate_type = ["cdylib"] [dependencies] jni = "*" tl = "*" +log = "*" +android_logger = "*" diff --git a/app/src/main/rust/src/lib.rs b/app/src/main/rust/src/lib.rs index c82859436..72d4fed2f 100644 --- a/app/src/main/rust/src/lib.rs +++ b/app/src/main/rust/src/lib.rs @@ -1,27 +1,57 @@ +extern crate android_logger; extern crate jni; +extern crate log; extern crate tl; +use std::ffi::c_void; + +use android_logger::Config; use jni::JNIEnv; -use jni::objects::{JClass, JString}; -use jni::sys::jintArray; +use jni::objects::{JClass, JObjectArray, JString}; +use jni::sys::{JavaVM, jint, jintArray, JNI_VERSION_1_6}; use tl::{Parser, VDom}; fn parse_jni_string(env: &mut JNIEnv, str: &JString, mut f: F) -> Option - where F: FnMut(&VDom, &Parser) -> Option { + where F: FnMut(&VDom, &Parser, &JNIEnv) -> Option { let html = env.get_string(str).ok()?; let dom = tl::parse(html.to_str().ok()?, tl::ParserOptions::default()).ok()?; let parser = dom.parser(); - Some(f(&dom, parser)?) + Some(f(&dom, parser, env)?) } #[no_mangle] -pub extern "system" fn Java_com_hippo_ehviewer_client_parser_HomeParserKt_parseLimit<'local>(mut env: JNIEnv<'local>, _class: JClass<'local>, input: JString<'local>) -> jintArray { - let vec = parse_jni_string(&mut env, &input, |dom, parser| { +pub extern "system" fn Java_com_hippo_ehviewer_client_parser_HomeParserKt_parseLimit(mut env: JNIEnv, _class: JClass, input: JString) -> jintArray { + let vec = parse_jni_string(&mut env, &input, |dom, parser, _env| { let iter = dom.query_selector("strong")?; let vec: Vec = iter.filter_map(|e| Some(e.get(parser)?.inner_text(parser).parse::().ok()?)).collect(); if vec.len() == 3 { Some(vec) } else { None } - }).unwrap_or(vec![-1, -1, -1]); + }).unwrap_or(vec![]); let jir = env.new_int_array(3).unwrap(); env.set_int_array_region(&jir, 0, &vec).unwrap(); jir.into_raw() } + +#[no_mangle] +pub extern "system" fn Java_com_hippo_ehviewer_client_parser_FavoritesParserKt_parseFav(mut env: JNIEnv, _class: JClass, input: JString, str: JObjectArray) -> jintArray { + let vec = parse_jni_string(&mut env, &input, |dom, parser, env| { + let fp = dom.get_elements_by_class_name("fp"); + let vec: Vec = fp.enumerate().filter_map(|(i, e)| { + if i == 10 { return None; } + let top = e.get(parser)?.children()?; + let children = top.top(); + let cat = children[5].get(parser)?.inner_text(parser); + env.set_object_array_element(&str, i as i32, env.new_string(cat.trim()).ok()?).ok()?; + Some(children[1].get(parser)?.inner_text(parser).parse::().ok()?) + }).collect(); + if vec.len() == 10 { Some(vec) } else { None } + }).unwrap_or(vec![]); + let jir = env.new_int_array(10).unwrap(); + env.set_int_array_region(&jir, 0, &vec).unwrap(); + jir.into_raw() +} + +#[no_mangle] +pub extern "system" fn JNI_OnLoad(_: JavaVM, _: *mut c_void) -> jint { + android_logger::init_once(Config::default()); + JNI_VERSION_1_6 +}