Coverage Report

Created: 2025-11-11 06:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/spdm-rs/codec/src/codec.rs
Line
Count
Source
1
// Taken from rustls <https://github.com/rustls/rustls>
2
//
3
// Copyright (c) 2016 Joe Birr-Pixton and rustls project contributors
4
// Copyright (c) 2020 Intel Corporation
5
//
6
// SPDX-License-Identifier: Apache-2.0 or MIT
7
8
#[cfg(feature = "alloc")]
9
extern crate alloc;
10
11
use core::{fmt::Debug, mem};
12
13
/// Read from a byte slice.
14
pub struct Reader<'a> {
15
    buf: &'a [u8],
16
    offs: usize,
17
}
18
19
impl Reader<'_> {
20
0
    pub fn init(bytes: &[u8]) -> Reader {
21
0
        Reader {
22
0
            buf: bytes,
23
0
            offs: 0,
24
0
        }
25
0
    }
26
27
0
    pub fn rest(&mut self) -> &[u8] {
28
0
        let ret = &self.buf[self.offs..];
29
0
        self.offs = self.buf.len();
30
0
        ret
31
0
    }
32
33
0
    pub fn take(&mut self, len: usize) -> Option<&[u8]> {
34
0
        if self.left() < len {
35
0
            return None;
36
0
        }
37
38
0
        let current = self.offs;
39
0
        self.offs += len;
40
0
        Some(&self.buf[current..current + len])
41
0
    }
42
43
0
    pub fn any_left(&self) -> bool {
44
0
        self.offs < self.buf.len()
45
0
    }
46
47
0
    pub fn left(&self) -> usize {
48
0
        self.buf.len() - self.offs
49
0
    }
50
51
0
    pub fn used(&self) -> usize {
52
0
        self.offs
53
0
    }
54
55
0
    pub fn sub(&mut self, len: usize) -> Option<Reader> {
56
0
        self.take(len).map(Reader::init)
57
0
    }
58
}
59
60
impl AsRef<[u8]> for Reader<'_> {
61
0
    fn as_ref(&self) -> &[u8] {
62
0
        &self.buf[self.offs..]
63
0
    }
64
}
65
66
/// Write to a byte slice.
67
pub struct Writer<'a> {
68
    buf: &'a mut [u8],
69
    offs: usize,
70
}
71
72
impl Writer<'_> {
73
0
    pub fn init(bytes: &mut [u8]) -> Writer {
74
0
        Writer {
75
0
            buf: bytes,
76
0
            offs: 0,
77
0
        }
78
0
    }
79
80
0
    pub fn clear(&mut self) {
81
0
        self.offs = 0;
82
0
    }
83
84
0
    pub fn extend_from_slice(&mut self, value: &[u8]) -> Option<usize> {
85
0
        if self.left() < value.len() {
86
0
            return None;
87
0
        }
88
0
        let added = value.len();
89
0
        for (i, v) in value.iter().enumerate().take(added) {
90
0
            self.buf[self.offs + i] = *v;
91
0
        }
92
0
        self.offs += added;
93
0
        Some(added)
94
0
    }
95
96
0
    pub fn push(&mut self, value: u8) -> Option<u8> {
97
0
        if self.left() < 1 {
98
0
            return None;
99
0
        }
100
0
        self.buf[self.offs] = value;
101
0
        self.offs += 1;
102
0
        Some(value)
103
0
    }
104
105
0
    pub fn left(&self) -> usize {
106
0
        self.buf.len() - self.offs
107
0
    }
108
109
0
    pub fn left_slice(&self) -> &[u8] {
110
0
        &self.buf[self.offs..]
111
0
    }
112
113
0
    pub fn mut_left_slice(&mut self) -> &mut [u8] {
114
0
        &mut self.buf[self.offs..]
115
0
    }
116
117
0
    pub fn used(&self) -> usize {
118
0
        self.offs
119
0
    }
120
121
0
    pub fn used_slice(&self) -> &[u8] {
122
0
        &self.buf[..self.offs]
123
0
    }
