perf_event_data/records/
text_poke.rs1use std::borrow::Cow;
2use std::fmt;
3
4use crate::prelude::*;
5
6#[derive(Clone)]
13pub struct TextPoke<'a> {
14 pub addr: u64,
16
17 pub old_bytes: Cow<'a, [u8]>,
19
20 pub new_bytes: Cow<'a, [u8]>,
22}
23
24impl<'a> TextPoke<'a> {
25 pub fn to_owned(self) -> TextPoke<'static> {
27 TextPoke {
28 old_bytes: self.old_bytes.into_owned().into(),
29 new_bytes: self.new_bytes.into_owned().into(),
30 ..self
31 }
32 }
33}
34
35impl<'p> Parse<'p> for TextPoke<'p> {
36 fn parse<B, E>(p: &mut Parser<B, E>) -> ParseResult<Self>
37 where
38 E: Endian,
39 B: ParseBuf<'p>,
40 {
41 use crate::util::cow::CowSliceExt;
42
43 let addr = p.parse()?;
44 let old_len = p.parse_u16()? as usize;
45 let new_len = p.parse_u16()? as usize;
46
47 let full_len = round_up_mod(old_len + new_len, 4, 8);
52 let bytes = p.parse_bytes(full_len)?;
53
54 let (old_bytes, mut new_bytes) = bytes.split_at(old_len);
55 new_bytes.truncate(new_len);
56
57 Ok(Self {
58 addr,
59 old_bytes,
60 new_bytes,
61 })
62 }
63}
64
65impl fmt::Debug for TextPoke<'_> {
66 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67 f.debug_struct("TextPoke")
68 .field("addr", &crate::util::fmt::HexAddr(self.addr))
69 .field("old_bytes", &self.old_bytes)
70 .field("new_bytes", &self.new_bytes)
71 .finish()
72 }
73}
74
75fn round_up_mod(v: usize, k: usize, m: usize) -> usize {
77 assert!(k < m);
78
79 v + match v % m {
80 vm if vm <= k => k - vm,
81 vm if vm > k => (k + m) - vm,
82 _ => unreachable!(),
83 }
84}