leyline-http 0.1.1

HTTP client that mimics browsers on the wire
Documentation
pub fn encode(value: usize, prefix_bits: u8, prefix_pattern: u8, dst: &mut Vec<u8>) {
    let max_prefix = (1 << prefix_bits) - 1;

    if value < max_prefix {
        dst.push(prefix_pattern | value as u8);
    } else {
        dst.push(prefix_pattern | max_prefix as u8);
        let mut remaining = value - max_prefix;
        while remaining >= 128 {
            dst.push((remaining & 0x7F) as u8 | 0x80);
            remaining >>= 7;
        }
        dst.push(remaining as u8);
    }
}

pub fn decode(
    first_byte: u8,
    prefix_bits: u8,
    src: &[u8],
    pos: usize,
) -> Result<(usize, usize), &'static str> {
    let max_prefix = (1usize << prefix_bits) - 1;
    let value = (first_byte & max_prefix as u8) as usize;

    if value < max_prefix {
        return Ok((value, 0));
    }

    let mut result = max_prefix;
    let mut shift = 0u32;
    let mut i = pos;

    loop {
        if i >= src.len() {
            return Err("unexpected end of integer");
        }
        let byte = src[i];
        i += 1;

        if shift > 28 {
            return Err("integer overflow");
        }

        result += ((byte & 0x7F) as usize) << shift;
        shift += 7;

        if result > 0x7FFF_FFFF {
            return Err("integer overflow");
        }

        if byte & 0x80 == 0 {
            break;
        }
    }

    Ok((result, i - pos))
}

#[cfg(test)]
mod tests;