1use crate::error::{Error, Result};
22
23pub struct CdrEncoder<'a> {
37 buf: &'a mut [u8],
38 pos: usize,
39}
40
41impl<'a> CdrEncoder<'a> {
42 pub fn new(buf: &'a mut [u8]) -> Self {
44 Self { buf, pos: 0 }
45 }
46
47 pub const fn position(&self) -> usize {
49 self.pos
50 }
51
52 pub fn finish(self) -> &'a [u8] {
54 &self.buf[0..self.pos]
55 }
56
57 fn align(&mut self, alignment: usize) -> Result<()> {
59 let remainder = self.pos % alignment;
60 if remainder != 0 {
61 let padding = alignment - remainder;
62 if self.pos + padding > self.buf.len() {
63 return Err(Error::BufferTooSmall);
64 }
65 for i in 0..padding {
67 self.buf[self.pos + i] = 0;
68 }
69 self.pos += padding;
70 }
71 Ok(())
72 }
73
74 fn write_bytes(&mut self, bytes: &[u8]) -> Result<()> {
76 if self.pos + bytes.len() > self.buf.len() {
77 return Err(Error::BufferTooSmall);
78 }
79 self.buf[self.pos..self.pos + bytes.len()].copy_from_slice(bytes);
80 self.pos += bytes.len();
81 Ok(())
82 }
83
84 pub fn encode_u8(&mut self, value: u8) -> Result<()> {
86 self.write_bytes(&[value])
87 }
88
89 pub fn encode_i8(&mut self, value: i8) -> Result<()> {
91 self.write_bytes(&[value as u8])
92 }
93
94 pub fn encode_bool(&mut self, value: bool) -> Result<()> {
96 self.encode_u8(if value { 1 } else { 0 })
97 }
98
99 pub fn encode_u16(&mut self, value: u16) -> Result<()> {
101 self.align(2)?;
102 self.write_bytes(&value.to_le_bytes())
103 }
104
105 pub fn encode_i16(&mut self, value: i16) -> Result<()> {
107 self.align(2)?;
108 self.write_bytes(&value.to_le_bytes())
109 }
110
111 pub fn encode_u32(&mut self, value: u32) -> Result<()> {
113 self.align(4)?;
114 self.write_bytes(&value.to_le_bytes())
115 }
116
117 pub fn encode_i32(&mut self, value: i32) -> Result<()> {
119 self.align(4)?;
120 self.write_bytes(&value.to_le_bytes())
121 }
122
123 pub fn encode_u64(&mut self, value: u64) -> Result<()> {
125 self.align(8)?;
126 self.write_bytes(&value.to_le_bytes())
127 }
128
129 pub fn encode_i64(&mut self, value: i64) -> Result<()> {
131 self.align(8)?;
132 self.write_bytes(&value.to_le_bytes())
133 }
134
135 pub fn encode_f32(&mut self, value: f32) -> Result<()> {
137 self.align(4)?;
138 self.write_bytes(&value.to_le_bytes())
139 }
140
141 pub fn encode_f64(&mut self, value: f64) -> Result<()> {
143 self.align(8)?;
144 self.write_bytes(&value.to_le_bytes())
145 }
146
147 pub fn encode_string(&mut self, value: &str) -> Result<()> {
149 let bytes = value.as_bytes();
150 let len = bytes.len() as u32;
151
152 self.encode_u32(len + 1)?;
154
155 self.write_bytes(bytes)?;
157
158 self.encode_u8(0)?;
160
161 Ok(())
162 }
163
164 pub fn encode_bytes(&mut self, bytes: &[u8]) -> Result<()> {
166 self.write_bytes(bytes)
167 }
168
169 pub fn encode_seq_len(&mut self, len: usize) -> Result<()> {
173 self.encode_u32(len as u32)
174 }
175}
176
177pub struct CdrDecoder<'a> {
188 buf: &'a [u8],
189 pos: usize,
190}
191
192impl<'a> CdrDecoder<'a> {
193 pub const fn new(buf: &'a [u8]) -> Self {
195 Self { buf, pos: 0 }
196 }
197
198 pub const fn position(&self) -> usize {
200 self.pos
201 }
202
203 pub const fn remaining(&self) -> usize {
205 self.buf.len() - self.pos
206 }
207
208 fn align(&mut self, alignment: usize) -> Result<()> {
210 let remainder = self.pos % alignment;
211 if remainder != 0 {
212 let padding = alignment - remainder;
213 if self.pos + padding > self.buf.len() {
214 return Err(Error::BufferTooSmall);
215 }
216 self.pos += padding;
217 }
218 Ok(())
219 }
220
221 fn read_bytes(&mut self, count: usize) -> Result<&'a [u8]> {
223 if self.pos + count > self.buf.len() {
224 return Err(Error::BufferTooSmall);
225 }
226 let bytes = &self.buf[self.pos..self.pos + count];
227 self.pos += count;
228 Ok(bytes)
229 }
230
231 pub fn decode_u8(&mut self) -> Result<u8> {
233 let bytes = self.read_bytes(1)?;
234 Ok(bytes[0])
235 }
236
237 pub fn decode_i8(&mut self) -> Result<i8> {
239 Ok(self.decode_u8()? as i8)
240 }
241
242 pub fn decode_bool(&mut self) -> Result<bool> {
244 Ok(self.decode_u8()? != 0)
245 }
246
247 pub fn decode_u16(&mut self) -> Result<u16> {
249 self.align(2)?;
250 let bytes = self.read_bytes(2)?;
251 let mut arr = [0u8; 2];
252 arr.copy_from_slice(bytes);
253 Ok(u16::from_le_bytes(arr))
254 }
255
256 pub fn decode_i16(&mut self) -> Result<i16> {
258 self.align(2)?;
259 let bytes = self.read_bytes(2)?;
260 let mut arr = [0u8; 2];
261 arr.copy_from_slice(bytes);
262 Ok(i16::from_le_bytes(arr))
263 }
264
265 pub fn decode_u32(&mut self) -> Result<u32> {
267 self.align(4)?;
268 let bytes = self.read_bytes(4)?;
269 let mut arr = [0u8; 4];
270 arr.copy_from_slice(bytes);
271 Ok(u32::from_le_bytes(arr))
272 }
273
274 pub fn decode_i32(&mut self) -> Result<i32> {
276 self.align(4)?;
277 let bytes = self.read_bytes(4)?;
278 let mut arr = [0u8; 4];
279 arr.copy_from_slice(bytes);
280 Ok(i32::from_le_bytes(arr))
281 }
282
283 pub fn decode_u64(&mut self) -> Result<u64> {
285 self.align(8)?;
286 let bytes = self.read_bytes(8)?;
287 let mut arr = [0u8; 8];
288 arr.copy_from_slice(bytes);
289 Ok(u64::from_le_bytes(arr))
290 }
291
292 pub fn decode_i64(&mut self) -> Result<i64> {
294 self.align(8)?;
295 let bytes = self.read_bytes(8)?;
296 let mut arr = [0u8; 8];
297 arr.copy_from_slice(bytes);
298 Ok(i64::from_le_bytes(arr))
299 }
300
301 pub fn decode_f32(&mut self) -> Result<f32> {
303 self.align(4)?;
304 let bytes = self.read_bytes(4)?;
305 let mut arr = [0u8; 4];
306 arr.copy_from_slice(bytes);
307 Ok(f32::from_le_bytes(arr))
308 }
309
310 pub fn decode_f64(&mut self) -> Result<f64> {
312 self.align(8)?;
313 let bytes = self.read_bytes(8)?;
314 let mut arr = [0u8; 8];
315 arr.copy_from_slice(bytes);
316 Ok(f64::from_le_bytes(arr))
317 }
318
319 pub fn decode_string_borrowed(&mut self) -> Result<&'a str> {
323 let len = self.decode_u32()? as usize;
325
326 if len == 0 {
327 return Err(Error::DecodingError);
328 }
329
330 let bytes = self.read_bytes(len - 1)?;
332
333 self.decode_u8()?;
335
336 core::str::from_utf8(bytes).map_err(|_| Error::DecodingError)
338 }
339
340 pub fn decode_bytes(&mut self, count: usize) -> Result<&'a [u8]> {
342 self.read_bytes(count)
343 }
344
345 pub fn decode_seq_len(&mut self) -> Result<usize> {
349 Ok(self.decode_u32()? as usize)
350 }
351
352 #[cfg(feature = "heapless")]
357 pub fn decode_string<const N: usize>(&mut self) -> Result<heapless::String<N>> {
358 let s = self.decode_string_borrowed()?;
359 heapless::String::try_from(s).map_err(|_| Error::BufferTooSmall)
360 }
361}
362
363#[cfg(test)]
364mod tests {
365 use super::*;
366
367 #[test]
368 fn test_encode_decode_u32() {
369 let mut buf = [0u8; 16];
370 let mut encoder = CdrEncoder::new(&mut buf);
371 encoder.encode_u32(0x1234_5678).unwrap();
372
373 let bytes = encoder.finish();
374 let mut decoder = CdrDecoder::new(bytes);
375 let value = decoder.decode_u32().unwrap();
376
377 assert_eq!(value, 0x1234_5678);
378 }
379
380 #[test]
381 fn test_encode_decode_string() {
382 let mut buf = [0u8; 64];
383 let mut encoder = CdrEncoder::new(&mut buf);
384 encoder.encode_string("hello").unwrap();
385
386 let bytes = encoder.finish();
387 let mut decoder = CdrDecoder::new(bytes);
388 let value = decoder.decode_string_borrowed().unwrap();
389
390 assert_eq!(value, "hello");
391 }
392
393 #[test]
394 fn test_alignment() {
395 let mut buf = [0u8; 64];
396 let mut encoder = CdrEncoder::new(&mut buf);
397
398 encoder.encode_u8(0x11).unwrap(); encoder.encode_u32(0x2222_2222).unwrap(); assert_eq!(encoder.position(), 8); }
403
404 #[test]
405 fn test_mixed_types() {
406 let mut buf = [0u8; 128];
407 let mut encoder = CdrEncoder::new(&mut buf);
408
409 encoder.encode_bool(true).unwrap();
410 encoder.encode_i16(-42).unwrap();
411 encoder.encode_f32(2.72).unwrap();
412 encoder.encode_string("test").unwrap();
413
414 let bytes = encoder.finish();
415 let mut decoder = CdrDecoder::new(bytes);
416
417 assert!(decoder.decode_bool().unwrap());
418 assert_eq!(decoder.decode_i16().unwrap(), -42);
419 assert!((decoder.decode_f32().unwrap() - 2.72).abs() < 0.01);
420 assert_eq!(decoder.decode_string_borrowed().unwrap(), "test");
421 }
422
423 #[test]
424 fn test_buffer_too_small() {
425 let mut buf = [0u8; 2];
426 let mut encoder = CdrEncoder::new(&mut buf);
427
428 let result = encoder.encode_u32(42);
429 assert_eq!(result, Err(Error::BufferTooSmall));
430 }
431}