1use 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 spent: usize,
40 limits: crate::decode_limits::DecodeLimits,
48 decoded_bytes: u64,
49}
50
51impl<'a> DecoderBuffer<'a> {
52 pub fn new(data: &'a [u8]) -> Self {
54 Self {
55 data,
56 pos: 0,
57 bit_decoder_active: false,
58 bit_start_pos: 0,
59 current_bit_offset: 0,
60 bit_stream_end_pos: 0,
61 bit_sequence_size_known: false,
62 version_major: DEFAULT_MESH_VERSION.0,
64 version_minor: DEFAULT_MESH_VERSION.1,
65 spent: 0,
66 limits: crate::decode_limits::DecodeLimits::default(),
67 decoded_bytes: 0,
68 }
69 }
70
71 #[must_use]
82 pub fn with_limits(mut self, limits: crate::decode_limits::DecodeLimits) -> Self {
83 self.limits = limits;
84 self
85 }
86
87 #[cfg(feature = "point_cloud_decode")]
89 pub(crate) fn check_points(&self, points: usize) -> crate::status::Status {
90 self.limits.check_points(points as u64)
91 }
92
93 pub(crate) fn check_faces(&self, faces: usize) -> crate::status::Status {
95 self.limits.check_faces(faces as u64)
96 }
97
98 pub(crate) fn charge_decoded_bytes(&mut self, bytes: usize) -> crate::status::Status {
106 let total = self.decoded_bytes.saturating_add(bytes as u64);
107 self.limits.check_decoded_bytes(total)?;
108 self.decoded_bytes = total;
109 Ok(())
110 }
111
112 pub(crate) fn charge(&mut self, bytes: usize) -> crate::status::Status {
138 let total = self.spent.saturating_add(bytes);
139 crate::decode_budget::ensure_allocation_is_backed(total, self.data.len())?;
140 self.spent = total;
141 Ok(())
142 }
143
144 pub(crate) fn charge_elements(
146 &mut self,
147 count: usize,
148 element_size: usize,
149 ) -> crate::status::Status {
150 self.charge(count.saturating_mul(element_size))
151 }
152
153 #[cfg(test)]
156 pub(crate) fn spent(&self) -> usize {
157 self.spent
158 }
159
160 pub fn set_version(&mut self, major: u8, minor: u8) {
162 self.version_major = major;
163 self.version_minor = minor;
164 }
165
166 pub fn version_major(&self) -> u8 {
168 self.version_major
169 }
170
171 pub fn version_minor(&self) -> u8 {
173 self.version_minor
174 }
175
176 pub fn bitstream_version(&self) -> u16 {
178 crate::version::bitstream_version(self.version_major, self.version_minor)
179 }
180
181 pub fn position(&self) -> usize {
183 self.pos
184 }
185
186 pub fn set_position(&mut self, pos: usize) -> Result<(), DracoError> {
194 if self.bit_decoder_active {
195 return Err(DracoError::buffer(
196 "Cannot set position while bit decoding is active",
197 ));
198 }
199 if pos > self.data.len() {
200 return Err(DracoError::buffer(format!(
201 "Position {} exceeds buffer length {}",
202 pos,
203 self.data.len()
204 )));
205 }
206 self.pos = pos;
207 Ok(())
208 }
209
210 pub fn remaining_size(&self) -> usize {
212 self.data.len().saturating_sub(self.pos)
213 }
214
215 pub fn size(&self) -> usize {
223 self.data.len()
224 }
225
226 pub fn peek_bytes(&self, len: usize) -> Vec<u8> {
228 let start = self.pos.min(self.data.len());
229 let end = start.saturating_add(len).min(self.data.len());
230 self.data[start..end].to_vec()
231 }
232
233 pub fn start_bit_decoding(&mut self, decode_size: bool) -> Result<u64, DracoError> {
242 if self.bit_decoder_active {
243 return Err(DracoError::buffer("Bit decoding already active"));
244 }
245 let bitstream_version = self.bitstream_version();
246 let mut size_bytes: u64 = 0;
248 if decode_size {
249 if bitstream_version < 0x0202 {
250 if !cfg!(feature = "legacy_bitstream_decode") {
251 return Err(DracoError::bitstream_version_unsupported());
252 }
253 size_bytes = self.decode_u64()?;
254 } else {
255 size_bytes = self.decode_varint()?;
256 }
257 }
258
259 self.bit_start_pos = self.pos;
260 self.bit_decoder_active = true;
261 self.current_bit_offset = 0;
262 self.bit_sequence_size_known = decode_size;
263
264 if decode_size {
265 let size_bytes = usize::try_from(size_bytes)
266 .map_err(|_| DracoError::buffer("Bit stream size too large"))?;
267 let declared_end = self
275 .bit_start_pos
276 .checked_add(size_bytes)
277 .ok_or_else(|| DracoError::buffer("Bit stream end position overflow"))?;
278 self.bit_stream_end_pos = declared_end.min(self.data.len());
279 } else {
280 self.bit_stream_end_pos = self.data.len();
282 }
283
284 Ok(size_bytes)
285 }
286
287 pub fn end_bit_decoding(&mut self) {
289 self.bit_decoder_active = false;
290 if self.bit_sequence_size_known {
294 self.pos = self.bit_stream_end_pos;
295 } else {
296 let bytes_consumed = self.current_bit_offset.div_ceil(8);
297 self.pos = self.bit_start_pos + bytes_consumed;
298 }
299 }
300
301 #[inline(always)]
307 pub fn decode_least_significant_bits32(&mut self, nbits: u32) -> Result<u32, DracoError> {
308 if !self.bit_decoder_active {
309 return Err(DracoError::buffer("Bit decoding not active"));
310 }
311 self.decode_least_significant_bits32_fast(nbits)
312 }
313
314 #[inline(always)]
316 pub fn decode_least_significant_bits32_fast(&mut self, nbits: u32) -> Result<u32, DracoError> {
317 if nbits == 0 {
318 return Ok(0);
319 }
320 if nbits > 32 {
326 return Err(DracoError::buffer("Bit width exceeds 32 bits"));
327 }
328
329 let total_bit_offset = self.current_bit_offset;
330 let byte_offset = self.bit_start_pos + total_bit_offset / 8;
331 let bit_shift = (total_bit_offset % 8) as u32;
332
333 if byte_offset >= self.bit_stream_end_pos || byte_offset >= self.data.len() {
334 return Err(DracoError::buffer("Unexpected end of bit stream"));
335 }
336 let available_end = self.bit_stream_end_pos.min(self.data.len());
337 let remaining = available_end - byte_offset;
338
339 let raw = if remaining >= 8 {
341 let mut bytes = [0u8; 8];
342 bytes.copy_from_slice(&self.data[byte_offset..byte_offset + 8]);
343 u64::from_le_bytes(bytes)
344 } else {
345 let needed_bytes = (bit_shift + nbits).div_ceil(8) as usize;
346 if remaining < needed_bytes {
347 return Err(DracoError::buffer("Unexpected end of bit stream"));
348 }
349 let mut v = 0u64;
350 for i in 0..needed_bytes {
351 v |= (self.data[byte_offset + i] as u64) << (i * 8);
352 }
353 v
354 };
355 let mask = (1u64 << nbits) - 1;
358 let value = ((raw >> bit_shift) & mask) as u32;
359
360 self.current_bit_offset += nbits as usize;
361 Ok(value)
362 }
363
364 #[inline]
365 #[allow(dead_code)]
366 fn get_bit(&mut self) -> Result<u32, DracoError> {
367 let total_bit_offset = self.current_bit_offset;
368 let byte_offset = self.bit_start_pos + total_bit_offset / 8;
369 let bit_shift = total_bit_offset % 8;
370
371 if byte_offset < self.bit_stream_end_pos && byte_offset < self.data.len() {
372 let bit = (self.data[byte_offset] >> bit_shift) & 1;
373 self.current_bit_offset += 1;
374 Ok(bit as u32)
375 } else {
376 Err(DracoError::buffer("Unexpected end of bit stream"))
377 }
378 }
379
380 pub fn decode<T: Copy + bytemuck::Pod>(&mut self) -> Result<T, DracoError> {
388 if self.bit_decoder_active {
389 return Err(DracoError::buffer(
390 "Cannot decode bytes while bit decoding is active",
391 ));
392 }
393 let size = mem::size_of::<T>();
394 if size > self.data.len().saturating_sub(self.pos) {
395 return Err(DracoError::buffer(format!(
396 "Unexpected end of buffer: need {} bytes, have {}",
397 size,
398 self.remaining_size()
399 )));
400 }
401
402 let val = bytemuck::pod_read_unaligned::<T>(&self.data[self.pos..self.pos + size]);
404 self.pos += size;
405 Ok(val)
406 }
407
408 pub fn decode_u8(&mut self) -> Result<u8, DracoError> {
410 self.decode::<u8>()
411 }
412
413 pub fn decode_u16(&mut self) -> Result<u16, DracoError> {
415 let mut bytes = [0u8; 2];
416 self.decode_bytes(&mut bytes)?;
417 Ok(u16::from_le_bytes(bytes))
418 }
419
420 pub fn decode_u32(&mut self) -> Result<u32, DracoError> {
422 let mut bytes = [0u8; 4];
423 self.decode_bytes(&mut bytes)?;
424 Ok(u32::from_le_bytes(bytes))
425 }
426
427 pub fn decode_u64(&mut self) -> Result<u64, DracoError> {
429 let mut bytes = [0u8; 8];
430 self.decode_bytes(&mut bytes)?;
431 Ok(u64::from_le_bytes(bytes))
432 }
433
434 pub fn decode_f32(&mut self) -> Result<f32, DracoError> {
436 let mut bytes = [0u8; 4];
437 self.decode_bytes(&mut bytes)?;
438 Ok(f32::from_le_bytes(bytes))
439 }
440
441 pub fn decode_f64(&mut self) -> Result<f64, DracoError> {
443 let mut bytes = [0u8; 8];
444 self.decode_bytes(&mut bytes)?;
445 Ok(f64::from_le_bytes(bytes))
446 }
447
448 pub fn decode_string(&mut self) -> Result<String, DracoError> {
450 let mut bytes = Vec::new();
451 loop {
452 let b = self.decode_u8()?;
453 if b == 0 {
454 break;
455 }
456 bytes.push(b);
457 }
458 String::from_utf8(bytes)
459 .map_err(|e| DracoError::buffer(format!("Invalid UTF-8 string: {}", e)))
460 }
461
462 pub fn decode_bytes(&mut self, out: &mut [u8]) -> Result<(), DracoError> {
468 let size = out.len();
469 if size > self.data.len().saturating_sub(self.pos) {
470 return Err(DracoError::buffer(format!(
471 "Unexpected end of buffer: need {} bytes, have {}",
472 size,
473 self.remaining_size()
474 )));
475 }
476 out.copy_from_slice(&self.data[self.pos..self.pos + size]);
477 self.pos += size;
478 Ok(())
479 }
480
481 pub fn decode_varint(&mut self) -> Result<u64, DracoError> {
483 let mut val = 0u64;
484 let mut shift = 0;
485 loop {
486 let b = self.decode_u8()?;
487 val |= ((b & 0x7F) as u64) << shift;
488 if (b & 0x80) == 0 {
489 break;
490 }
491 shift += 7;
492 if shift >= 64 {
493 return Err(DracoError::buffer("Varint exceeds 64 bits"));
494 }
495 }
496 Ok(val)
497 }
498
499 pub fn decode_varint_signed_i32(&mut self) -> Result<i32, DracoError> {
503 let symbol = self.decode_varint()? as u32;
504 let is_positive = (symbol & 1) == 0;
505 let v = symbol >> 1;
506 if is_positive {
507 Ok(v as i32)
508 } else {
509 Ok(-(v as i32) - 1)
510 }
511 }
512
513 pub fn remaining_data(&self) -> &'a [u8] {
515 &self.data[self.pos..]
516 }
517
518 pub fn advance(&mut self, n: usize) {
520 self.pos = self.pos.saturating_add(n).min(self.data.len());
521 }
522
523 pub fn try_advance(&mut self, n: usize) -> Result<(), DracoError> {
530 let new_pos = self
531 .pos
532 .checked_add(n)
533 .ok_or_else(|| DracoError::buffer("Buffer advance overflow"))?;
534 if new_pos > self.data.len() {
535 return Err(DracoError::buffer(format!(
536 "Cannot advance buffer by {} bytes: need position {}, buffer length {}",
537 n,
538 new_pos,
539 self.data.len()
540 )));
541 }
542 self.pos = new_pos;
543 Ok(())
544 }
545
546 pub fn decode_slice(&mut self, size: usize) -> Result<&'a [u8], DracoError> {
552 if size > self.data.len().saturating_sub(self.pos) {
553 return Err(DracoError::buffer(format!(
554 "Unexpected end of buffer: need {} bytes, have {}",
555 size,
556 self.remaining_size()
557 )));
558 }
559 let slice = &self.data[self.pos..self.pos + size];
560 self.pos += size;
561 Ok(slice)
562 }
563}
564
565#[cfg(test)]
566mod tests {
567 use super::DecoderBuffer;
568
569 #[test]
570 fn bit_decode_respects_declared_byte_size() {
571 let data = [1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff];
572 let mut buffer = DecoderBuffer::new(&data);
573
574 assert_eq!(buffer.start_bit_decoding(true).unwrap(), 1);
575 assert!(buffer.decode_least_significant_bits32(16).is_err());
576 }
577
578 #[test]
579 fn try_advance_rejects_out_of_bounds_skip() {
580 let data = [0u8; 4];
581 let mut buffer = DecoderBuffer::new(&data);
582
583 assert!(buffer.try_advance(5).is_err());
584 assert_eq!(buffer.position(), 0);
585 assert!(buffer.try_advance(4).is_ok());
586 assert_eq!(buffer.position(), 4);
587 }
588
589 #[test]
590 fn decode_least_significant_bits32_reads_full_width() {
591 let data = [0xffu8; 5];
593 let mut buffer = DecoderBuffer::new(&data);
594
595 buffer.start_bit_decoding(false).unwrap();
596 assert_eq!(
597 buffer.decode_least_significant_bits32(32).unwrap(),
598 u32::MAX
599 );
600 }
601
602 #[test]
603 fn decode_least_significant_bits32_reads_full_width_past_a_bit_shift() {
604 let data = [0xffu8; 6];
607 let mut buffer = DecoderBuffer::new(&data);
608
609 buffer.start_bit_decoding(false).unwrap();
610 assert_eq!(buffer.decode_least_significant_bits32(3).unwrap(), 0b111);
611 assert_eq!(
612 buffer.decode_least_significant_bits32(32).unwrap(),
613 u32::MAX
614 );
615 }
616
617 #[test]
618 fn decode_least_significant_bits32_rejects_width_above_32() {
619 let data = [0xffu8; 5];
620 let mut buffer = DecoderBuffer::new(&data);
621
622 buffer.start_bit_decoding(false).unwrap();
623 assert!(buffer.decode_least_significant_bits32(33).is_err());
624 }
625}