Skip to main content

micromegas_transit/
static_string.rs

1use crate::{
2    InProcSerialize, InProcSize, Reflect, UserDefinedType, read_consume_pod,
3    string_codec::StringCodec, write_any,
4};
5use lazy_static::lazy_static;
6use std::sync::Arc;
7
8/// Utf8StaticStringDependency serializes the value of the pointer and the contents of the string
9/// It should not be part of the event - it's the dependency of the StringId
10#[derive(Debug)]
11pub struct Utf8StaticStringDependency {
12    pub len: u32,
13    pub ptr: *const u8,
14}
15
16impl std::convert::From<&str> for Utf8StaticStringDependency {
17    fn from(src: &str) -> Self {
18        Self {
19            len: src.len() as u32,
20            ptr: src.as_ptr(),
21        }
22    }
23}
24
25// dummy impl for Reflect
26impl Reflect for Utf8StaticStringDependency {
27    fn reflect() -> UserDefinedType {
28        lazy_static! {
29            static ref TYPE_NAME: Arc<String> = Arc::new("StaticString".into());
30        }
31        UserDefinedType {
32            name: TYPE_NAME.clone(),
33            size: 0,
34            members: vec![],
35            is_reference: false,
36            secondary_udts: vec![],
37        }
38    }
39}
40
41impl InProcSerialize for Utf8StaticStringDependency {
42    const IN_PROC_SIZE: InProcSize = InProcSize::Dynamic;
43
44    fn get_value_size(&self) -> Option<u32> {
45        let id_size = std::mem::size_of::<usize>() as u32;
46        Some(self.len + id_size)
47    }
48
49    #[allow(unsafe_code)]
50    fn write_value(&self, buffer: &mut Vec<u8>) {
51        write_any(buffer, &self.ptr);
52        unsafe {
53            let slice = std::slice::from_raw_parts(self.ptr, self.len as usize);
54            buffer.extend_from_slice(slice);
55        }
56    }
57
58    #[allow(unsafe_code)]
59    unsafe fn read_value(mut window: &[u8]) -> Self {
60        let static_buffer_ptr: *const u8 = read_consume_pod(&mut window);
61        let buffer_size = window.len() as u32;
62        Self {
63            len: buffer_size,
64            ptr: static_buffer_ptr,
65        }
66    }
67}
68
69/// StaticStringDependency serializes the value of the pointer and the contents of the string
70/// It is designed to be wire-compatible with the unreal instrumentation
71#[derive(Debug)]
72pub struct StaticStringDependency {
73    /// Key of the string in the block's dependency map. Static strings use their address.
74    pub id: u64,
75    pub codec: StringCodec,
76    pub len: u32,
77    pub ptr: *const u8,
78}
79
80// dummy impl for Reflect
81impl Reflect for StaticStringDependency {
82    fn reflect() -> UserDefinedType {
83        lazy_static! {
84            static ref TYPE_NAME: Arc<String> = Arc::new("StaticStringDependency".into());
85        }
86        UserDefinedType {
87            name: TYPE_NAME.clone(),
88            size: 0,
89            members: vec![],
90            is_reference: false,
91            secondary_udts: vec![],
92        }
93    }
94}
95
96impl InProcSerialize for StaticStringDependency {
97    const IN_PROC_SIZE: InProcSize = InProcSize::Dynamic;
98
99    fn get_value_size(&self) -> Option<u32> {
100        let id_size = std::mem::size_of::<usize>() as u32;
101        let size =
102			id_size +
103			1 + // codec
104			std::mem::size_of::<u32>() as u32 +// size in bytes
105			self.len // actual buffer
106			;
107        Some(size)
108    }
109
110    #[allow(unsafe_code)]
111    fn write_value(&self, buffer: &mut Vec<u8>) {
112        write_any(buffer, &self.id);
113        let codec = self.codec as u8;
114        write_any(buffer, &codec);
115        write_any(buffer, &self.len);
116        unsafe {
117            let slice = std::slice::from_raw_parts(self.ptr, self.len as usize);
118            buffer.extend_from_slice(slice);
119        }
120    }
121
122    #[allow(unsafe_code)]
123    unsafe fn read_value(_window: &[u8]) -> Self {
124        // dependencies don't need to be read in the instrumented process
125        unimplemented!();
126    }
127}