1#[derive(Debug, Default)]
8pub struct OutputStream {
9 buf: Vec<u8>,
10}
11
12impl OutputStream {
13 pub fn new() -> Self {
14 Self { buf: Vec::new() }
15 }
16
17 pub fn with_capacity(cap: usize) -> Self {
18 Self {
19 buf: Vec::with_capacity(cap),
20 }
21 }
22
23 #[inline]
25 pub fn position(&self) -> usize {
26 self.buf.len()
27 }
28
29 #[inline]
31 pub fn as_slice(&self) -> &[u8] {
32 &self.buf
33 }
34
35 #[inline]
37 pub fn into_bytes(self) -> Vec<u8> {
38 self.buf
39 }
40
41 #[inline]
43 pub fn write_u8(&mut self, v: u8) {
44 self.buf.push(v);
45 }
46
47 #[inline]
49 pub fn write_u16(&mut self, v: u16) {
50 self.buf.extend_from_slice(&v.to_le_bytes());
51 }
52
53 #[inline]
55 pub fn write_u32(&mut self, v: u32) {
56 self.buf.extend_from_slice(&v.to_le_bytes());
57 }
58
59 #[inline]
61 pub fn write_i16(&mut self, v: i16) {
62 self.buf.extend_from_slice(&v.to_le_bytes());
63 }
64
65 #[inline]
67 pub fn write_i32(&mut self, v: i32) {
68 self.buf.extend_from_slice(&v.to_le_bytes());
69 }
70
71 #[inline]
73 pub fn write_u64(&mut self, v: u64) {
74 self.buf.extend_from_slice(&v.to_le_bytes());
75 }
76
77 #[inline]
79 pub fn write_i64(&mut self, v: i64) {
80 self.buf.extend_from_slice(&v.to_le_bytes());
81 }
82
83 #[inline]
85 pub fn write_bytes(&mut self, bytes: &[u8]) {
86 self.buf.extend_from_slice(bytes);
87 }
88
89 #[inline]
91 pub fn patch(&mut self, offset: usize, bytes: &[u8]) {
92 self.buf[offset..offset + bytes.len()].copy_from_slice(bytes);
93 }
94}
95
96#[cfg(test)]
97mod tests {
98 use super::*;
99
100 #[test]
101 fn write_primitives() {
102 let mut s = OutputStream::new();
103 s.write_u8(0x01);
104 s.write_u16(0x0203);
105 s.write_u32(0x04050607);
106 assert_eq!(s.as_slice(), &[0x01, 0x03, 0x02, 0x07, 0x06, 0x05, 0x04]);
107 }
108
109 #[test]
110 fn write_bytes_and_position() {
111 let mut s = OutputStream::new();
112 assert_eq!(s.position(), 0);
113 s.write_bytes(b".FIT");
114 assert_eq!(s.position(), 4);
115 assert_eq!(s.as_slice(), b".FIT");
116 }
117
118 #[test]
119 fn patch_overwrites() {
120 let mut s = OutputStream::new();
121 s.write_u32(0); s.write_u32(0x12345678);
123 s.patch(0, &0xAABBCCDDu32.to_le_bytes());
124 assert_eq!(&s.as_slice()[0..4], &0xAABBCCDDu32.to_le_bytes());
125 assert_eq!(&s.as_slice()[4..8], &0x12345678u32.to_le_bytes());
126 }
127
128 #[test]
129 fn into_bytes_consumes() {
130 let mut s = OutputStream::with_capacity(16);
131 s.write_u8(42);
132 let bytes = s.into_bytes();
133 assert_eq!(bytes, vec![42]);
134 }
135
136 #[test]
137 fn signed_types() {
138 let mut s = OutputStream::new();
139 s.write_i16(-1);
140 s.write_i32(-2);
141 assert_eq!(&s.as_slice()[0..2], &(-1i16).to_le_bytes());
142 assert_eq!(&s.as_slice()[2..6], &(-2i32).to_le_bytes());
143 }
144}