1use crate::error::Error;
19use crate::types::bfloat16::bfloat16;
20use crate::types::float16::float16;
21use crate::util::buffer_rw_string::read_latin1_simd;
22use byteorder::{ByteOrder, LittleEndian};
23use std::cmp::max;
24
25const SIMD_THRESHOLD: usize = 128;
28
29pub struct Writer<'a> {
30 pub(crate) bf: &'a mut Vec<u8>,
31}
32impl<'a> Writer<'a> {
33 #[inline(always)]
36 pub fn from_buffer(bf: &'a mut Vec<u8>) -> Writer<'a> {
37 Writer { bf }
38 }
39
40 #[inline(always)]
41 pub fn dump(&self) -> Vec<u8> {
42 self.bf.clone()
43 }
44
45 #[inline(always)]
46 pub fn reset(&mut self) {
47 self.bf.clear();
48 }
49
50 #[inline(always)]
51 pub fn len(&self) -> usize {
52 self.bf.len()
53 }
54
55 #[inline(always)]
56 pub fn is_empty(&self) -> bool {
57 self.bf.is_empty()
58 }
59
60 #[inline(always)]
61 pub fn reserve(&mut self, additional: usize) {
62 if self.bf.capacity() - self.len() < additional {
63 self.bf.reserve(max(additional * 2, self.bf.capacity()));
64 }
65 }
66
67 #[inline(always)]
68 pub fn skip(&mut self, len: usize) {
69 self.bf.resize(self.bf.len() + len, 0);
70 }
71
72 #[inline(always)]
73 pub fn set_bytes(&mut self, offset: usize, data: &[u8]) {
74 self.bf
75 .get_mut(offset..offset + data.len())
76 .unwrap()
77 .copy_from_slice(data);
78 }
79
80 #[inline(always)]
81 pub fn write_bytes(&mut self, v: &[u8]) -> usize {
82 self.bf.extend_from_slice(v);
83 v.len()
84 }
85
86 #[inline(always)]
87 pub(crate) unsafe fn write_bytes_from_ptr(&mut self, ptr: *const u8, len: usize) {
88 let offset = self.bf.len();
89 self.bf.reserve(len);
90 std::ptr::copy_nonoverlapping(ptr, self.bf.as_mut_ptr().add(offset), len);
91 self.bf.set_len(offset + len);
92 }
93
94 #[inline(always)]
97 pub fn write_bool(&mut self, value: bool) {
98 self.bf.push(if value { 1 } else { 0 });
99 }
100
101 #[inline(always)]
104 pub fn write_i8(&mut self, value: i8) {
105 self.bf.push(value as u8);
106 }
107
108 #[inline(always)]
111 pub fn write_i16(&mut self, value: i16) {
112 self.write_u16(value as u16);
113 }
114
115 #[inline(always)]
118 pub fn write_i32(&mut self, value: i32) {
119 self.write_u32(value as u32);
120 }
121
122 #[inline(always)]
125 pub fn write_var_i32(&mut self, value: i32) {
126 let zigzag = ((value as u32) << 1) ^ ((value >> 31) as u32);
127 self._write_var_u32(zigzag)
128 }
129
130 #[inline(always)]
133 pub fn write_i64(&mut self, value: i64) {
134 self.write_u64(value as u64);
135 }
136
137 #[inline(always)]
140 pub fn write_var_i64(&mut self, value: i64) {
141 let zigzag = ((value as u64) << 1) ^ ((value >> 63) as u64);
142 self._write_var_u64(zigzag);
143 }
144
145 #[inline(always)]
152 pub fn write_tagged_i64(&mut self, value: i64) {
153 const HALF_MIN_INT_VALUE: i64 = i32::MIN as i64 / 2; const HALF_MAX_INT_VALUE: i64 = i32::MAX as i64 / 2; if (HALF_MIN_INT_VALUE..=HALF_MAX_INT_VALUE).contains(&value) {
156 let v = (value as i32) << 1;
158 self.write_i32(v);
159 } else {
160 self.bf.push(0b1);
162 self.write_i64(value);
163 }
164 }
165
166 #[inline(always)]
169 pub fn write_u8(&mut self, value: u8) {
170 self.bf.push(value);
171 }
172
173 #[inline(always)]
176 pub fn write_u16(&mut self, value: u16) {
177 #[cfg(target_endian = "little")]
178 {
179 let bytes = unsafe { &*(&value as *const u16 as *const [u8; 2]) };
180 self.bf.extend_from_slice(bytes);
181 }
182 #[cfg(target_endian = "big")]
183 {
184 self.bf.extend_from_slice(&value.to_le_bytes());
185 }
186 }
187
188 #[inline(always)]
191 pub fn write_u32(&mut self, value: u32) {
192 #[cfg(target_endian = "little")]
193 {
194 let bytes = unsafe { &*(&value as *const u32 as *const [u8; 4]) };
195 self.bf.extend_from_slice(bytes);
196 }
197 #[cfg(target_endian = "big")]
198 {
199 self.bf.extend_from_slice(&value.to_le_bytes());
200 }
201 }
202
203 #[inline(always)]
204 fn write_u24(&mut self, value: u32) {
205 let bytes = value.to_le_bytes();
206 self.bf.extend_from_slice(&bytes[..3]);
207 }
208
209 #[inline(always)]
210 fn write_u40(&mut self, value: u64) {
211 let bytes = value.to_le_bytes();
212 self.bf.extend_from_slice(&bytes[..5]);
213 }
214
215 #[inline(always)]
218 pub fn write_var_u32(&mut self, value: u32) {
219 self._write_var_u32(value)
220 }
221
222 #[inline(always)]
223 fn _write_var_u32(&mut self, value: u32) {
224 if value < 0x80 {
225 self.bf.push(value as u8);
226 } else if value < 0x4000 {
227 let u1 = ((value as u8) & 0x7F) | 0x80;
229 let u2 = (value >> 7) as u8;
230 self.write_u16(((u2 as u16) << 8) | u1 as u16);
231 } else if value < 0x200000 {
232 let u1 = ((value as u8) & 0x7F) | 0x80;
234 let u2 = (((value >> 7) as u8) & 0x7F) | 0x80;
235 let u3 = (value >> 14) as u8;
236 self.write_u24(((u3 as u32) << 16) | ((u2 as u32) << 8) | u1 as u32);
237 } else if value < 0x10000000 {
238 let u1 = ((value as u8) & 0x7F) | 0x80;
240 let u2 = (((value >> 7) as u8) & 0x7F) | 0x80;
241 let u3 = (((value >> 14) as u8) & 0x7F) | 0x80;
242 let u4 = (value >> 21) as u8;
243 self.write_u32(
244 ((u4 as u32) << 24) | ((u3 as u32) << 16) | ((u2 as u32) << 8) | u1 as u32,
245 );
246 } else {
247 let u1 = ((value as u8) & 0x7F) | 0x80;
249 let u2 = (((value >> 7) as u8) & 0x7F) | 0x80;
250 let u3 = (((value >> 14) as u8) & 0x7F) | 0x80;
251 let u4 = (((value >> 21) as u8) & 0x7F) | 0x80;
252 let u5 = (value >> 28) as u8;
253 self.write_u40(
254 ((u5 as u64) << 32)
255 | ((u4 as u64) << 24)
256 | ((u3 as u64) << 16)
257 | ((u2 as u64) << 8)
258 | u1 as u64,
259 );
260 }
261 }
262
263 #[inline(always)]
266 pub fn write_u64(&mut self, value: u64) {
267 #[cfg(target_endian = "little")]
268 {
269 let bytes = unsafe { &*(&value as *const u64 as *const [u8; 8]) };
270 self.bf.extend_from_slice(bytes);
271 }
272 #[cfg(target_endian = "big")]
273 {
274 self.bf.extend_from_slice(&value.to_le_bytes());
275 }
276 }
277
278 #[inline(always)]
281 pub fn write_var_u64(&mut self, value: u64) {
282 self._write_var_u64(value);
283 }
284
285 #[inline(always)]
286 fn _write_var_u64(&mut self, value: u64) {
287 if value < 0x80 {
288 self.bf.push(value as u8);
289 } else if value < 0x4000 {
290 let u1 = ((value as u8) & 0x7F) | 0x80;
291 let u2 = (value >> 7) as u8;
292 self.write_u16(((u2 as u16) << 8) | u1 as u16);
293 } else if value < 0x200000 {
294 let u1 = ((value as u8) & 0x7F) | 0x80;
295 let u2 = (((value >> 7) as u8) & 0x7F) | 0x80;
296 let u3 = (value >> 14) as u8;
297 self.write_u24(((u3 as u32) << 16) | ((u2 as u32) << 8) | u1 as u32);
298 } else if value < 0x10000000 {
299 let u1 = ((value as u8) & 0x7F) | 0x80;
300 let u2 = (((value >> 7) as u8) & 0x7F) | 0x80;
301 let u3 = (((value >> 14) as u8) & 0x7F) | 0x80;
302 let u4 = (value >> 21) as u8;
303 self.write_u32(
304 ((u4 as u32) << 24) | ((u3 as u32) << 16) | ((u2 as u32) << 8) | u1 as u32,
305 );
306 } else if value < 0x800000000 {
307 let u1 = ((value as u8) & 0x7F) | 0x80;
308 let u2 = (((value >> 7) as u8) & 0x7F) | 0x80;
309 let u3 = (((value >> 14) as u8) & 0x7F) | 0x80;
310 let u4 = (((value >> 21) as u8) & 0x7F) | 0x80;
311 let u5 = (value >> 28) as u8;
312 self.write_u40(
313 ((u5 as u64) << 32)
314 | ((u4 as u64) << 24)
315 | ((u3 as u64) << 16)
316 | ((u2 as u64) << 8)
317 | u1 as u64,
318 );
319 } else if value < 0x40000000000 {
320 let u1 = ((value as u8) & 0x7F) | 0x80;
321 let u2 = (((value >> 7) as u8) & 0x7F) | 0x80;
322 let u3 = (((value >> 14) as u8) & 0x7F) | 0x80;
323 let u4 = (((value >> 21) as u8) & 0x7F) | 0x80;
324 let u5 = (((value >> 28) as u8) & 0x7F) | 0x80;
325 let u6 = (value >> 35) as u8;
326 self.write_u32(
327 ((u4 as u32) << 24) | ((u3 as u32) << 16) | ((u2 as u32) << 8) | u1 as u32,
328 );
329 self.write_u16(((u6 as u16) << 8) | u5 as u16);
330 } else if value < 0x2000000000000 {
331 let u1 = ((value as u8) & 0x7F) | 0x80;
332 let u2 = (((value >> 7) as u8) & 0x7F) | 0x80;
333 let u3 = (((value >> 14) as u8) & 0x7F) | 0x80;
334 let u4 = (((value >> 21) as u8) & 0x7F) | 0x80;
335 let u5 = (((value >> 28) as u8) & 0x7F) | 0x80;
336 let u6 = (((value >> 35) as u8) & 0x7F) | 0x80;
337 let u7 = (value >> 42) as u8;
338 self.write_u32(
339 ((u4 as u32) << 24) | ((u3 as u32) << 16) | ((u2 as u32) << 8) | u1 as u32,
340 );
341 self.write_u16(((u6 as u16) << 8) | u5 as u16);
342 self.bf.push(u7);
343 } else if value < 0x100000000000000 {
344 let u1 = ((value as u8) & 0x7F) | 0x80;
345 let u2 = (((value >> 7) as u8) & 0x7F) | 0x80;
346 let u3 = (((value >> 14) as u8) & 0x7F) | 0x80;
347 let u4 = (((value >> 21) as u8) & 0x7F) | 0x80;
348 let u5 = (((value >> 28) as u8) & 0x7F) | 0x80;
349 let u6 = (((value >> 35) as u8) & 0x7F) | 0x80;
350 let u7 = (((value >> 42) as u8) & 0x7F) | 0x80;
351 let u8 = (value >> 49) as u8;
352 self.write_u64(
353 (u8 as u64) << 56
354 | (u7 as u64) << 48
355 | (u6 as u64) << 40
356 | (u5 as u64) << 32
357 | (u4 as u64) << 24
358 | (u3 as u64) << 16
359 | (u2 as u64) << 8
360 | (u1 as u64),
361 );
362 } else {
363 let u1 = ((value as u8) & 0x7F) | 0x80;
364 let u2 = (((value >> 7) as u8) & 0x7F) | 0x80;
365 let u3 = (((value >> 14) as u8) & 0x7F) | 0x80;
366 let u4 = (((value >> 21) as u8) & 0x7F) | 0x80;
367 let u5 = (((value >> 28) as u8) & 0x7F) | 0x80;
368 let u6 = (((value >> 35) as u8) & 0x7F) | 0x80;
369 let u7 = (((value >> 42) as u8) & 0x7F) | 0x80;
370 let u8 = (((value >> 49) as u8) & 0x7F) | 0x80;
371 let u9 = (value >> 56) as u8;
372 self.write_u64(
373 (u8 as u64) << 56
374 | (u7 as u64) << 48
375 | (u6 as u64) << 40
376 | (u5 as u64) << 32
377 | (u4 as u64) << 24
378 | (u3 as u64) << 16
379 | (u2 as u64) << 8
380 | (u1 as u64),
381 );
382 self.bf.push(u9);
383 }
384 }
385
386 #[inline(always)]
392 pub fn write_tagged_u64(&mut self, value: u64) {
393 if value <= i32::MAX as u64 {
394 let v = (value as u32) << 1;
396 self.write_u32(v);
397 } else {
398 self.bf.push(0b1);
400 self.write_u64(value);
401 }
402 }
403
404 #[inline(always)]
407 pub fn write_f32(&mut self, value: f32) {
408 #[cfg(target_endian = "little")]
409 {
410 let bytes = unsafe { &*(&value as *const f32 as *const [u8; 4]) };
411 self.bf.extend_from_slice(bytes);
412 }
413 #[cfg(target_endian = "big")]
414 {
415 self.bf.extend_from_slice(&value.to_bits().to_le_bytes());
416 }
417 }
418
419 #[inline(always)]
421 pub fn write_f16(&mut self, value: float16) {
422 self.write_u16(value.to_bits());
423 }
424
425 #[inline(always)]
427 pub fn write_bf16(&mut self, value: bfloat16) {
428 self.write_u16(value.to_bits());
429 }
430
431 #[inline(always)]
434 pub fn write_f64(&mut self, value: f64) {
435 #[cfg(target_endian = "little")]
436 {
437 let bytes = unsafe { &*(&value as *const f64 as *const [u8; 8]) };
438 self.bf.extend_from_slice(bytes);
439 }
440 #[cfg(target_endian = "big")]
441 {
442 self.bf.extend_from_slice(&value.to_bits().to_le_bytes());
443 }
444 }
445
446 #[inline(always)]
449 pub fn write_utf8_string(&mut self, s: &str) {
450 let bytes = s.as_bytes();
451 let len = bytes.len();
452 self.bf.reserve(len);
453 self.bf.extend_from_slice(bytes);
454 }
455
456 #[inline(always)]
459 pub fn write_i128(&mut self, value: i128) {
460 self.write_u128(value as u128);
461 }
462
463 #[inline(always)]
464 pub fn write_u128(&mut self, value: u128) {
465 #[cfg(target_endian = "little")]
466 {
467 let bytes = unsafe { &*(&value as *const u128 as *const [u8; 16]) };
468 self.bf.extend_from_slice(bytes);
469 }
470 #[cfg(target_endian = "big")]
471 {
472 self.bf.extend_from_slice(&value.to_le_bytes());
473 }
474 }
475
476 #[inline(always)]
477 pub fn write_isize(&mut self, value: isize) {
478 const SIZE: usize = std::mem::size_of::<isize>();
479 match SIZE {
480 2 => self.write_i16(value as i16),
481 4 => self.write_var_i32(value as i32),
482 8 => self.write_var_i64(value as i64),
483 _ => unreachable!("unsupported isize size"),
484 }
485 }
486
487 #[inline(always)]
488 pub fn write_usize(&mut self, value: usize) {
489 const SIZE: usize = std::mem::size_of::<usize>();
490 match SIZE {
491 2 => self.write_u16(value as u16),
492 4 => self.write_var_u32(value as u32),
493 8 => self.write_var_u64(value as u64),
494 _ => unreachable!("unsupported usize size"),
495 }
496 }
497
498 #[inline(always)]
501 pub fn write_var_u36_small(&mut self, value: u64) {
502 assert!(
503 value < (1u64 << 36),
504 "value too large for 36-bit variable-length integer"
505 );
506 if value < 0x80 {
507 self.bf.push(value as u8);
508 } else if value < 0x4000 {
509 let b0 = ((value & 0x7F) as u8) | 0x80;
510 let b1 = (value >> 7) as u8;
511 let combined = ((b1 as u16) << 8) | (b0 as u16);
512 self.write_u16(combined);
513 } else if value < 0x200000 {
514 let b0 = (value & 0x7F) | 0x80;
515 let b1 = ((value >> 7) & 0x7F) | 0x80;
516 let b2 = value >> 14;
517 let combined = b0 | (b1 << 8) | (b2 << 16);
518 self.write_u32(combined as u32);
519 } else if value < 0x10000000 {
520 let b0 = (value & 0x7F) | 0x80;
521 let b1 = ((value >> 7) & 0x7F) | 0x80;
522 let b2 = ((value >> 14) & 0x7F) | 0x80;
523 let b3 = value >> 21;
524 let combined = b0 | (b1 << 8) | (b2 << 16) | (b3 << 24);
525 self.write_u32(combined as u32);
526 } else {
527 let b0 = (value & 0x7F) | 0x80;
528 let b1 = ((value >> 7) & 0x7F) | 0x80;
529 let b2 = ((value >> 14) & 0x7F) | 0x80;
530 let b3 = ((value >> 21) & 0x7F) | 0x80;
531 let b4 = value >> 28;
532 let combined = b0 | (b1 << 8) | (b2 << 16) | (b3 << 24) | (b4 << 32);
533 self.write_u64(combined);
534 }
535 }
536}
537
538#[derive(Default)]
539#[allow(clippy::needless_lifetimes)]
540pub struct Reader<'a> {
541 pub(crate) bf: &'a [u8],
542 pub(crate) cursor: usize,
543}
544
545#[allow(clippy::needless_lifetimes)]
546impl<'a> Reader<'a> {
547 #[inline(always)]
550 pub fn new(bf: &[u8]) -> Reader<'_> {
551 Reader { bf, cursor: 0 }
552 }
553
554 #[inline(always)]
555 pub(crate) fn move_next(&mut self, additional: usize) {
556 self.cursor += additional;
557 }
558
559 #[inline(always)]
560 pub(crate) fn move_back(&mut self, additional: usize) {
561 self.cursor -= additional;
562 }
563
564 #[inline(always)]
565 pub fn sub_slice(&self, start: usize, end: usize) -> Result<&[u8], Error> {
566 if start > self.bf.len() || end > self.bf.len() || end < start {
568 Err(Error::buffer_out_of_bound(
569 start,
570 self.bf.len(),
571 self.bf.len(),
572 ))
573 } else {
574 Ok(&self.bf[start..end])
575 }
576 }
577
578 #[inline(always)]
579 pub fn slice_after_cursor(&self) -> &[u8] {
580 &self.bf[self.cursor..]
581 }
582
583 #[inline(always)]
584 pub fn get_cursor(&self) -> usize {
585 self.cursor
586 }
587
588 #[inline(always)]
589 fn value_at(&self, index: usize) -> Result<u8, Error> {
590 match self.bf.get(index) {
591 None => Err(Error::buffer_out_of_bound(
592 index,
593 self.bf.len(),
594 self.bf.len(),
595 )),
596 Some(v) => Ok(*v),
597 }
598 }
599
600 #[inline(always)]
601 pub(crate) fn check_bound(&self, n: usize) -> Result<(), Error> {
602 let end = self
603 .cursor
604 .checked_add(n)
605 .ok_or_else(|| Error::buffer_out_of_bound(self.cursor, n, self.bf.len()))?;
606 if end > self.bf.len() {
607 Err(Error::buffer_out_of_bound(self.cursor, n, self.bf.len()))
608 } else {
609 Ok(())
610 }
611 }
612
613 #[inline(always)]
614 fn read_u8_uncheck(&mut self) -> u8 {
615 let result = unsafe { self.bf.get_unchecked(self.cursor) };
616 self.move_next(1);
617 *result
618 }
619
620 #[inline(always)]
621 pub fn skip(&mut self, len: usize) -> Result<(), Error> {
622 self.check_bound(len)?;
623 self.move_next(len);
624 Ok(())
625 }
626
627 #[inline(always)]
628 pub fn read_bytes(&mut self, len: usize) -> Result<&[u8], Error> {
629 self.check_bound(len)?;
630 let result = &self.bf[self.cursor..self.cursor + len];
631 self.move_next(len);
632 Ok(result)
633 }
634
635 #[inline(always)]
636 pub fn reset_cursor_to_here(&self) -> impl FnOnce(&mut Self) {
637 let raw_cursor = self.cursor;
638 move |this: &mut Self| {
639 this.cursor = raw_cursor;
640 }
641 }
642
643 pub fn set_cursor(&mut self, cursor: usize) {
644 self.cursor = cursor;
645 }
646
647 #[inline(always)]
650 pub fn read_bool(&mut self) -> Result<bool, Error> {
651 Ok(self.read_u8()? != 0)
652 }
653
654 #[inline(always)]
657 pub fn read_i8(&mut self) -> Result<i8, Error> {
658 Ok(self.read_u8()? as i8)
659 }
660
661 #[inline(always)]
664 pub fn read_i16(&mut self) -> Result<i16, Error> {
665 Ok(self.read_u16()? as i16)
666 }
667
668 #[inline(always)]
671 pub fn read_i32(&mut self) -> Result<i32, Error> {
672 Ok(self.read_u32()? as i32)
673 }
674
675 #[inline(always)]
678 pub fn read_var_i32(&mut self) -> Result<i32, Error> {
679 let encoded = self.read_var_u32()?;
680 Ok(((encoded >> 1) as i32) ^ -((encoded & 1) as i32))
681 }
682
683 #[inline(always)]
686 pub fn read_i64(&mut self) -> Result<i64, Error> {
687 Ok(self.read_u64()? as i64)
688 }
689
690 #[inline(always)]
693 pub fn read_var_i64(&mut self) -> Result<i64, Error> {
694 let encoded = self.read_var_u64()?;
695 Ok(((encoded >> 1) as i64) ^ -((encoded & 1) as i64))
696 }
697
698 #[inline(always)]
704 pub fn read_tagged_i64(&mut self) -> Result<i64, Error> {
705 self.check_bound(4)?;
706 let i = LittleEndian::read_i32(&self.bf[self.cursor..]);
707 if (i & 0b1) != 0b1 {
708 self.cursor += 4;
710 Ok((i >> 1) as i64) } else {
712 self.check_bound(9)?;
714 self.cursor += 1;
715 let value = LittleEndian::read_i64(&self.bf[self.cursor..]);
716 self.cursor += 8;
717 Ok(value)
718 }
719 }
720
721 #[inline(always)]
724 pub fn peek_u8(&mut self) -> Result<u8, Error> {
725 let result = self.value_at(self.cursor)?;
726 Ok(result)
727 }
728
729 #[inline(always)]
730 pub fn read_u8(&mut self) -> Result<u8, Error> {
731 let result = self.value_at(self.cursor)?;
732 self.move_next(1);
733 Ok(result)
734 }
735
736 #[inline(always)]
739 pub fn read_u16(&mut self) -> Result<u16, Error> {
740 self.check_bound(2)?;
741 let result = LittleEndian::read_u16(&self.bf[self.cursor..self.cursor + 2]);
742 self.cursor += 2;
743 Ok(result)
744 }
745
746 #[inline(always)]
749 pub fn read_u32(&mut self) -> Result<u32, Error> {
750 self.check_bound(4)?;
751 let result = LittleEndian::read_u32(&self.bf[self.cursor..self.cursor + 4]);
752 self.cursor += 4;
753 Ok(result)
754 }
755
756 #[inline(always)]
759 pub fn read_var_u32(&mut self) -> Result<u32, Error> {
760 let b0 = self.value_at(self.cursor)? as u32;
761 if b0 < 0x80 {
762 self.move_next(1);
763 return Ok(b0);
764 }
765
766 let b1 = self.value_at(self.cursor + 1)? as u32;
767 let mut encoded = (b0 & 0x7F) | ((b1 & 0x7F) << 7);
768 if b1 < 0x80 {
769 self.move_next(2);
770 return Ok(encoded);
771 }
772
773 let b2 = self.value_at(self.cursor + 2)? as u32;
774 encoded |= (b2 & 0x7F) << 14;
775 if b2 < 0x80 {
776 self.move_next(3);
777 return Ok(encoded);
778 }
779
780 let b3 = self.value_at(self.cursor + 3)? as u32;
781 encoded |= (b3 & 0x7F) << 21;
782 if b3 < 0x80 {
783 self.move_next(4);
784 return Ok(encoded);
785 }
786
787 let b4 = self.value_at(self.cursor + 4)? as u32;
788 encoded |= b4 << 28;
789 self.move_next(5);
790 Ok(encoded)
791 }
792
793 #[inline(always)]
796 pub fn read_u64(&mut self) -> Result<u64, Error> {
797 self.check_bound(8)?;
798 let result = LittleEndian::read_u64(&self.bf[self.cursor..self.cursor + 8]);
799 self.cursor += 8;
800 Ok(result)
801 }
802
803 #[inline(always)]
806 pub fn read_var_u64(&mut self) -> Result<u64, Error> {
807 let b0 = self.value_at(self.cursor)? as u64;
808 if b0 < 0x80 {
809 self.move_next(1);
810 return Ok(b0);
811 }
812
813 let b1 = self.value_at(self.cursor + 1)? as u64;
814 let mut result = (b0 & 0x7F) | ((b1 & 0x7F) << 7);
815 if b1 < 0x80 {
816 self.move_next(2);
817 return Ok(result);
818 }
819
820 let b2 = self.value_at(self.cursor + 2)? as u64;
821 result |= (b2 & 0x7F) << 14;
822 if b2 < 0x80 {
823 self.move_next(3);
824 return Ok(result);
825 }
826
827 let b3 = self.value_at(self.cursor + 3)? as u64;
828 result |= (b3 & 0x7F) << 21;
829 if b3 < 0x80 {
830 self.move_next(4);
831 return Ok(result);
832 }
833
834 let b4 = self.value_at(self.cursor + 4)? as u64;
835 result |= (b4 & 0x7F) << 28;
836 if b4 < 0x80 {
837 self.move_next(5);
838 return Ok(result);
839 }
840
841 let b5 = self.value_at(self.cursor + 5)? as u64;
842 result |= (b5 & 0x7F) << 35;
843 if b5 < 0x80 {
844 self.move_next(6);
845 return Ok(result);
846 }
847
848 let b6 = self.value_at(self.cursor + 6)? as u64;
849 result |= (b6 & 0x7F) << 42;
850 if b6 < 0x80 {
851 self.move_next(7);
852 return Ok(result);
853 }
854
855 let b7 = self.value_at(self.cursor + 7)? as u64;
856 result |= (b7 & 0x7F) << 49;
857 if b7 < 0x80 {
858 self.move_next(8);
859 return Ok(result);
860 }
861
862 let b8 = self.value_at(self.cursor + 8)? as u64;
863 result |= (b8 & 0xFF) << 56;
864 self.move_next(9);
865 Ok(result)
866 }
867
868 #[inline(always)]
874 pub fn read_tagged_u64(&mut self) -> Result<u64, Error> {
875 self.check_bound(4)?;
876 let i = LittleEndian::read_u32(&self.bf[self.cursor..]);
877 if (i & 0b1) != 0b1 {
878 self.cursor += 4;
880 Ok((i >> 1) as u64)
881 } else {
882 self.check_bound(9)?;
884 self.cursor += 1;
885 let value = LittleEndian::read_u64(&self.bf[self.cursor..]);
886 self.cursor += 8;
887 Ok(value)
888 }
889 }
890
891 #[inline(always)]
894 pub fn read_f32(&mut self) -> Result<f32, Error> {
895 self.check_bound(4)?;
896 let result = LittleEndian::read_f32(&self.bf[self.cursor..self.cursor + 4]);
897 self.cursor += 4;
898 Ok(result)
899 }
900
901 #[inline(always)]
903 pub fn read_f16(&mut self) -> Result<float16, Error> {
904 self.check_bound(2)?;
905 let bits = LittleEndian::read_u16(&self.bf[self.cursor..self.cursor + 2]);
906 self.cursor += 2;
907 Ok(float16::from_bits(bits))
908 }
909
910 #[inline(always)]
911 pub fn read_bf16(&mut self) -> Result<bfloat16, Error> {
912 self.check_bound(2)?;
913 let bits = LittleEndian::read_u16(&self.bf[self.cursor..self.cursor + 2]);
914 self.cursor += 2;
915 Ok(bfloat16::from_bits(bits))
916 }
917
918 pub fn read_f64(&mut self) -> Result<f64, Error> {
919 self.check_bound(8)?;
920 let result = LittleEndian::read_f64(&self.bf[self.cursor..self.cursor + 8]);
921 self.cursor += 8;
922 Ok(result)
923 }
924
925 #[inline(always)]
928 pub fn read_latin1_string(&mut self, len: usize) -> Result<String, Error> {
929 self.check_bound(len)?;
930 if len < SIMD_THRESHOLD {
931 unsafe {
933 let src = self.sub_slice(self.cursor, self.cursor + len)?;
934
935 let is_ascii = src.iter().all(|&b| b < 0x80);
937
938 if is_ascii {
939 let mut vec = Vec::with_capacity(len);
941 let dst = vec.as_mut_ptr();
942 std::ptr::copy_nonoverlapping(src.as_ptr(), dst, len);
943 vec.set_len(len);
944 self.move_next(len);
945 Ok(String::from_utf8_unchecked(vec))
946 } else {
947 let mut out: Vec<u8> = Vec::with_capacity(len * 2);
949 let out_ptr = out.as_mut_ptr();
950 let mut out_len = 0;
951
952 for &b in src {
953 if b < 0x80 {
954 *out_ptr.add(out_len) = b;
955 out_len += 1;
956 } else {
957 *out_ptr.add(out_len) = 0xC0 | (b >> 6);
959 *out_ptr.add(out_len + 1) = 0x80 | (b & 0x3F);
960 out_len += 2;
961 }
962 }
963
964 out.set_len(out_len);
965 self.move_next(len);
966 Ok(String::from_utf8_unchecked(out))
967 }
968 }
969 } else {
970 read_latin1_simd(self, len)
972 }
973 }
974
975 #[inline(always)]
976 pub fn read_utf8_string(&mut self, len: usize) -> Result<String, Error> {
977 self.check_bound(len)?;
978 let src = &self.bf[self.cursor..self.cursor + len];
979 let string =
982 std::str::from_utf8(src).map_err(|_| Error::encoding_error("invalid UTF-8 string"))?;
983 let string = string.to_owned();
984 self.move_next(len);
985 Ok(string)
986 }
987
988 #[inline(always)]
989 pub fn read_utf8_string_unchecked(&mut self, len: usize) -> Result<String, Error> {
990 self.check_bound(len)?;
991 unsafe {
993 let mut vec = Vec::with_capacity(len);
994 let src = self.bf.as_ptr().add(self.cursor);
995 let dst = vec.as_mut_ptr();
996 std::ptr::copy_nonoverlapping(src, dst, len);
998 vec.set_len(len);
999 self.move_next(len);
1000 Ok(String::from_utf8_unchecked(vec))
1001 }
1002 }
1003
1004 #[inline(always)]
1005 pub fn read_utf16_string(&mut self, len: usize) -> Result<String, Error> {
1006 self.check_bound(len)?;
1007 let slice = self.sub_slice(self.cursor, self.cursor + len)?;
1008 let units: Vec<u16> = slice
1009 .chunks_exact(2)
1010 .map(|c| u16::from_le_bytes([c[0], c[1]]))
1011 .collect();
1012 self.move_next(len);
1013 Ok(String::from_utf16_lossy(&units))
1014 }
1015
1016 #[inline(always)]
1019 pub fn read_i128(&mut self) -> Result<i128, Error> {
1020 Ok(self.read_u128()? as i128)
1021 }
1022
1023 #[inline(always)]
1024 pub fn read_u128(&mut self) -> Result<u128, Error> {
1025 self.check_bound(16)?;
1026 let result = LittleEndian::read_u128(&self.bf[self.cursor..self.cursor + 16]);
1027 self.cursor += 16;
1028 Ok(result)
1029 }
1030
1031 #[inline(always)]
1032 pub fn read_isize(&mut self) -> Result<isize, Error> {
1033 const SIZE: usize = std::mem::size_of::<isize>();
1034 match SIZE {
1035 2 => Ok(self.read_i16()? as isize),
1036 4 => Ok(self.read_var_i32()? as isize),
1037 8 => Ok(self.read_var_i64()? as isize),
1038 _ => unreachable!("unsupported isize size"),
1039 }
1040 }
1041
1042 #[inline(always)]
1043 pub fn read_usize(&mut self) -> Result<usize, Error> {
1044 const SIZE: usize = std::mem::size_of::<usize>();
1045 match SIZE {
1046 2 => Ok(self.read_u16()? as usize),
1047 4 => Ok(self.read_var_u32()? as usize),
1048 8 => Ok(self.read_var_u64()? as usize),
1049 _ => unreachable!("unsupported usize size"),
1050 }
1051 }
1052
1053 #[inline(always)]
1056 pub fn read_var_u36_small(&mut self) -> Result<u64, Error> {
1057 self.check_bound(0)?;
1059 let start = self.cursor;
1060 let slice = self.slice_after_cursor();
1061
1062 if slice.len() >= 8 {
1063 let bulk = self.read_u64()?;
1065 let mut result = bulk & 0x7F;
1066 let mut read_idx = start;
1067
1068 if (bulk & 0x80) != 0 {
1069 read_idx += 1;
1070 result |= (bulk >> 1) & 0x3F80;
1071 if (bulk & 0x8000) != 0 {
1072 read_idx += 1;
1073 result |= (bulk >> 2) & 0x1FC000;
1074 if (bulk & 0x800000) != 0 {
1075 read_idx += 1;
1076 result |= (bulk >> 3) & 0xFE00000;
1077 if (bulk & 0x80000000) != 0 {
1078 read_idx += 1;
1079 result |= (bulk >> 4) & 0xFF0000000;
1080 }
1081 }
1082 }
1083 }
1084 self.cursor = read_idx + 1;
1085 return Ok(result);
1086 }
1087
1088 let mut result = 0u64;
1089 let mut shift = 0;
1090 while self.cursor < self.bf.len() {
1091 let b = self.read_u8_uncheck();
1092 result |= ((b & 0x7F) as u64) << shift;
1093 if (b & 0x80) == 0 {
1094 break;
1095 }
1096 shift += 7;
1097 if shift >= 36 {
1098 return Err(Error::encode_error("var_u36_small overflow"));
1099 }
1100 }
1101 Ok(result)
1102 }
1103}
1104
1105#[allow(clippy::needless_lifetimes)]
1106unsafe impl<'a> Send for Reader<'a> {}
1107#[allow(clippy::needless_lifetimes)]
1108unsafe impl<'a> Sync for Reader<'a> {}
1109
1110#[cfg(test)]
1111mod tests {
1112 use super::{Reader, Writer};
1113
1114 #[test]
1115 fn varuint_boundary_roundtrip() {
1116 let cases = [
1117 (0x3fff_u32, 2),
1118 (0x4000, 3),
1119 (0x1f_ffff, 3),
1120 (0x20_0000, 4),
1121 (0x0fff_ffff, 4),
1122 (0x1000_0000, 5),
1123 (u32::MAX, 5),
1124 ];
1125 for (value, expected_len) in cases {
1126 let mut buffer = Vec::new();
1127 let mut writer = Writer::from_buffer(&mut buffer);
1128 writer.write_var_u32(value);
1129 assert_eq!(writer.len(), expected_len);
1130 let bytes = writer.dump();
1131 assert_eq!(Reader::new(&bytes).read_var_u32().unwrap(), value);
1132 let mut padded = bytes;
1133 padded.extend_from_slice(&[0; 8]);
1134 let mut reader = Reader::new(&padded);
1135 assert_eq!(reader.read_var_u32().unwrap(), value);
1136 assert_eq!(reader.get_cursor(), expected_len);
1137
1138 let mut buffer = Vec::new();
1139 let mut writer = Writer::from_buffer(&mut buffer);
1140 writer.write_var_u64(u64::from(value));
1141 assert_eq!(writer.len(), expected_len);
1142 let bytes = writer.dump();
1143 assert_eq!(
1144 Reader::new(&bytes).read_var_u64().unwrap(),
1145 u64::from(value)
1146 );
1147 }
1148 }
1149}