1mod iter;
7#[doc(inline)]
8pub use iter::*;
9
10mod kind;
11#[doc(inline)]
12pub use kind::*;
13
14pub mod fields;
15pub mod number;
16pub mod primitive;
17pub mod visitor;
18
19mod records;
20#[doc(inline)]
21pub use records::*;
22
23pub use fields::FieldList;
24
25use self::primitive::dump_primitive_type_index;
26use crate::parser::{Number, Parse, Parser, ParserError};
27use bitfield::bitfield;
28use bstr::BStr;
29use std::fmt::Debug;
30use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, Unaligned, LE, U16, U32};
31
32#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
34pub struct TypeIndex(pub u32);
35
36impl TypeIndex {
37 pub const MIN_BEGIN: TypeIndex = TypeIndex(0x1000);
42}
43
44impl std::fmt::Debug for TypeIndex {
45 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
46 if self.0 < TypeIndex::MIN_BEGIN.0 {
47 dump_primitive_type_index(fmt, *self)
48 } else {
49 write!(fmt, "T#0x{:x}", self.0)
50 }
51 }
52}
53
54#[derive(
57 Copy, Clone, Eq, PartialEq, Hash, FromBytes, IntoBytes, Immutable, KnownLayout, Unaligned,
58)]
59#[repr(transparent)]
60pub struct TypeIndexLe(pub U32<LE>);
61
62impl From<TypeIndex> for TypeIndexLe {
63 #[inline(always)]
64 fn from(value: TypeIndex) -> TypeIndexLe {
65 TypeIndexLe(U32::new(value.0))
66 }
67}
68
69impl Debug for TypeIndexLe {
70 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
71 let ti = self.get();
72 Debug::fmt(&ti, fmt)
73 }
74}
75
76impl TypeIndexLe {
77 #[inline(always)]
79 pub fn get(self) -> TypeIndex {
80 TypeIndex(self.0.get())
81 }
82}
83
84#[derive(Clone, Debug)]
86#[allow(missing_docs)]
87pub enum TypeData<'a> {
88 Array(Array<'a>),
89 Struct(Struct<'a>),
90 Union(Union<'a>),
91 Enum(Enum<'a>),
92 Proc(&'a Proc),
93 MemberFunc(&'a MemberFunc),
94 VTableShape(VTableShapeData<'a>),
95 Pointer(Pointer<'a>),
96 Modifier(TypeModifier),
97 Bitfield(&'a Bitfield),
98 FieldList(FieldList<'a>),
99 MethodList(MethodListData<'a>),
100 ArgList(ArgList<'a>),
101 Alias(Alias<'a>),
102 UdtSrcLine(&'a UdtSrcLine),
103 UdtModSrcLine(&'a UdtModSrcLine),
104 FuncId(FuncId<'a>),
105 MFuncId(MFuncId<'a>),
106 StringId(StringId<'a>),
107 SubStrList(SubStrList<'a>),
108 BuildInfo(BuildInfo<'a>),
109 VFTable(&'a VFTable),
110 Unknown,
111}
112
113impl<'a> TypeData<'a> {
114 pub fn parse_bytes(kind: Leaf, bytes: &'a [u8]) -> Result<Self, ParserError> {
116 let mut p = Parser::new(bytes);
117 Self::parse(kind, &mut p)
118 }
119
120 pub fn parse(kind: Leaf, p: &mut Parser<'a>) -> Result<Self, ParserError> {
122 Ok(match kind {
123 Leaf::LF_ARRAY => Self::Array(p.parse()?),
124 Leaf::LF_CLASS | Leaf::LF_STRUCTURE | Leaf::LF_INTERFACE => Self::Struct(p.parse()?),
125 Leaf::LF_UNION => Self::Union(p.parse()?),
126 Leaf::LF_ENUM => Self::Enum(p.parse()?),
127 Leaf::LF_PROCEDURE => Self::Proc(p.get()?),
128 Leaf::LF_MEMBER => Self::MemberFunc(p.get()?),
129
130 Leaf::LF_VTSHAPE => {
131 let fixed: &VTableShapeFixed = p.get()?;
132 Self::VTableShape(VTableShapeData {
133 count: fixed.count.get(),
134 descriptors: p.take_rest(),
135 })
136 }
137
138 Leaf::LF_VFTABLE => Self::VFTable(p.get()?),
139
140 Leaf::LF_POINTER => {
141 let fixed = p.get()?;
142 let variant = p.take_rest();
143 Self::Pointer(Pointer { fixed, variant })
144 }
145
146 Leaf::LF_MFUNCTION => Self::MemberFunc(p.get()?),
147 Leaf::LF_MODIFIER => Self::Modifier(p.copy()?),
148 Leaf::LF_BITFIELD => Self::Bitfield(p.get()?),
149
150 Leaf::LF_FIELDLIST => Self::FieldList(FieldList {
151 bytes: p.take_rest(),
152 }),
153
154 Leaf::LF_METHODLIST => Self::MethodList(MethodListData {
155 bytes: p.take_rest(),
156 }),
157
158 Leaf::LF_ARGLIST => Self::ArgList(p.parse()?),
159 Leaf::LF_ALIAS => Self::Alias(Alias::from_parser(p)?),
160 Leaf::LF_UDT_SRC_LINE => Self::UdtSrcLine(p.get()?),
161 Leaf::LF_UDT_MOD_SRC_LINE => Self::UdtModSrcLine(p.get()?),
162 Leaf::LF_FUNC_ID => Self::FuncId(p.parse()?),
163 Leaf::LF_MFUNC_ID => Self::MFuncId(p.parse()?),
164 Leaf::LF_STRING_ID => Self::StringId(p.parse()?),
165 Leaf::LF_SUBSTR_LIST => Self::SubStrList(p.parse()?),
166 Leaf::LF_BUILDINFO => Self::BuildInfo(p.parse()?),
167
168 _ => Self::Unknown,
169 })
170 }
171
172 pub fn name(&self) -> Option<&'a BStr> {
174 match self {
175 Self::Struct(t) => Some(t.name),
177 Self::Union(t) => Some(t.name),
178 Self::Enum(t) => Some(t.name),
179 Self::Alias(t) => Some(t.name),
180
181 Self::FuncId(t) => Some(t.name),
183 Self::StringId(t) => Some(t.name),
184
185 _ => None,
186 }
187 }
188
189 pub fn udt_name(&self) -> Option<&'a BStr> {
191 match self {
192 Self::Struct(t) => Some(t.name),
193 Self::Union(t) => Some(t.name),
194 Self::Enum(t) => Some(t.name),
195 Self::Alias(t) => Some(t.name),
196 _ => None,
197 }
198 }
199}