-
-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathhash_map_values.rs
More file actions
109 lines (83 loc) · 5.11 KB
/
Copy pathhash_map_values.rs
File metadata and controls
109 lines (83 loc) · 5.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
use alloc::vec;
use java_class_proto::{JavaFieldProto, JavaMethodProto};
use java_constants::MethodAccessFlags;
use jvm::{ClassInstanceRef, Jvm, Result};
use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object};
use super::HashMap;
// class java.util.HashMap$Values
pub struct HashMapValues;
impl HashMapValues {
pub fn as_proto() -> RuntimeClassProto {
RuntimeClassProto {
name: "java/util/HashMap$Values",
parent_class: Some("java/util/AbstractCollection"),
interfaces: vec![],
methods: vec![
JavaMethodProto::new("<init>", "(Ljava/util/HashMap;)V", Self::init, Default::default()),
JavaMethodProto::new("size", "()I", Self::size, Default::default()),
JavaMethodProto::new("isEmpty", "()Z", Self::is_empty, Default::default()),
JavaMethodProto::new("contains", "(Ljava/lang/Object;)Z", Self::contains, Default::default()),
JavaMethodProto::new("remove", "(Ljava/lang/Object;)Z", Self::remove, MethodAccessFlags::PUBLIC),
JavaMethodProto::new("clear", "()V", Self::clear, Default::default()),
JavaMethodProto::new("iterator", "()Ljava/util/Iterator;", Self::iterator, Default::default()),
],
fields: vec![JavaFieldProto::new("map", "Ljava/util/HashMap;", Default::default())],
access_flags: Default::default(),
}
}
async fn init(jvm: &Jvm, _: &mut RuntimeContext, mut this: ClassInstanceRef<Self>, map: ClassInstanceRef<HashMap>) -> Result<()> {
tracing::debug!("java.util.HashMap$Values::<init>({this:?}, {map:?})");
let _: () = jvm.invoke_special(&this, "java/util/AbstractCollection", "<init>", "()V", ()).await?;
jvm.put_field(&mut this, "map", "Ljava/util/HashMap;", map).await?;
Ok(())
}
async fn size(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef<Self>) -> Result<i32> {
tracing::debug!("java.util.HashMap$Values::size({this:?})");
let map: ClassInstanceRef<HashMap> = jvm.get_field(&this, "map", "Ljava/util/HashMap;").await?;
jvm.invoke_virtual(&map, "size", "()I", ()).await
}
async fn is_empty(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef<Self>) -> Result<bool> {
tracing::debug!("java.util.HashMap$Values::isEmpty({this:?})");
let map: ClassInstanceRef<HashMap> = jvm.get_field(&this, "map", "Ljava/util/HashMap;").await?;
jvm.invoke_virtual(&map, "isEmpty", "()Z", ()).await
}
async fn contains(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef<Self>, value: ClassInstanceRef<Object>) -> Result<bool> {
tracing::debug!("java.util.HashMap$Values::contains({this:?}, {value:?})");
let map: ClassInstanceRef<HashMap> = jvm.get_field(&this, "map", "Ljava/util/HashMap;").await?;
jvm.invoke_virtual(&map, "containsValue", "(Ljava/lang/Object;)Z", (value,)).await
}
async fn remove(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef<Self>, value: ClassInstanceRef<Object>) -> Result<bool> {
tracing::debug!("java.util.HashMap$Values::remove({this:?}, {value:?})");
let map: ClassInstanceRef<HashMap> = jvm.get_field(&this, "map", "Ljava/util/HashMap;").await?;
let iterator: ClassInstanceRef<Object> = jvm.invoke_virtual(&map, "entryIterator", "()Ljava/util/Iterator;", ()).await?;
while jvm.invoke_virtual::<_, bool>(&iterator, "hasNext", "()Z", ()).await? {
let entry: ClassInstanceRef<Object> = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?;
let entry_value: ClassInstanceRef<Object> = jvm.invoke_virtual(&entry, "getValue", "()Ljava/lang/Object;", ()).await?;
let equal = if value.is_null() {
entry_value.is_null()
} else if entry_value.is_null() {
false
} else {
jvm.invoke_virtual(&value, "equals", "(Ljava/lang/Object;)Z", (entry_value,)).await?
};
if equal {
let key: ClassInstanceRef<Object> = jvm.invoke_virtual(&entry, "getKey", "()Ljava/lang/Object;", ()).await?;
let _: ClassInstanceRef<Object> = jvm
.invoke_virtual(&map, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;", (key,))
.await?;
return Ok(true);
}
}
Ok(false)
}
async fn clear(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef<Self>) -> Result<()> {
tracing::debug!("java.util.HashMap$Values::clear({this:?})");
let map: ClassInstanceRef<HashMap> = jvm.get_field(&this, "map", "Ljava/util/HashMap;").await?;
jvm.invoke_virtual(&map, "clear", "()V", ()).await
}
async fn iterator(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef<Self>) -> Result<ClassInstanceRef<Object>> {
tracing::debug!("java.util.HashMap$Values::iterator({this:?})");
let map: ClassInstanceRef<HashMap> = jvm.get_field(&this, "map", "Ljava/util/HashMap;").await?;
jvm.invoke_virtual(&map, "valueIterator", "()Ljava/util/Iterator;", ()).await
}
}