feature. See also
. The project being documented here (as the example) is the Zig library itself.
Threaded.lookupHostsReader
fn lookupHostsReader(
t: *Threaded,
host_name: HostName,
resolved: *Io.Queue(HostName.LookupResult),
options: HostName.LookupOptions,
reader: *Io.Reader,
) error
File
Code
fn lookupHostsReader(
t: *Threaded,
host_name: HostName,
resolved: *Io.Queue(HostName.LookupResult),
options: HostName.LookupOptions,
reader: *Io.Reader,
) error{ ReadFailed, Canceled, UnknownHostName, Closed }!void {
const t_io = io(t);
var addresses_len: usize = 0;
var canonical_name: ?HostName = null;
while (true) {
const line = reader.takeDelimiterExclusive('\n') catch |err| switch (err) {
error.StreamTooLong => {
_ = reader.discardDelimiterInclusive('\n') catch |er| switch (er) {
error.EndOfStream => break,
error.ReadFailed => |e| return e,
};
continue;
},
error.ReadFailed => |e| return e,
error.EndOfStream => break,
};
reader.toss(@min(1, reader.bufferedLen()));
var split_it = std.mem.splitScalar(u8, if (is_windows and std.mem.endsWith(u8, line, "\r"))
line[0 .. line.len - 1]
else
line, '#');
const no_comment_line = split_it.first();
var line_it = std.mem.tokenizeAny(u8, no_comment_line, " \t");
const ip_text = line_it.next() orelse continue;
var first_name_text: ?[]const u8 = null;
while (line_it.next()) |name_text| {
if (std.ascii.eqlIgnoreCase(name_text, host_name.bytes)) {
if (first_name_text == null) first_name_text = name_text;
break;
}
} else continue;
if (canonical_name == null) {
if (options.canonical_name_buffer) |buf| {
if (HostName.init(first_name_text.?)) |name_text| {
if (name_text.bytes.len <= buf.len) {
const canonical_name_dest = buf[0..name_text.bytes.len];
@memcpy(canonical_name_dest, name_text.bytes);
canonical_name = .{ .bytes = canonical_name_dest };
}
} else |_| {}
}
}
if (options.family != .ip6) {
if (IpAddress.parseIp4(ip_text, options.port)) |addr| {
try resolved.putOne(t_io, .{ .address = addr });
addresses_len += 1;
} else |_| {}
}
if (options.family != .ip4) {
if (IpAddress.parseIp6(ip_text, options.port)) |addr| {
try resolved.putOne(t_io, .{ .address = addr });
addresses_len += 1;
} else |_| {}
}
}
if (canonical_name) |canon_name| try resolved.putOne(t_io, .{ .canonical_name = canon_name });
if (addresses_len == 0) return error.UnknownHostName;
}