From 82c92203b623db8cd147da0bb60c7e7b9af1aed5 Mon Sep 17 00:00:00 2001 From: tarsin Date: Mon, 12 Jun 2023 15:36:58 +0800 Subject: [PATCH] Initial refactor HomeParser with rust --- .../java/com/hippo/ehviewer/EhApplication.kt | 1 + .../ehviewer/client/parser/HomeParser.kt | 22 +- app/src/main/rust/Cargo.lock | 308 +++++++++++++++++- app/src/main/rust/Cargo.toml | 7 +- app/src/main/rust/src/lib.rs | 34 +- 5 files changed, 354 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/com/hippo/ehviewer/EhApplication.kt b/app/src/main/java/com/hippo/ehviewer/EhApplication.kt index bdb9e38b6..d9752e6a6 100644 --- a/app/src/main/java/com/hippo/ehviewer/EhApplication.kt +++ b/app/src/main/java/com/hippo/ehviewer/EhApplication.kt @@ -68,6 +68,7 @@ class EhApplication : Application(), ImageLoaderFactory { } super.onCreate() System.loadLibrary("ehviewer") + System.loadLibrary("ehviewer_rust") ReadableTime.initialize(this) launchIO { val theme = Settings.theme 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 49828c8ad..79b343e18 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 @@ -3,24 +3,16 @@ package com.hippo.ehviewer.client.parser import android.os.Parcelable import com.hippo.ehviewer.client.exception.ParseException import kotlinx.parcelize.Parcelize -import org.jsoup.Jsoup object HomeParser { - private val PATTERN_FUNDS = - Regex("Available: ([\\d,]+) Credits.*Available: ([\\d,]+) kGP", RegexOption.DOT_MATCHES_ALL) + private val PATTERN_FUNDS = Regex("Available: ([\\d,]+) Credits.*Available: ([\\d,]+) kGP", RegexOption.DOT_MATCHES_ALL) private const val RESET_SUCCEED = "Image limit was successfully reset." fun parse(body: String): Limits { - Jsoup.parse(body).selectFirst("div.homebox")?.let { - val es = it.select("p > strong") - if (es.size == 3) { - val current = ParserUtils.parseInt(es[0].text(), 0) - val maximum = ParserUtils.parseInt(es[1].text(), 0) - val resetCost = ParserUtils.parseInt(es[2].text(), 0) - return Limits(current, maximum, resetCost) - } - } - throw ParseException("Parse image limits error", body) + val value = parseLimit(body) + check(value.size == 3) + if (value[0] == -1) throw ParseException("Parse image limits error", body) + return Limits(value[0], value[1], value[2]) } fun parseResetLimits(body: String): Limits? { @@ -41,9 +33,11 @@ object HomeParser { } @Parcelize - data class Limits(val current: Int = 0, val maximum: Int, val resetCost: Int = 0) : Parcelable + data class Limits(val current: Int = 0, val maximum: Int = 0, val resetCost: Int = 0) : Parcelable @Parcelize data class Funds(val fundsGP: Int, val fundsC: Int) : Parcelable class Result(val limits: Limits, val funds: Funds) } + +private external fun parseLimit(body: String): IntArray diff --git a/app/src/main/rust/Cargo.lock b/app/src/main/rust/Cargo.lock index 4c12743ce..ef3247cc4 100644 --- a/app/src/main/rust/Cargo.lock +++ b/app/src/main/rust/Cargo.lock @@ -2,6 +2,312 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "aho-corasick" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +dependencies = [ + "memchr", +] + +[[package]] +name = "android_log-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27f0fc03f560e1aebde41c2398b691cb98b5ea5996a6184a7a67bbbb77448969" + +[[package]] +name = "android_logger" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fa490e751f3878eb9accb9f18988eca52c2337ce000a8bf31ef50d4c723ca9e" +dependencies = [ + "android_log-sys", + "env_logger", + "log", + "once_cell", +] + +[[package]] +name = "bytes" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" + +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "combine" +version = "4.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" +dependencies = [ + "bytes", + "memchr", +] + [[package]] name = "ehviewer_rust" -version = "0.1.0" +version = "0.0.0" +dependencies = [ + "android_logger", + "jni", + "log", + "regex", + "tl", +] + +[[package]] +name = "env_logger" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", + "windows-sys", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "log" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "proc-macro2" +version = "1.0.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "regex" +version = "1.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "syn" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tl" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5e993a1c7c32fdf90a308cec4d457f507b2573acc909bd6e7a092321664fdb3" + +[[package]] +name = "unicode-ident" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" + +[[package]] +name = "walkdir" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" diff --git a/app/src/main/rust/Cargo.toml b/app/src/main/rust/Cargo.toml index 5c26e0a6e..6306d9366 100644 --- a/app/src/main/rust/Cargo.toml +++ b/app/src/main/rust/Cargo.toml @@ -1,8 +1,13 @@ [package] name = "ehviewer_rust" -version = "0.1.0" +version = "0.0.0" [lib] crate_type = ["cdylib"] [dependencies] +jni = "*" +tl = "*" +regex = "*" +android_logger = "*" +log = "*" diff --git a/app/src/main/rust/src/lib.rs b/app/src/main/rust/src/lib.rs index aa0e8287e..93fe0cad7 100644 --- a/app/src/main/rust/src/lib.rs +++ b/app/src/main/rust/src/lib.rs @@ -1,3 +1,33 @@ -fn main() { - println!(""); +extern crate android_logger; +extern crate jni; +extern crate log; + +use android_logger::Config; +use jni::JNIEnv; +use jni::objects::{JClass, JString}; +use jni::sys::jintArray; +use log::LevelFilter; + +fn parse_limit(body: &str) -> Option> { + let dom = tl::parse(body, tl::ParserOptions::default()).ok()?; + let parser = dom.parser(); + let home_box = dom.query_selector("div.homebox")?.next()?.get(parser)?; + let html2 = home_box.inner_html(parser); + let dom2 = tl::parse(&*html2, tl::ParserOptions::default()).ok()?; + let parser = dom2.parser(); + let mut iter = dom2.query_selector("strong")?; + let v1 = iter.next()?.get(parser)?.inner_text(parser).parse::().unwrap_or(0); + let v2 = iter.next()?.get(parser)?.inner_text(parser).parse::().unwrap_or(0); + let v3 = iter.next()?.get(parser)?.inner_text(parser).parse::().unwrap_or(0); + Some(vec![v1, v2, v3]) +} + +#[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 { + android_logger::init_once(Config::default().with_max_level(LevelFilter::Trace)); + let html = env.get_string(input.as_ref()).unwrap(); + let vec = parse_limit(html.to_str().unwrap()); + let jir = env.new_int_array(3).unwrap(); + env.set_int_array_region(&jir, 0, vec.unwrap_or(vec![-1, -1, -1]).as_ref()).unwrap(); + jir.into_raw() }