124
125
0
    pub fn mut_used_slice(&mut self) -> &mut [u8] {
126
0
        &mut self.buf[..self.offs]
127
0
    }
128
}
129
130
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
131
pub struct EncodeErr;
132
133
/// Things we can encode and read from a Reader.
134
pub trait Codec: Debug + Sized {
135
    /// Encode yourself by appending onto `bytes`.
136
    /// Return Ok(encoded size) or Err(())
137
    fn encode(&self, bytes: &mut Writer) -> Result<usize, EncodeErr>;
138
139
    /// Decode yourself by fiddling with the `Reader`.
140
    /// Return Some if it worked, None if not.
141
    fn read(_: &mut Reader) -> Option<Self>;
142
143
    /// Read one of these from the front of `bytes` and
144
    /// return it.
145
0
    fn read_bytes(bytes: &[u8]) -> Option<Self> {
146
0
        let mut rd = Reader::init(bytes);
147
0
        Self::read(&mut rd)
148
0
    }
Unexecuted instantiation: <spdmlib::error::SpdmStatus as codec::codec::Codec>::read_bytes
Unexecuted instantiation: <spdmlib::message::version::SpdmVersionStruct as codec::codec::Codec>::read_bytes
Unexecuted instantiation: <_ as codec::codec::Codec>::read_bytes
149
150
    #[cfg(feature = "alloc")]
151
    /// Read count T's and returns Vec<T>
152
    /// count: the number of T wants to read.
153
0
    fn read_vec<T: Codec>(reader: &mut Reader, count: usize) -> Option<alloc::vec::Vec<T>> {
154
0
        let mut data = alloc::vec::Vec::new();
155
0
        for _ in 0..count {
156
0
            let t = T::read(reader)?;
157
0
            data.push(t)
158
        }
159
0
        Some(data)
160
0
    }
161
}
162
163
#[cfg(feature = "alloc")]
164
impl<T: Codec + Copy> Codec for alloc::vec::Vec<T> {
165
0
    fn encode(&self, bytes: &mut Writer) -> Result<usize, EncodeErr> {
166
0
        let used = bytes.used();
167
0
        for t in self.iter() {
168
0
            let _ = t.encode(bytes)?;
169
        }
170
0
        Ok(bytes.used() - used)
171
0
    }
172
173
0
    fn read(_reader: &mut Reader) -> Option<Self> {
174
        // Not support can't known the length
175
0
        panic!("Should not call this API for reading vec. Use read_vec instead.")
176
    }
177
}
178
179
// Encoding functions.
180
impl<T: Codec> Codec for Option<T> {
181
0
    fn encode(&self, writer: &mut Writer) -> Result<usize, EncodeErr> {
182
0
        match self {
183
0
            Some(val) => {
184
0
                let mut size = 0;
185
0
                size += 1u8.encode(writer)?; // 1 means present
186
0
                size += val.encode(writer)?;
187
0
                Ok(size)
188
            }
189
            None => {
190
0
                0u8.encode(writer) // 0 means absent
191
            }
192
        }
193
0
    }
194
195
0
    fn read(reader: &mut Reader) -> Option<Self> {
196
0
        let present = u8::read(reader)?;
197
0
        if present != 0 {
198
0
            Some(T::read(reader))
199
        } else {
200
0
            Some(None)
201
        }
202
0
    }
203
}
204
205
0
pub fn decode_u8(bytes: &[u8]) -> Option<u8> {
206
0
    Some(bytes[0])
207
0
}
208
209
impl Codec for u8 {
210
0
    fn encode(&self, bytes: &mut Writer) -> Result<usize, EncodeErr> {
211
0
        bytes.push(*self).ok_or(EncodeErr)?;
212
0
        Ok(1)
213
0
    }
214
0
    fn read(r: &mut Reader) -> Option<u8> {
215
0
        r.take(1).and_then(decode_u8)
216
0
    }
217
}
218
219
0
pub fn put_u16(v: u16, out: &mut [u8]) {
220
0
    out[0] = v as u8;
221
0
    out[1] = (v >> 8) as u8;
222
0
}
223
224
0
pub fn decode_u16(bytes: &[u8]) -> Option<u16> {
225
0
    Some(u16::from(bytes[0]) | (u16::from(bytes[1]) << 8))
226
0
}
227
228
impl Codec for u16 {
229
0
    fn encode(&self, bytes: &mut Writer) -> Result<usize, EncodeErr> {
230
0
        let mut b16 = [0u8; 2];
231
0
        put_u16(*self, &mut b16);
232
0
        bytes.extend_from_slice(&b16).ok_or(EncodeErr)?;
233
0
        Ok(2)
234
0
    }
235
236
0
    fn read(r: &mut Reader) -> Option<u16> {
237
0
        r.take(2).and_then(decode_u16)
238
0
    }
239
}
240
241
// Make a distinct type for u24, even though it's a u32 underneath
242
#[allow(non_camel_case_types)]
243
#[derive(Debug, Copy, Clone, Default)]
244
pub struct u24(u32);
245
246
impl u24 {
247
0
    pub fn new(v: u32) -> u24 {
248
0
        assert_eq!(v >> 24, 0);
249
0
        u24(v)
250
0
    }
251
252
0
    pub fn get(&self) -> u32 {
253
0
        self.0
254
0
    }
255
256
0
    fn decode(bytes: &[u8]) -> Option<u24> {
257
0
        Some(u24(u32::from(bytes[0])
258
0
            | (u32::from(bytes[1]) << 8)
259
0
            | (u32::from(bytes[2]) << 16)))
260
0
    }
261
}
262
263
impl Codec for u24 {
264
0
    fn encode(&self, bytes: &mut Writer) -> Result<usize, EncodeErr> {
265
0
        bytes.push(self.0 as u8).ok_or(EncodeErr)?;
266
0
        bytes.push((self.0 >> 8) as u8).ok_or(EncodeErr)?;
267
0
        bytes.push((self.0 >> 16) as u8).ok_or(EncodeErr)?;
268
0
        Ok(3)
269
0
    }
270
271
0
    fn read(r: &mut Reader) -> Option<u24> {
272
0
        r.take(3).and_then(u24::decode)
273
0
    }
274
}
275
276
0
pub fn decode_u32(bytes: &[u8]) -> Option<u32> {
277
0
    Some(
278
0
        u32::from(bytes[0])
279
0
            | (u32::from(bytes[1]) << 8)
280
0
            | (u32::from(bytes[2]) << 16)
281
0
            | (u32::from(bytes[3]) << 24),
282
0
    )
283
0
}
284
285
impl Codec for u32 {
286
0
    fn encode(&self, bytes: &mut Writer) -> Result<usize, EncodeErr> {
287
0
        bytes.push(*self as u8).ok_or(EncodeErr)?;
288
0
        bytes.push((*self >> 8) as u8).ok_or(EncodeErr)?;
289
0
        bytes.push((*self >> 16) as u8).ok_or(EncodeErr)?;
290
0
        bytes.push((*self >> 24) as u8).ok_or(EncodeErr)?;
291
0
        Ok(4)
292
0
    }
293
294
0
    fn read(r: &mut Reader) -> Option<u32> {
295
0
        r.take(4).and_then(decode_u32)
296
0
    }
297
}
298
299
0
pub fn put_u64(v: u64, bytes: &mut [u8]) {
300
0
    bytes[0] = v as u8;
301
0
    bytes[1] = (v >> 8) as u8;
302
0
    bytes[2] = (v >> 16) as u8;
303
0
    bytes[3] = (v >> 24) as u8;
304
0
    bytes[4] = (v >> 32) as u8;
305
0
    bytes[5] = (v >> 40) as u8;
306
0
    bytes[6] = (v >> 48) as u8;
307
0
    bytes[7] = (v >> 56) as u8;
308
0
}
309
310
0
pub fn decode_u64(bytes: &[u8]) -> Option<u64> {
311
0
    Some(
312
0
        u64::from(bytes[0])
313
0
            | (u64::from(bytes[1]) << 8)
314
0
            | (u64::from(bytes[2]) << 16)
315
0
            | (u64::from(bytes[3]) << 24)
316
0
            | (u64::from(bytes[4]) << 32)
317
0
            | (u64::from(bytes[5]) << 40)
318
0
            | (u64::from(bytes[6]) << 48)
319
0
            | (u64::from(bytes[7]) << 56),
320
0
    )
321
0
}
322
323
impl Codec for u64 {
324
0
    fn encode(&self, bytes: &mut Writer) -> Result<usize, EncodeErr> {
325
0
        let mut b64 = [0u8; 8];
326
0
        put_u64(*self, &mut b64);
327
0
        bytes.extend_from_slice(&b64).ok_or(EncodeErr)?;
328
0
        Ok(8)
329
0
    }
330
331
0
    fn read(r: &mut Reader) -> Option<u64> {
332
0
        r.take(8).and_then(decode_u64)
333
0
    }
334
}
335
336
impl Codec for u128 {
337
0
    fn encode(&self, bytes: &mut Writer) -> Result<usize, EncodeErr> {
338
0
        bytes
339
0
            .extend_from_slice(&u128::to_le_bytes(*self))
340
0
            .ok_or(EncodeErr)?;
341
0
        Ok(16)
342
0
    }
343
344
0
    fn read(r: &mut Reader) -> Option<Self> {
345
0
        let mut v = [0u8; mem::size_of::<u128>()];
346
0
        v.copy_from_slice(r.take(mem::size_of::<u128>())?);
347
348
0
        Some(u128::from_le_bytes(v))
349
0
    }
350
}
351
352
impl<T: Codec + Copy + Default, const N: usize> Codec for [T; N] {
353
0
    fn encode(&self, bytes: &mut Writer) -> Result<usize, EncodeErr> {
354
0
        let used = bytes.used();
355
0
        for d in self.iter() {
356
0
            let _ = d.encode(bytes)?;
357
        }
358
0
        Ok(bytes.used() - used)
359
0
    }
360
361
0
    fn read(reader: &mut Reader) -> Option<Self> {
362
0
        let mut target = [T::default(); N];
363
0
        for t in target.iter_mut() {
364
0
            *t = T::read(reader)?;
365
        }
366
367
0
        Some(target)
368
0
    }
369
}
370
371
#[cfg(test)]
372
mod tests {
373
    use crate::codec::Codec;
374
    use crate::codec::{Reader, Writer};
375
    use crate::u24;
376
377
    #[test]
378
    fn test_u128() {
379
        let u8_slice = &mut [0u8; 16];
380
        {
381
            let mut writer = Writer::init(u8_slice);
382
            let value = 0x1234567890FFFEFEFFFFFE1234567890u128;
383
            assert_eq!(value.encode(&mut writer), Ok(16));
384
        }
385
        let mut ser_data = [
386
            0x12u8, 0x34, 0x56, 0x78, 0x90, 0xFF, 0xFE, 0xFE, 0xFF, 0xFF, 0xFE, 0x12, 0x34, 0x56,
387
            0x78, 0x90,
388
        ];
389
        ser_data.reverse();
390
391
        let mut reader = Reader::init(u8_slice);
392
        assert_eq!(16, reader.left());
393
        assert_eq!(u8_slice, &ser_data);
394
        assert_eq!(
395
            u128::read(&mut reader).unwrap(),
396
            0x1234567890FFFEFEFFFFFE1234567890u128
397
        );
398
    }
399
400
    #[test]
401
    fn test_u64() {
402
        let u8_slice = &mut [0u8; 8];
403
        u8_slice[1] = 1;
404
        {
405
            let mut writer = Writer::init(u8_slice);
406
            let value = 100u64;
407
            assert_eq!(value.encode(&mut writer), Ok(8));
408
        }
409
410
        let mut reader = Reader::init(u8_slice);
411
        assert_eq!(8, reader.left());
412
        assert_eq!(u64::read(&mut reader).unwrap(), 100);
413
    }
414
    #[test]
415
    fn test_u32() {
416
        let u8_slice = &mut [0u8; 4];
417
        let mut witer = Writer::init(u8_slice);
418
        let value = 100u32;
419
        assert_eq!(value.encode(&mut witer), Ok(4));
420
421
        let mut reader = Reader::init(u8_slice);
422
        assert_eq!(4, reader.left());
423
        assert_eq!(u32::read(&mut reader).unwrap(), 100);
424
    }
425
    #[test]
426
    fn test_u16() {
427
        let u8_slice = &mut [0u8; 2];
428
        let mut witer = Writer::init(u8_slice);
429
        let value = 10u16;
430
        assert_eq!(value.encode(&mut witer), Ok(2));
431
432
        let mut reader = Reader::init(u8_slice);
433
        assert_eq!(2, reader.left());
434
        assert_eq!(u16::read(&mut reader).unwrap(), 10);
435
    }
436
    #[test]
437
    fn test_u24() {
438
        let u8_slice = &mut [0u8; 3];
439
        let mut witer = Writer::init(u8_slice);
440
        let value = u24::new(100);
441
        assert_eq!(value.encode(&mut witer), Ok(3));
442
        let mut reader = Reader::init(u8_slice);
443
        assert_eq!(3, reader.left());
444
        assert_eq!(u24::read(&mut reader).unwrap().0, u24::new(100).0);
445
    }
446
    #[test]
447
    #[should_panic]
448
    fn test_u24_max_size() {
449
        let _ = u24::new(1 << 24);
450
    }
451
    #[test]
452
    fn test_u8() {
453
        let u8_slice = &mut [0u8; 4];
454
        let mut witer = Writer::init(u8_slice);
455
        let value = 100u8;
456
        assert_eq!(value.encode(&mut witer), Ok(1));
457
        let mut reader = Reader::init(u8_slice);
458
        assert_eq!(4, reader.left());
459
        assert_eq!(u8::read(&mut reader).unwrap(), 100);
460
    }
461
    #[test]
462
    fn test_case0_rest() {
463
        let u8_slice = &mut [0u8; 4];
464
        let mut witer = Writer::init(u8_slice);
465
        let value = 0xAA5555AAu32;
466
        assert_eq!(value.encode(&mut witer), Ok(4));
467
        let mut reader = Reader::init(u8_slice);
468
        let rust_ret = reader.rest();
469
        assert_eq!(rust_ret[0], 0xAA);
470
        assert_eq!(rust_ret[1], 0x55);
471
        assert_eq!(rust_ret[2], 0x55);
472
        assert_eq!(rust_ret[3], 0xAA);
473
    }
474
    #[test]
475
    fn test_case0_any_left() {
476
        let u8_slice = &mut [0u8; 4];
477
        let reader = Reader {
478
            buf: u8_slice,
479
            offs: 0,
480
        };
481
        assert_eq!(reader.any_left(), true);
482
    }
483
    #[test]
484
    fn test_case1_any_left() {
485
        let u8_slice = &mut [0u8; 4];
486
        let reader = Reader {
487
            buf: u8_slice,
488
            offs: 4,
489
        };
490
        assert_eq!(reader.any_left(), false);
491
    }
492
    #[test]
493
    fn test_case0_read_bytes() {
494
        let u8_slice = &mut [0u8; 4];
495
        let mut witer = Writer::init(u8_slice);
496
        let value = 0xAA5555AAu32;
497
        assert_eq!(value.encode(&mut witer), Ok(4));
498
        assert_eq!(u32::read_bytes(u8_slice).unwrap(), 0xAA5555AAu32);
499
    }
500
    #[test]
501
    fn test_case0_sub() {
502
        let u8_slice = &mut [100u8; 4];
503
        let mut reader = Reader {
504
            buf: u8_slice,
505
            offs: 4,
506
        };
507
        assert_eq!(reader.sub(4).is_none(), true);
508
    }
509
510
    #[test]
511
    fn test_case0_array() {
512
        let u8_slice = &mut [0x0u8; 2];
513
        let value = [0x5au8; 2];
514
        let writer = &mut Writer::init(u8_slice);
515
        value.encode(writer).unwrap();
516
        let reader = &mut Reader::init(u8_slice);
517
        assert_eq!(value, <[u8; 2]>::read(reader).unwrap());
518
    }
519
}