cure_java_simplify/
jdk.rs1use std::sync::OnceLock;
14
15const JAVA_BASE_PKGS: &[&str] = &[
17 "java.io",
18 "java.lang",
19 "java.lang.annotation",
20 "java.lang.constant",
21 "java.lang.invoke",
22 "java.lang.module",
23 "java.lang.ref",
24 "java.lang.reflect",
25 "java.math",
26 "java.net",
27 "java.net.spi",
28 "java.nio",
29 "java.nio.channels",
30 "java.nio.channels.spi",
31 "java.nio.charset",
32 "java.nio.charset.spi",
33 "java.nio.file",
34 "java.nio.file.attribute",
35 "java.nio.file.spi",
36 "java.security",
37 "java.security.cert",
38 "java.security.interfaces",
39 "java.security.spec",
40 "java.text",
41 "java.text.spi",
42 "java.time",
43 "java.time.chrono",
44 "java.time.format",
45 "java.time.temporal",
46 "java.time.zone",
47 "java.util",
48 "java.util.concurrent",
49 "java.util.concurrent.atomic",
50 "java.util.concurrent.locks",
51 "java.util.function",
52 "java.util.jar",
53 "java.util.logging",
54 "java.util.prefs",
55 "java.util.random",
56 "java.util.regex",
57 "java.util.spi",
58 "java.util.stream",
59 "java.util.zip",
60 "javax.crypto",
61 "javax.crypto.interfaces",
62 "javax.crypto.spec",
63 "javax.net",
64 "javax.net.ssl",
65 "javax.security.auth",
66 "javax.security.auth.callback",
67 "javax.security.auth.login",
68 "javax.security.auth.spi",
69 "javax.security.auth.x500",
70 "javax.security.cert",
71];
72
73fn java_base_prefix(name: &str) -> bool {
74 let base = name.split('$').next().unwrap_or(name);
76 let base = base.trim();
77 JAVA_BASE_PKGS
78 .iter()
79 .any(|p| base == *p || base.starts_with(p) && base.as_bytes().get(p.len()) == Some(&b'.'))
80}
81
82static JDK_SRC: OnceLock<Option<std::sync::Arc<Vec<u8>>>> = OnceLock::new();
84
85pub fn set_jdk_home(path: &std::path::Path) {
87 let zip = path.join("lib").join("src.zip");
88 if let Ok(data) = std::fs::read(&zip) {
89 let _ = JDK_SRC.set(Some(std::sync::Arc::new(data)));
90 }
91}
92
93fn jdk_src() -> Option<std::sync::Arc<Vec<u8>>> {
94 if let Some(v) = JDK_SRC.get() {
95 return v.clone();
96 }
97 if let Ok(p) = std::env::var("CURE_JDK_HOME") {
98 set_jdk_home(std::path::Path::new(&p));
99 }
100 JDK_SRC.get().cloned().flatten()
101}
102
103pub fn class_loads(name: &str) -> bool {
106 if let Some(src) = jdk_src() {
107 let slash: String = name.replace('.', "/");
110 let needle = format!("{}.java", slash);
111 return find_sub(&src, needle.as_bytes());
112 }
113 java_base_prefix(name)
114}
115
116fn find_sub(hay: &[u8], needle: &[u8]) -> bool {
117 if needle.is_empty() || hay.len() < needle.len() {
118 return false;
119 }
120 let n = needle.len();
121 let first = needle[0];
122 let mut i = 0usize;
123 let last = hay.len() - n;
124 while i <= last {
125 if hay[i] == first && &hay[i..i + n] == needle {
126 return true;
127 }
128 i += 1;
129 }
130 false
131}