Skip to content

Commit ba66769

Browse files
committed
Scoped unsafe
1 parent bc71d38 commit ba66769

File tree

1 file changed

+54
-36
lines changed

1 file changed

+54
-36
lines changed

src/lib.rs

Lines changed: 54 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -572,20 +572,22 @@ pub fn decode_alternative<T: AsRef<[u8]>>(input: T) -> Result<u128, DecodeError>
572572

573573
// Common encoding function
574574
unsafe fn encode_impl(num: u128, digits: usize, buf: &mut [u8], encode_table: &[u8; 62]) -> usize {
575-
if let Ok(num) = TryInto::<u64>::try_into(num) {
576-
encode_impl_u64(num, digits, buf, encode_table)
577-
} else if digits > 20 {
578-
encode_impl_over_20_digits(num, digits, buf, encode_table)
579-
} else if digits == 20 {
580-
// (AAAAAAAAAA, BBBBBBBBBB)
581-
let (first_u64, second_u64) = div_base_to_10(num);
582-
// AAAAAAAAAA
583-
let first_u64 = first_u64 as u64;
584-
585-
encode_impl_20_digits(first_u64, second_u64, buf, encode_table)
586-
} else {
587-
// digits between 11 and 20 (10 digits would always fit into a u64, which we checked first)
588-
encode_impl_over_10_under_20_digits(num, digits, buf, encode_table)
575+
unsafe {
576+
if let Ok(num) = TryInto::<u64>::try_into(num) {
577+
encode_impl_u64(num, digits, buf, encode_table)
578+
} else if digits > 20 {
579+
encode_impl_over_20_digits(num, digits, buf, encode_table)
580+
} else if digits == 20 {
581+
// (AAAAAAAAAA, BBBBBBBBBB)
582+
let (first_u64, second_u64) = div_base_to_10(num);
583+
// AAAAAAAAAA
584+
let first_u64 = first_u64 as u64;
585+
586+
encode_impl_20_digits(first_u64, second_u64, buf, encode_table)
587+
} else {
588+
// digits between 11 and 20 (10 digits would always fit into a u64, which we checked first)
589+
encode_impl_over_10_under_20_digits(num, digits, buf, encode_table)
590+
}
589591
}
590592
}
591593

@@ -607,21 +609,27 @@ unsafe fn encode_impl_over_20_digits(
607609

608610
// encode the first one or two digits
609611
if digits == 21 {
610-
*buf.get_unchecked_mut(0) = *encode_table.get_unchecked(first_u64 as usize);
612+
unsafe {
613+
*buf.get_unchecked_mut(0) = *encode_table.get_unchecked(first_u64 as usize);
614+
}
611615
} else {
612616
let second_digit = first_u64 % BASE;
613617
let first_digit = first_u64 / BASE;
614-
*buf.get_unchecked_mut(1) = *encode_table.get_unchecked(second_digit as usize);
615-
*buf.get_unchecked_mut(0) = *encode_table.get_unchecked(first_digit as usize);
618+
unsafe {
619+
*buf.get_unchecked_mut(1) = *encode_table.get_unchecked(second_digit as usize);
620+
*buf.get_unchecked_mut(0) = *encode_table.get_unchecked(first_digit as usize);
621+
}
616622
}
617623

618624
// encode the last 20 digits
619-
encode_impl_20_digits(
620-
second_u64,
621-
third_u64,
622-
&mut buf[(digits - 20)..],
623-
encode_table,
624-
);
625+
unsafe {
626+
encode_impl_20_digits(
627+
second_u64,
628+
third_u64,
629+
&mut buf[(digits - 20)..],
630+
encode_table,
631+
);
632+
}
625633

626634
digits
627635
}
@@ -650,8 +658,10 @@ unsafe fn encode_impl_20_digits(
650658
let remainder = (*num - (BASE as u32) * quotient) as usize;
651659
*num = quotient;
652660

653-
*buf.get_unchecked_mut(starting_write_idx - i - 1) =
654-
*encode_table.get_unchecked(remainder)
661+
unsafe {
662+
*buf.get_unchecked_mut(starting_write_idx - i - 1) =
663+
*encode_table.get_unchecked(remainder)
664+
}
655665
});
656666
}
657667

@@ -678,7 +688,9 @@ unsafe fn encode_impl_over_10_under_20_digits(
678688
let remainder = num % BASE;
679689
num /= BASE;
680690

681-
*buf.get_unchecked_mut(write_idx) = *encode_table.get_unchecked(remainder as usize);
691+
unsafe {
692+
*buf.get_unchecked_mut(write_idx) = *encode_table.get_unchecked(remainder as usize);
693+
}
682694

683695
digit_index = digit_index.wrapping_add(1);
684696
if digit_index == 10 {
@@ -704,14 +716,16 @@ unsafe fn encode_impl_u64(
704716
// BBBBBBBBBB
705717
let second_u64 = num % (BASE_TO_10 as u64);
706718

707-
*buf.get_unchecked_mut(0) = *encode_table.get_unchecked(first_u64 as usize);
719+
unsafe {
720+
*buf.get_unchecked_mut(0) = *encode_table.get_unchecked(first_u64 as usize);
708721

709-
encode_impl_u64_10_digits(second_u64, &mut buf[1..], encode_table);
722+
encode_impl_u64_10_digits(second_u64, &mut buf[1..], encode_table);
723+
}
710724
digits
711725
} else if digits == 10 {
712-
encode_impl_u64_10_digits(num, buf, encode_table)
726+
unsafe { encode_impl_u64_10_digits(num, buf, encode_table) }
713727
} else {
714-
encode_impl_u64_under_10_digits(num, digits, buf, encode_table)
728+
unsafe { encode_impl_u64_under_10_digits(num, digits, buf, encode_table) }
715729
}
716730
}
717731

@@ -730,7 +744,9 @@ unsafe fn encode_impl_u64_under_10_digits(
730744
let remainder = num % BASE;
731745
num /= BASE;
732746

733-
*buf.get_unchecked_mut(write_idx) = *encode_table.get_unchecked(remainder as usize);
747+
unsafe {
748+
*buf.get_unchecked_mut(write_idx) = *encode_table.get_unchecked(remainder as usize);
749+
}
734750

735751
digit_index = digit_index.wrapping_add(1);
736752
}
@@ -754,8 +770,10 @@ unsafe fn encode_impl_u64_10_digits(num: u64, buf: &mut [u8], encode_table: &[u8
754770
let remainder = (*num - (BASE as u32) * quotient) as usize;
755771
*num = quotient;
756772

757-
*buf.get_unchecked_mut(starting_write_idx - i - 1) =
758-
*encode_table.get_unchecked(remainder)
773+
unsafe {
774+
*buf.get_unchecked_mut(starting_write_idx - i - 1) =
775+
*encode_table.get_unchecked(remainder)
776+
}
759777
});
760778
}
761779

@@ -790,11 +808,11 @@ const fn mulh(x: u128, y: u128) -> u128 {
790808
}
791809

792810
unsafe fn _encode_buf(num: u128, digits: usize, buf: &mut [u8]) -> usize {
793-
encode_impl(num, digits, buf, &STANDARD_TABLES.encode)
811+
unsafe { encode_impl(num, digits, buf, &STANDARD_TABLES.encode) }
794812
}
795813

796814
unsafe fn _encode_alternative_buf(num: u128, digits: usize, buf: &mut [u8]) -> usize {
797-
encode_impl(num, digits, buf, &ALTERNATIVE_TABLES.encode)
815+
unsafe { encode_impl(num, digits, buf, &ALTERNATIVE_TABLES.encode) }
798816
}
799817

800818
#[cfg(feature = "alloc")]
@@ -944,7 +962,7 @@ mod tests {
944962
mod quickcheck_tests {
945963
use super::*;
946964
use alloc::string::ToString;
947-
use quickcheck::{quickcheck, TestResult};
965+
use quickcheck::{TestResult, quickcheck};
948966
quickcheck! {
949967
fn encode_decode(num: u128) -> bool {
950968
decode(encode(num)) == Ok(num)

0 commit comments

Comments
 (0)