use core::fmt;
use crate::MASK_28_BIT;
use super::{
get_subslice, header::BinHeader, read_u16, BinIndex, BinaryDeserializerError, CharsetFamily,
FormatVersion, ResDescriptor, ResourceReprType,
};
extern crate alloc;
use alloc::string::String;
use serde::{de, forward_to_deserialize_any, Deserialize};
const SYSTEM_CHARSET_FAMILY: CharsetFamily = CharsetFamily::Ascii;
pub fn from_bytes<'a, T>(input: &'a [u8]) -> Result<T, BinaryDeserializerError>
where
T: Deserialize<'a>,
{
let mut deserializer = ResourceTreeDeserializer::from_bytes(input)?;
let t = T::deserialize(&mut deserializer)?;
Ok(t)
}
struct ResourceTreeDeserializer<'de> {
input: &'de [u8],
_format_version: FormatVersion,
data_16_bit: Option<&'de [u8]>,
keys: &'de [u8],
body: &'de [u8],
}
impl<'de> ResourceTreeDeserializer<'de> {
fn from_bytes(input: &'de [u8]) -> Result<Self, BinaryDeserializerError> {
let header = BinHeader::try_from(input)?;
if header.repr_info.charset_family != SYSTEM_CHARSET_FAMILY {
return Err(BinaryDeserializerError::unsupported_format(
"bundle and system character set families do not match",
));
}
if header.repr_info.size_of_char != 2 {
return Err(BinaryDeserializerError::unsupported_format(
"characters of size other than 2 are not supported",
));
}
if header.repr_info.format_version != FormatVersion::V2_0 {
return Err(BinaryDeserializerError::unsupported_format(
"format versions other than 2.0 are not supported at this time",
));
}
let body = get_subslice(input, header.size as usize..)?;
let index = get_subslice(body, core::mem::size_of::<u32>()..)?;
let index = BinIndex::try_from(index)?;
let keys = get_subslice(
body,
..(index.keys_end as usize) * core::mem::size_of::<u32>(),
)?;
let data_16_bit = if header.repr_info.format_version < FormatVersion::V2_0 {
None
} else if let Some(data_16_bit_end) = index.data_16_bit_end {
let data_16_bit = get_subslice(
body,
(index.keys_end as usize) * core::mem::size_of::<u32>()
..(data_16_bit_end as usize) * core::mem::size_of::<u32>(),
)?;
Some(data_16_bit)
} else {
return Err(BinaryDeserializerError::invalid_data(
"offset to the end of 16-bit data not specified",
));
};
Ok(Self {
input: body,
_format_version: header.repr_info.format_version,
data_16_bit,
keys,
body,
})
}
fn peek_next_resource_descriptor(&self) -> Result<ResDescriptor, BinaryDeserializerError> {
let input = get_subslice(self.input, 0..4)?;
let descriptor = match input.try_into() {
Ok(value) => value,
Err(_) => {
return Err(BinaryDeserializerError::invalid_data(
"unable to read resource descriptor",
))
}
};
let descriptor = u32::from_le_bytes(descriptor);
ResDescriptor::try_from(descriptor)
}
fn get_next_resource_descriptor(&mut self) -> Result<ResDescriptor, BinaryDeserializerError> {
let result = self.peek_next_resource_descriptor();
self.input = get_subslice(self.input, core::mem::size_of::<u32>()..)?;
result
}
fn parse_signed(&mut self) -> Result<i32, BinaryDeserializerError> {
let descriptor = self.get_next_resource_descriptor()?;
match descriptor.resource_type() {
ResourceReprType::Int => Ok(descriptor.value_as_signed_int()),
_ => Err(BinaryDeserializerError::resource_type_mismatch(
"expected integer resource",
)),
}
}
fn parse_unsigned(&mut self) -> Result<u32, BinaryDeserializerError> {
let descriptor = self.get_next_resource_descriptor()?;
match descriptor.resource_type() {
ResourceReprType::Int => Ok(descriptor.value_as_unsigned_int()),
_ => Err(BinaryDeserializerError::resource_type_mismatch(
"expected integer resource",
)),
}
}
}
impl<'de> de::Deserializer<'de> for &mut ResourceTreeDeserializer<'de> {
type Error = BinaryDeserializerError;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
let descriptor = self.peek_next_resource_descriptor()?;
match descriptor.resource_type() {
ResourceReprType::_String | ResourceReprType::StringV2 => {
self.deserialize_string(visitor)
}
ResourceReprType::Binary => self.deserialize_bytes(visitor),
ResourceReprType::Table | ResourceReprType::Table16 | ResourceReprType::_Table32 => {
self.deserialize_map(visitor)
}
ResourceReprType::_Alias => todo!(),
ResourceReprType::Int => self.deserialize_u32(visitor),
ResourceReprType::Array | ResourceReprType::Array16 | ResourceReprType::IntVector => {
self.deserialize_seq(visitor)
}
}
}
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
let value = self.parse_unsigned()?;
let value = match value {
0 => false,
1 => true,
_ => {
return Err(BinaryDeserializerError::resource_type_mismatch(
"expected integer resource representable as boolean",
))
}
};
visitor.visit_bool(value)
}
fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
self.deserialize_i32(visitor)
}
fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
self.deserialize_i32(visitor)
}
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
visitor.visit_i32(self.parse_signed()?)
}
fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
visitor.visit_i64(self.parse_signed()? as i64)
}
fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
self.deserialize_u32(visitor)
}
fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
self.deserialize_u32(visitor)
}
fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
visitor.visit_u32(self.parse_unsigned()?)
}
fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
visitor.visit_u64(self.parse_unsigned()? as u64)
}
fn deserialize_f32<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
unimplemented!()
}
fn deserialize_f64<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
unimplemented!()
}
fn deserialize_char<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
unimplemented!()
}
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
self.deserialize_string(visitor)
}
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
let descriptor = self.get_next_resource_descriptor()?;
match descriptor.resource_type() {
ResourceReprType::_String => todo!(),
ResourceReprType::StringV2 => {
if let Some(data_16_bit) = self.data_16_bit {
if descriptor.is_empty() {
return visitor.visit_str("");
}
let input = get_subslice(data_16_bit, descriptor.value_as_16_bit_offset()..)?;
let de = Resource16BitDeserializer::new(input);
de.deserialize_string(visitor)
} else {
Err(BinaryDeserializerError::invalid_data(
"StringV2 resource without 16-bit data block",
))
}
}
_ => Err(BinaryDeserializerError::resource_type_mismatch(
"expected string resource",
)),
}
}
fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
let descriptor = self.get_next_resource_descriptor()?;
let value = match descriptor.resource_type() {
ResourceReprType::Binary => {
if descriptor.is_empty() {
return visitor.visit_borrowed_bytes(&[]);
}
let input = get_subslice(self.body, descriptor.value_as_32_bit_offset()..)?;
let (length, input) = read_u32(input)?;
get_subslice(input, 0..length as usize)?
}
ResourceReprType::IntVector => {
if descriptor.is_empty() {
return visitor.visit_borrowed_bytes(&[]);
}
let input = get_subslice(self.body, descriptor.value_as_32_bit_offset()..)?;
let (length, input) = read_u32(input)?;
get_subslice(input, ..(length as usize) * core::mem::size_of::<u32>())?
}
ResourceReprType::StringV2 => {
if let Some(data_16_bit) = self.data_16_bit {
if descriptor.is_empty() {
return visitor.visit_borrowed_bytes(&[]);
}
let input = get_subslice(data_16_bit, descriptor.value_as_16_bit_offset()..)?;
let (length, input) = get_length_and_start_of_utf16_string(input)?;
get_subslice(input, ..length * core::mem::size_of::<u16>())?
} else {
return Err(BinaryDeserializerError::invalid_data(
"StringV2 resource without 16-bit data block",
));
}
}
_ => {
return Err(BinaryDeserializerError::resource_type_mismatch(
"expected binary data resource",
))
}
};
visitor.visit_borrowed_bytes(value)
}
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
self.deserialize_bytes(visitor)
}
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
visitor.visit_some(self)
}
fn deserialize_unit<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
unimplemented!()
}
fn deserialize_unit_struct<V>(
self,
_name: &'static str,
_visitor: V,
) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
unimplemented!()
}
fn deserialize_newtype_struct<V>(
self,
_name: &'static str,
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
visitor.visit_newtype_struct(self)
}
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
let descriptor = self.get_next_resource_descriptor()?;
match descriptor.resource_type() {
ResourceReprType::Array => {
if descriptor.is_empty() {
return visitor.visit_seq(EmptySeqAccess);
}
let input = get_subslice(self.body, descriptor.value_as_32_bit_offset()..)?;
let (length, offsets) = read_u32(input)?;
visitor.visit_seq(ArraySeqAccess {
de: self,
descriptors: offsets,
remaining: length as usize,
})
}
ResourceReprType::Array16 => {
if descriptor.is_empty() {
return visitor.visit_seq(EmptySeqAccess);
}
if let Some(data_16_bit) = self.data_16_bit {
let input = get_subslice(data_16_bit, descriptor.value_as_16_bit_offset()..)?;
let (length, offsets) = read_u16(input)?;
let result = visitor.visit_seq(Array16SeqAccess {
data_16_bit,
offsets,
remaining: length as usize,
});
result
} else {
Err(BinaryDeserializerError::invalid_data(
"StringV2 resource with no 16-bit data",
))
}
}
ResourceReprType::IntVector => {
if descriptor.is_empty() {
return visitor.visit_seq(EmptySeqAccess);
}
let input = get_subslice(self.body, descriptor.value_as_32_bit_offset()..)?;
let (length, values) = read_u32(input)?;
let result = visitor.visit_seq(IntVectorSeqAccess {
values,
remaining: length as usize,
});
result
}
_ => Err(BinaryDeserializerError::resource_type_mismatch(
"expected array resource",
)),
}
}
fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
self.deserialize_seq(visitor)
}
fn deserialize_tuple_struct<V>(
self,
_name: &'static str,
_len: usize,
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
self.deserialize_seq(visitor)
}
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
let descriptor = self.get_next_resource_descriptor()?;
match descriptor.resource_type() {
ResourceReprType::Table => {
if descriptor.is_empty() {
return visitor.visit_map(EmptyMapAccess);
}
let input = get_subslice(self.body, descriptor.value_as_32_bit_offset()..)?;
let (length, keys) = read_u16(input)?;
let length_with_padding = (length + ((length + 1) % 2)) as usize;
let values_offset = length_with_padding * core::mem::size_of::<u16>();
let values = get_subslice(keys, values_offset..)?;
visitor.visit_map(TableMapAccess {
de: self,
keys,
values,
remaining: length as usize,
})
}
ResourceReprType::_Table32 => todo!(),
ResourceReprType::Table16 => todo!(),
_ => Err(BinaryDeserializerError::resource_type_mismatch(
"expected table resource",
)),
}
}
fn deserialize_struct<V>(
self,
_name: &'static str,
_fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
self.deserialize_map(visitor)
}
fn deserialize_enum<V>(
self,
_name: &'static str,
_variants: &'static [&'static str],
_visitor: V,
) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
todo!()
}
fn deserialize_identifier<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
unimplemented!()
}
fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
let (_, input) = read_u32(self.input)?;
self.input = input;
visitor.visit_none()
}
#[inline]
fn is_human_readable(&self) -> bool {
false
}
}
struct Array16SeqAccess<'de> {
data_16_bit: &'de [u8],
offsets: &'de [u8],
remaining: usize,
}
impl<'de> de::SeqAccess<'de> for Array16SeqAccess<'de> {
type Error = BinaryDeserializerError;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where
T: de::DeserializeSeed<'de>,
{
if self.remaining == 0 {
return Ok(None);
}
let (offset, rest) = read_u16(self.offsets)?;
self.offsets = rest;
self.remaining -= 1;
let input = get_subslice(
self.data_16_bit,
(offset as usize) * core::mem::size_of::<u16>()..,
)?;
let de = Resource16BitDeserializer::new(input);
seed.deserialize(de).map(Some)
}
fn size_hint(&self) -> Option<usize> {
Some(self.remaining)
}
}
struct ArraySeqAccess<'a, 'de: 'a> {
de: &'a mut ResourceTreeDeserializer<'de>,
descriptors: &'de [u8],
remaining: usize,
}
impl<'de> de::SeqAccess<'de> for ArraySeqAccess<'_, 'de> {
type Error = BinaryDeserializerError;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where
T: de::DeserializeSeed<'de>,
{
if self.remaining == 0 {
return Ok(None);
}
let input = self.descriptors;
self.descriptors = get_subslice(self.descriptors, core::mem::size_of::<u32>()..)?;
self.remaining -= 1;
self.de.input = input;
seed.deserialize(&mut *self.de).map(Some)
}
fn size_hint(&self) -> Option<usize> {
Some(self.remaining)
}
}
struct IntVectorSeqAccess<'de> {
values: &'de [u8],
remaining: usize,
}
impl<'de> de::SeqAccess<'de> for IntVectorSeqAccess<'de> {
type Error = BinaryDeserializerError;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where
T: de::DeserializeSeed<'de>,
{
if self.remaining == 0 {
return Ok(None);
}
let input = self.values;
self.values = get_subslice(self.values, core::mem::size_of::<u32>()..)?;
self.remaining -= 1;
let de = IntVectorDeserializer::new(input);
seed.deserialize(de).map(Some)
}
fn size_hint(&self) -> Option<usize> {
Some(self.remaining)
}
}
struct EmptySeqAccess;
impl<'de> de::SeqAccess<'de> for EmptySeqAccess {
type Error = BinaryDeserializerError;
fn next_element_seed<T>(&mut self, _seed: T) -> Result<Option<T::Value>, Self::Error>
where
T: de::DeserializeSeed<'de>,
{
Ok(None)
}
fn size_hint(&self) -> Option<usize> {
Some(0)
}
}
struct EmptyMapAccess;
impl<'de> de::MapAccess<'de> for EmptyMapAccess {
type Error = BinaryDeserializerError;
fn next_key_seed<K>(&mut self, _seed: K) -> Result<Option<K::Value>, Self::Error>
where
K: de::DeserializeSeed<'de>,
{
Ok(None)
}
#[allow(clippy::panic)]
fn next_value_seed<V>(&mut self, _seed: V) -> Result<V::Value, Self::Error>
where
V: de::DeserializeSeed<'de>,
{
panic!("Unable to process value for empty map. This is likely a `serde` bug.");
}
fn size_hint(&self) -> Option<usize> {
Some(0)
}
}
struct TableMapAccess<'de, 'a> {
de: &'a mut ResourceTreeDeserializer<'de>,
keys: &'de [u8],
values: &'de [u8],
remaining: usize,
}
impl<'de> de::MapAccess<'de> for TableMapAccess<'de, '_> {
type Error = BinaryDeserializerError;
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
where
K: de::DeserializeSeed<'de>,
{
if self.remaining == 0 {
return Ok(None);
}
let (key, keys) = read_u16(self.keys)?;
self.keys = keys;
self.remaining -= 1;
let input = get_subslice(self.de.keys, key as usize..).or(Err(
BinaryDeserializerError::invalid_data("unexpected end of data while deserializing key"),
))?;
let de = KeyDeserializer::new(input);
seed.deserialize(de).map(Some)
}
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
where
V: de::DeserializeSeed<'de>,
{
let value = self.values;
self.values = get_subslice(self.values, core::mem::size_of::<u32>()..)?;
self.de.input = value;
seed.deserialize(&mut *self.de)
}
fn size_hint(&self) -> Option<usize> {
Some(self.remaining)
}
}
pub struct Resource16BitDeserializer<'de> {
input: &'de [u8],
}
impl<'de> Resource16BitDeserializer<'de> {
fn new(input: &'de [u8]) -> Self {
Self { input }
}
fn read_string_v2(self) -> Result<String, BinaryDeserializerError> {
let (length, input) = get_length_and_start_of_utf16_string(self.input)?;
let byte_slices = input.chunks_exact(2).take(length);
if byte_slices.len() != length {
return Err(BinaryDeserializerError::invalid_data(
"unexpected end of input while reading string",
));
}
let units = byte_slices.map(|bytes| {
#[allow(clippy::unwrap_used)]
let bytes = <[u8; 2]>::try_from(bytes).unwrap();
u16::from_le_bytes(bytes)
});
char::decode_utf16(units)
.collect::<Result<String, _>>()
.map_err(|_| {
BinaryDeserializerError::invalid_data("string resource is not valid UTF-16")
})
}
}
impl<'de> de::Deserializer<'de> for Resource16BitDeserializer<'de> {
type Error = BinaryDeserializerError;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
self.deserialize_string(visitor)
}
forward_to_deserialize_any! {
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str
byte_buf option unit unit_struct newtype_struct seq tuple
tuple_struct map struct enum identifier ignored_any
}
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
visitor.visit_string(self.read_string_v2()?)
}
fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
let (length, input) = get_length_and_start_of_utf16_string(self.input)?;
let bytes = get_subslice(input, 0..length * core::mem::size_of::<u16>())?;
visitor.visit_borrowed_bytes(bytes)
}
fn is_human_readable(&self) -> bool {
false
}
}
pub struct IntVectorDeserializer<'de> {
input: &'de [u8],
}
impl<'de> IntVectorDeserializer<'de> {
fn new(input: &'de [u8]) -> Self {
Self { input }
}
fn read_signed(mut self) -> Result<i32, BinaryDeserializerError> {
let (value, next) = read_u32(self.input)?;
self.input = next;
Ok(value as i32)
}
fn read_unsigned(mut self) -> Result<u32, BinaryDeserializerError> {
let (value, next) = read_u32(self.input)?;
self.input = next;
Ok(value)
}
}
impl<'de> de::Deserializer<'de> for IntVectorDeserializer<'de> {
type Error = BinaryDeserializerError;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
self.deserialize_u32(visitor)
}
forward_to_deserialize_any! {
bool f32 f64 char str string
bytes byte_buf option unit unit_struct newtype_struct seq tuple
tuple_struct map struct enum identifier ignored_any
}
fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
self.deserialize_i32(visitor)
}
fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
self.deserialize_i32(visitor)
}
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
visitor.visit_i32(self.read_signed()?)
}
fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
visitor.visit_i64(self.read_signed()? as i64)
}
fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
self.deserialize_u32(visitor)
}
fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
self.deserialize_u32(visitor)
}
fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
visitor.visit_u32(self.read_unsigned()?)
}
fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
visitor.visit_u64(self.read_unsigned()? as u64)
}
}
pub struct KeyDeserializer<'de> {
input: &'de [u8],
}
impl<'de> KeyDeserializer<'de> {
fn new(input: &'de [u8]) -> Self {
Self { input }
}
fn read_key(self) -> Result<&'de str, BinaryDeserializerError> {
let terminator_pos = self.input.iter().position(|&byte| byte == 0).ok_or(
BinaryDeserializerError::invalid_data("unterminated key string"),
)?;
let input = get_subslice(self.input, 0..terminator_pos)?;
core::str::from_utf8(input)
.map_err(|_| BinaryDeserializerError::invalid_data("key string is not valid UTF-8"))
}
}
impl<'de> de::Deserializer<'de> for KeyDeserializer<'de> {
type Error = BinaryDeserializerError;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
self.deserialize_str(visitor)
}
forward_to_deserialize_any! {
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char string
bytes byte_buf option unit unit_struct newtype_struct seq tuple
tuple_struct map struct enum identifier ignored_any
}
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
visitor.visit_borrowed_str(self.read_key()?)
}
}
fn get_length_and_start_of_utf16_string(
input: &[u8],
) -> Result<(usize, &[u8]), BinaryDeserializerError> {
let (first, rest) = read_u16(input)?;
let (length, rest) = if (0xdc00..0xdfef).contains(&first) {
((first & 0x03ff) as usize, rest)
} else if (0xdfef..0xdfff).contains(&first) {
let (second, rest) = read_u16(rest)?;
(((first as usize - 0xdfef) << 16) | second as usize, rest)
} else if first == 0xdfff {
let (second, rest) = read_u16(rest)?;
let (third, rest) = read_u16(rest)?;
(((second as usize) << 16) | third as usize, rest)
} else {
let length = rest
.chunks_exact(2)
.take(40)
.position(|chunk| chunk == [0, 0])
.ok_or(BinaryDeserializerError::invalid_data(
"unterminated string with implicit length",
))?
+ 1;
(length, input)
};
Ok((length, rest))
}
impl de::StdError for BinaryDeserializerError {}
impl de::Error for BinaryDeserializerError {
fn custom<T>(_msg: T) -> Self
where
T: fmt::Display,
{
#[cfg(feature = "logging")]
log::warn!("Error during resource bundle deserialization: {_msg}");
BinaryDeserializerError::unknown("error during deserialization; see logs")
}
}
impl TryFrom<&[u8]> for BinIndex {
type Error = BinaryDeserializerError;
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
let (field_count, value) = read_u32(value)?;
if field_count < 5 {
return Err(BinaryDeserializerError::invalid_data(
"invalid index field count",
));
}
let (keys_end, value) = read_u32(value)?;
let (resources_end, value) = read_u32(value)?;
let (bundle_end, value) = read_u32(value)?;
let (largest_table_entry_count, value) = read_u32(value)?;
let (bundle_attributes, data_16_bit_end, pool_checksum) = if field_count >= 6 {
let (bundle_attributes, value) = read_u32(value)?;
let (data_16_bit_end, pool_checksum) = if field_count >= 7 {
let (data_16_bit_end, value) = read_u32(value)?;
let pool_checksum = if field_count >= 8 {
let (pool_checksum, _) = read_u32(value)?;
Some(pool_checksum)
} else {
None
};
(Some(data_16_bit_end), pool_checksum)
} else {
(None, None)
};
(Some(bundle_attributes), data_16_bit_end, pool_checksum)
} else {
(None, None, None)
};
Ok(Self {
field_count,
keys_end,
resources_end,
bundle_end,
largest_table_entry_count,
bundle_attributes,
data_16_bit_end,
pool_checksum,
})
}
}
impl TryFrom<&[u8]> for FormatVersion {
type Error = BinaryDeserializerError;
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
let value = match value {
[1, 0, 0, 0] => FormatVersion::V1_0,
[1, 1, 0, 0] => FormatVersion::V1_1,
[1, 2, 0, 0] => FormatVersion::V1_2,
[1, 3, 0, 0] => FormatVersion::V1_3,
[2, 0, 0, 0] => FormatVersion::V2_0,
[3, 0, 0, 0] => FormatVersion::V3_0,
_ => {
return Err(BinaryDeserializerError::invalid_data(
"unrecognized format version",
))
}
};
Ok(value)
}
}
impl TryFrom<u32> for ResDescriptor {
type Error = BinaryDeserializerError;
fn try_from(value: u32) -> Result<Self, Self::Error> {
let resource_type = ResourceReprType::try_from((value >> 28) as u16)?;
Ok(Self::new(resource_type, value & MASK_28_BIT))
}
}
fn read_u32(input: &[u8]) -> Result<(u32, &[u8]), BinaryDeserializerError> {
#[allow(clippy::unwrap_used)]
let bytes = input
.get(0..core::mem::size_of::<u32>())
.ok_or(BinaryDeserializerError::invalid_data(
"unexpected end of input",
))?
.try_into()
.unwrap();
let value = u32::from_le_bytes(bytes);
let rest =
input
.get(core::mem::size_of::<u32>()..)
.ok_or(BinaryDeserializerError::invalid_data(
"unexpected end of input",
))?;
Ok((value, rest))
}