meshopt_rs/index/
mod.rs

1pub mod buffer;
2pub mod generator;
3#[cfg(feature = "experimental")]
4pub mod sequence;
5
6use crate::util::{read_byte, write_byte};
7
8use std::io::{Read, Write};
9
10#[derive(Debug)]
11pub enum DecodeError {
12    InvalidHeader,
13    UnsupportedVersion,
14    ExtraBytes,
15    UnexpectedEof,
16}
17
18pub enum IndexEncodingVersion {
19    /// Decodable by all versions
20    V0,
21    /// Decodable by 0.14+
22    #[cfg(feature = "experimental")]
23    V1,
24}
25
26impl Default for IndexEncodingVersion {
27    fn default() -> Self {
28        #[cfg(not(feature = "experimental"))]
29        {
30            Self::V0
31        }
32        #[cfg(feature = "experimental")]
33        {
34            Self::V1
35        }
36    }
37}
38
39impl Into<u8> for IndexEncodingVersion {
40    fn into(self) -> u8 {
41        match self {
42            Self::V0 => 0,
43            #[cfg(feature = "experimental")]
44            Self::V1 => 1,
45        }
46    }
47}
48
49fn encode_v_byte<W: Write>(data: &mut W, mut v: u32) {
50    // encode 32-bit value in up to 5 7-bit groups
51    loop {
52        write_byte(data, ((v & 127) | (if v > 127 { 128 } else { 0 })) as u8);
53        v >>= 7;
54
55        if v == 0 {
56            break;
57        }
58    }
59}
60
61fn decode_v_byte<R: Read>(data: &mut R) -> u32 {
62    let lead = read_byte(data) as u32;
63
64    // fast path: single byte
65    if lead < 128 {
66        return lead;
67    }
68
69    // slow path: up to 4 extra bytes
70    // note that this loop always terminates, which is important for malformed data
71    let mut result = lead & 127;
72    let mut shift = 7;
73
74    for _ in 0..4 {
75        let group = read_byte(data) as u32;
76        result |= (group & 127) << shift;
77        shift += 7;
78
79        if group < 128 {
80            break;
81        }
82    }
83
84    result
85}