@@ -20,9 +20,10 @@ use serde::{Deserialize, Serialize};
20
20
#[ derive( Default , Debug , Clone , Eq , Hash , PartialEq , Serialize , Deserialize ) ]
21
21
pub enum TypeVariant {
22
22
#[ default]
23
- /// A fixed size type like [`u64`]
23
+ /// A fixed size type which is determined during compile.
24
+ /// A structure holds some pointer fields should be clarified as Dynamic.
24
25
FixedSize ,
25
- /// A dynamic sized type like a slice
26
+ /// A dynamic sized type like a slice or it contains some pointer fields.
26
27
Dynamic ,
27
28
}
28
29
@@ -33,9 +34,9 @@ pub struct TypeDetail {
33
34
pub variant : TypeVariant ,
34
35
/// Contains the output of [`core::any::type_name()`].
35
36
pub type_name : String ,
36
- /// The size of the underlying type.
37
+ /// The size of the underlying type calculated by [`core::mem::size_of`] .
37
38
pub size : usize ,
38
- /// The alignment of the underlying type.
39
+ /// The ABI-required minimum alignment of the underlying type calculated by [`core::mem::align_of`] .
39
40
pub alignment : usize ,
40
41
}
41
42
@@ -64,11 +65,11 @@ pub struct MessageTypeDetails {
64
65
}
65
66
66
67
impl MessageTypeDetails {
67
- pub ( crate ) fn from < Header , UserHeader , Payload > ( variant : TypeVariant ) -> Self {
68
+ pub ( crate ) fn from < Header , UserHeader , Payload > ( payload_variant : TypeVariant ) -> Self {
68
69
Self {
69
70
header : TypeDetail :: __internal_new :: < Header > ( TypeVariant :: FixedSize ) ,
70
71
user_header : TypeDetail :: __internal_new :: < UserHeader > ( TypeVariant :: FixedSize ) ,
71
- payload : TypeDetail :: __internal_new :: < Payload > ( variant ) ,
72
+ payload : TypeDetail :: __internal_new :: < Payload > ( payload_variant ) ,
72
73
}
73
74
}
74
75
@@ -78,6 +79,7 @@ impl MessageTypeDetails {
78
79
payload_start as * const u8
79
80
}
80
81
82
+ /// returns pointer of user_header which is the field follows the header field in a structure.
81
83
pub ( crate ) fn user_header_ptr_from_header ( & self , header : * const u8 ) -> * const u8 {
82
84
let header = header as usize ;
83
85
let user_header_start = align ( header + self . header . size , self . user_header . alignment ) ;
@@ -120,3 +122,124 @@ impl MessageTypeDetails {
120
122
&& self . payload . alignment <= rhs. payload . alignment
121
123
}
122
124
}
125
+
126
+ #[ cfg( test) ]
127
+ mod tests {
128
+ use super :: * ;
129
+ use iceoryx2_bb_testing:: assert_that;
130
+
131
+ #[ test]
132
+ fn test_from ( ) {
133
+ struct MyPayload {
134
+ _a : i32 ,
135
+ _b : bool ,
136
+ _c : i64 ,
137
+ }
138
+
139
+ let got = MessageTypeDetails :: from :: < i32 , i64 , MyPayload > ( TypeVariant :: FixedSize ) ;
140
+ let want = MessageTypeDetails {
141
+ header : TypeDetail {
142
+ variant : TypeVariant :: FixedSize ,
143
+ type_name : "i32" . to_string ( ) ,
144
+ size : 4 ,
145
+ alignment : 4 ,
146
+ } ,
147
+ user_header : TypeDetail {
148
+ variant : TypeVariant :: FixedSize ,
149
+ type_name : "i64" . to_string ( ) ,
150
+ size : 8 ,
151
+ alignment : 8 ,
152
+ } ,
153
+ payload : TypeDetail {
154
+ variant : TypeVariant :: FixedSize ,
155
+ type_name : "iceoryx2::service::static_config::message_type_details::tests::test_from::MyPayload" . to_string ( ) ,
156
+ size : 16 ,
157
+ alignment : 8 ,
158
+ } ,
159
+ } ;
160
+ assert_that ! ( want, eq got) ;
161
+
162
+ let got = MessageTypeDetails :: from :: < i32 , bool , String > ( TypeVariant :: Dynamic ) ;
163
+ let want = MessageTypeDetails {
164
+ header : TypeDetail {
165
+ variant : TypeVariant :: FixedSize ,
166
+ type_name : "i32" . to_string ( ) ,
167
+ size : 4 ,
168
+ alignment : 4 ,
169
+ } ,
170
+ user_header : TypeDetail {
171
+ variant : TypeVariant :: FixedSize ,
172
+ type_name : "bool" . to_string ( ) ,
173
+ size : 1 ,
174
+ alignment : 1 ,
175
+ } ,
176
+ payload : TypeDetail {
177
+ variant : TypeVariant :: Dynamic ,
178
+ type_name : "alloc::string::String" . to_string ( ) ,
179
+ size : 24 ,
180
+ alignment : 8 ,
181
+ } ,
182
+ } ;
183
+ assert_that ! ( want, eq got) ;
184
+ }
185
+
186
+ #[ test]
187
+ fn test_user_header_ptr_from_header ( ) {
188
+ let details = MessageTypeDetails :: from :: < i32 , bool , String > ( TypeVariant :: Dynamic ) ;
189
+ struct Demo {
190
+ header : i32 ,
191
+ user_header : bool ,
192
+ _payload : String ,
193
+ }
194
+
195
+ let demo = Demo {
196
+ header : 123 ,
197
+ user_header : true ,
198
+ _payload : "test" . to_string ( ) ,
199
+ } ;
200
+
201
+ let ptr: * const u8 = & demo. header as * const _ as * const u8 ;
202
+ let user_header_ptr = details. user_header_ptr_from_header ( ptr) ;
203
+ let got: * const bool = user_header_ptr as * const bool ;
204
+ assert_that ! ( unsafe { * got } , eq demo. user_header) ;
205
+
206
+ let details = MessageTypeDetails :: from :: < i64 , i32 , String > ( TypeVariant :: Dynamic ) ;
207
+ struct Demo2 {
208
+ header : i64 ,
209
+ user_header : i32 ,
210
+ _payload : String ,
211
+ }
212
+
213
+ let demo = Demo2 {
214
+ header : 123 ,
215
+ user_header : 999 ,
216
+ _payload : "test" . to_string ( ) ,
217
+ } ;
218
+
219
+ let ptr: * const u8 = & demo. header as * const _ as * const u8 ;
220
+ let user_header_ptr = details. user_header_ptr_from_header ( ptr) ;
221
+ let got: * const i32 = user_header_ptr as * const i32 ;
222
+ assert_that ! ( unsafe { * got } , eq demo. user_header) ;
223
+ }
224
+
225
+ #[ test]
226
+ fn test_payload_ptr_from_header ( ) {
227
+ let details = MessageTypeDetails :: from :: < i32 , i32 , i32 > ( TypeVariant :: Dynamic ) ;
228
+ struct Demo {
229
+ header : i32 ,
230
+ _user_header : i32 ,
231
+ payload : i32 ,
232
+ }
233
+
234
+ let demo = Demo {
235
+ header : 123 ,
236
+ _user_header : 123 ,
237
+ payload : 9999 ,
238
+ } ;
239
+
240
+ let ptr: * const u8 = & demo. header as * const _ as * const u8 ;
241
+ let payload_ptr = details. payload_ptr_from_header ( ptr) as * const i32 ;
242
+ let got = unsafe { * payload_ptr } ;
243
+ assert_that ! ( got, eq demo. payload) ;
244
+ }
245
+ }
0 commit comments