Zig 0.17.0-dev (Split by item)

This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.

expand

Decompresses a DNS name.

Returns number of bytes consumed from packet starting at i, along with the expanded HostName.

Asserts buffer is has length at least max_len.

HostName.expand
pub fn expand(noalias packet: []const u8, start_i: usize, noalias dest_buffer: []u8) ExpandError!struct

File

lib/std/Io/net/HostName.zig:191

Code

pub fn expand(noalias packet: []const u8, start_i: usize, noalias dest_buffer: []u8) ExpandError!struct { usize, HostName } {
    const dest = dest_buffer[0..max_len];

    var i = start_i;
    var dest_i: usize = 0;
    var len: ?usize = null;

    // Detect reference loop using an iteration counter.
    for (0..packet.len / 2) |_| {
        if (i >= packet.len) return error.InvalidDnsPacket;

        const c = packet[i];
        if ((c & 0xc0) != 0) {
            if (i + 1 >= packet.len) return error.InvalidDnsPacket;
            const j: usize = (@as(usize, c & 0x3F) << 8) | packet[i + 1];
            if (j >= packet.len) return error.InvalidDnsPacket;
            if (len == null) len = (i + 2) - start_i;
            i = j;
        } else if (c != 0) {
            if (dest_i != 0) {
                dest[dest_i] = '.';
                dest_i += 1;
            }
            const label_len: usize = c;
            if (i + 1 + label_len > packet.len) return error.InvalidDnsPacket;
            if (dest_i + label_len + 1 > dest.len) return error.InvalidDnsPacket;
            @memcpy(dest[dest_i..][0..label_len], packet[i + 1 ..][0..label_len]);
            dest_i += label_len;
            i += 1 + label_len;
        } else {
            return .{
                len orelse i - start_i + 1,
                try .init(dest[0..dest_i]),
            };
        }
    }
    return error.InvalidDnsPacket;
}