MCPcopy Create free account
hub / github.com/SoftbearStudios/bitcode / unpack_bytes_less_than

Function unpack_bytes_less_than

src/pack.rs:210–348  ·  view source on GitHub ↗

Like `unpack_bytes` but all values are less than `N` so it can avoid encoding the packing. Bytes returned by this function are guaranteed less than `N`. If `HISTOGRAM` is set to `N` it also returns a histogram of the output bytes. This is because the histogram can be calculated much faster when operating on the packed bytes. If `HISTOGRAM` is set to `0` it only checks variants < `N` and doesn't

(
    input: &mut &'a [u8],
    length: usize,
    out: &mut CowSlice<'a, u8>,
)

Source from the content-addressed store, hash-verified

208///
209/// If `HISTOGRAM` is set to `0` it only checks variants < `N` and doesn't calculate a histogram.
210pub fn unpack_bytes_less_than<'a, const N: usize, const HISTOGRAM: usize>(
211 input: &mut &'a [u8],
212 length: usize,
213 out: &mut CowSlice<'a, u8>,
214) -> Result<[usize; HISTOGRAM]> {
215 assert!(HISTOGRAM == N || HISTOGRAM == 0);
216
217 /// Checks that `unpacked` bytes are less than `N`. All of `unpacked` is assumed to be < `FACTOR`.
218 /// `HISTOGRAM` must be 0.
219 fn check_less_than<const N: usize, const HISTOGRAM: usize, const FACTOR: usize>(
220 unpacked: &[u8],
221 ) -> Result<[usize; HISTOGRAM]> {
222 assert!(FACTOR >= N);
223 debug_assert!(unpacked.iter().all(|&v| (v as usize) < FACTOR));
224 if FACTOR > N && unpacked.iter().copied().max().unwrap_or(0) as usize >= N {
225 return invalid_packing();
226 }
227 Ok(std::array::from_fn(|_| unreachable!("HISTOGRAM not 0")))
228 }
229
230 /// Returns `Ok(histogram)` if buckets after `OUT` are 0.
231 fn check_histogram<const IN: usize, const OUT: usize>(
232 histogram: [usize; IN],
233 ) -> Result<[usize; OUT]> {
234 let (histogram, remaining) = histogram.split_at(OUT);
235 if remaining.iter().copied().sum::<usize>() != 0 {
236 return invalid_packing();
237 }
238 Ok(*<&[usize; OUT]>::try_from(histogram).unwrap())
239 }
240
241 let p = Packing::new(N.saturating_sub(1) as u8);
242 if p == Packing::_256 {
243 let bytes = consume_bytes(input, length)?;
244 out.set_borrowed(bytes);
245 return if HISTOGRAM == 0 {
246 check_less_than::<N, HISTOGRAM, 256>(bytes)
247 } else {
248 check_histogram(crate::histogram::histogram(bytes))
249 };
250 }
251
252 /// `FACTOR_POW_DIVISOR == (FACTOR as usize).pow(factor_to_divisor::<FACTOR>() as u32)` but as a constant.
253 fn unpack_arithmetic_less_than<
254 const N: usize,
255 const HISTOGRAM: usize,
256 const FACTOR: usize,
257 const FACTOR_POW_DIVISOR: usize,
258 >(
259 input: &mut &[u8],
260 length: usize,
261 out: &mut Vec<u8>,
262 ) -> Result<[usize; HISTOGRAM]> {
263 assert!(HISTOGRAM == N || HISTOGRAM == 0);
264 assert!(FACTOR >= 2 && FACTOR >= N);
265 let divisor = factor_to_divisor::<FACTOR>();
266 assert_eq!(FACTOR.pow(divisor as u32), FACTOR_POW_DIVISOR);
267

Callers

nothing calls this directly

Calls 5

consume_bytesFunction · 0.85
check_histogramFunction · 0.85
histogramFunction · 0.85
set_borrowedMethod · 0.80
set_ownedMethod · 0.80

Tested by

no test coverage detected