~nickbp/originz

ref: d94f181c5fbfdf0f62b40ea46d3f301f4ec681e5 originz/src/codec/character_string.rs -rw-r--r-- 1.8 KiB
d94f181cNick Parker Backport current benchmark to older code 1 year, 8 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#![deny(warnings)]

/// Implementation of `character-string`s as defined by RFC1035 section 3.3
use anyhow::{bail, Result};
use bytes::{BufMut, Bytes, BytesMut};

/// Writes a `character-string`: A length byte followed by a 0-255 byte payload.
/// Returns an error if the provided `in_buf` exceeds 255 bytes.
pub fn write(in_buf: &[u8], out_buf: &mut BytesMut, description: &str) -> Result<()> {
    if in_buf.len() > 255 {
        bail!(
            "{} length {} exceeds maximum 255",
            description,
            in_buf.len()
        );
    }
    out_buf.reserve(1 + in_buf.len());
    out_buf.put_u8(in_buf.len() as u8);
    out_buf.put_slice(&in_buf);
    return Ok(());
}

/// Reads a `character-string`: A length byte followed by a 0-255 byte payload, from the specified offset in `in_buf`.
/// This is different from `domain-name`s where each label is 0-63 bytes, and a "length" exceeding 192 indicates a pointer.
/// Returns an error if `in_buf`+`original_offset` doesn't have enough room for the length byte or the payload
pub fn read(in_buf: &[u8], original_offset: usize, description: &str) -> Result<(usize, Bytes)> {
    let mut offset = original_offset;
    let mut out = BytesMut::new();

    // First byte should be size of label (0-255)
    if in_buf.len() < offset + 1 {
        bail!("{} is empty, expected string size", description);
    }
    let label_size = in_buf[offset] as usize;
    offset += 1;
    // Fetch remaining bytes and include trailing '.'
    if in_buf.len() < offset + label_size {
        bail!(
            "{} remaining buffer length {} is shorter than required offset {} + string {}",
            description,
            in_buf.len(),
            offset,
            label_size
        );
    }
    out.extend_from_slice(&in_buf[offset..offset + label_size]);
    return Ok((1 + label_size, out.freeze()));
}