upd5
This commit is contained in:
+43
-19
@@ -2,6 +2,8 @@ module netio
|
||||
|
||||
import encoding.binary
|
||||
|
||||
struct C.sockaddr_storage {}
|
||||
|
||||
// max_unix_path_size value is used to pad the sockaddr_un struct.
|
||||
const max_unix_path_size = $if linux {
|
||||
108
|
||||
@@ -11,6 +13,13 @@ const max_unix_path_size = $if linux {
|
||||
104
|
||||
}
|
||||
|
||||
pub struct SocketAddr {
|
||||
mut:
|
||||
data &u8 = unsafe { nil }
|
||||
len int
|
||||
pos int
|
||||
}
|
||||
|
||||
// SocketAddr.ipv4 creates new AF_INET socket address.
|
||||
// addr must be set in network (big-endian) byte order.
|
||||
pub fn SocketAddr.ipv4(addr [4]u8, port u16) SocketAddr {
|
||||
@@ -54,14 +63,14 @@ pub fn SocketAddr.unix(path string) !SocketAddr {
|
||||
// the address itself, you need to do that manually. The benefit is that you can create the
|
||||
// any kind of socket address.
|
||||
//
|
||||
// SocketAddr is a "constructor" for
|
||||
// SocketAddr is a builder for
|
||||
// [sockaddr(3type)](https://www.man7.org/linux/man-pages/man3/sockaddr.3type.html) objects.
|
||||
// Use this function only if you understand what you do. You must manually write the data
|
||||
// for the desired socket address, ensuring the correct sizes of all types, the order of
|
||||
// the fields in the struct, the byte order, and the total size of the struct. The sizes
|
||||
// and byte order may vary by platform, so you'll need to keep an eye on that as well.
|
||||
// A mistake while creating an address will crash your application. So this function is
|
||||
// marked as `unsafe`.
|
||||
// Use this function only if you understand what you do. Using the `push()` method you must
|
||||
// write the data for the desired socket address, ensuring the correct sizes of all types,
|
||||
// the order of the fields in the struct, the byte order, and the total size of the struct.
|
||||
// The sizes and byte order may vary by platform, so you'll need to keep an eye on that as
|
||||
// well. A mistake while creating an address will crash your application. So this function
|
||||
// is marked as `unsafe`.
|
||||
//
|
||||
// The example below creates a sockaddr_in struct describing the loopback IPv4-address
|
||||
// 127.0.0.1 with port number 1080. Note the comment in the example. This is a fragment
|
||||
@@ -118,6 +127,9 @@ pub fn SocketAddr.new(af AddrFamily, size isize) SocketAddr {
|
||||
// SocketAddr.from_ptr creates new socket address by copying data from specified pointer.
|
||||
@[unsafe]
|
||||
pub fn SocketAddr.from_ptr(ptr voidptr, size isize) !SocketAddr {
|
||||
if isnil(ptr) {
|
||||
return error('${@METHOD}: cannot accept nil ptr')
|
||||
}
|
||||
data := unsafe { vcalloc(usize(size)) }
|
||||
unsafe {
|
||||
vmemcpy(data, ptr, size)
|
||||
@@ -128,25 +140,37 @@ pub fn SocketAddr.from_ptr(ptr voidptr, size isize) !SocketAddr {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SocketAddr {
|
||||
mut:
|
||||
data &u8 = unsafe { nil }
|
||||
len int
|
||||
pos int
|
||||
}
|
||||
|
||||
// family returns the socket address family.
|
||||
// Note: It returns 0 if socket address is nil, see also `is_empty()`.
|
||||
pub fn (a SocketAddr) family() AddrFamily {
|
||||
mut f := AddrFamily(0)
|
||||
if isnil(a.data) {
|
||||
return 0
|
||||
}
|
||||
mut f := 0
|
||||
unsafe { vmemcpy(&f, a.data, isize(2)) }
|
||||
return f
|
||||
}
|
||||
|
||||
// is_empty returns true if socket address is unspecified — the data pointer is nil or
|
||||
// data contains only zeros. Empty address cannot be used in `bind` and `connect` calls.
|
||||
pub fn (a SocketAddr) is_empty() bool {
|
||||
if isnil(a.data) {
|
||||
return true
|
||||
}
|
||||
if a.u8_array().all(|e| e == 0) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// push appends the `inp` bytes into internal data buffer.
|
||||
@[unsafe]
|
||||
pub fn (mut a SocketAddr) push(inp []u8) ! {
|
||||
if isnil(a.data) {
|
||||
return error('${@METHOD}: SocketAddr is nil')
|
||||
}
|
||||
if a.pos + inp.len > a.len {
|
||||
return error('push: data overflow')
|
||||
return error('${@METHOD}: data overflow')
|
||||
}
|
||||
mut i := 0
|
||||
for a.pos + 1 < a.len {
|
||||
@@ -180,9 +204,9 @@ pub fn (a SocketAddr) u8_array() []u8 {
|
||||
|
||||
// str returns the string representation of socket address.
|
||||
// Supported address families are AF_INET, AF_INET6, and AF_UNIX.
|
||||
// For others a string like 'SocketAddr(0x00000000)' will be returned.
|
||||
// Examples: '172.16.16.132:1080', '[fdf1:72d1:0033:0000:0000:0000:0000:0247]:25535,
|
||||
// '/run/app.sock'. See also `translate_name()`.
|
||||
// Examples: '172.16.16.132:1080', '[fdf1:72d1:0033:0000:0000:0000:0000:0247]:25535',
|
||||
// '/run/app.sock'. For others a string like 'SocketAddr(0x00000000)' will be returned.
|
||||
// See also `translate_name()`.
|
||||
pub fn (a SocketAddr) str() string {
|
||||
match a.family() {
|
||||
af_inet {
|
||||
|
||||
Reference in New Issue
Block a user