package zmq import "core:c" import "core:os" import "core:strings" foreign import lib "system:zmq" @(default_calling_convention = "c") foreign lib { @(link_name = "zmq_ctx_new") _ctx_new :: proc() -> rawptr --- @(link_name = "zmq_ctx_term") _ctx_term :: proc(ctx: rawptr) -> c.int --- @(link_name = "zmq_socket") _socket :: proc(ctx: rawptr, type: Socket_Type) -> rawptr --- @(link_name = "zmq_close") _close :: proc(s: rawptr) -> c.int --- @(link_name = "zmq_bind") _bind :: proc(s: rawptr, addr: cstring) -> c.int --- @(link_name = "zmq_connect") _connect :: proc(s: rawptr, addr: cstring) -> c.int --- @(link_name = "zmq_send") _send :: proc(s: rawptr, buf: rawptr, len: c.size_t, flags: c.int) -> c.int --- @(link_name = "zmq_recv") _recv :: proc(s: rawptr, buf: rawptr, len: c.size_t, flags: c.int) -> c.int --- @(link_name = "zmq_errno") _errno :: proc() -> c.int --- @(link_name = "zmq_strerror") _strerror :: proc(errnum: c.int) -> cstring --- @(link_name = "zmq_version") _version :: proc(major, minor, patch: ^c.int) --- } Context :: distinct rawptr Socket :: distinct rawptr Socket_Type :: enum c.int { PAIR = 0, PUB = 1, SUB = 2, REQ = 3, REP = 4, DEALER = 5, ROUTER = 6, PULL = 7, PUSH = 8, XPUB = 9, XSUB = 10, STREAM = 11, } Flag :: enum c.int { DONTWAIT = 1, SNDMORE = 2, } Flags :: bit_set[Flag;c.int] NoBlock :: Flags{.DONTWAIT} HAUSNUMERO :: 156384712 ZMQ_Error :: enum c.int { EFSM = HAUSNUMERO + 51, ENOCOMPATPROTO = HAUSNUMERO + 52, ETERM = HAUSNUMERO + 53, EMTHREAD = HAUSNUMERO + 54, } Error :: union #shared_nil { os.Platform_Error, ZMQ_Error, } from_errno :: proc(raw: c.int) -> Error { if raw >= HAUSNUMERO { return ZMQ_Error(raw) } return os.Platform_Error(raw) } last_error :: proc() -> Error {return from_errno(_errno())} strerror :: proc(e: Error) -> string { switch v in e { case os.Platform_Error: return string(_strerror(c.int(v))) case ZMQ_Error: return string(_strerror(c.int(v))) case: return "" } } version :: proc() -> (major, minor, patch: int) { ma, mi, pa: c.int = 0, 0, 0 _version(&ma, &mi, &pa) return int(ma), int(mi), int(pa) } ctx_new :: proc() -> Context { return Context(_ctx_new()) } ctx_term :: proc(ctx: Context) -> Error { return _ctx_term(rawptr(ctx)) == 0 ? nil : last_error() } socket :: proc(ctx: Context, type: Socket_Type) -> (Socket, Error) { s := _socket(rawptr(ctx), type) if s == nil { return nil, last_error() } return Socket(s), nil } close :: proc(s: Socket) -> Error { return _close(rawptr(s)) == 0 ? nil : last_error() } bind :: proc(s: Socket, addr: string, allocator := context.temp_allocator) -> Error { c := strings.clone_to_cstring(addr, allocator) return _bind(rawptr(s), c) == 0 ? nil : last_error() } connect :: proc(s: Socket, addr: string, allocator := context.temp_allocator) -> Error { c := strings.clone_to_cstring(addr, allocator) return _connect(rawptr(s), c) == 0 ? nil : last_error() } send :: proc(s: Socket, buf: []u8, flags: Flags = Flags{}) -> (int, Error) { n := _send(rawptr(s), rawptr(&buf[0]), c.size_t(len(buf)), transmute(c.int)flags) if n < 0 { return -1, last_error() } return int(n), nil } recv :: proc(s: Socket, buf: []u8, flags: Flags = Flags{}) -> (int, Error) { n := _recv(rawptr(s), rawptr(&buf[0]), c.size_t(len(buf)), transmute(c.int)flags) if n < 0 { return -1, last_error() } return int(n), nil }