1use binrw::{BinRead, BinWrite};
2
3pub type JdwpIdSize = u8;
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub struct JdwpIdSizes {
6 pub field_id_size: JdwpIdSize,
7 pub method_id_size: JdwpIdSize,
8 pub object_id_size: JdwpIdSize,
9 pub reference_type_id_size: JdwpIdSize,
10 pub frame_id_size: JdwpIdSize,
11}
12
13#[derive(Debug)]
14pub struct JdwpString {
15 pub string: String,
16}
17impl BinRead for JdwpString {
18 type Args<'a> = ();
19
20 fn read_options<R: std::io::Read + std::io::Seek>(
21 reader: &mut R,
22 endian: binrw::Endian,
23 args: Self::Args<'_>,
24 ) -> binrw::BinResult<Self> {
25 let length = u32::read_options(reader, endian, args)?;
26 if length == 0 {
27 return Ok(JdwpString {
28 string: String::from(""),
29 });
30 }
31
32 let mut bytes = vec![0u8; length as usize];
33 reader.read_exact(&mut bytes)?;
34 Ok(JdwpString {
35 string: String::from_utf8(bytes).map_err(|e| binrw::Error::Custom {
36 pos: reader.stream_position().unwrap_or(0),
37 err: Box::new(e),
38 })?,
39 })
40 }
41}
42impl BinWrite for JdwpString {
43 type Args<'a> = ();
44
45 fn write_options<W: std::io::Write + std::io::Seek>(
46 &self,
47 writer: &mut W,
48 endian: binrw::Endian,
49 args: Self::Args<'_>,
50 ) -> binrw::BinResult<()> {
51 let bytes = self.string.as_bytes();
52 let length = bytes.len() as u32;
53 length.write_options(writer, endian, args)?;
54
55 if length > 0 {
56 return bytes.write_options(writer, endian, args);
57 }
58 Ok(())
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65 use std::io::Cursor;
66
67 #[test]
68 fn test_read_jdwp_string_empty() {
69 let data = [0u8, 0u8, 0u8, 0u8]; let mut cursor = Cursor::new(&data);
71 let value = JdwpString::read_be(&mut cursor).unwrap();
72 assert!(value.string.is_empty());
73 }
74
75 #[test]
76 fn test_read_jdwp_string() {
77 let data = [0u8, 0u8, 0u8, 4u8, 74u8, 68u8, 87u8, 80u8]; let mut cursor = Cursor::new(&data);
79 let value = JdwpString::read_be(&mut cursor).unwrap();
80 assert_eq!(value.string, "JDWP");
81 }
82
83 #[test]
84 fn test_write_jdwp_string() {
85 let value = JdwpString {
86 string: String::from("JDWP"),
87 };
88 let mut buffer: Vec<u8> = vec![];
89 let mut cursor = Cursor::new(&mut buffer);
90 value.write_be(&mut cursor).unwrap();
91
92 let expected = [0u8, 0u8, 0u8, 4u8, 74u8, 68u8, 87u8, 80u8]; assert_eq!(buffer, expected);
94 }
95
96 #[test]
97 fn test_write_jdwp_string_empty() {
98 let value = JdwpString {
99 string: String::from(""),
100 };
101 let mut buffer: Vec<u8> = vec![];
102 let mut cursor = Cursor::new(&mut buffer);
103 value.write_be(&mut cursor).unwrap();
104
105 let expected = [0u8, 0u8, 0u8, 0u8]; assert_eq!(buffer, expected);
107 }
108}