add encoded scalar values
This commit is contained in:
parent
49d6094d6f
commit
6020b173a0
4 changed files with 713 additions and 0 deletions
18
androscalpel_serializer/src/annotation.rs
Normal file
18
androscalpel_serializer/src/annotation.rs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
use crate::{ReadSeek, Result, Serializable};
|
||||
use std::io::Write;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct EncodedAnnotation;
|
||||
|
||||
impl Serializable for EncodedAnnotation {
|
||||
fn serialize(&self, _output: &mut dyn Write) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
fn deserialize(_input: &mut dyn ReadSeek) -> Result<Self> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn size(&self) -> usize {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
18
androscalpel_serializer/src/array.rs
Normal file
18
androscalpel_serializer/src/array.rs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
use crate::{ReadSeek, Result, Serializable};
|
||||
use std::io::Write;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct EncodedArray;
|
||||
|
||||
impl Serializable for EncodedArray {
|
||||
fn serialize(&self, _output: &mut dyn Write) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
fn deserialize(_input: &mut dyn ReadSeek) -> Result<Self> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn size(&self) -> usize {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,13 @@
|
|||
pub mod annotation;
|
||||
pub mod array;
|
||||
pub mod constant;
|
||||
pub mod core;
|
||||
pub mod value;
|
||||
|
||||
pub use androscalpel_serializer_derive::*;
|
||||
|
||||
pub use crate::core::*;
|
||||
pub use annotation::*;
|
||||
pub use array::*;
|
||||
pub use constant::*;
|
||||
pub use value::*;
|
||||
|
|
|
|||
671
androscalpel_serializer/src/value.rs
Normal file
671
androscalpel_serializer/src/value.rs
Normal file
|
|
@ -0,0 +1,671 @@
|
|||
//! The encoded value format: https://source.android.com/docs/core/runtime/dex-format#encoding
|
||||
|
||||
use crate::{EncodedAnnotation, EncodedArray, Error, ReadSeek, Result, Serializable};
|
||||
use std::io::Write;
|
||||
|
||||
// TODO: TESTS!!!
|
||||
/// An encoded value of arbitrary hierachically structured data:
|
||||
/// https://source.android.com/docs/core/runtime/dex-format#encoding
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum EncodedValue {
|
||||
Byte(i8),
|
||||
Short(i16),
|
||||
Char(u16),
|
||||
Int(i32),
|
||||
Long(i64),
|
||||
Float(f32),
|
||||
Double(f64),
|
||||
MethodType(u32),
|
||||
MethodHandle(u32),
|
||||
String(u32),
|
||||
Type(u32),
|
||||
Field(u32),
|
||||
Method(u32),
|
||||
Enum(u32),
|
||||
Array(EncodedArray),
|
||||
Annotation(EncodedAnnotation),
|
||||
Null,
|
||||
Boolean(bool),
|
||||
}
|
||||
|
||||
/// The id of a type used by a value.
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
struct ValueType(u8);
|
||||
|
||||
const VALUE_BYTE: ValueType = ValueType(0x00);
|
||||
const VALUE_SHORT: ValueType = ValueType(0x02);
|
||||
const VALUE_CHAR: ValueType = ValueType(0x03);
|
||||
const VALUE_INT: ValueType = ValueType(0x04);
|
||||
const VALUE_LONG: ValueType = ValueType(0x06);
|
||||
const VALUE_FLOAT: ValueType = ValueType(0x10);
|
||||
const VALUE_DOUBLE: ValueType = ValueType(0x11);
|
||||
const VALUE_METHOD_TYPE: ValueType = ValueType(0x15);
|
||||
const VALUE_METHOD_HANDLE: ValueType = ValueType(0x16);
|
||||
const VALUE_STRING: ValueType = ValueType(0x17);
|
||||
const VALUE_TYPE: ValueType = ValueType(0x18);
|
||||
const VALUE_FIELD: ValueType = ValueType(0x19);
|
||||
const VALUE_METHOD: ValueType = ValueType(0x1a);
|
||||
const VALUE_ENUM: ValueType = ValueType(0x1b);
|
||||
const VALUE_ARRAY: ValueType = ValueType(0x1c);
|
||||
const VALUE_ANNOTATION: ValueType = ValueType(0x1d);
|
||||
const VALUE_NULL: ValueType = ValueType(0x1e);
|
||||
const VALUE_BOOLEAN: ValueType = ValueType(0x1f);
|
||||
|
||||
impl PartialEq for EncodedValue {
|
||||
fn eq(&self, item: &Self) -> bool {
|
||||
match (self, item) {
|
||||
(Self::Byte(val1), Self::Byte(val2)) => val1 == val2,
|
||||
(Self::Short(val1), Self::Short(val2)) => val1 == val2,
|
||||
(Self::Char(val1), Self::Char(val2)) => val1 == val2,
|
||||
(Self::Int(val1), Self::Int(val2)) => val1 == val2,
|
||||
(Self::Long(val1), Self::Long(val2)) => val1 == val2,
|
||||
(Self::Float(val1), Self::Float(val2)) => val1.to_be_bytes() == val2.to_be_bytes(),
|
||||
(Self::Double(val1), Self::Double(val2)) => val1.to_be_bytes() == val2.to_be_bytes(),
|
||||
(Self::MethodType(val1), Self::MethodType(val2)) => val1 == val2,
|
||||
(Self::MethodHandle(val1), Self::MethodHandle(val2)) => val1 == val2,
|
||||
(Self::String(val1), Self::String(val2)) => val1 == val2,
|
||||
(Self::Type(val1), Self::Type(val2)) => val1 == val2,
|
||||
(Self::Field(val1), Self::Field(val2)) => val1 == val2,
|
||||
(Self::Method(val1), Self::Method(val2)) => val1 == val2,
|
||||
(Self::Enum(val1), Self::Enum(val2)) => val1 == val2,
|
||||
(Self::Array(val1), Self::Array(val2)) => val1 == val2,
|
||||
(Self::Annotation(val1), Self::Annotation(val2)) => val1 == val2,
|
||||
(Self::Null, Self::Null) => true,
|
||||
(Self::Boolean(val1), Self::Boolean(val2)) => val1 == val2,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for EncodedValue {}
|
||||
|
||||
impl Serializable for EncodedValue {
|
||||
fn serialize(&self, output: &mut dyn Write) -> Result<()> {
|
||||
match self {
|
||||
Self::Byte(byte) => {
|
||||
let bytes = byte.to_be_bytes();
|
||||
output.write_all(&[VALUE_BYTE.0]).map_err(|err| {
|
||||
Error::SerializationError(format!(
|
||||
"Failed to write serialized Byte to output: {err}"
|
||||
))
|
||||
})?;
|
||||
output.write_all(&bytes).map_err(|err| {
|
||||
Error::SerializationError(format!(
|
||||
"Failed to write serialized Byte to output: {err}"
|
||||
))
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
Self::Short(val) => {
|
||||
let size = self.size();
|
||||
let bytes: [u8; 2] = val.to_be_bytes();
|
||||
output
|
||||
.write_all(&[((size as u8 - 2) << 5) | VALUE_SHORT.0])
|
||||
.map_err(|err| {
|
||||
Error::SerializationError(format!(
|
||||
"Failed to write serialized Short to output: {err}"
|
||||
))
|
||||
})?;
|
||||
output.write_all(&bytes[(2 - size + 1)..]).map_err(|err| {
|
||||
Error::SerializationError(format!(
|
||||
"Failed to write serialized Short to output: {err}"
|
||||
))
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
Self::Char(val) => {
|
||||
let size = self.size();
|
||||
let bytes: [u8; 2] = val.to_be_bytes();
|
||||
output
|
||||
.write_all(&[((size as u8 - 2) << 5) | VALUE_CHAR.0])
|
||||
.map_err(|err| {
|
||||
Error::SerializationError(format!(
|
||||
"Failed to write serialized Char to output: {err}"
|
||||
))
|
||||
})?;
|
||||
output.write_all(&bytes[(2 - size + 1)..]).map_err(|err| {
|
||||
Error::SerializationError(format!(
|
||||
"Failed to write serialized Char to output: {err}"
|
||||
))
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
Self::Int(val) => {
|
||||
let size = self.size();
|
||||
let bytes: [u8; 4] = val.to_be_bytes();
|
||||
output
|
||||
.write_all(&[((size as u8 - 2) << 5) | VALUE_INT.0])
|
||||
.map_err(|err| {
|
||||
Error::SerializationError(format!(
|
||||
"Failed to write serialized Int to output: {err}"
|
||||
))
|
||||
})?;
|
||||
output.write_all(&bytes[(2 - size + 1)..]).map_err(|err| {
|
||||
Error::SerializationError(format!(
|
||||
"Failed to write serialized Int to output: {err}"
|
||||
))
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
Self::Long(val) => {
|
||||
let size = self.size();
|
||||
let bytes: [u8; 8] = val.to_be_bytes();
|
||||
output
|
||||
.write_all(&[((size as u8 - 2) << 5) | VALUE_LONG.0])
|
||||
.map_err(|err| {
|
||||
Error::SerializationError(format!(
|
||||
"Failed to write serialized Long to output: {err}"
|
||||
))
|
||||
})?;
|
||||
output.write_all(&bytes[(2 - size + 1)..]).map_err(|err| {
|
||||
Error::SerializationError(format!(
|
||||
"Failed to write serialized Long to output: {err}"
|
||||
))
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
Self::Float(val) => {
|
||||
let size = self.size();
|
||||
let bytes = val.to_be_bytes();
|
||||
output
|
||||
.write_all(&[((size as u8 - 2) << 5) | VALUE_FLOAT.0])
|
||||
.map_err(|err| {
|
||||
Error::SerializationError(format!(
|
||||
"Failed to write serialized Float to output: {err}"
|
||||
))
|
||||
})?;
|
||||
output.write_all(&bytes[..(size - 1)]).map_err(|err| {
|
||||
Error::SerializationError(format!(
|
||||
"Failed to write serialized Float to output: {err}"
|
||||
))
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
Self::Double(val) => {
|
||||
let size = self.size();
|
||||
let bytes = val.to_be_bytes();
|
||||
output
|
||||
.write_all(&[((size as u8 - 2) << 5) | VALUE_DOUBLE.0])
|
||||
.map_err(|err| {
|
||||
Error::SerializationError(format!(
|
||||
"Failed to write serialized Double to output: {err}"
|
||||
))
|
||||
})?;
|
||||
output.write_all(&bytes[..(size - 1)]).map_err(|err| {
|
||||
Error::SerializationError(format!(
|
||||
"Failed to write serialized Double to output: {err}"
|
||||
))
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
Self::MethodType(idx) => Idx(*idx, VALUE_METHOD_TYPE).serialize(output),
|
||||
Self::MethodHandle(idx) => Idx(*idx, VALUE_METHOD_HANDLE).serialize(output),
|
||||
Self::String(idx) => Idx(*idx, VALUE_STRING).serialize(output),
|
||||
Self::Type(idx) => Idx(*idx, VALUE_TYPE).serialize(output),
|
||||
Self::Field(idx) => Idx(*idx, VALUE_FIELD).serialize(output),
|
||||
Self::Method(idx) => Idx(*idx, VALUE_METHOD).serialize(output),
|
||||
Self::Enum(idx) => Idx(*idx, VALUE_ENUM).serialize(output),
|
||||
Self::Array(arr) => {
|
||||
output.write_all(&[VALUE_ARRAY.0]).map_err(|err| {
|
||||
Error::SerializationError(format!(
|
||||
"Failed to write serialized Array to output: {err}"
|
||||
))
|
||||
})?;
|
||||
arr.serialize(output)
|
||||
}
|
||||
Self::Annotation(ann) => {
|
||||
output.write_all(&[VALUE_ANNOTATION.0]).map_err(|err| {
|
||||
Error::SerializationError(format!(
|
||||
"Failed to write serialized Annotation to output: {err}"
|
||||
))
|
||||
})?;
|
||||
ann.serialize(output)
|
||||
}
|
||||
Self::Null => {
|
||||
output.write_all(&[VALUE_NULL.0]).map_err(|err| {
|
||||
Error::SerializationError(format!(
|
||||
"Failed to write serialized Null to output: {err}"
|
||||
))
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
Self::Boolean(b) => {
|
||||
let val = if *b { 1 } else { 0 };
|
||||
output
|
||||
.write_all(&[(val << 5) | VALUE_BOOLEAN.0])
|
||||
.map_err(|err| {
|
||||
Error::SerializationError(format!(
|
||||
"Failed to write serialized Bool to output: {err}"
|
||||
))
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
|
||||
let mut buffer = [0u8; 1];
|
||||
input.read_exact(&mut buffer).map_err(|_| {
|
||||
Error::InputTooSmall(
|
||||
"Failed to read all bytes for the EncodedValue from the input".into(),
|
||||
)
|
||||
})?;
|
||||
let [byte] = buffer;
|
||||
let arg = (byte & 0b1110_0000) >> 5;
|
||||
match ValueType(byte & 0b0011_1111) {
|
||||
VALUE_BYTE => {
|
||||
if arg != 0 {
|
||||
Err(Error::DeserializationError(format!(
|
||||
"Unexpected value argument 0x{arg:02x}: expected 0 for VALUE_BYTE"
|
||||
)))
|
||||
} else {
|
||||
let mut buffer = [0u8; 1];
|
||||
input.read_exact(&mut buffer).map_err(|_| {
|
||||
Error::InputTooSmall(
|
||||
"Failed to read all bytes for the EncodedValue (Byte) from the input"
|
||||
.into(),
|
||||
)
|
||||
})?;
|
||||
Ok(Self::Byte(i8::from_be_bytes(buffer)))
|
||||
}
|
||||
}
|
||||
VALUE_SHORT => {
|
||||
if arg >= 2 {
|
||||
Err(Error::DeserializationError(format!(
|
||||
"Unexpected value argument 0x{arg:02x}: expected 0 or 1 for VALUE_SHORT"
|
||||
)))
|
||||
} else {
|
||||
let mut buffer = [0x00u8; 2];
|
||||
let size = (arg + 1) as usize;
|
||||
let first_byte = 2 - size;
|
||||
input.read_exact(&mut buffer[first_byte..]).map_err(|_| {
|
||||
Error::InputTooSmall(
|
||||
"Failed to read all bytes for the EncodedValue (Short) from the input"
|
||||
.into(),
|
||||
)
|
||||
})?;
|
||||
// Sign extention
|
||||
if (buffer[first_byte] & 0b1000_0000) != 0 {
|
||||
for b in buffer.iter_mut().take(first_byte - 1) {
|
||||
*b = 0xff;
|
||||
}
|
||||
}
|
||||
Ok(Self::Short(i16::from_be_bytes(buffer)))
|
||||
}
|
||||
}
|
||||
VALUE_CHAR => {
|
||||
if arg >= 2 {
|
||||
Err(Error::DeserializationError(format!(
|
||||
"Unexpected value argument 0x{arg:02x}: expected 0 or 1 for VALUE_CHAR"
|
||||
)))
|
||||
} else {
|
||||
let mut buffer = [0x00u8; 2];
|
||||
let size = (arg + 1) as usize;
|
||||
let first_byte = 2 - size;
|
||||
input.read_exact(&mut buffer[first_byte..]).map_err(|_| {
|
||||
Error::InputTooSmall(
|
||||
"Failed to read all bytes for the EncodedValue (Char) from the input"
|
||||
.into(),
|
||||
)
|
||||
})?;
|
||||
Ok(Self::Char(u16::from_be_bytes(buffer)))
|
||||
}
|
||||
}
|
||||
VALUE_INT => {
|
||||
if arg >= 4 {
|
||||
Err(Error::DeserializationError(format!(
|
||||
"Unexpected value argument 0x{arg:02x}: expected 0, 1, 2 or 3 for VALUE_INT"
|
||||
)))
|
||||
} else {
|
||||
let mut buffer = [0x00u8; 4];
|
||||
let size = (arg + 1) as usize;
|
||||
let first_byte = 4 - size;
|
||||
input.read_exact(&mut buffer[first_byte..]).map_err(|_| {
|
||||
Error::InputTooSmall(
|
||||
"Failed to read all bytes for the EncodedValue (Int) from the input"
|
||||
.into(),
|
||||
)
|
||||
})?;
|
||||
// Sign extention
|
||||
if (buffer[first_byte] & 0b1000_0000) != 0 {
|
||||
for b in buffer.iter_mut().take(first_byte - 1) {
|
||||
*b = 0xff;
|
||||
}
|
||||
}
|
||||
Ok(Self::Int(i32::from_be_bytes(buffer)))
|
||||
}
|
||||
}
|
||||
VALUE_LONG => {
|
||||
if arg >= 8 {
|
||||
Err(Error::DeserializationError(format!(
|
||||
"Unexpected value argument 0x{arg:02x}: expected 0 to 7 for VALUE_LONG"
|
||||
)))
|
||||
} else {
|
||||
let mut buffer = [0x00u8; 8];
|
||||
let size = (arg + 1) as usize;
|
||||
let first_byte = 8 - size;
|
||||
input.read_exact(&mut buffer[first_byte..]).map_err(|_| {
|
||||
Error::InputTooSmall(
|
||||
"Failed to read all bytes for the EncodedValue (Long) from the input"
|
||||
.into(),
|
||||
)
|
||||
})?;
|
||||
// Sign extention
|
||||
if (buffer[first_byte] & 0b1000_0000) != 0 {
|
||||
for b in buffer.iter_mut().take(first_byte - 1) {
|
||||
*b = 0xff;
|
||||
}
|
||||
}
|
||||
Ok(Self::Long(i64::from_be_bytes(buffer)))
|
||||
}
|
||||
}
|
||||
VALUE_FLOAT => {
|
||||
if arg >= 4 {
|
||||
Err(Error::DeserializationError(format!(
|
||||
"Unexpected value argument 0x{arg:02x}: expected 0, 1, 2 or 3 for VALUE_FLOAT"
|
||||
)))
|
||||
} else {
|
||||
let mut buffer = [0x00u8; 4];
|
||||
let size = (arg + 1) as usize;
|
||||
input.read_exact(&mut buffer[..size]).map_err(|_| {
|
||||
Error::InputTooSmall(
|
||||
"Failed to read all bytes for the EncodedValue (Float) from the input"
|
||||
.into(),
|
||||
)
|
||||
})?;
|
||||
Ok(Self::Float(f32::from_be_bytes(buffer)))
|
||||
}
|
||||
}
|
||||
VALUE_DOUBLE => {
|
||||
if arg >= 8 {
|
||||
Err(Error::DeserializationError(format!(
|
||||
"Unexpected value argument 0x{arg:02x}: expected 0 to 7 for VALUE_DOUBLE"
|
||||
)))
|
||||
} else {
|
||||
let mut buffer = [0x00u8; 8];
|
||||
let size = (arg + 1) as usize;
|
||||
input.read_exact(&mut buffer[..size]).map_err(|_| {
|
||||
Error::InputTooSmall(
|
||||
"Failed to read all bytes for the EncodedValue (Double) from the input"
|
||||
.into(),
|
||||
)
|
||||
})?;
|
||||
Ok(Self::Double(f64::from_be_bytes(buffer)))
|
||||
}
|
||||
}
|
||||
VALUE_METHOD_TYPE => {
|
||||
if arg >= 4 {
|
||||
Err(Error::DeserializationError(format!(
|
||||
"Unexpected value argument 0x{arg:02x}: expected 0, 1, 2 or 3 for VALUE_METHOD_TYPE"
|
||||
)))
|
||||
} else {
|
||||
let mut buffer = [0x00u8; 4];
|
||||
let size = (arg + 1) as usize;
|
||||
let first_byte = 4 - size;
|
||||
input.read_exact(&mut buffer[first_byte..]).map_err(|_| {
|
||||
Error::InputTooSmall(
|
||||
"Failed to read all bytes for the EncodedValue (MethodType) from the input"
|
||||
.into(),
|
||||
)
|
||||
})?;
|
||||
Ok(Self::MethodType(u32::from_be_bytes(buffer)))
|
||||
}
|
||||
}
|
||||
VALUE_METHOD_HANDLE => {
|
||||
if arg >= 4 {
|
||||
Err(Error::DeserializationError(format!(
|
||||
"Unexpected value argument 0x{arg:02x}: expected 0, 1, 2 or 3 for VALUE_METHOD_HANDLE"
|
||||
)))
|
||||
} else {
|
||||
let mut buffer = [0x00u8; 4];
|
||||
let size = (arg + 1) as usize;
|
||||
let first_byte = 4 - size;
|
||||
input.read_exact(&mut buffer[first_byte..]).map_err(|_| {
|
||||
Error::InputTooSmall(
|
||||
"Failed to read all bytes for the EncodedValue (MethodHandle) from the input"
|
||||
.into(),
|
||||
)
|
||||
})?;
|
||||
Ok(Self::MethodHandle(u32::from_be_bytes(buffer)))
|
||||
}
|
||||
}
|
||||
VALUE_STRING => {
|
||||
if arg >= 4 {
|
||||
Err(Error::DeserializationError(format!(
|
||||
"Unexpected value argument 0x{arg:02x}: expected 0, 1, 2 or 3 for VALUE_STRING"
|
||||
)))
|
||||
} else {
|
||||
let mut buffer = [0x00u8; 4];
|
||||
let size = (arg + 1) as usize;
|
||||
let first_byte = 4 - size;
|
||||
input.read_exact(&mut buffer[first_byte..]).map_err(|_| {
|
||||
Error::InputTooSmall(
|
||||
"Failed to read all bytes for the EncodedValue (String) from the input"
|
||||
.into(),
|
||||
)
|
||||
})?;
|
||||
Ok(Self::String(u32::from_be_bytes(buffer)))
|
||||
}
|
||||
}
|
||||
VALUE_TYPE => {
|
||||
if arg >= 4 {
|
||||
Err(Error::DeserializationError(format!(
|
||||
"Unexpected value argument 0x{arg:02x}: expected 0, 1, 2 or 3 for VALUE_TYPE"
|
||||
)))
|
||||
} else {
|
||||
let mut buffer = [0x00u8; 4];
|
||||
let size = (arg + 1) as usize;
|
||||
let first_byte = 4 - size;
|
||||
input.read_exact(&mut buffer[first_byte..]).map_err(|_| {
|
||||
Error::InputTooSmall(
|
||||
"Failed to read all bytes for the EncodedValue (Type) from the input"
|
||||
.into(),
|
||||
)
|
||||
})?;
|
||||
Ok(Self::Type(u32::from_be_bytes(buffer)))
|
||||
}
|
||||
}
|
||||
VALUE_FIELD => {
|
||||
if arg >= 4 {
|
||||
Err(Error::DeserializationError(format!(
|
||||
"Unexpected value argument 0x{arg:02x}: expected 0, 1, 2 or 3 for VALUE_FIELD"
|
||||
)))
|
||||
} else {
|
||||
let mut buffer = [0x00u8; 4];
|
||||
let size = (arg + 1) as usize;
|
||||
let first_byte = 4 - size;
|
||||
input.read_exact(&mut buffer[first_byte..]).map_err(|_| {
|
||||
Error::InputTooSmall(
|
||||
"Failed to read all bytes for the EncodedValue (Field) from the input"
|
||||
.into(),
|
||||
)
|
||||
})?;
|
||||
Ok(Self::Field(u32::from_be_bytes(buffer)))
|
||||
}
|
||||
}
|
||||
VALUE_METHOD => {
|
||||
if arg >= 4 {
|
||||
Err(Error::DeserializationError(format!(
|
||||
"Unexpected value argument 0x{arg:02x}: expected 0, 1, 2 or 3 for VALUE_METHOD"
|
||||
)))
|
||||
} else {
|
||||
let mut buffer = [0x00u8; 4];
|
||||
let size = (arg + 1) as usize;
|
||||
let first_byte = 4 - size;
|
||||
input.read_exact(&mut buffer[first_byte..]).map_err(|_| {
|
||||
Error::InputTooSmall(
|
||||
"Failed to read all bytes for the EncodedValue (Method) from the input"
|
||||
.into(),
|
||||
)
|
||||
})?;
|
||||
Ok(Self::Method(u32::from_be_bytes(buffer)))
|
||||
}
|
||||
}
|
||||
VALUE_ENUM => {
|
||||
if arg >= 4 {
|
||||
Err(Error::DeserializationError(format!(
|
||||
"Unexpected value argument 0x{arg:02x}: expected 0, 1, 2 or 3 for VALUE_ENUM"
|
||||
)))
|
||||
} else {
|
||||
let mut buffer = [0x00u8; 4];
|
||||
let size = (arg + 1) as usize;
|
||||
let first_byte = 4 - size;
|
||||
input.read_exact(&mut buffer[first_byte..]).map_err(|_| {
|
||||
Error::InputTooSmall(
|
||||
"Failed to read all bytes for the EncodedValue (Enum) from the input"
|
||||
.into(),
|
||||
)
|
||||
})?;
|
||||
Ok(Self::Enum(u32::from_be_bytes(buffer)))
|
||||
}
|
||||
}
|
||||
VALUE_ARRAY => {
|
||||
if arg != 0 {
|
||||
Err(Error::DeserializationError(format!(
|
||||
"Unexpected value argument 0x{arg:02x}: expected 0 for VALUE_ARRAY"
|
||||
)))
|
||||
} else {
|
||||
Ok(Self::Array(EncodedArray::deserialize(input)?))
|
||||
}
|
||||
}
|
||||
VALUE_ANNOTATION => {
|
||||
if arg != 0 {
|
||||
Err(Error::DeserializationError(format!(
|
||||
"Unexpected value argument 0x{arg:02x}: expected 0 for VALUE_ANNOTATION"
|
||||
)))
|
||||
} else {
|
||||
Ok(Self::Array(EncodedArray::deserialize(input)?))
|
||||
}
|
||||
}
|
||||
VALUE_NULL => {
|
||||
if arg != 0 {
|
||||
Err(Error::DeserializationError(format!(
|
||||
"Unexpected value argument 0x{arg:02x}: expected 0 for VALUE_NULL"
|
||||
)))
|
||||
} else {
|
||||
Ok(Self::Null)
|
||||
}
|
||||
}
|
||||
VALUE_BOOLEAN => {
|
||||
if arg == 0 {
|
||||
Ok(Self::Boolean(false))
|
||||
} else if arg == 1 {
|
||||
Ok(Self::Boolean(true))
|
||||
} else {
|
||||
Err(Error::DeserializationError(format!(
|
||||
"Unexpected value argument 0x{arg:02x}: expected 0 or 1 for VALUE_BOOLEAN"
|
||||
)))
|
||||
}
|
||||
}
|
||||
ValueType(vt) => Err(Error::DeserializationError(format!(
|
||||
"Unknown Value Type: 0x{vt:02x}"
|
||||
))),
|
||||
}
|
||||
}
|
||||
|
||||
fn size(&self) -> usize {
|
||||
match self {
|
||||
Self::Byte(_) => 2,
|
||||
Self::Short(val) => 1 + if *val <= 0x7f && *val >= -0x80 { 1 } else { 2 },
|
||||
Self::Char(val) => 1 + if *val <= 0xff { 1 } else { 2 },
|
||||
Self::Int(val) => {
|
||||
1 + if *val <= 0x7f && *val >= -0x80 {
|
||||
1
|
||||
} else if *val <= 0x7f_ff && *val >= -0x80_00 {
|
||||
2
|
||||
} else if *val <= 0x7f_ff_ff && *val >= -0x80_00_00 {
|
||||
3
|
||||
} else {
|
||||
4
|
||||
}
|
||||
}
|
||||
Self::Long(val) => {
|
||||
1 + if *val <= 0x7f && *val >= -0x80 {
|
||||
1
|
||||
} else if *val <= 0x7f_ff && *val >= -0x80_00 {
|
||||
2
|
||||
} else if *val <= 0x7f_ff_ff && *val >= -0x80_00_00 {
|
||||
3
|
||||
} else if *val <= 0x7f_ff_ff_ff && *val >= -0x80_00_00_00 {
|
||||
4
|
||||
} else if *val <= 0x7f_ff_ff_ff_ff && *val >= -0x80_00_00_00_00 {
|
||||
5
|
||||
} else if *val <= 0x7f_ff_ff_ff_ff_ff && *val >= -0x80_00_00_00_00_00 {
|
||||
6
|
||||
} else if *val <= 0x7f_ff_ff_ff_ff_ff_ff && *val >= -0x80_00_00_00_00_00 {
|
||||
7
|
||||
} else {
|
||||
8
|
||||
}
|
||||
}
|
||||
Self::Float(val) => {
|
||||
let trailing_zeros = val
|
||||
.to_be_bytes()
|
||||
.iter()
|
||||
.rev()
|
||||
.take_while(|b| **b == 0)
|
||||
.count();
|
||||
1 + 4 - trailing_zeros
|
||||
}
|
||||
Self::Double(val) => {
|
||||
let trailing_zeros = val
|
||||
.to_be_bytes()
|
||||
.iter()
|
||||
.rev()
|
||||
.take_while(|b| **b == 0)
|
||||
.count();
|
||||
1 + 8 - trailing_zeros
|
||||
}
|
||||
Self::MethodType(idx) => Idx(*idx, VALUE_TYPE).size(),
|
||||
Self::MethodHandle(idx) => Idx(*idx, VALUE_METHOD_HANDLE).size(),
|
||||
Self::String(idx) => Idx(*idx, VALUE_STRING).size(),
|
||||
Self::Type(idx) => Idx(*idx, VALUE_TYPE).size(),
|
||||
Self::Field(idx) => Idx(*idx, VALUE_FIELD).size(),
|
||||
Self::Method(idx) => Idx(*idx, VALUE_METHOD).size(),
|
||||
Self::Enum(idx) => Idx(*idx, VALUE_ENUM).size(),
|
||||
Self::Array(arr) => 1 + arr.size(),
|
||||
Self::Annotation(ann) => 1 + ann.size(),
|
||||
Self::Null => 1,
|
||||
Self::Boolean(_) => 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Utility type to encode/decode an Idx.
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
struct Idx(u32, ValueType);
|
||||
impl Serializable for Idx {
|
||||
fn serialize(&self, output: &mut dyn Write) -> Result<()> {
|
||||
let Idx(idx, ValueType(vt)) = self;
|
||||
let size = self.size() - 2;
|
||||
let bytes: [u8; 4] = idx.to_be_bytes();
|
||||
let vec = &bytes[(4 - size + 1)..];
|
||||
output
|
||||
.write_all(&[((size as u8) << 5) | vt])
|
||||
.map_err(|err| {
|
||||
Error::SerializationError(format!(
|
||||
"Failed to write serialized Idx to output: {err}"
|
||||
))
|
||||
})?;
|
||||
output.write_all(vec).map_err(|err| {
|
||||
Error::SerializationError(format!("Failed to write serialized Idx to output: {err}"))
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
/// unimplemented, not used because the ValueType must be known before deserializing the idx.
|
||||
fn deserialize(_input: &mut dyn ReadSeek) -> Result<Self> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn size(&self) -> usize {
|
||||
let Idx(idx, _) = *self;
|
||||
1 + if idx <= 0xff {
|
||||
1
|
||||
} else if idx <= 0xffff {
|
||||
2
|
||||
} else if idx <= 0xffffff {
|
||||
3
|
||||
} else {
|
||||
4
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue