1use crate::{BitBuf, Error, Result, StorageMut};
2
3impl<S: StorageMut> BitBuf<S> {
4 #[inline(always)]
14 pub unsafe fn write_u8_be_aligned_full_at_unchecked(
15 &mut self,
16 byte_offset: usize,
17 v: u8,
18 ) -> &mut Self {
19 let bytes = self.bytes_mut();
20
21 debug_assert!(
22 byte_offset < bytes.len(),
23 "BitBuf::write_u8_be_aligned_full_at_unchecked: index out of bounds! len is {}, offset is {}",
24 bytes.len(),
25 byte_offset,
26 );
27
28 unsafe { *bytes.get_unchecked_mut(byte_offset) = v };
29 self
30 }
31
32 #[inline(always)]
44 pub unsafe fn write_u8_be_aligned_full_unchecked(&mut self, v: u8) -> &mut Self {
45 debug_assert!(
46 self.is_aligned(),
47 "BitBuf::write_u8_be_aligned_full_unchecked called at unaligned bit position: {}",
48 self.pos(),
49 );
50
51 unsafe { self.write_u8_be_aligned_full_at_unchecked(self.byte_pos(), v) };
52 self.advance_bytes(1);
53 self
54 }
55
56 #[inline(always)]
68 pub unsafe fn write_u8_be_full_at_unchecked(&mut self, offset: usize, v: u8) -> &mut Self {
69 let byte_idx = offset / 8;
70 let shift = offset % 8;
71
72 let bytes = self.bytes_mut();
73
74 debug_assert!(
75 byte_idx < bytes.len(),
76 "BitBuf::write_u8_be_full_at_unchecked: index out of bounds! len is {}, byte_idx is {}",
77 bytes.len(),
78 byte_idx,
79 );
80
81 if shift == 0 {
82 unsafe { self.write_u8_be_aligned_full_at_unchecked(byte_idx, v) };
83 } else {
84 let next_idx = byte_idx + 1;
85
86 debug_assert!(
87 next_idx < bytes.len(),
88 "BitBuf::write_u8_be_full_at_unchecked: lookahead index out of bounds! len is {}, lookahead byte_idx is {}",
89 bytes.len(),
90 next_idx,
91 );
92
93 unsafe {
95 let mask = !0 << (8 - shift);
97 let b = bytes.get_unchecked(byte_idx) & mask;
98 let new = v >> shift;
100 *bytes.get_unchecked_mut(byte_idx) = b | new;
101 }
102
103 unsafe {
105 let mask = !0 >> shift;
107 let b = bytes.get_unchecked(next_idx) & mask;
108 let new = v << (8 - shift);
110 *bytes.get_unchecked_mut(next_idx) = b | new;
111 }
112 }
113
114 self
115 }
116
117 #[inline(always)]
129 pub unsafe fn write_u8_be_full_unchecked(&mut self, v: u8) -> &mut Self {
130 unsafe { self.write_u8_be_full_at_unchecked(self.pos(), v) };
131 self.advance_bytes(1);
132 self
133 }
134
135 #[inline(always)]
143 pub fn try_write_u8_be_full_at(&mut self, offset: usize, v: u8) -> Result<&mut Self> {
144 let byte_idx = offset / 8;
145 let shift = offset % 8;
146
147 let len = self.bytes().len();
148
149 if byte_idx >= len {
150 return Err(Error::OutOfBounds);
151 }
152
153 if shift != 0 && byte_idx + 1 >= len {
154 return Err(Error::OutOfBounds);
155 }
156
157 Ok(unsafe { self.write_u8_be_full_at_unchecked(offset, v) })
158 }
159
160 #[inline(always)]
168 pub fn try_write_u8_be_full(&mut self, v: u8) -> Result<&mut Self> {
169 self.try_write_u8_be_full_at(self.pos(), v)?;
170 self.advance_bytes(1);
171 Ok(self)
172 }
173
174 #[inline(always)]
181 pub fn write_u8_be_full_at(&mut self, offset: usize, v: u8) -> &mut Self {
182 self
183 .try_write_u8_be_full_at(offset, v)
184 .expect("BitBuf::write_u8_be_full_at out of bounds")
185 }
186
187 #[inline(always)]
194 pub fn write_u8_be_full(&mut self, v: u8) -> &mut Self {
195 self
196 .try_write_u8_be_full(v)
197 .expect("BitBuf::write_u8_be_full out of bounds")
198 }
199
200 #[inline(always)]
210 pub unsafe fn write_u16_be_aligned_full_at_unchecked(
211 &mut self,
212 byte_offset: usize,
213 v: u16,
214 ) -> &mut Self {
215 let bytes = self.bytes_mut();
216
217 debug_assert!(
218 byte_offset + 1 < bytes.len(),
219 "BitBuf::write_u16_be_aligned_full_at_unchecked: index out of bounds! len is {}, offset is {}",
220 bytes.len(),
221 byte_offset + 1,
222 );
223
224 let [high, low] = v.to_be_bytes();
225
226 unsafe {
227 *bytes.get_unchecked_mut(byte_offset) = high;
228 *bytes.get_unchecked_mut(byte_offset + 1) = low;
229 }
230
231 self
232 }
233
234 #[inline(always)]
246 pub unsafe fn write_u16_be_aligned_full_unchecked(&mut self, v: u16) -> &mut Self {
247 debug_assert!(
248 self.is_aligned(),
249 "BitBuf::write_u16_be_aligned_full_unchecked called at unaligned bit position: {}",
250 self.pos(),
251 );
252
253 unsafe { self.write_u16_be_aligned_full_at_unchecked(self.byte_pos(), v) };
254 self.advance_bytes(2);
255 self
256 }
257
258 #[inline(always)]
270 pub unsafe fn write_u16_be_full_at_unchecked(&mut self, offset: usize, v: u16) -> &mut Self {
271 let first_idx = offset / 8;
272 let shift = offset % 8;
273
274 let bytes = self.bytes_mut();
275
276 debug_assert!(
277 first_idx + 1 < bytes.len(),
278 "BitBuf::write_u16_be_full_at_unchecked: index out of bounds! len is {}, byte_idx is {}",
279 bytes.len(),
280 first_idx + 1,
281 );
282
283 if shift == 0 {
284 unsafe { self.write_u16_be_aligned_full_at_unchecked(first_idx, v) };
285 } else {
286 let second_idx = first_idx + 1;
287 let third_idx = first_idx + 2;
288
289 debug_assert!(
290 third_idx < bytes.len(),
291 "BitBuf::write_u16_be_full_at_unchecked: lookahead index out of bounds! len is {}, lookahead byte_idx is {}",
292 bytes.len(),
293 third_idx,
294 );
295
296 let [high, low] = v.to_be_bytes();
297
298 unsafe {
300 let mask = !0 << (8 - shift);
302 let b = bytes.get_unchecked(first_idx) & mask;
303 let new = high >> shift;
305 *bytes.get_unchecked_mut(first_idx) = b | new;
306 }
307
308 unsafe {
310 let b_high = high << (8 - shift);
313 let b_low = low >> shift;
315 *bytes.get_unchecked_mut(second_idx) = b_high | b_low;
316 }
317
318 unsafe {
320 let mask = !0 >> shift;
322 let b = bytes.get_unchecked(third_idx) & mask;
323 let new = low << (8 - shift);
325 *bytes.get_unchecked_mut(third_idx) = b | new;
326 }
327 }
328
329 self
330 }
331
332 #[inline(always)]
344 pub unsafe fn write_u16_be_full_unchecked(&mut self, v: u16) -> &mut Self {
345 unsafe { self.write_u16_be_full_at_unchecked(self.pos(), v) };
346 self.advance_bytes(2);
347 self
348 }
349
350 #[inline(always)]
358 pub fn try_write_u16_be_full_at(&mut self, offset: usize, v: u16) -> Result<&mut Self> {
359 let first_idx = offset / 8;
360 let shift = offset % 8;
361
362 let len = self.bytes().len();
363
364 if first_idx + 1 >= len {
365 return Err(Error::OutOfBounds);
366 }
367
368 if shift != 0 && first_idx + 2 >= len {
369 return Err(Error::OutOfBounds);
370 }
371
372 Ok(unsafe { self.write_u16_be_full_at_unchecked(offset, v) })
373 }
374
375 #[inline(always)]
383 pub fn try_write_u16_be_full(&mut self, v: u16) -> Result<&mut Self> {
384 self.try_write_u16_be_full_at(self.pos(), v)?;
385 self.advance_bytes(2);
386 Ok(self)
387 }
388
389 #[inline(always)]
396 pub fn write_u16_be_full_at(&mut self, offset: usize, v: u16) -> &mut Self {
397 self
398 .try_write_u16_be_full_at(offset, v)
399 .expect("BitBuf::write_u16_be_full_at out of bounds")
400 }
401
402 #[inline(always)]
409 pub fn write_u16_be_full(&mut self, v: u16) -> &mut Self {
410 self
411 .try_write_u16_be_full(v)
412 .expect("BitBuf::write_u16_be_full out of bounds")
413 }
414}
415
416pub trait Write: Sized {
417 unsafe fn write_be_aligned_full_at_unchecked<S: StorageMut>(
418 buf: &mut BitBuf<S>,
419 byte_offset: usize,
420 v: Self,
421 ) -> &mut BitBuf<S>;
422
423 unsafe fn write_be_aligned_full_unchecked<S: StorageMut>(
424 buf: &mut BitBuf<S>,
425 v: Self,
426 ) -> &mut BitBuf<S>;
427
428 unsafe fn write_be_full_at_unchecked<S: StorageMut>(
429 buf: &mut BitBuf<S>,
430 offset: usize,
431 v: Self,
432 ) -> &mut BitBuf<S>;
433
434 unsafe fn write_be_full_unchecked<S: StorageMut>(buf: &mut BitBuf<S>, v: Self) -> &mut BitBuf<S>;
435
436 fn try_write_be_full_at<S: StorageMut>(
437 buf: &mut BitBuf<S>,
438 offset: usize,
439 v: Self,
440 ) -> Result<&mut BitBuf<S>>;
441
442 fn try_write_be_full<S: StorageMut>(buf: &mut BitBuf<S>, v: Self) -> Result<&mut BitBuf<S>>;
443
444 fn write_be_full_at<S: StorageMut>(buf: &mut BitBuf<S>, offset: usize, v: Self)
445 -> &mut BitBuf<S>;
446
447 fn write_be_full<S: StorageMut>(buf: &mut BitBuf<S>, v: Self) -> &mut BitBuf<S>;
448}
449
450impl Write for u8 {
451 #[inline(always)]
452 unsafe fn write_be_aligned_full_at_unchecked<S: StorageMut>(
453 buf: &mut BitBuf<S>,
454 byte_offset: usize,
455 v: Self,
456 ) -> &mut BitBuf<S> {
457 unsafe { buf.write_u8_be_aligned_full_at_unchecked(byte_offset, v) }
458 }
459
460 #[inline(always)]
461 unsafe fn write_be_aligned_full_unchecked<S: StorageMut>(
462 buf: &mut BitBuf<S>,
463 v: Self,
464 ) -> &mut BitBuf<S> {
465 unsafe { buf.write_u8_be_aligned_full_unchecked(v) }
466 }
467
468 #[inline(always)]
469 unsafe fn write_be_full_at_unchecked<S: StorageMut>(
470 buf: &mut BitBuf<S>,
471 offset: usize,
472 v: Self,
473 ) -> &mut BitBuf<S> {
474 unsafe { buf.write_u8_be_full_at_unchecked(offset, v) }
475 }
476
477 #[inline(always)]
478 unsafe fn write_be_full_unchecked<S: StorageMut>(buf: &mut BitBuf<S>, v: Self) -> &mut BitBuf<S> {
479 unsafe { buf.write_u8_be_full_unchecked(v) }
480 }
481
482 #[inline(always)]
483 fn try_write_be_full_at<S: StorageMut>(
484 buf: &mut BitBuf<S>,
485 offset: usize,
486 v: Self,
487 ) -> Result<&mut BitBuf<S>> {
488 buf.try_write_u8_be_full_at(offset, v)
489 }
490
491 #[inline(always)]
492 fn try_write_be_full<S: StorageMut>(buf: &mut BitBuf<S>, v: Self) -> Result<&mut BitBuf<S>> {
493 buf.try_write_u8_be_full(v)
494 }
495
496 #[inline(always)]
497 fn write_be_full_at<S: StorageMut>(
498 buf: &mut BitBuf<S>,
499 offset: usize,
500 v: Self,
501 ) -> &mut BitBuf<S> {
502 buf.write_u8_be_full_at(offset, v)
503 }
504
505 #[inline(always)]
506 fn write_be_full<S: StorageMut>(buf: &mut BitBuf<S>, v: Self) -> &mut BitBuf<S> {
507 buf.write_u8_be_full(v)
508 }
509}
510
511impl Write for u16 {
512 #[inline(always)]
513 unsafe fn write_be_aligned_full_at_unchecked<S: StorageMut>(
514 buf: &mut BitBuf<S>,
515 byte_offset: usize,
516 v: Self,
517 ) -> &mut BitBuf<S> {
518 unsafe { buf.write_u16_be_aligned_full_at_unchecked(byte_offset, v) }
519 }
520
521 #[inline(always)]
522 unsafe fn write_be_aligned_full_unchecked<S: StorageMut>(
523 buf: &mut BitBuf<S>,
524 v: Self,
525 ) -> &mut BitBuf<S> {
526 unsafe { buf.write_u16_be_aligned_full_unchecked(v) }
527 }
528
529 #[inline(always)]
530 unsafe fn write_be_full_at_unchecked<S: StorageMut>(
531 buf: &mut BitBuf<S>,
532 offset: usize,
533 v: Self,
534 ) -> &mut BitBuf<S> {
535 unsafe { buf.write_u16_be_full_at_unchecked(offset, v) }
536 }
537
538 #[inline(always)]
539 unsafe fn write_be_full_unchecked<S: StorageMut>(buf: &mut BitBuf<S>, v: Self) -> &mut BitBuf<S> {
540 unsafe { buf.write_u16_be_full_unchecked(v) }
541 }
542
543 #[inline(always)]
544 fn try_write_be_full_at<S: StorageMut>(
545 buf: &mut BitBuf<S>,
546 offset: usize,
547 v: Self,
548 ) -> Result<&mut BitBuf<S>> {
549 buf.try_write_u16_be_full_at(offset, v)
550 }
551
552 #[inline(always)]
553 fn try_write_be_full<S: StorageMut>(buf: &mut BitBuf<S>, v: Self) -> Result<&mut BitBuf<S>> {
554 buf.try_write_u16_be_full(v)
555 }
556
557 #[inline(always)]
558 fn write_be_full_at<S: StorageMut>(
559 buf: &mut BitBuf<S>,
560 offset: usize,
561 v: Self,
562 ) -> &mut BitBuf<S> {
563 buf.write_u16_be_full_at(offset, v)
564 }
565
566 #[inline(always)]
567 fn write_be_full<S: StorageMut>(buf: &mut BitBuf<S>, v: Self) -> &mut BitBuf<S> {
568 buf.write_u16_be_full(v)
569 }
570}
571
572impl<S: StorageMut> BitBuf<S> {
573 #[inline(always)]
583 pub unsafe fn write_be_aligned_full_at_unchecked<T: Write>(
584 &mut self,
585 byte_offset: usize,
586 v: T,
587 ) -> &mut Self {
588 unsafe { T::write_be_aligned_full_at_unchecked(self, byte_offset, v) }
589 }
590
591 #[inline(always)]
601 pub unsafe fn write_be_aligned_full_unchecked<T: Write>(&mut self, v: T) -> &mut Self {
602 unsafe { T::write_be_aligned_full_unchecked(self, v) }
603 }
604
605 #[inline(always)]
615 pub unsafe fn write_be_full_at_unchecked<T: Write>(&mut self, offset: usize, v: T) -> &mut Self {
616 unsafe { T::write_be_full_at_unchecked(self, offset, v) }
617 }
618
619 #[inline(always)]
629 pub unsafe fn write_be_full_unchecked<T: Write>(&mut self, v: T) -> &mut Self {
630 unsafe { T::write_be_full_unchecked(self, v) }
631 }
632
633 #[inline(always)]
639 pub fn try_write_be_full_at<T: Write>(&mut self, offset: usize, v: T) -> Result<&mut Self> {
640 T::try_write_be_full_at(self, offset, v)
641 }
642
643 #[inline(always)]
649 pub fn try_write_be_full<T: Write>(&mut self, v: T) -> Result<&mut Self> {
650 T::try_write_be_full(self, v)
651 }
652
653 #[inline(always)]
659 #[must_use]
660 pub fn write_be_full_at<T: Write>(&mut self, offset: usize, v: T) -> &mut Self {
661 T::write_be_full_at(self, offset, v)
662 }
663
664 #[inline(always)]
670 #[must_use]
671 pub fn write_be_full<T: Write>(&mut self, v: T) -> &mut Self {
672 T::write_be_full(self, v)
673 }
674}