extern struct Ip4Address [src]

Fields

sa: posix.sockaddr.in

Members

Source

pub const Ip4Address = extern struct { sa: posix.sockaddr.in, pub fn parse(buf: []const u8, port: u16) IPv4ParseError!Ip4Address { var result: Ip4Address = .{ .sa = .{ .port = mem.nativeToBig(u16, port), .addr = undefined, }, }; const out_ptr = mem.asBytes(&result.sa.addr); var x: u8 = 0; var index: u8 = 0; var saw_any_digits = false; var has_zero_prefix = false; for (buf) |c| { if (c == '.') { if (!saw_any_digits) { return error.InvalidCharacter; } if (index == 3) { return error.InvalidEnd; } out_ptr[index] = x; index += 1; x = 0; saw_any_digits = false; has_zero_prefix = false; } else if (c >= '0' and c <= '9') { if (c == '0' and !saw_any_digits) { has_zero_prefix = true; } else if (has_zero_prefix) { return error.NonCanonical; } saw_any_digits = true; x = try std.math.mul(u8, x, 10); x = try std.math.add(u8, x, c - '0'); } else { return error.InvalidCharacter; } } if (index == 3 and saw_any_digits) { out_ptr[index] = x; return result; } return error.Incomplete; } pub fn resolveIp(name: []const u8, port: u16) !Ip4Address { if (parse(name, port)) |ip4| return ip4 else |err| switch (err) { error.Overflow, error.InvalidEnd, error.InvalidCharacter, error.Incomplete, error.NonCanonical, => {}, } return error.InvalidIPAddressFormat; } pub fn init(addr: [4]u8, port: u16) Ip4Address { return Ip4Address{ .sa = posix.sockaddr.in{ .port = mem.nativeToBig(u16, port), .addr = @as(*align(1) const u32, @ptrCast(&addr)).*, }, }; } /// Returns the port in native endian. /// Asserts that the address is ip4 or ip6. pub fn getPort(self: Ip4Address) u16 { return mem.bigToNative(u16, self.sa.port); } /// `port` is native-endian. /// Asserts that the address is ip4 or ip6. pub fn setPort(self: *Ip4Address, port: u16) void { self.sa.port = mem.nativeToBig(u16, port); } pub fn format( self: Ip4Address, comptime fmt: []const u8, options: std.fmt.FormatOptions, out_stream: anytype, ) !void { if (fmt.len != 0) std.fmt.invalidFmtError(fmt, self); _ = options; const bytes = @as(*const [4]u8, @ptrCast(&self.sa.addr)); try std.fmt.format(out_stream, "{}.{}.{}.{}:{}", .{ bytes[0], bytes[1], bytes[2], bytes[3], self.getPort(), }); } pub fn getOsSockLen(self: Ip4Address) posix.socklen_t { _ = self; return @sizeOf(posix.sockaddr.in); } }