draco_core/
decoder_buffer.rs1use crate::status::DracoError;
2use crate::version::DEFAULT_MESH_VERSION;
3use std::mem;
4
5pub struct DecoderBuffer<'a> {
23 data: &'a [u8],
24 pos: usize,
25 bit_decoder_active: bool,
26 bit_start_pos: usize,
27 current_bit_offset: usize,
28 bit_stream_end_pos: usize,
29 bit_sequence_size_known: bool,
30 version_major: u8,
31 version_minor: u8,
32}
33
34impl<'a> DecoderBuffer<'a> {
35 pub fn new(data: &'a [u8]) -> Self {
37 Self {
38 data,
39 pos: 0,
40 bit_decoder_active: false,
41 bit_start_pos: 0,
42 current_bit_offset: 0,
43 bit_stream_end_pos: 0,
44 bit_sequence_size_known: false,
45 version_major: DEFAULT_MESH_VERSION.0,
47 version_minor: DEFAULT_MESH_VERSION.1,
48 }
49 }
50
51 pub fn set_version(&mut self, major: u8, minor: u8) {
53 self.version_major = major;
54 self.version_minor = minor;
55 }
56
57 pub fn version_major(&self) -> u8 {
59 self.version_major
60 }
61
62 pub fn version_minor(&self) -> u8 {
64 self.version_minor
65 }
66
67 pub fn bitstream_version(&self) -> u16 {
69 crate::version::bitstream_version(self.version_major, self.version_minor)
70 }
71
72 pub fn position(&self) -> usize {
74 self.pos
75 }
76
77 pub fn set_position(&mut self, pos: usize) -> Result<(), DracoError> {
85 if self.bit_decoder_active {
86 return Err(DracoError::BufferError(
87 "Cannot set position while bit decoding is active".into(),
88 ));
89 }
90 if pos > self.data.len() {
91 return Err(DracoError::BufferError(format!(
92 "Position {} exceeds buffer length {}",
93 pos,
94 self.data.len()
95 )));
96 }
97 self.pos = pos;
98 Ok(())
99 }
100
101 pub fn remaining_size(&self) -> usize {
103 self.data.len().saturating_sub(self.pos)
104 }
105
106 pub fn peek_bytes(&self, len: usize) -> Vec<u8> {
108 let end = std::cmp::min(self.pos + len, self.data.len());
109 self.data[self.pos..end].to_vec()
110 }
111
112 pub fn start_bit_decoding(&mut self, decode_size: bool) -> Result<u64, DracoError> {
121 if self.bit_decoder_active {
122 return Err(DracoError::BufferError(
123 "Bit decoding already active".into(),
124 ));
125 }
126 let bitstream_version = self.bitstream_version();
127 let mut size_bytes: u64 = 0;
129 if decode_size {
130 if bitstream_version < 0x0202 {
131 if !cfg!(feature = "legacy_bitstream_decode") {
132 return Err(DracoError::BitstreamVersionUnsupported);
133 }
134 size_bytes = self.decode_u64()?;
135 } else {
136 size_bytes = self.decode_varint()?;
137 }
138 }
139
140 self.bit_start_pos = self.pos;
141 self.bit_decoder_active = true;
142 self.current_bit_offset = 0;
143 self.bit_sequence_size_known = decode_size;
144
145 if decode_size {
146 let size_bytes = usize::try_from(size_bytes)
147 .map_err(|_| DracoError::BufferError("Bit stream size too large".into()))?;
148 self.bit_stream_end_pos =
149 self.bit_start_pos.checked_add(size_bytes).ok_or_else(|| {
150 DracoError::BufferError("Bit stream end position overflow".into())
151 })?;
152 } else {
153 self.bit_stream_end_pos = self.data.len();
155 }
156
157 Ok(size_bytes)
158 }
159
160 pub fn end_bit_decoding(&mut self) {
162 self.bit_decoder_active = false;
163 if self.bit_sequence_size_known {
167 self.pos = self.bit_stream_end_pos;
168 } else {
169 let bytes_consumed = self.current_bit_offset.div_ceil(8);
170 self.pos = self.bit_start_pos + bytes_consumed;
171 }
172 }
173
174 #[inline(always)]
180 pub fn decode_least_significant_bits32(&mut self, nbits: u32) -> Result<u32, DracoError> {
181 if !self.bit_decoder_active {
182 return Err(DracoError::BufferError("Bit decoding not active".into()));
183 }
184 self.decode_least_significant_bits32_fast(nbits)
185 }
186
187 #[inline(always)]
189 pub fn decode_least_significant_bits32_fast(&mut self, nbits: u32) -> Result<u32, DracoError> {
190 if nbits == 0 {
191 return Ok(0);
192 }
193
194 let total_bit_offset = self.current_bit_offset;
195 let byte_offset = self.bit_start_pos + total_bit_offset / 8;
196 let bit_shift = (total_bit_offset % 8) as u32;
197
198 if byte_offset >= self.bit_stream_end_pos || byte_offset >= self.data.len() {
199 return Err(DracoError::BufferError(
200 "Unexpected end of bit stream".into(),
201 ));
202 }
203 let available_end = self.bit_stream_end_pos.min(self.data.len());
204 let remaining = available_end - byte_offset;
205
206 let raw = if remaining >= 8 {
208 let mut bytes = [0u8; 8];
209 bytes.copy_from_slice(&self.data[byte_offset..byte_offset + 8]);
210 u64::from_le_bytes(bytes)
211 } else {
212 let needed_bytes = (bit_shift + nbits).div_ceil(8) as usize;
213 if remaining < needed_bytes {
214 return Err(DracoError::BufferError(
215 "Unexpected end of bit stream".into(),
216 ));
217 }
218 let mut v = 0u64;
219 for i in 0..needed_bytes {
220 v |= (self.data[byte_offset + i] as u64) << (i * 8);
221 }
222 v
223 };
224 let value = ((raw >> bit_shift) as u32) & ((1u32 << nbits) - 1);
225
226 self.current_bit_offset += nbits as usize;
227 Ok(value)
228 }
229
230 #[inline]
231 #[allow(dead_code)]
232 fn get_bit(&mut self) -> Result<u32, DracoError> {
233 let total_bit_offset = self.current_bit_offset;
234 let byte_offset = self.bit_start_pos + total_bit_offset / 8;
235 let bit_shift = total_bit_offset % 8;
236
237 if byte_offset < self.bit_stream_end_pos && byte_offset < self.data.len() {
238 let bit = (self.data[byte_offset] >> bit_shift) & 1;
239 self.current_bit_offset += 1;
240 Ok(bit as u32)
241 } else {
242 Err(DracoError::BufferError(
243 "Unexpected end of bit stream".into(),
244 ))
245 }
246 }
247
248 pub fn decode<T: Copy + bytemuck::Pod>(&mut self) -> Result<T, DracoError> {
256 if self.bit_decoder_active {
257 return Err(DracoError::BufferError(
258 "Cannot decode bytes while bit decoding is active".into(),
259 ));
260 }
261 let size = mem::size_of::<T>();
262 if self.pos + size > self.data.len() {
263 return Err(DracoError::BufferError(format!(
264 "Unexpected end of buffer: need {} bytes, have {}",
265 size,
266 self.remaining_size()
267 )));
268 }
269
270 let val = bytemuck::pod_read_unaligned::<T>(&self.data[self.pos..self.pos + size]);
272 self.pos += size;
273 Ok(val)
274 }
275
276 pub fn decode_u8(&mut self) -> Result<u8, DracoError> {
278 self.decode::<u8>()
279 }
280
281 pub fn decode_u16(&mut self) -> Result<u16, DracoError> {
283 let mut bytes = [0u8; 2];
284 self.decode_bytes(&mut bytes)?;
285 Ok(u16::from_le_bytes(bytes))
286 }
287
288 pub fn decode_u32(&mut self) -> Result<u32, DracoError> {
290 let mut bytes = [0u8; 4];
291 self.decode_bytes(&mut bytes)?;
292 Ok(u32::from_le_bytes(bytes))
293 }
294
295 pub fn decode_u64(&mut self) -> Result<u64, DracoError> {
297 let mut bytes = [0u8; 8];
298 self.decode_bytes(&mut bytes)?;
299 Ok(u64::from_le_bytes(bytes))
300 }
301
302 pub fn decode_f32(&mut self) -> Result<f32, DracoError> {
304 let mut bytes = [0u8; 4];
305 self.decode_bytes(&mut bytes)?;
306 Ok(f32::from_le_bytes(bytes))
307 }
308
309 pub fn decode_f64(&mut self) -> Result<f64, DracoError> {
311 let mut bytes = [0u8; 8];
312 self.decode_bytes(&mut bytes)?;
313 Ok(f64::from_le_bytes(bytes))
314 }
315
316 pub fn decode_string(&mut self) -> Result<String, DracoError> {
318 let mut bytes = Vec::new();
319 loop {
320 let b = self.decode_u8()?;
321 if b == 0 {
322 break;
323 }
324 bytes.push(b);
325 }
326 String::from_utf8(bytes)
327 .map_err(|e| DracoError::BufferError(format!("Invalid UTF-8 string: {}", e)))
328 }
329
330 pub fn decode_bytes(&mut self, out: &mut [u8]) -> Result<(), DracoError> {
336 let size = out.len();
337 if self.pos + size > self.data.len() {
338 return Err(DracoError::BufferError(format!(
339 "Unexpected end of buffer: need {} bytes, have {}",
340 size,
341 self.remaining_size()
342 )));
343 }
344 out.copy_from_slice(&self.data[self.pos..self.pos + size]);
345 self.pos += size;
346 Ok(())
347 }
348
349 pub fn decode_varint(&mut self) -> Result<u64, DracoError> {
351 let mut val = 0u64;
352 let mut shift = 0;
353 loop {
354 let b = self.decode_u8()?;
355 val |= ((b & 0x7F) as u64) << shift;
356 if (b & 0x80) == 0 {
357 break;
358 }
359 shift += 7;
360 if shift >= 64 {
361 return Err(DracoError::BufferError("Varint exceeds 64 bits".into()));
362 }
363 }
364 Ok(val)
365 }
366
367 pub fn decode_varint_signed_i32(&mut self) -> Result<i32, DracoError> {
371 let symbol = self.decode_varint()? as u32;
372 let is_positive = (symbol & 1) == 0;
373 let v = symbol >> 1;
374 if is_positive {
375 Ok(v as i32)
376 } else {
377 Ok(-(v as i32) - 1)
378 }
379 }
380
381 pub fn remaining_data(&self) -> &'a [u8] {
383 &self.data[self.pos..]
384 }
385
386 pub fn advance(&mut self, n: usize) {
388 self.pos = self.pos.saturating_add(n).min(self.data.len());
389 }
390
391 pub fn try_advance(&mut self, n: usize) -> Result<(), DracoError> {
398 let new_pos = self
399 .pos
400 .checked_add(n)
401 .ok_or_else(|| DracoError::BufferError("Buffer advance overflow".into()))?;
402 if new_pos > self.data.len() {
403 return Err(DracoError::BufferError(format!(
404 "Cannot advance buffer by {} bytes: need position {}, buffer length {}",
405 n,
406 new_pos,
407 self.data.len()
408 )));
409 }
410 self.pos = new_pos;
411 Ok(())
412 }
413
414 pub fn decode_slice(&mut self, size: usize) -> Result<&'a [u8], DracoError> {
420 if self.pos + size > self.data.len() {
421 return Err(DracoError::BufferError(format!(
422 "Unexpected end of buffer: need {} bytes, have {}",
423 size,
424 self.remaining_size()
425 )));
426 }
427 let slice = &self.data[self.pos..self.pos + size];
428 self.pos += size;
429 Ok(slice)
430 }
431}
432
433#[cfg(test)]
434mod tests {
435 use super::DecoderBuffer;
436
437 #[test]
438 fn bit_decode_respects_declared_byte_size() {
439 let data = [1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff];
440 let mut buffer = DecoderBuffer::new(&data);
441
442 assert_eq!(buffer.start_bit_decoding(true).unwrap(), 1);
443 assert!(buffer.decode_least_significant_bits32(16).is_err());
444 }
445
446 #[test]
447 fn try_advance_rejects_out_of_bounds_skip() {
448 let data = [0u8; 4];
449 let mut buffer = DecoderBuffer::new(&data);
450
451 assert!(buffer.try_advance(5).is_err());
452 assert_eq!(buffer.position(), 0);
453 assert!(buffer.try_advance(4).is_ok());
454 assert_eq!(buffer.position(), 4);
455 }
456}