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 FieldList(FieldList<'a>),
98 MethodList(MethodListData<'a>),
99 ArgList(ArgList<'a>),
100 Alias(Alias<'a>),
101 UdtSrcLine(&'a UdtSrcLine),
102 UdtModSrcLine(&'a UdtModSrcLine),
103 FuncId(FuncId<'a>),
104 MFuncId(MFuncId<'a>),
105 StringId(StringId<'a>),
106 SubStrList(SubStrList<'a>),
107 BuildInfo(BuildInfo<'a>),
108 VFTable(&'a VFTable),
109 Unknown,
110}
111
112impl<'a> TypeData<'a> {
113 pub fn parse_bytes(kind: Leaf, bytes: &'a [u8]) -> Result<Self, ParserError> {
115 let mut p = Parser::new(bytes);
116 Self::parse(kind, &mut p)
117 }
118
119 pub fn parse(kind: Leaf, p: &mut Parser<'a>) -> Result<Self, ParserError> {
121 Ok(match kind {
122 Leaf::LF_ARRAY => Self::Array(p.parse()?),
123 Leaf::LF_CLASS | Leaf::LF_STRUCTURE | Leaf::LF_INTERFACE => Self::Struct(p.parse()?),
124 Leaf::LF_UNION => Self::Union(p.parse()?),
125 Leaf::LF_ENUM => Self::Enum(p.parse()?),
126 Leaf::LF_PROCEDURE => Self::Proc(p.get()?),
127 Leaf::LF_MEMBER => Self::MemberFunc(p.get()?),
128
129 Leaf::LF_VTSHAPE => {
130 let fixed: &VTableShapeFixed = p.get()?;
131 Self::VTableShape(VTableShapeData {
132 count: fixed.count.get(),
133 descriptors: p.take_rest(),
134 })
135 }
136
137 Leaf::LF_VFTABLE => Self::VFTable(p.get()?),
138
139 Leaf::LF_POINTER => {
140 let fixed = p.get()?;
141 let variant = p.take_rest();
142 Self::Pointer(Pointer { fixed, variant })
143 }
144
145 Leaf::LF_MFUNCTION => Self::MemberFunc(p.get()?),
146 Leaf::LF_MODIFIER => Self::Modifier(p.copy()?),
147
148 Leaf::LF_FIELDLIST => Self::FieldList(FieldList {
149 bytes: p.take_rest(),
150 }),
151
152 Leaf::LF_METHODLIST => Self::MethodList(MethodListData {
153 bytes: p.take_rest(),
154 }),
155
156 Leaf::LF_ARGLIST => Self::ArgList(p.parse()?),
157 Leaf::LF_ALIAS => Self::Alias(Alias::from_parser(p)?),
158 Leaf::LF_UDT_SRC_LINE => Self::UdtSrcLine(p.get()?),
159 Leaf::LF_UDT_MOD_SRC_LINE => Self::UdtModSrcLine(p.get()?),
160 Leaf::LF_FUNC_ID => Self::FuncId(p.parse()?),
161 Leaf::LF_MFUNC_ID => Self::MFuncId(p.parse()?),
162 Leaf::LF_STRING_ID => Self::StringId(p.parse()?),
163 Leaf::LF_SUBSTR_LIST => Self::SubStrList(p.parse()?),
164 Leaf::LF_BUILDINFO => Self::BuildInfo(p.parse()?),
165
166 _ => Self::Unknown,
167 })
168 }
169
170 pub fn name(&self) -> Option<&'a BStr> {
172 match self {
173 Self::Struct(t) => Some(t.name),
175 Self::Union(t) => Some(t.name),
176 Self::Enum(t) => Some(t.name),
177 Self::Alias(t) => Some(t.name),
178
179 Self::FuncId(t) => Some(t.name),
181 Self::StringId(t) => Some(t.name),
182
183 _ => None,
184 }
185 }
186
187 pub fn udt_name(&self) -> Option<&'a BStr> {
189 match self {
190 Self::Struct(t) => Some(t.name),
191 Self::Union(t) => Some(t.name),
192 Self::Enum(t) => Some(t.name),
193 Self::Alias(t) => Some(t.name),
194 _ => None,
195 }
196 }
197}