use crate::context::ReadContext;
use crate::ensure;
use crate::error::Error;
use crate::meta::FieldType;
use crate::serializer::collection::{DECL_ELEMENT_TYPE, HAS_NULL, IS_SAME_TYPE};
use crate::serializer::util;
use crate::serializer::Serializer;
use crate::type_id as types;
use crate::types::{Date, Duration, Timestamp};
use crate::util::ENABLE_FORY_DEBUG_OUTPUT;
use crate::RefFlag;
use std::rc::Rc;
#[allow(unreachable_code)]
pub fn skip_field_value(
context: &mut ReadContext,
field_type: &FieldType,
read_ref_flag: bool,
) -> Result<(), Error> {
skip_value(context, field_type, read_ref_flag, true, &None)
}
#[inline(always)]
fn unknown_field_type() -> FieldType {
FieldType::new(types::UNKNOWN, true, Vec::new())
}
pub fn skip_any_value(context: &mut ReadContext, read_ref_flag: bool) -> Result<(), Error> {
if read_ref_flag {
let ref_flag = context.reader.read_i8()?;
if ref_flag == (RefFlag::Null as i8) {
return Ok(());
}
if ref_flag == (RefFlag::Ref as i8) {
let _ref_index = context.reader.read_var_u32()?;
return Ok(());
}
}
let type_id = context.reader.read_u8()? as u32;
let internal_id = type_id;
let _user_type_id = if types::needs_user_type_id(type_id) && type_id != types::COMPATIBLE_STRUCT
{
Some(context.reader.read_var_u32()?)
} else {
None
};
if internal_id == types::NONE {
return Ok(());
}
let (field_type, type_info_opt) = match internal_id {
types::LIST | types::SET => (
FieldType::new(type_id, true, vec![unknown_field_type()]),
None,
),
types::MAP => (
FieldType::new(
type_id,
true,
vec![unknown_field_type(), unknown_field_type()],
),
None,
),
types::COMPATIBLE_STRUCT | types::NAMED_COMPATIBLE_STRUCT => {
let type_info = context.read_type_meta()?;
(FieldType::new(type_id, true, Vec::new()), Some(type_info))
}
types::NAMED_ENUM | types::NAMED_EXT | types::NAMED_STRUCT | types::NAMED_UNION => {
if context.is_share_meta() {
let type_info = context.read_type_meta()?;
(FieldType::new(type_id, true, Vec::new()), Some(type_info))
} else {
let namespace = context.read_meta_string()?.to_owned();
let type_name = context.read_meta_string()?.to_owned();
let rc_namespace = Rc::from(namespace);
let rc_type_name = Rc::from(type_name);
let type_info = context
.get_type_resolver()
.get_type_info_by_meta_string_name(rc_namespace, rc_type_name)
.ok_or_else(|| crate::Error::type_error("Name harness not found"))?;
(FieldType::new(type_id, true, Vec::new()), Some(type_info))
}
}
_ => {
let type_info = if let Some(user_type_id) = _user_type_id {
context
.get_type_resolver()
.get_user_type_info_by_id(user_type_id)
} else {
None
};
(
FieldType::new_with_user_type_id(
type_id,
_user_type_id.unwrap_or(u32::MAX),
true,
false,
Vec::new(),
),
type_info,
)
}
};
skip_value(context, &field_type, false, false, &type_info_opt)
}
fn skip_collection(context: &mut ReadContext, field_type: &FieldType) -> Result<(), Error> {
let length = context.reader.read_var_u32()? as usize;
if length == 0 {
return Ok(());
}
let header = context.reader.read_u8()?;
let has_null = (header & HAS_NULL) != 0;
let is_same_type = (header & IS_SAME_TYPE) != 0;
let skip_ref_flag = is_same_type && !has_null;
let is_declared = (header & DECL_ELEMENT_TYPE) != 0;
if field_type.generics.is_empty() {
return Err(Error::invalid_data("empty generics"));
}
let default_elem_type = field_type.generics.first().unwrap();
let (type_info, elem_field_type);
let elem_type = if is_same_type && !is_declared {
let type_info_rc = context.read_any_type_info()?;
elem_field_type = FieldType::new_with_user_type_id(
type_info_rc.get_type_id() as u32,
type_info_rc.get_user_type_id(),
has_null,
false,
Vec::new(),
);
type_info = Some(type_info_rc);
&elem_field_type
} else {
type_info = None;
default_elem_type
};
context.inc_depth()?;
for _ in 0..length {
skip_value(context, elem_type, !skip_ref_flag, false, &type_info)?;
}
context.dec_depth();
Ok(())
}
fn skip_map(context: &mut ReadContext, field_type: &FieldType) -> Result<(), Error> {
let length = context.reader.read_var_u32()?;
if length == 0 {
return Ok(());
}
let mut len_counter = 0;
if field_type.generics.len() < 2 {
return Err(Error::invalid_data("map must have at least 2 generics"));
}
let default_key_type = field_type.generics.first().unwrap();
let default_value_type = field_type.generics.get(1).unwrap();
loop {
if len_counter == length {
break;
}
let header = context.reader.read_u8()?;
if header & crate::serializer::map::KEY_NULL != 0
&& header & crate::serializer::map::VALUE_NULL != 0
{
len_counter += 1;
continue;
}
if header & crate::serializer::map::KEY_NULL != 0 {
let value_declared = (header & crate::serializer::map::DECL_VALUE_TYPE) != 0;
let (value_type_info, value_field_type);
let value_type = if !value_declared {
let type_info = context.read_any_type_info()?;
value_field_type = FieldType::new_with_user_type_id(
type_info.get_type_id() as u32,
type_info.get_user_type_id(),
true,
false,
Vec::new(),
);
value_type_info = Some(type_info);
&value_field_type
} else {
value_type_info = None;
default_value_type
};
context.inc_depth()?;
skip_value(context, value_type, false, false, &value_type_info)?;
context.dec_depth();
len_counter += 1;
continue;
}
if header & crate::serializer::map::VALUE_NULL != 0 {
let key_declared = (header & crate::serializer::map::DECL_KEY_TYPE) != 0;
let (key_type_info, key_field_type);
let key_type = if !key_declared {
let type_info = context.read_any_type_info()?;
key_field_type = FieldType::new_with_user_type_id(
type_info.get_type_id() as u32,
type_info.get_user_type_id(),
true,
false,
Vec::new(),
);
key_type_info = Some(type_info);
&key_field_type
} else {
key_type_info = None;
default_key_type
};
context.inc_depth()?;
skip_value(context, key_type, false, false, &key_type_info)?;
context.dec_depth();
len_counter += 1;
continue;
}
let chunk_size = context.reader.read_u8()?;
let key_declared = (header & crate::serializer::map::DECL_KEY_TYPE) != 0;
let value_declared = (header & crate::serializer::map::DECL_VALUE_TYPE) != 0;
let (key_type_info, key_field_type);
let key_type = if !key_declared {
let type_info = context.read_any_type_info()?;
key_field_type = FieldType::new_with_user_type_id(
type_info.get_type_id() as u32,
type_info.get_user_type_id(),
true,
false,
Vec::new(),
);
key_type_info = Some(type_info);
&key_field_type
} else {
key_type_info = None;
default_key_type
};
let (value_type_info, value_field_type);
let value_type = if !value_declared {
let type_info = context.read_any_type_info()?;
value_field_type = FieldType::new_with_user_type_id(
type_info.get_type_id() as u32,
type_info.get_user_type_id(),
true,
false,
Vec::new(),
);
value_type_info = Some(type_info);
&value_field_type
} else {
value_type_info = None;
default_value_type
};
context.inc_depth()?;
for _ in 0..chunk_size {
skip_value(context, key_type, false, false, &key_type_info)?;
skip_value(context, value_type, false, false, &value_type_info)?;
}
context.dec_depth();
len_counter += chunk_size as u32;
}
Ok(())
}
fn skip_struct(
context: &mut ReadContext,
type_id_num: u32,
type_info: &Option<Rc<crate::TypeInfo>>,
) -> Result<(), Error> {
let type_info_rc: Option<Rc<crate::TypeInfo>>;
let type_info_value = if type_info.is_none() {
let remote_type_info = context.read_any_type_info()?;
let remote_type_id = remote_type_info.get_type_id() as u32;
if type_id_num != types::UNKNOWN && remote_type_id != types::UNKNOWN {
ensure!(
type_id_num == remote_type_id,
Error::type_mismatch(type_id_num, remote_type_id)
);
}
type_info_rc = Some(remote_type_info);
type_info_rc.as_ref().unwrap()
} else {
type_info.as_ref().unwrap()
};
let type_meta = type_info_value.get_type_meta();
if ENABLE_FORY_DEBUG_OUTPUT {
eprintln!(
"[skip_struct] type_name: {:?}, num_fields: {}",
type_meta.get_type_name(),
type_meta.get_field_infos().len()
);
}
let field_infos = type_meta.get_field_infos().to_vec();
context.inc_depth()?;
for field_info in field_infos.iter() {
if ENABLE_FORY_DEBUG_OUTPUT {
eprintln!(
"[skip_struct] field: {:?}, type_id: {}, internal_id: {}",
field_info.field_name, field_info.field_type.type_id, field_info.field_type.type_id
);
}
let read_ref_flag = util::field_need_write_ref_into(
field_info.field_type.type_id,
field_info.field_type.nullable,
);
skip_value(context, &field_info.field_type, read_ref_flag, true, &None)?;
}
context.dec_depth();
Ok(())
}
fn skip_ext(
context: &mut ReadContext,
type_id_num: u32,
type_info: &Option<Rc<crate::TypeInfo>>,
) -> Result<(), Error> {
let type_info_rc: Option<Rc<crate::TypeInfo>>;
let type_info_value = if type_info.is_none() {
let remote_type_info = context.read_any_type_info()?;
let remote_type_id = remote_type_info.get_type_id() as u32;
ensure!(
type_id_num == remote_type_id,
Error::type_mismatch(type_id_num, remote_type_id)
);
type_info_rc = Some(remote_type_info);
type_info_rc.as_ref().unwrap()
} else {
type_info.as_ref().unwrap()
};
type_info_value.get_harness().get_read_data_fn()(context)?;
Ok(())
}
#[allow(unreachable_code)]
fn skip_value(
context: &mut ReadContext,
field_type: &FieldType,
read_ref_flag: bool,
_is_field: bool,
type_info: &Option<Rc<crate::TypeInfo>>,
) -> Result<(), Error> {
if read_ref_flag {
let ref_flag = context.reader.read_i8()?;
if ref_flag == (RefFlag::Null as i8) {
return Ok(());
}
if ref_flag == (RefFlag::Ref as i8) {
let _ref_index = context.reader.read_var_u32()?;
return Ok(());
}
}
let type_id_num = field_type.type_id;
if type_id_num == types::UNKNOWN {
return skip_any_value(context, false);
}
if types::is_user_type(type_id_num) {
if type_id_num == types::COMPATIBLE_STRUCT
|| type_id_num == types::STRUCT
|| type_id_num == types::NAMED_STRUCT
|| type_id_num == types::NAMED_COMPATIBLE_STRUCT
{
return skip_struct(context, type_id_num, type_info);
} else if type_id_num == types::ENUM || type_id_num == types::NAMED_ENUM {
let _ordinal = context.reader.read_var_u32()?;
return Ok(());
} else if type_id_num == types::UNION
|| type_id_num == types::TYPED_UNION
|| type_id_num == types::NAMED_UNION
{
let _ordinal = context.reader.read_var_u32()?;
return skip_any_value(context, true);
} else if type_id_num == types::EXT || type_id_num == types::NAMED_EXT {
return skip_ext(context, type_id_num, type_info);
} else {
return Err(Error::type_error(format!(
"Unknown type id: {} (type_info provided: {})",
type_id_num,
type_info.is_some()
)));
}
}
match type_id_num {
types::UNKNOWN => {
return skip_any_value(context, false);
}
types::BOOL => {
<bool as Serializer>::fory_read_data(context)?;
}
types::INT8 => {
<i8 as Serializer>::fory_read_data(context)?;
}
types::INT16 => {
<i16 as Serializer>::fory_read_data(context)?;
}
types::INT32 => {
context.reader.read_i32()?;
}
types::VARINT32 => {
<i32 as Serializer>::fory_read_data(context)?;
}
types::INT64 => {
context.reader.read_i64()?;
}
types::VARINT64 => {
<i64 as Serializer>::fory_read_data(context)?;
}
types::TAGGED_INT64 => {
context.reader.read_tagged_i64()?;
}
types::UINT8 => {
<u8 as Serializer>::fory_read_data(context)?;
}
types::UINT16 => {
<u16 as Serializer>::fory_read_data(context)?;
}
types::UINT32 => {
context.reader.read_u32()?;
}
types::VAR_UINT32 => {
<u32 as Serializer>::fory_read_data(context)?;
}
types::UINT64 => {
context.reader.read_u64()?;
}
types::VAR_UINT64 => {
<u64 as Serializer>::fory_read_data(context)?;
}
types::TAGGED_UINT64 => {
context.reader.read_tagged_u64()?;
}
types::FLOAT16 => {
<crate::types::float16::float16 as Serializer>::fory_read_data(context)?;
}
types::BFLOAT16 => {
<crate::types::bfloat16::bfloat16 as Serializer>::fory_read_data(context)?;
}
types::FLOAT32 => {
<f32 as Serializer>::fory_read_data(context)?;
}
types::FLOAT64 => {
<f64 as Serializer>::fory_read_data(context)?;
}
types::STRING => {
<String as Serializer>::fory_read_data(context)?;
}
types::LIST | types::SET => {
return skip_collection(context, field_type);
}
types::MAP => {
return skip_map(context, field_type);
}
types::ENUM => {
let _ordinal = context.reader.read_var_u32()?;
}
types::NAMED_ENUM => {
let _ordinal = context.reader.read_var_u32()?;
}
types::STRUCT => {
return skip_struct(context, type_id_num, type_info);
}
types::COMPATIBLE_STRUCT => {
return skip_struct(context, type_id_num, type_info);
}
types::NAMED_STRUCT => {
return skip_struct(context, type_id_num, type_info);
}
types::NAMED_COMPATIBLE_STRUCT => {
return skip_struct(context, type_id_num, type_info);
}
types::EXT => {
return skip_ext(context, type_id_num, type_info);
}
types::NAMED_EXT => {
return skip_ext(context, type_id_num, type_info);
}
types::UNION => {
let _ = context.reader.read_var_u32()?;
return skip_any_value(context, true);
}
types::TYPED_UNION => {
let _ = context.reader.read_var_u32()?;
return skip_any_value(context, true);
}
types::NAMED_UNION => {
let _ = context.reader.read_var_u32()?;
return skip_any_value(context, true);
}
types::NONE => {
return Ok(());
}
types::DURATION => {
<Duration as Serializer>::fory_read_data(context)?;
}
types::TIMESTAMP => {
<Timestamp as Serializer>::fory_read_data(context)?;
}
types::DATE => {
<Date as Serializer>::fory_read_data(context)?;
}
types::DECIMAL => {
<crate::Decimal as Serializer>::fory_read_data(context)?;
}
types::BINARY => {
<Vec<u8> as Serializer>::fory_read_data(context)?;
}
types::BOOL_ARRAY => {
<Vec<bool> as Serializer>::fory_read_data(context)?;
}
types::INT8_ARRAY => {
<Vec<i8> as Serializer>::fory_read_data(context)?;
}
types::INT16_ARRAY => {
<Vec<i16> as Serializer>::fory_read_data(context)?;
}
types::INT32_ARRAY => {
<Vec<i32> as Serializer>::fory_read_data(context)?;
}
types::INT64_ARRAY => {
<Vec<i64> as Serializer>::fory_read_data(context)?;
}
types::UINT8_ARRAY => {
<Vec<u8> as Serializer>::fory_read_data(context)?;
}
types::UINT16_ARRAY => {
<Vec<u16> as Serializer>::fory_read_data(context)?;
}
types::UINT32_ARRAY => {
<Vec<u32> as Serializer>::fory_read_data(context)?;
}
types::UINT64_ARRAY => {
<Vec<u64> as Serializer>::fory_read_data(context)?;
}
types::FLOAT16_ARRAY => {
<Vec<crate::types::float16::float16> as Serializer>::fory_read_data(context)?;
}
types::BFLOAT16_ARRAY => {
<Vec<crate::types::bfloat16::bfloat16> as Serializer>::fory_read_data(context)?;
}
types::FLOAT32_ARRAY => {
<Vec<f32> as Serializer>::fory_read_data(context)?;
}
types::FLOAT64_ARRAY => {
<Vec<f64> as Serializer>::fory_read_data(context)?;
}
types::U128 => {
<u128 as Serializer>::fory_read_data(context)?;
}
types::INT128 => {
<i128 as Serializer>::fory_read_data(context)?;
}
types::USIZE => {
<usize as Serializer>::fory_read_data(context)?;
}
types::ISIZE => {
<isize as Serializer>::fory_read_data(context)?;
}
types::U128_ARRAY => {
<Vec<u128> as Serializer>::fory_read_data(context)?;
}
types::INT128_ARRAY => {
<Vec<i128> as Serializer>::fory_read_data(context)?;
}
types::USIZE_ARRAY => {
<Vec<usize> as Serializer>::fory_read_data(context)?;
}
types::ISIZE_ARRAY => {
<Vec<isize> as Serializer>::fory_read_data(context)?;
}
_ => {
return Err(Error::type_error(format!(
"Unimplemented type id: {}",
type_id_num
)));
}
}
Ok(())
}
pub fn skip_enum_variant(
context: &mut ReadContext,
variant_type: u32,
type_info: &Option<Rc<crate::TypeInfo>>,
) -> Result<(), Error> {
match variant_type {
0b0 => {
Ok(())
}
0b1 => {
let field_type = FieldType::new(types::LIST, false, vec![unknown_field_type()]);
skip_collection(context, &field_type)
}
0b10 => {
if type_info.is_some() {
let type_id = type_info.as_ref().unwrap().get_type_id() as u32;
skip_struct(context, type_id, type_info)
} else {
let type_info_rc = context.read_type_meta()?;
let type_id = type_info_rc.get_type_id() as u32;
let type_info_opt = Some(type_info_rc);
skip_struct(context, type_id, &type_info_opt)
}
}
_ => {
Err(Error::type_error(format!(
"Invalid enum variant type: {}",
variant_type
)))
}
}
}