Somewhat recursive string construction
This commit is contained in:
parent
4dabd6c3a8
commit
3c4921aa54
9 changed files with 1130 additions and 185 deletions
|
@ -5,7 +5,7 @@ use core::str::Utf8Error;
|
|||
|
||||
use crate::accessmasks::*;
|
||||
use crate::bytecode::Bytecode;
|
||||
use crate::constantpool::{ ConstantPoolInfo, ConstantUtf8Info, ConstantMethodRefInfo, ConstantClassInfo, ConstantNameAndTypeInfo, ConstantIntegerInfo };
|
||||
use crate::constantpool::{ ConstantFieldRefInfo, ConstantPoolInfo, ConstantUtf8Info, ConstantStringInfo, ConstantMethodRefInfo, ConstantClassInfo, ConstantNameAndTypeInfo, ConstantIntegerInfo, ConstantLongInfo };
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
|
@ -217,6 +217,17 @@ impl JavaClassFile {
|
|||
return Ok(methodref_entry);
|
||||
}
|
||||
|
||||
pub fn pool_fieldref_entry(&self, index: u16) -> Result<&ConstantFieldRefInfo, Error> {
|
||||
let pool_entry = self.pool_entry(index)?;
|
||||
|
||||
let fieldref_entry = match pool_entry {
|
||||
ConstantPoolInfo::FieldRef(data) => data,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
return Ok(fieldref_entry);
|
||||
}
|
||||
|
||||
pub fn pool_class_entry(&self, index: u16) -> Result<&ConstantClassInfo, Error> {
|
||||
let pool_entry = self.pool_entry(index)?;
|
||||
|
||||
|
@ -235,6 +246,15 @@ impl JavaClassFile {
|
|||
};
|
||||
}
|
||||
|
||||
pub fn pool_long_entry(&self, index: u16) -> Result<&ConstantLongInfo, Error> {
|
||||
let pool_entry = self.pool_entry(index)?;
|
||||
|
||||
return match pool_entry {
|
||||
ConstantPoolInfo::Long(data) => Ok(data),
|
||||
_ => Err(Error::BadFileError(format!("Expected constant pool entry {} in class {} to be of type Long but found {:?}", index, self.get_classname()?, pool_entry)))
|
||||
};
|
||||
}
|
||||
|
||||
pub fn pool_int_entry(&self, index: u16) -> Result<&ConstantIntegerInfo, Error> {
|
||||
let pool_entry = self.pool_entry(index)?;
|
||||
|
||||
|
@ -253,6 +273,47 @@ impl JavaClassFile {
|
|||
};
|
||||
}
|
||||
|
||||
pub fn pool_string_entry(&self, index: u16) -> Result<&ConstantStringInfo, Error> {
|
||||
let pool_entry = self.pool_entry(index)?;
|
||||
|
||||
return match pool_entry {
|
||||
ConstantPoolInfo::String(data) => Ok(data),
|
||||
_ => Err(Error::BadFileError(format!("Expected constant pool entry {} in class {} to be of type String but found {:?}", index, self.get_classname()?, pool_entry)))
|
||||
};
|
||||
}
|
||||
|
||||
pub fn gather_string(&self, index: u16) -> Result<&String, Error> {
|
||||
let string = self.pool_string_entry(index)?;
|
||||
|
||||
return Ok(&(self.pool_utf8_entry(string.string_index)?.utf8));
|
||||
}
|
||||
|
||||
pub fn gather_nameandtype(&self, index: u16) -> Result<(&String, &String), Error> {
|
||||
let nameandtype = self.pool_nameandtype_entry(index)?;
|
||||
|
||||
let name = &self.pool_utf8_entry(nameandtype.name_index)?.utf8;
|
||||
let descriptor = &self.pool_utf8_entry(nameandtype.descriptor_index)?.utf8;
|
||||
|
||||
Ok((name, descriptor))
|
||||
}
|
||||
|
||||
pub fn gather_fieldref(&self, index: u16) -> Result<(&String, &String, &String), Error> {
|
||||
let fieldref = self.pool_fieldref_entry(index)?;
|
||||
|
||||
let (field_name, field_descriptor) = self.gather_nameandtype(fieldref.name_and_type_index)?;
|
||||
let class_name = self.gather_class(fieldref.class_index)?;
|
||||
|
||||
Ok((class_name, field_name, field_descriptor))
|
||||
}
|
||||
|
||||
pub fn gather_class(&self, index: u16) -> Result<&String, Error> {
|
||||
let class_entry = self.pool_class_entry(index)?;
|
||||
let class_name_entry = self.pool_utf8_entry(class_entry.name_index)?;
|
||||
let class_name = &class_name_entry.utf8;
|
||||
|
||||
Ok(class_name)
|
||||
}
|
||||
|
||||
pub fn gather_methodref(&self, index: u16) -> Result<(&String, &String, &String), Error> {
|
||||
let methodref = self.pool_methodref_entry(index)?;
|
||||
let class_entry = self.pool_class_entry(methodref.class_index)?;
|
||||
|
@ -671,7 +732,7 @@ impl ExceptionAttributeData {
|
|||
}
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
#[derive(Debug, Eq, PartialEq, Clone, Hash)]
|
||||
pub enum AbstractTypeKind {
|
||||
Void() = b'V', // void
|
||||
Byte() = b'B', // signed byte
|
||||
|
@ -702,7 +763,7 @@ impl Into<String> for &AbstractTypeKind {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
#[derive(Debug, Eq, PartialEq, Clone, Hash)]
|
||||
pub struct AbstractTypeDescription {
|
||||
pub array_level: u8,
|
||||
pub kind: AbstractTypeKind,
|
||||
|
@ -725,7 +786,7 @@ impl Into<String> for &AbstractTypeDescription {
|
|||
}
|
||||
|
||||
impl AbstractTypeDescription {
|
||||
fn parse_first(s: &str) -> Result<(usize, Self), Error> {
|
||||
pub fn parse_first(s: &str) -> Result<(usize, Self), Error> {
|
||||
let mut offset: usize = 0;
|
||||
let arrays_parsed = s.trim_start_matches("[");
|
||||
let array_level = (s.len() - arrays_parsed.len()).try_into();
|
||||
|
@ -757,7 +818,7 @@ impl AbstractTypeDescription {
|
|||
|
||||
AbstractTypeKind::Classname(classname_string.to_string())
|
||||
}
|
||||
_ => return Err(Error::BadFileError(format!("Invalid Type character: '{}' in string \"{}\"", type_char, s))),
|
||||
_ => return Err(Error::BadFileError(format!("Invalid Type character: '{}' in string '{}'", type_char, s))),
|
||||
};
|
||||
|
||||
return Ok((offset, AbstractTypeDescription { array_level, kind }))
|
||||
|
@ -809,13 +870,14 @@ impl TryFrom<&String> for MethodDescriptor {
|
|||
|
||||
s.get(total_offset..).unwrap()
|
||||
.strip_prefix(")")
|
||||
// unreachable?
|
||||
.ok_or(Error::BadFileError(format!("Bad method descriptor")))?;
|
||||
total_offset += 1;
|
||||
|
||||
|
||||
let (offset, return_type) = AbstractTypeDescription::parse_first(s.get(total_offset..).unwrap())?;
|
||||
if offset != s.get(total_offset..).unwrap().len() {
|
||||
return Err(Error::BadFileError(format!("Trailing characters in method descriptor string: \"{}\"", s)))
|
||||
return Err(Error::BadFileError(format!("Trailing characters in method descriptor string: '{}'", s)))
|
||||
}
|
||||
|
||||
Ok(
|
||||
|
@ -942,11 +1004,11 @@ pub fn read_i32(reader: &mut dyn Read) -> Result<i32, std::io::Error> {
|
|||
return Ok(i32::from_be_bytes(buffer));
|
||||
}
|
||||
|
||||
pub fn read_u64(reader: &mut dyn Read) -> Result<u64, std::io::Error> {
|
||||
let high_bytes: u64 = read_u32(reader)?.into();
|
||||
let low_bytes: u64 = read_u32(reader)?.into();
|
||||
pub fn read_i64(reader: &mut dyn Read) -> Result<i64, std::io::Error> {
|
||||
let mut buffer: [u8; 8] = [0; 8];
|
||||
reader.read_exact(&mut buffer)?;
|
||||
|
||||
return Ok((high_bytes << 32) | low_bytes);
|
||||
return Ok(i64::from_be_bytes(buffer));
|
||||
}
|
||||
|
||||
pub fn read_u32(reader: &mut dyn Read) -> Result<u32, std::io::Error> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue