Repository: alecthomas/gozmq Branch: master Commit: d1b01a2df6b2 Files: 33 Total size: 161.8 KB Directory structure: gitextract_1mu0pk_t/ ├── .gitignore ├── .godocdown.md ├── .todo2 ├── .travis.yml ├── AUTHORS ├── README.md ├── examples/ │ ├── client/ │ │ └── client.go │ └── server/ │ └── server.go ├── gozmqfix/ │ ├── LICENSE │ ├── README.md │ ├── fix.go │ ├── main.go │ ├── main_test.go │ ├── zmqstruct.go │ └── zmqstruct_test.go ├── gozmqgen/ │ ├── README.md │ ├── header.txt │ ├── main.go │ ├── main_test.go │ └── template.txt ├── zmq.go ├── zmq_2_2.go ├── zmq_2_x.go ├── zmq_3_x.go ├── zmq_3_x_test.go ├── zmq_4_x.go ├── zmq_test.go ├── zmq_unix.go ├── zmq_windows.go ├── zmqgen_2_1.go ├── zmqgen_2_2.go ├── zmqgen_3_2.go └── zmqgen_4_0.go ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ *.o *.a *.[568vq] [568vq].out *.cgo1.go *.cgo2.c _cgo_defun.c _cgo_gotypes.go _cgo_export.* *.so _obj _test _testmain.go *.exe .cache ================================================ FILE: .godocdown.md ================================================ # Go (golang) Bindings for 0mq (zmq, zeromq) [![Build Status](https://travis-ci.org/alecthomas/gozmq.png)](https://travis-ci.org/alecthomas/gozmq) This package implements [Go](http://golang.org) (golang) bindings for the [0mq](http://zeromq.org) C API. It is licensed under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0). GoZMQ [does not](#zero-copy) support zero-copy. A full list of examples is included in the [zguide](https://github.com/imatix/zguide/tree/master/examples/Go). Note that this is *not* the same as [this implementation](http://github.com/boggle/gozero) or [this implementation](http://code.google.com/p/gozmq/). ## Upgrading GoZMQ has made some public changes that will break old code. Fortunately, we've also written a tool based on `go fix` that will upgrade your code for you! Here's how to run it over your source (after making a backup of course): go get github.com/alecthomas/gozmq/gozmqfix cd $YOUR_SOURCE_DIR gozmqfix . ## Installing GoZMQ currently supports ZMQ 2.1.x, 2.2.x and *basic* support for 3.x. Following are instructions on how to compile against these versions. Install gozmq with: go get github.com/alecthomas/gozmq This implementation works currently against:: ZeroMQ 2.2.x ### ZeroMQ 2.1.x If you're using ZeroMQ 2.1.x, install with: go get -tags zmq_2_1 github.com/alecthomas/gozmq ### ZeroMQ 3.x There is *basic* support for ZeroMQ 3.x. Install with: go get -tags zmq_3_x github.com/alecthomas/gozmq ### Troubleshooting #### Go can't find ZMQ If the go tool can't find zmq and you know it is installed, you may need to override the C compiler/linker flags. eg. If you installed zmq into `/opt/zmq` you might try: CGO_CFLAGS=-I/opt/zmq/include CGO_LDFLAGS=-L/opt/zmq/lib \ go get github.com/alecthomas/gozmq #### Mismatch in version of ZMQ If you get errors like this with 'go get' or 'go build': 1: error: 'ZMQ_FOO' undeclared (first use in this function) There are two possibilities: 1. Your version of zmq is *very* old. In this case you will need to download and build zmq yourself. 2. You are building gozmq against the wrong version of zmq. See the [installation](#installation) instructions for details on how to target the correct version. ## Differences from the C API The API implemented by this package does not attempt to expose `zmq_msg_t` at all. Instead, `Recv()` and `Send()` both operate on byte slices, allocating and freeing the memory automatically. Currently this requires copying to/from C malloced memory, but a future implementation may be able to avoid this to a certain extent. All major features are supported: contexts, sockets, devices, and polls. ## Example Here are direct translations of some of the examples from [this blog post](http://nichol.as/zeromq-an-introduction). A simple echo server: ```go package main import zmq "github.com/alecthomas/gozmq" func main() { context, _ := zmq.NewContext() socket, _ := context.NewSocket(zmq.REP) socket.Bind("tcp://127.0.0.1:5000") socket.Bind("tcp://127.0.0.1:6000") for { msg, _ := socket.Recv(0) println("Got", string(msg)) socket.Send(msg, 0) } } ``` A simple client for the above server: ```go package main import "fmt" import zmq "github.com/alecthomas/gozmq" func main() { context, _ := zmq.NewContext() socket, _ := context.NewSocket(zmq.REQ) socket.Connect("tcp://127.0.0.1:5000") socket.Connect("tcp://127.0.0.1:6000") for i := 0; i < 10; i++ { msg := fmt.Sprintf("msg %d", i) socket.Send([]byte(msg), 0) println("Sending", msg) socket.Recv(0) } } ``` ## Caveats ### Zero-copy GoZMQ does not support zero-copy. GoZMQ does not attempt to expose `zmq_msg_t` at all. Instead, `Recv()` and `Send()` both operate on byte slices, allocating and freeing the memory automatically. Currently this requires copying to/from C malloced memory, but a future implementation may be able to avoid this to a certain extent. ### Memory management It's not entirely clear from the 0mq documentation how memory for `zmq_msg_t` and packet data is managed once 0mq takes ownership. After digging into the source a little, this package operates under the following (educated) assumptions: - References to `zmq_msg_t` structures are not held by the C API beyond the duration of any function call. - Packet data is reference counted internally by the C API. The count is incremented when a packet is queued for delivery to a destination (the inference being that for delivery to N destinations, the reference count will be incremented N times) and decremented once the packet has either been delivered or errored. {{ .EmitUsage }} *(generated from .[godocdown](https://github.com/robertkrimen/godocdown).md with `godocdown github.com/alecthomas/gozmq > README.md`)* ================================================ FILE: .todo2 ================================================ { "title": "GoZMQ - ZMQ bindings for Go", "tasks": [] } ================================================ FILE: .travis.yml ================================================ before_install: - sudo apt-get install libzmq3-dev language: go go: 1.1.1 install: go get -tags zmq_3_x -d -v ./... && go build -tags zmq_3_x -v ./... script: go test -v -tags zmq_3_x ./... ================================================ FILE: AUTHORS ================================================ The GoZmq package was originally written by Alec Thomas . Thanks to the following frequent contributors: @mcgoo Jim McGrath (https://github.com/mcgoo) @jtacoma Joshua Tacoma (https://github.com/jtacoma) @jhawk28 And many others. ================================================ FILE: README.md ================================================ # _NOTE:_ These gozmq bindings are in maintenance mode. Only critical bugs will be fixed. Henceforth I would suggest using [@pebbe's](https://github.com/pebbe) actively maintained bindings for [zmq2](https://github.com/pebbe/zmq2), [zmq3](https://github.com/pebbe/zmq3) and [zmq4](https://github.com/pebbe/zmq4). ## Go (golang) Bindings for 0mq (zmq, zeromq) [![Build Status](https://travis-ci.org/alecthomas/gozmq.png)](https://travis-ci.org/alecthomas/gozmq) This package implements [Go](http://golang.org) (golang) bindings for the [0mq](http://zeromq.org) C API. GoZMQ [does not](#zero-copy) support zero-copy. A full list of examples is included in the [zguide](https://github.com/imatix/zguide/tree/master/examples/Go). Note that this is *not* the same as [this implementation](http://github.com/boggle/gozero) or [this implementation](http://code.google.com/p/gozmq/). ## Upgrading GoZMQ has made some public changes that will break old code. Fortunately, we've also written a tool based on `go fix` that will upgrade your code for you! Here's how to run it over your source (after making a backup of course): go get github.com/alecthomas/gozmq/gozmqfix cd $YOUR_SOURCE_DIR gozmqfix . ## Installing GoZMQ currently supports ZMQ 2.1.x, 2.2.x, 3.x and 4.x. Following are instructions on how to compile against these versions. For ZeroMQ 2.2.x install with: go get github.com/alecthomas/gozmq For 2.1.x install with: go get -tags zmq_2_1 github.com/alecthomas/gozmq For 3.x install with: go get -tags zmq_3_x github.com/alecthomas/gozmq For 4.x install with: go get -tags zmq_4_x github.com/alecthomas/gozmq ### Troubleshooting #### Go can't find ZMQ If the go tool can't find zmq and you know it is installed, you may need to override the C compiler/linker flags. eg. If you installed zmq into `/opt/zmq` you might try: CGO_CFLAGS=-I/opt/zmq/include CGO_LDFLAGS=-L/opt/zmq/lib \ go get github.com/alecthomas/gozmq #### Mismatch in version of ZMQ If you get errors like this with 'go get' or 'go build': 1: error: 'ZMQ_FOO' undeclared (first use in this function) There are two possibilities: 1. Your version of zmq is *very* old. In this case you will need to download and build zmq yourself. 2. You are building gozmq against the wrong version of zmq. See the [installation](#installation) instructions for details on how to target the correct version. ## Differences from the C API The API implemented by this package does not attempt to expose `zmq_msg_t` at all. Instead, `Recv()` and `Send()` both operate on byte slices, allocating and freeing the memory automatically. Currently this requires copying to/from C malloced memory, but a future implementation may be able to avoid this to a certain extent. All major features are supported: contexts, sockets, devices, and polls. ## Example Here are direct translations of some of the examples from [this blog post](http://nichol.as/zeromq-an-introduction). A simple echo server: ```go package main import zmq "github.com/alecthomas/gozmq" func main() { context, _ := zmq.NewContext() socket, _ := context.NewSocket(zmq.REP) socket.Bind("tcp://127.0.0.1:5000") socket.Bind("tcp://127.0.0.1:6000") for { msg, _ := socket.Recv(0) println("Got", string(msg)) socket.Send(msg, 0) } } ``` A simple client for the above server: ```go package main import "fmt" import zmq "github.com/alecthomas/gozmq" func main() { context, _ := zmq.NewContext() socket, _ := context.NewSocket(zmq.REQ) socket.Connect("tcp://127.0.0.1:5000") socket.Connect("tcp://127.0.0.1:6000") for i := 0; i < 10; i++ { msg := fmt.Sprintf("msg %d", i) socket.Send([]byte(msg), 0) println("Sending", msg) socket.Recv(0) } } ``` ## Caveats ### Zero-copy GoZMQ does not support zero-copy. GoZMQ does not attempt to expose `zmq_msg_t` at all. Instead, `Recv()` and `Send()` both operate on byte slices, allocating and freeing the memory automatically. Currently this requires copying to/from C malloced memory, but a future implementation may be able to avoid this to a certain extent. ### Memory management It's not entirely clear from the 0mq documentation how memory for `zmq_msg_t` and packet data is managed once 0mq takes ownership. After digging into the source a little, this package operates under the following (educated) assumptions: - References to `zmq_msg_t` structures are not held by the C API beyond the duration of any function call. - Packet data is reference counted internally by the C API. The count is incremented when a packet is queued for delivery to a destination (the inference being that for delivery to N destinations, the reference count will be incremented N times) and decremented once the packet has either been delivered or errored. ## Usage ```go const ( // NewSocket types PAIR = SocketType(C.ZMQ_PAIR) PUB = SocketType(C.ZMQ_PUB) SUB = SocketType(C.ZMQ_SUB) REQ = SocketType(C.ZMQ_REQ) REP = SocketType(C.ZMQ_REP) DEALER = SocketType(C.ZMQ_DEALER) ROUTER = SocketType(C.ZMQ_ROUTER) PULL = SocketType(C.ZMQ_PULL) PUSH = SocketType(C.ZMQ_PUSH) XPUB = SocketType(C.ZMQ_XPUB) XSUB = SocketType(C.ZMQ_XSUB) // Deprecated aliases XREQ = DEALER XREP = ROUTER UPSTREAM = PULL DOWNSTREAM = PUSH // NewSocket options AFFINITY = UInt64SocketOption(C.ZMQ_AFFINITY) IDENTITY = StringSocketOption(C.ZMQ_IDENTITY) SUBSCRIBE = StringSocketOption(C.ZMQ_SUBSCRIBE) UNSUBSCRIBE = StringSocketOption(C.ZMQ_UNSUBSCRIBE) RATE = Int64SocketOption(C.ZMQ_RATE) RECOVERY_IVL = Int64SocketOption(C.ZMQ_RECOVERY_IVL) SNDBUF = UInt64SocketOption(C.ZMQ_SNDBUF) RCVBUF = UInt64SocketOption(C.ZMQ_RCVBUF) FD = Int64SocketOption(C.ZMQ_FD) EVENTS = UInt64SocketOption(C.ZMQ_EVENTS) TYPE = UInt64SocketOption(C.ZMQ_TYPE) LINGER = IntSocketOption(C.ZMQ_LINGER) RECONNECT_IVL = IntSocketOption(C.ZMQ_RECONNECT_IVL) RECONNECT_IVL_MAX = IntSocketOption(C.ZMQ_RECONNECT_IVL_MAX) BACKLOG = IntSocketOption(C.ZMQ_BACKLOG) // Send/recv options SNDMORE = SendRecvOption(C.ZMQ_SNDMORE) ) ``` ```go const ( POLLIN = PollEvents(C.ZMQ_POLLIN) POLLOUT = PollEvents(C.ZMQ_POLLOUT) POLLERR = PollEvents(C.ZMQ_POLLERR) ) ``` ```go const ( STREAMER = DeviceType(C.ZMQ_STREAMER) FORWARDER = DeviceType(C.ZMQ_FORWARDER) QUEUE = DeviceType(C.ZMQ_QUEUE) ) ``` ```go const ( RCVTIMEO = IntSocketOption(C.ZMQ_RCVTIMEO) SNDTIMEO = IntSocketOption(C.ZMQ_SNDTIMEO) ) ``` ```go const ( RCVMORE = UInt64SocketOption(C.ZMQ_RCVMORE) RECOVERY_IVL_MSEC = Int64SocketOption(C.ZMQ_RECOVERY_IVL_MSEC) SWAP = Int64SocketOption(C.ZMQ_SWAP) MCAST_LOOP = Int64SocketOption(C.ZMQ_MCAST_LOOP) HWM = UInt64SocketOption(C.ZMQ_HWM) NOBLOCK = SendRecvOption(C.ZMQ_NOBLOCK) // Forwards-compatible aliases: DONTWAIT = NOBLOCK ) ``` ```go const ( RCVMORE = IntSocketOption(C.ZMQ_RCVMORE) SNDHWM = IntSocketOption(C.ZMQ_SNDHWM) RCVHWM = IntSocketOption(C.ZMQ_RCVHWM) // TODO Not documented in the man page... //LAST_ENDPOINT = UInt64SocketOption(C.ZMQ_LAST_ENDPOINT) FAIL_UNROUTABLE = BoolSocketOption(C.ZMQ_FAIL_UNROUTABLE) TCP_KEEPALIVE = IntSocketOption(C.ZMQ_TCP_KEEPALIVE) TCP_KEEPALIVE_CNT = IntSocketOption(C.ZMQ_TCP_KEEPALIVE_CNT) TCP_KEEPALIVE_IDLE = IntSocketOption(C.ZMQ_TCP_KEEPALIVE_IDLE) TCP_KEEPALIVE_INTVL = IntSocketOption(C.ZMQ_TCP_KEEPALIVE_INTVL) TCP_ACCEPT_FILTER = StringSocketOption(C.ZMQ_TCP_ACCEPT_FILTER) // Message options MORE = MessageOption(C.ZMQ_MORE) // Send/recv options DONTWAIT = SendRecvOption(C.ZMQ_DONTWAIT) // Deprecated aliases NOBLOCK = DONTWAIT ) ``` ```go var ( // Additional ZMQ errors ENOTSOCK error = zmqErrno(C.ENOTSOCK) EFSM error = zmqErrno(C.EFSM) EINVAL error = zmqErrno(C.EINVAL) ENOCOMPATPROTO error = zmqErrno(C.ENOCOMPATPROTO) ETERM error = zmqErrno(C.ETERM) EMTHREAD error = zmqErrno(C.EMTHREAD) ) ``` #### func Device ```go func Device(t DeviceType, in, out *Socket) error ``` run a zmq_device passing messages between in and out #### func Poll ```go func Poll(items []PollItem, timeout time.Duration) (count int, err error) ``` Poll ZmqSockets and file descriptors for I/O readiness. Timeout is in time.Duration. The smallest possible timeout is time.Millisecond for ZeroMQ version 3 and above, and time.Microsecond for earlier versions. #### func Proxy ```go func Proxy(in, out, capture *Socket) error ``` run a zmq_proxy with in, out and capture sockets #### func Version ```go func Version() (int, int, int) ``` void zmq_version (int *major, int *minor, int *patch); #### type BoolSocketOption ```go type BoolSocketOption int ``` #### type Context ```go type Context struct { } ``` * A context handles socket creation and asynchronous message delivery. * There should generally be one context per application. #### func NewContext ```go func NewContext() (*Context, error) ``` Create a new context. #### func (*Context) Close ```go func (c *Context) Close() ``` #### func (*Context) IOThreads ```go func (c *Context) IOThreads() (int, error) ``` Get a context option. #### func (*Context) MaxSockets ```go func (c *Context) MaxSockets() (int, error) ``` #### func (*Context) NewSocket ```go func (c *Context) NewSocket(t SocketType) (*Socket, error) ``` Create a new socket. void *zmq_socket (void *context, int type); #### func (*Context) SetIOThreads ```go func (c *Context) SetIOThreads(value int) error ``` Set a context option. #### func (*Context) SetMaxSockets ```go func (c *Context) SetMaxSockets(value int) error ``` #### type DeviceType ```go type DeviceType int ``` #### type Int64SocketOption ```go type Int64SocketOption int ``` #### type IntSocketOption ```go type IntSocketOption int ``` #### type MessageOption ```go type MessageOption int ``` #### type PollEvents ```go type PollEvents C.short ``` #### type PollItem ```go type PollItem struct { Socket *Socket // socket to poll for events on Fd ZmqOsSocketType // fd to poll for events on as returned from os.File.Fd() Events PollEvents // event set to poll for REvents PollEvents // events that were present } ``` Item to poll for read/write events on, either a *Socket or a file descriptor #### type PollItems ```go type PollItems []PollItem ``` a set of items to poll for events on #### type SendRecvOption ```go type SendRecvOption int ``` #### type Socket ```go type Socket struct { } ``` #### func (*Socket) Affinity ```go func (s *Socket) Affinity() (uint64, error) ``` ZMQ_AFFINITY: Retrieve I/O thread affinity. See: http://api.zeromq.org/2.1:zmq-getsockopt#toc7 #### func (*Socket) Backlog ```go func (s *Socket) Backlog() (int, error) ``` ZMQ_BACKLOG: Retrieve maximum length of the queue of outstanding connections. See: http://api.zeromq.org/2.1:zmq-getsockopt#toc18 #### func (*Socket) Bind ```go func (s *Socket) Bind(address string) error ``` Bind the socket to a listening address. int zmq_bind (void *s, const char *addr); #### func (*Socket) Close ```go func (s *Socket) Close() error ``` Shutdown the socket. int zmq_close (void *s); #### func (*Socket) Connect ```go func (s *Socket) Connect(address string) error ``` Connect the socket to an address. int zmq_connect (void *s, const char *addr); #### func (*Socket) Events ```go func (s *Socket) Events() (uint64, error) ``` ZMQ_EVENTS: Retrieve socket event state. See: http://api.zeromq.org/2.1:zmq-getsockopt#toc20 #### func (*Socket) GetSockOptBool ```go func (s *Socket) GetSockOptBool(option BoolSocketOption) (value bool, err error) ``` #### func (*Socket) GetSockOptInt ```go func (s *Socket) GetSockOptInt(option IntSocketOption) (value int, err error) ``` Get an int option from the socket. int zmq_getsockopt (void *s, int option, void *optval, size_t *optvallen); #### func (*Socket) GetSockOptInt64 ```go func (s *Socket) GetSockOptInt64(option Int64SocketOption) (value int64, err error) ``` Get an int64 option from the socket. int zmq_getsockopt (void *s, int option, void *optval, size_t *optvallen); #### func (*Socket) GetSockOptString ```go func (s *Socket) GetSockOptString(option StringSocketOption) (value string, err error) ``` Get a string option from the socket. int zmq_getsockopt (void *s, int option, void *optval, size_t *optvallen); #### func (*Socket) GetSockOptUInt64 ```go func (s *Socket) GetSockOptUInt64(option UInt64SocketOption) (value uint64, err error) ``` Get a uint64 option from the socket. int zmq_getsockopt (void *s, int option, void *optval, size_t *optvallen); #### func (*Socket) HWM ```go func (s *Socket) HWM() (uint64, error) ``` ZMQ_HWM: Retrieve high water mark. See: http://api.zeromq.org/2.1:zmq-getsockopt#toc5 #### func (*Socket) Identity ```go func (s *Socket) Identity() (string, error) ``` ZMQ_IDENTITY: Retrieve socket identity. See: http://api.zeromq.org/2.1:zmq-getsockopt#toc8 #### func (*Socket) Linger ```go func (s *Socket) Linger() (time.Duration, error) ``` ZMQ_LINGER: Retrieve linger period for socket shutdown. See: http://api.zeromq.org/2.1:zmq-getsockopt#toc15 #### func (*Socket) McastLoop ```go func (s *Socket) McastLoop() (bool, error) ``` ZMQ_MCAST_LOOP: Control multicast loop-back. See: http://api.zeromq.org/2.1:zmq-getsockopt#toc12 #### func (*Socket) Rate ```go func (s *Socket) Rate() (int64, error) ``` ZMQ_RATE: Retrieve multicast data rate. See: http://api.zeromq.org/2.1:zmq-getsockopt#toc9 #### func (*Socket) RcvBuf ```go func (s *Socket) RcvBuf() (uint64, error) ``` ZMQ_RCVBUF: Retrieve kernel receive buffer size. See: http://api.zeromq.org/2.1:zmq-getsockopt#toc14 #### func (*Socket) RcvHWM ```go func (s *Socket) RcvHWM() (int, error) ``` ZMQ_RCVHWM: Retrieve high water mark for inbound messages. See: http://api.zeromq.org/3.2:zmq-getsockopt#toc6 #### func (*Socket) RcvMore ```go func (s *Socket) RcvMore() (bool, error) ``` ZMQ_RCVMORE: More message parts to follow. See: http://api.zeromq.org/2.1:zmq-getsockopt#toc4 #### func (*Socket) RcvTimeout ```go func (s *Socket) RcvTimeout() (time.Duration, error) ``` ZMQ_RCVTIMEO: Maximum time before a socket operation returns with EAGAIN. See: http://api.zeromq.org/2.2:zmq-getsockopt#toc6 #### func (*Socket) ReconnectIvl ```go func (s *Socket) ReconnectIvl() (time.Duration, error) ``` ZMQ_RECONNECT_IVL: Retrieve reconnection interval. See: http://api.zeromq.org/2.1:zmq-getsockopt#toc16 #### func (*Socket) ReconnectIvlMax ```go func (s *Socket) ReconnectIvlMax() (time.Duration, error) ``` ZMQ_RECONNECT_IVL_MAX: Retrieve maximum reconnection interval. See: http://api.zeromq.org/2.1:zmq-getsockopt#toc17 #### func (*Socket) RecoveryIvl ```go func (s *Socket) RecoveryIvl() (time.Duration, error) ``` ZMQ_RECOVERY_IVL_MSEC: Get multicast recovery interval in milliseconds. See: http://api.zeromq.org/2.1:zmq-getsockopt#toc11 #### func (*Socket) Recv ```go func (s *Socket) Recv(flags SendRecvOption) (data []byte, err error) ``` Receive a message from the socket. int zmq_recv (void *s, zmq_msg_t *msg, int flags); #### func (*Socket) RecvMultipart ```go func (s *Socket) RecvMultipart(flags SendRecvOption) (parts [][]byte, err error) ``` Receive a multipart message. #### func (*Socket) Send ```go func (s *Socket) Send(data []byte, flags SendRecvOption) error ``` Send a message to the socket. int zmq_send (void *s, zmq_msg_t *msg, int flags); #### func (*Socket) SendMultipart ```go func (s *Socket) SendMultipart(parts [][]byte, flags SendRecvOption) (err error) ``` Send a multipart message. #### func (*Socket) SetAffinity ```go func (s *Socket) SetAffinity(value uint64) error ``` ZMQ_AFFINITY: Set I/O thread affinity. See: http://api.zeromq.org/2.1:zmq-setsockopt#toc5 #### func (*Socket) SetBacklog ```go func (s *Socket) SetBacklog(value int) error ``` ZMQ_BACKLOG: Set maximum length of the queue of outstanding connections. See: http://api.zeromq.org/2.1:zmq-setsockopt#toc18 #### func (*Socket) SetHWM ```go func (s *Socket) SetHWM(value uint64) error ``` ZMQ_HWM: Set high water mark. See: http://api.zeromq.org/2.1:zmq-setsockopt#toc3 #### func (*Socket) SetIdentity ```go func (s *Socket) SetIdentity(value string) error ``` ZMQ_IDENTITY: Set socket identity. See: http://api.zeromq.org/2.1:zmq-setsockopt#toc6 #### func (*Socket) SetLinger ```go func (s *Socket) SetLinger(value time.Duration) error ``` ZMQ_LINGER: Set linger period for socket shutdown. See: http://api.zeromq.org/2.1:zmq-setsockopt#toc15 #### func (*Socket) SetMcastLoop ```go func (s *Socket) SetMcastLoop(value bool) error ``` ZMQ_MCAST_LOOP: Control multicast loop-back. See: http://api.zeromq.org/2.1:zmq-setsockopt#toc12 #### func (*Socket) SetRate ```go func (s *Socket) SetRate(value int64) error ``` ZMQ_RATE: Set multicast data rate. See: http://api.zeromq.org/2.1:zmq-setsockopt#toc9 #### func (*Socket) SetRcvBuf ```go func (s *Socket) SetRcvBuf(value uint64) error ``` ZMQ_RCVBUF: Set kernel receive buffer size. See: http://api.zeromq.org/2.1:zmq-setsockopt#toc14 #### func (*Socket) SetRcvHWM ```go func (s *Socket) SetRcvHWM(value int) error ``` ZMQ_RCVHWM: Set high water mark for inbound messages. See: http://api.zeromq.org/3.2:zmq-setsockopt#toc4 #### func (*Socket) SetRcvTimeout ```go func (s *Socket) SetRcvTimeout(value time.Duration) error ``` ZMQ_RCVTIMEO: Maximum time before a recv operation returns with EAGAIN. See: http://api.zeromq.org/2.2:zmq-setsockopt#toc9 #### func (*Socket) SetReconnectIvl ```go func (s *Socket) SetReconnectIvl(value time.Duration) error ``` ZMQ_RECONNECT_IVL: Set reconnection interval. See: http://api.zeromq.org/2.1:zmq-setsockopt#toc16 #### func (*Socket) SetReconnectIvlMax ```go func (s *Socket) SetReconnectIvlMax(value time.Duration) error ``` ZMQ_RECONNECT_IVL_MAX: Set maximum reconnection interval. See: http://api.zeromq.org/2.1:zmq-setsockopt#toc17 #### func (*Socket) SetRecoveryIvl ```go func (s *Socket) SetRecoveryIvl(value time.Duration) error ``` ZMQ_RECOVERY_IVL_MSEC: Set multicast recovery interval in milliseconds. See: http://api.zeromq.org/2.1:zmq-setsockopt#toc11 #### func (*Socket) SetSndBuf ```go func (s *Socket) SetSndBuf(value uint64) error ``` ZMQ_SNDBUF: Set kernel transmit buffer size. See: http://api.zeromq.org/2.1:zmq-setsockopt#toc13 #### func (*Socket) SetSndHWM ```go func (s *Socket) SetSndHWM(value int) error ``` ZMQ_SNDHWM: Set high water mark for outbound messages. See: http://api.zeromq.org/3.2:zmq-setsockopt#toc3 #### func (*Socket) SetSndTimeout ```go func (s *Socket) SetSndTimeout(value time.Duration) error ``` ZMQ_SNDTIMEO: Maximum time before a send operation returns with EAGAIN. See: http://api.zeromq.org/2.2:zmq-setsockopt#toc10 #### func (*Socket) SetSockOptInt ```go func (s *Socket) SetSockOptInt(option IntSocketOption, value int) error ``` Set an int option on the socket. int zmq_setsockopt (void *s, int option, const void *optval, size_t optvallen); #### func (*Socket) SetSockOptInt64 ```go func (s *Socket) SetSockOptInt64(option Int64SocketOption, value int64) error ``` Set an int64 option on the socket. int zmq_setsockopt (void *s, int option, const void *optval, size_t optvallen); #### func (*Socket) SetSockOptString ```go func (s *Socket) SetSockOptString(option StringSocketOption, value string) error ``` Set a string option on the socket. int zmq_setsockopt (void *s, int option, const void *optval, size_t optvallen); #### func (*Socket) SetSockOptStringNil ```go func (s *Socket) SetSockOptStringNil(option StringSocketOption) error ``` Set a string option on the socket to nil. int zmq_setsockopt (void *s, int option, const void *optval, size_t optvallen); #### func (*Socket) SetSockOptUInt64 ```go func (s *Socket) SetSockOptUInt64(option UInt64SocketOption, value uint64) error ``` Set a uint64 option on the socket. int zmq_setsockopt (void *s, int option, const void *optval, size_t optvallen); #### func (*Socket) SetSubscribe ```go func (s *Socket) SetSubscribe(value string) error ``` ZMQ_SUBSCRIBE: Establish message filter. See: http://api.zeromq.org/2.1:zmq-setsockopt#toc7 #### func (*Socket) SetSwap ```go func (s *Socket) SetSwap(value int64) error ``` ZMQ_SWAP: Set disk offload size. See: http://api.zeromq.org/2.1:zmq-setsockopt#toc4 #### func (*Socket) SetTCPKeepalive ```go func (s *Socket) SetTCPKeepalive(value int) error ``` ZMQ_TCP_KEEPALIVE: Override SO_KEEPALIVE socket option. See: http://api.zeromq.org/3.2:zmq-setsockopt#toc25 #### func (*Socket) SetTCPKeepaliveCnt ```go func (s *Socket) SetTCPKeepaliveCnt(value int) error ``` ZMQ_TCP_KEEPALIVE_CNT: Override TCP_KEEPCNT socket option. See: http://api.zeromq.org/3.2:zmq-setsockopt#toc27 #### func (*Socket) SetTCPKeepaliveIdle ```go func (s *Socket) SetTCPKeepaliveIdle(value int) error ``` ZMQ_TCP_KEEPALIVE_IDLE: Override TCP_KEEPCNT(or TCP_KEEPALIVE on some OS). See: http://api.zeromq.org/3.2:zmq-setsockopt#toc26 #### func (*Socket) SetTCPKeepaliveIntvl ```go func (s *Socket) SetTCPKeepaliveIntvl(value int) error ``` ZMQ_TCP_KEEPALIVE_INTVL: Override TCP_KEEPINTVL socket option. See: http://api.zeromq.org/3.2:zmq-setsockopt#toc28 #### func (*Socket) SetUnsubscribe ```go func (s *Socket) SetUnsubscribe(value string) error ``` ZMQ_UNSUBSCRIBE: Remove message filter. See: http://api.zeromq.org/2.1:zmq-setsockopt#toc8 #### func (*Socket) SndBuf ```go func (s *Socket) SndBuf() (uint64, error) ``` ZMQ_SNDBUF: Retrieve kernel transmit buffer size. See: http://api.zeromq.org/2.1:zmq-getsockopt#toc13 #### func (*Socket) SndHWM ```go func (s *Socket) SndHWM() (int, error) ``` ZMQ_SNDHWM: Retrieves high water mark for outbound messages. See: http://api.zeromq.org/3.2:zmq-getsockopt#toc5 #### func (*Socket) SndTimeout ```go func (s *Socket) SndTimeout() (time.Duration, error) ``` ZMQ_SNDTIMEO: Maximum time before a socket operation returns with EAGAIN. See: http://api.zeromq.org/2.2:zmq-getsockopt#toc7 #### func (*Socket) Swap ```go func (s *Socket) Swap() (int64, error) ``` ZMQ_SWAP: Retrieve disk offload size. See: http://api.zeromq.org/2.1:zmq-getsockopt#toc6 #### func (*Socket) TCPKeepalive ```go func (s *Socket) TCPKeepalive() (int, error) ``` ZMQ_TCP_KEEPALIVE: Override SO_KEEPALIVE socket option. See: http://api.zeromq.org/3.2:zmq-getsockopt#toc26 #### func (*Socket) TCPKeepaliveCnt ```go func (s *Socket) TCPKeepaliveCnt() (int, error) ``` ZMQ_TCP_KEEPALIVE_CNT: Override TCP_KEEPCNT socket option. See: http://api.zeromq.org/3.2:zmq-getsockopt#toc28 #### func (*Socket) TCPKeepaliveIdle ```go func (s *Socket) TCPKeepaliveIdle() (int, error) ``` ZMQ_TCP_KEEPALIVE_IDLE: Override TCP_KEEPCNT(or TCP_KEEPALIVE on some OS). See: http://api.zeromq.org/3.2:zmq-getsockopt#toc27 #### func (*Socket) TCPKeepaliveIntvl ```go func (s *Socket) TCPKeepaliveIntvl() (int, error) ``` ZMQ_TCP_KEEPALIVE_INTVL: Override TCP_KEEPINTVL socket option. See: http://api.zeromq.org/3.2:zmq-getsockopt#toc29 #### func (*Socket) Type ```go func (s *Socket) Type() (SocketType, error) ``` ZMQ_TYPE: Retrieve socket type. See: http://api.zeromq.org/2.1:zmq-getsockopt#toc3 #### type SocketType ```go type SocketType int ``` #### type StringSocketOption ```go type StringSocketOption int ``` #### type UInt64SocketOption ```go type UInt64SocketOption int ``` #### type ZmqOsSocketType ```go type ZmqOsSocketType C.SOCKET ``` #### func (ZmqOsSocketType) ToRaw ```go func (self ZmqOsSocketType) ToRaw() C.SOCKET ``` *(generated from .[godocdown](https://github.com/robertkrimen/godocdown).md with `godocdown github.com/alecthomas/gozmq > README.md`)* ================================================ FILE: examples/client/client.go ================================================ /* Copyright 2010 Alec Thomas Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package main import "fmt" import zmq "github.com/alecthomas/gozmq" func main() { context, _ := zmq.NewContext() socket, _ := context.NewSocket(zmq.REQ) socket.Connect("tcp://127.0.0.1:5000") socket.Connect("tcp://127.0.0.1:6000") for i := 0; i < 10; i++ { msg := fmt.Sprintf("msg %d", i) socket.Send([]byte(msg), 0) println("Sending", msg) socket.Recv(0) } } ================================================ FILE: examples/server/server.go ================================================ /* Copyright 2010 Alec Thomas Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package main import zmq "github.com/alecthomas/gozmq" func main() { context, _ := zmq.NewContext() socket, _ := context.NewSocket(zmq.REP) socket.Bind("tcp://127.0.0.1:5000") socket.Bind("tcp://127.0.0.1:6000") for { msg, _ := socket.Recv(0) println("Got", string(msg)) socket.Send(msg, 0) } } ================================================ FILE: gozmqfix/LICENSE ================================================ Copyright (c) 2012 The Go Authors. All rights reserved. Copyright (c) 2013 Joshua Tacoma. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: gozmqfix/README.md ================================================ # gozmqfix A `go tool fix` for gozmq projects. ================================================ FILE: gozmqfix/fix.go ================================================ // Copyright 2011 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package main import ( "fmt" "go/ast" "go/parser" "go/token" "os" "path" "reflect" "strconv" "strings" ) type fix struct { name string date string // date that fix was introduced, in YYYY-MM-DD format f func(*ast.File) bool desc string } // main runs sort.Sort(byName(fixes)) before printing list of fixes. type byName []fix func (f byName) Len() int { return len(f) } func (f byName) Swap(i, j int) { f[i], f[j] = f[j], f[i] } func (f byName) Less(i, j int) bool { return f[i].name < f[j].name } // main runs sort.Sort(byDate(fixes)) before applying fixes. type byDate []fix func (f byDate) Len() int { return len(f) } func (f byDate) Swap(i, j int) { f[i], f[j] = f[j], f[i] } func (f byDate) Less(i, j int) bool { return f[i].date < f[j].date } var fixes []fix func register(f fix) { fixes = append(fixes, f) } // walk traverses the AST x, calling visit(y) for each node y in the tree but // also with a pointer to each ast.Expr, ast.Stmt, and *ast.BlockStmt, // in a bottom-up traversal. func walk(x interface{}, visit func(interface{})) { walkBeforeAfter(x, nop, visit) } func nop(interface{}) {} // walkBeforeAfter is like walk but calls before(x) before traversing // x's children and after(x) afterward. func walkBeforeAfter(x interface{}, before, after func(interface{})) { before(x) switch n := x.(type) { default: panic(fmt.Errorf("unexpected type %T in walkBeforeAfter", x)) case nil: // pointers to interfaces case *ast.Decl: walkBeforeAfter(*n, before, after) case *ast.Expr: walkBeforeAfter(*n, before, after) case *ast.Spec: walkBeforeAfter(*n, before, after) case *ast.Stmt: walkBeforeAfter(*n, before, after) // pointers to struct pointers case **ast.BlockStmt: walkBeforeAfter(*n, before, after) case **ast.CallExpr: walkBeforeAfter(*n, before, after) case **ast.FieldList: walkBeforeAfter(*n, before, after) case **ast.FuncType: walkBeforeAfter(*n, before, after) case **ast.Ident: walkBeforeAfter(*n, before, after) case **ast.BasicLit: walkBeforeAfter(*n, before, after) // pointers to slices case *[]ast.Decl: walkBeforeAfter(*n, before, after) case *[]ast.Expr: walkBeforeAfter(*n, before, after) case *[]*ast.File: walkBeforeAfter(*n, before, after) case *[]*ast.Ident: walkBeforeAfter(*n, before, after) case *[]ast.Spec: walkBeforeAfter(*n, before, after) case *[]ast.Stmt: walkBeforeAfter(*n, before, after) // These are ordered and grouped to match ../../pkg/go/ast/ast.go case *ast.Field: walkBeforeAfter(&n.Names, before, after) walkBeforeAfter(&n.Type, before, after) walkBeforeAfter(&n.Tag, before, after) case *ast.FieldList: for _, field := range n.List { walkBeforeAfter(field, before, after) } case *ast.BadExpr: case *ast.Ident: case *ast.Ellipsis: walkBeforeAfter(&n.Elt, before, after) case *ast.BasicLit: case *ast.FuncLit: walkBeforeAfter(&n.Type, before, after) walkBeforeAfter(&n.Body, before, after) case *ast.CompositeLit: walkBeforeAfter(&n.Type, before, after) walkBeforeAfter(&n.Elts, before, after) case *ast.ParenExpr: walkBeforeAfter(&n.X, before, after) case *ast.SelectorExpr: walkBeforeAfter(&n.X, before, after) case *ast.IndexExpr: walkBeforeAfter(&n.X, before, after) walkBeforeAfter(&n.Index, before, after) case *ast.SliceExpr: walkBeforeAfter(&n.X, before, after) if n.Low != nil { walkBeforeAfter(&n.Low, before, after) } if n.High != nil { walkBeforeAfter(&n.High, before, after) } case *ast.TypeAssertExpr: walkBeforeAfter(&n.X, before, after) walkBeforeAfter(&n.Type, before, after) case *ast.CallExpr: walkBeforeAfter(&n.Fun, before, after) walkBeforeAfter(&n.Args, before, after) case *ast.StarExpr: walkBeforeAfter(&n.X, before, after) case *ast.UnaryExpr: walkBeforeAfter(&n.X, before, after) case *ast.BinaryExpr: walkBeforeAfter(&n.X, before, after) walkBeforeAfter(&n.Y, before, after) case *ast.KeyValueExpr: walkBeforeAfter(&n.Key, before, after) walkBeforeAfter(&n.Value, before, after) case *ast.ArrayType: walkBeforeAfter(&n.Len, before, after) walkBeforeAfter(&n.Elt, before, after) case *ast.StructType: walkBeforeAfter(&n.Fields, before, after) case *ast.FuncType: walkBeforeAfter(&n.Params, before, after) if n.Results != nil { walkBeforeAfter(&n.Results, before, after) } case *ast.InterfaceType: walkBeforeAfter(&n.Methods, before, after) case *ast.MapType: walkBeforeAfter(&n.Key, before, after) walkBeforeAfter(&n.Value, before, after) case *ast.ChanType: walkBeforeAfter(&n.Value, before, after) case *ast.BadStmt: case *ast.DeclStmt: walkBeforeAfter(&n.Decl, before, after) case *ast.EmptyStmt: case *ast.LabeledStmt: walkBeforeAfter(&n.Stmt, before, after) case *ast.ExprStmt: walkBeforeAfter(&n.X, before, after) case *ast.SendStmt: walkBeforeAfter(&n.Chan, before, after) walkBeforeAfter(&n.Value, before, after) case *ast.IncDecStmt: walkBeforeAfter(&n.X, before, after) case *ast.AssignStmt: walkBeforeAfter(&n.Lhs, before, after) walkBeforeAfter(&n.Rhs, before, after) case *ast.GoStmt: walkBeforeAfter(&n.Call, before, after) case *ast.DeferStmt: walkBeforeAfter(&n.Call, before, after) case *ast.ReturnStmt: walkBeforeAfter(&n.Results, before, after) case *ast.BranchStmt: case *ast.BlockStmt: walkBeforeAfter(&n.List, before, after) case *ast.IfStmt: walkBeforeAfter(&n.Init, before, after) walkBeforeAfter(&n.Cond, before, after) walkBeforeAfter(&n.Body, before, after) walkBeforeAfter(&n.Else, before, after) case *ast.CaseClause: walkBeforeAfter(&n.List, before, after) walkBeforeAfter(&n.Body, before, after) case *ast.SwitchStmt: walkBeforeAfter(&n.Init, before, after) walkBeforeAfter(&n.Tag, before, after) walkBeforeAfter(&n.Body, before, after) case *ast.TypeSwitchStmt: walkBeforeAfter(&n.Init, before, after) walkBeforeAfter(&n.Assign, before, after) walkBeforeAfter(&n.Body, before, after) case *ast.CommClause: walkBeforeAfter(&n.Comm, before, after) walkBeforeAfter(&n.Body, before, after) case *ast.SelectStmt: walkBeforeAfter(&n.Body, before, after) case *ast.ForStmt: walkBeforeAfter(&n.Init, before, after) walkBeforeAfter(&n.Cond, before, after) walkBeforeAfter(&n.Post, before, after) walkBeforeAfter(&n.Body, before, after) case *ast.RangeStmt: walkBeforeAfter(&n.Key, before, after) walkBeforeAfter(&n.Value, before, after) walkBeforeAfter(&n.X, before, after) walkBeforeAfter(&n.Body, before, after) case *ast.ImportSpec: case *ast.ValueSpec: walkBeforeAfter(&n.Type, before, after) walkBeforeAfter(&n.Values, before, after) walkBeforeAfter(&n.Names, before, after) case *ast.TypeSpec: walkBeforeAfter(&n.Type, before, after) case *ast.BadDecl: case *ast.GenDecl: walkBeforeAfter(&n.Specs, before, after) case *ast.FuncDecl: if n.Recv != nil { walkBeforeAfter(&n.Recv, before, after) } walkBeforeAfter(&n.Type, before, after) if n.Body != nil { walkBeforeAfter(&n.Body, before, after) } case *ast.File: walkBeforeAfter(&n.Decls, before, after) case *ast.Package: walkBeforeAfter(&n.Files, before, after) case []*ast.File: for i := range n { walkBeforeAfter(&n[i], before, after) } case []ast.Decl: for i := range n { walkBeforeAfter(&n[i], before, after) } case []ast.Expr: for i := range n { walkBeforeAfter(&n[i], before, after) } case []*ast.Ident: for i := range n { walkBeforeAfter(&n[i], before, after) } case []ast.Stmt: for i := range n { walkBeforeAfter(&n[i], before, after) } case []ast.Spec: for i := range n { walkBeforeAfter(&n[i], before, after) } } after(x) } // imports returns true if f imports path. func imports(f *ast.File, path string) bool { return importSpec(f, path) != nil } // importSpec returns the import spec if f imports path, // or nil otherwise. func importSpec(f *ast.File, path string) *ast.ImportSpec { for _, s := range f.Imports { if importPath(s) == path { return s } } return nil } // importPath returns the unquoted import path of s, // or "" if the path is not properly quoted. func importPath(s *ast.ImportSpec) string { t, err := strconv.Unquote(s.Path.Value) if err == nil { return t } return "" } // declImports reports whether gen contains an import of path. func declImports(gen *ast.GenDecl, path string) bool { if gen.Tok != token.IMPORT { return false } for _, spec := range gen.Specs { impspec := spec.(*ast.ImportSpec) if importPath(impspec) == path { return true } } return false } // isPkgDot returns true if t is the expression "pkg.name" // where pkg is an imported identifier. func isPkgDot(t ast.Expr, pkg, name string) bool { sel, ok := t.(*ast.SelectorExpr) return ok && isTopName(sel.X, pkg) && sel.Sel.String() == name } // isPtrPkgDot returns true if f is the expression "*pkg.name" // where pkg is an imported identifier. func isPtrPkgDot(t ast.Expr, pkg, name string) bool { ptr, ok := t.(*ast.StarExpr) return ok && isPkgDot(ptr.X, pkg, name) } // isTopName returns true if n is a top-level unresolved identifier with the given name. func isTopName(n ast.Expr, name string) bool { id, ok := n.(*ast.Ident) return ok && id.Name == name && id.Obj == nil } // isName returns true if n is an identifier with the given name. func isName(n ast.Expr, name string) bool { id, ok := n.(*ast.Ident) return ok && id.String() == name } // isCall returns true if t is a call to pkg.name. func isCall(t ast.Expr, pkg, name string) bool { call, ok := t.(*ast.CallExpr) return ok && isPkgDot(call.Fun, pkg, name) } // If n is an *ast.Ident, isIdent returns it; otherwise isIdent returns nil. func isIdent(n interface{}) *ast.Ident { id, _ := n.(*ast.Ident) return id } // refersTo returns true if n is a reference to the same object as x. func refersTo(n ast.Node, x *ast.Ident) bool { id, ok := n.(*ast.Ident) // The test of id.Name == x.Name handles top-level unresolved // identifiers, which all have Obj == nil. return ok && id.Obj == x.Obj && id.Name == x.Name } // isBlank returns true if n is the blank identifier. func isBlank(n ast.Expr) bool { return isName(n, "_") } // isEmptyString returns true if n is an empty string literal. func isEmptyString(n ast.Expr) bool { lit, ok := n.(*ast.BasicLit) return ok && lit.Kind == token.STRING && len(lit.Value) == 2 } func warn(pos token.Pos, msg string, args ...interface{}) { if pos.IsValid() { msg = "%s: " + msg arg1 := []interface{}{fset.Position(pos).String()} args = append(arg1, args...) } fmt.Fprintf(os.Stderr, msg+"\n", args...) } // countUses returns the number of uses of the identifier x in scope. func countUses(x *ast.Ident, scope []ast.Stmt) int { count := 0 ff := func(n interface{}) { if n, ok := n.(ast.Node); ok && refersTo(n, x) { count++ } } for _, n := range scope { walk(n, ff) } return count } // rewriteUses replaces all uses of the identifier x and !x in scope // with f(x.Pos()) and fnot(x.Pos()). func rewriteUses(x *ast.Ident, f, fnot func(token.Pos) ast.Expr, scope []ast.Stmt) { var lastF ast.Expr ff := func(n interface{}) { ptr, ok := n.(*ast.Expr) if !ok { return } nn := *ptr // The child node was just walked and possibly replaced. // If it was replaced and this is a negation, replace with fnot(p). not, ok := nn.(*ast.UnaryExpr) if ok && not.Op == token.NOT && not.X == lastF { *ptr = fnot(nn.Pos()) return } if refersTo(nn, x) { lastF = f(nn.Pos()) *ptr = lastF } } for _, n := range scope { walk(n, ff) } } // assignsTo returns true if any of the code in scope assigns to or takes the address of x. func assignsTo(x *ast.Ident, scope []ast.Stmt) bool { assigned := false ff := func(n interface{}) { if assigned { return } switch n := n.(type) { case *ast.UnaryExpr: // use of &x if n.Op == token.AND && refersTo(n.X, x) { assigned = true return } case *ast.AssignStmt: for _, l := range n.Lhs { if refersTo(l, x) { assigned = true return } } } } for _, n := range scope { if assigned { break } walk(n, ff) } return assigned } // newPkgDot returns an ast.Expr referring to "pkg.name" at position pos. func newPkgDot(pos token.Pos, pkg, name string) ast.Expr { return &ast.SelectorExpr{ X: &ast.Ident{ NamePos: pos, Name: pkg, }, Sel: &ast.Ident{ NamePos: pos, Name: name, }, } } // renameTop renames all references to the top-level name old. // It returns true if it makes any changes. func renameTop(f *ast.File, old, new string) bool { var fixed bool // Rename any conflicting imports // (assuming package name is last element of path). for _, s := range f.Imports { if s.Name != nil { if s.Name.Name == old { s.Name.Name = new fixed = true } } else { _, thisName := path.Split(importPath(s)) if thisName == old { s.Name = ast.NewIdent(new) fixed = true } } } // Rename any top-level declarations. for _, d := range f.Decls { switch d := d.(type) { case *ast.FuncDecl: if d.Recv == nil && d.Name.Name == old { d.Name.Name = new d.Name.Obj.Name = new fixed = true } case *ast.GenDecl: for _, s := range d.Specs { switch s := s.(type) { case *ast.TypeSpec: if s.Name.Name == old { s.Name.Name = new s.Name.Obj.Name = new fixed = true } case *ast.ValueSpec: for _, n := range s.Names { if n.Name == old { n.Name = new n.Obj.Name = new fixed = true } } } } } } // Rename top-level old to new, both unresolved names // (probably defined in another file) and names that resolve // to a declaration we renamed. walk(f, func(n interface{}) { id, ok := n.(*ast.Ident) if ok && isTopName(id, old) { id.Name = new fixed = true } if ok && id.Obj != nil && id.Name == old && id.Obj.Name == new { id.Name = id.Obj.Name fixed = true } }) return fixed } // matchLen returns the length of the longest prefix shared by x and y. func matchLen(x, y string) int { i := 0 for i < len(x) && i < len(y) && x[i] == y[i] { i++ } return i } // addImport adds the import path to the file f, if absent. func addImport(f *ast.File, ipath string) (added bool) { if imports(f, ipath) { return false } // Determine name of import. // Assume added imports follow convention of using last element. _, name := path.Split(ipath) // Rename any conflicting top-level references from name to name_. renameTop(f, name, name+"_") newImport := &ast.ImportSpec{ Path: &ast.BasicLit{ Kind: token.STRING, Value: strconv.Quote(ipath), }, } // Find an import decl to add to. var ( bestMatch = -1 lastImport = -1 impDecl *ast.GenDecl impIndex = -1 ) for i, decl := range f.Decls { gen, ok := decl.(*ast.GenDecl) if ok && gen.Tok == token.IMPORT { lastImport = i // Do not add to import "C", to avoid disrupting the // association with its doc comment, breaking cgo. if declImports(gen, "C") { continue } // Compute longest shared prefix with imports in this block. for j, spec := range gen.Specs { impspec := spec.(*ast.ImportSpec) n := matchLen(importPath(impspec), ipath) if n > bestMatch { bestMatch = n impDecl = gen impIndex = j } } } } // If no import decl found, add one after the last import. if impDecl == nil { impDecl = &ast.GenDecl{ Tok: token.IMPORT, } f.Decls = append(f.Decls, nil) copy(f.Decls[lastImport+2:], f.Decls[lastImport+1:]) f.Decls[lastImport+1] = impDecl } // Ensure the import decl has parentheses, if needed. if len(impDecl.Specs) > 0 && !impDecl.Lparen.IsValid() { impDecl.Lparen = impDecl.Pos() } insertAt := impIndex + 1 if insertAt == 0 { insertAt = len(impDecl.Specs) } impDecl.Specs = append(impDecl.Specs, nil) copy(impDecl.Specs[insertAt+1:], impDecl.Specs[insertAt:]) impDecl.Specs[insertAt] = newImport if insertAt > 0 { // Assign same position as the previous import, // so that the sorter sees it as being in the same block. prev := impDecl.Specs[insertAt-1] newImport.Path.ValuePos = prev.Pos() newImport.EndPos = prev.Pos() } f.Imports = append(f.Imports, newImport) return true } // deleteImport deletes the import path from the file f, if present. func deleteImport(f *ast.File, path string) (deleted bool) { oldImport := importSpec(f, path) // Find the import node that imports path, if any. for i, decl := range f.Decls { gen, ok := decl.(*ast.GenDecl) if !ok || gen.Tok != token.IMPORT { continue } for j, spec := range gen.Specs { impspec := spec.(*ast.ImportSpec) if oldImport != impspec { continue } // We found an import spec that imports path. // Delete it. deleted = true copy(gen.Specs[j:], gen.Specs[j+1:]) gen.Specs = gen.Specs[:len(gen.Specs)-1] // If this was the last import spec in this decl, // delete the decl, too. if len(gen.Specs) == 0 { copy(f.Decls[i:], f.Decls[i+1:]) f.Decls = f.Decls[:len(f.Decls)-1] } else if len(gen.Specs) == 1 { gen.Lparen = token.NoPos // drop parens } if j > 0 { // We deleted an entry but now there will be // a blank line-sized hole where the import was. // Close the hole by making the previous // import appear to "end" where this one did. gen.Specs[j-1].(*ast.ImportSpec).EndPos = impspec.End() } break } } // Delete it from f.Imports. for i, imp := range f.Imports { if imp == oldImport { copy(f.Imports[i:], f.Imports[i+1:]) f.Imports = f.Imports[:len(f.Imports)-1] break } } return } // rewriteImport rewrites any import of path oldPath to path newPath. func rewriteImport(f *ast.File, oldPath, newPath string) (rewrote bool) { for _, imp := range f.Imports { if importPath(imp) == oldPath { rewrote = true // record old End, because the default is to compute // it using the length of imp.Path.Value. imp.EndPos = imp.End() imp.Path.Value = strconv.Quote(newPath) } } return } func usesImport(f *ast.File, path string) (used bool) { spec := importSpec(f, path) if spec == nil { return } name := spec.Name.String() switch name { case "": // If the package name is not explicitly specified, // make an educated guess. This is not guaranteed to be correct. lastSlash := strings.LastIndex(path, "/") if lastSlash == -1 { name = path } else { name = path[lastSlash+1:] } case "_", ".": // Not sure if this import is used - err on the side of caution. return true } walk(f, func(n interface{}) { sel, ok := n.(*ast.SelectorExpr) if ok && isTopName(sel.X, name) { used = true } }) return } func expr(s string) ast.Expr { x, err := parser.ParseExpr(s) if err != nil { panic("parsing " + s + ": " + err.Error()) } // Remove position information to avoid spurious newlines. killPos(reflect.ValueOf(x)) return x } var posType = reflect.TypeOf(token.Pos(0)) func killPos(v reflect.Value) { switch v.Kind() { case reflect.Ptr, reflect.Interface: if !v.IsNil() { killPos(v.Elem()) } case reflect.Slice: n := v.Len() for i := 0; i < n; i++ { killPos(v.Index(i)) } case reflect.Struct: n := v.NumField() for i := 0; i < n; i++ { f := v.Field(i) if f.Type() == posType { f.SetInt(0) continue } killPos(f) } } } // A Rename describes a single renaming. type rename struct { OldImport string // only apply rename if this import is present NewImport string // add this import during rewrite Old string // old name: p.T or *p.T New string // new name: p.T or *p.T } func renameFix(tab []rename) func(*ast.File) bool { return func(f *ast.File) bool { return renameFixTab(f, tab) } } func parseName(s string) (ptr bool, pkg, nam string) { i := strings.Index(s, ".") if i < 0 { panic("parseName: invalid name " + s) } if strings.HasPrefix(s, "*") { ptr = true s = s[1:] i-- } pkg = s[:i] nam = s[i+1:] return } func renameFixTab(f *ast.File, tab []rename) bool { fixed := false added := map[string]bool{} check := map[string]bool{} for _, t := range tab { if !imports(f, t.OldImport) { continue } optr, opkg, onam := parseName(t.Old) walk(f, func(n interface{}) { np, ok := n.(*ast.Expr) if !ok { return } x := *np if optr { p, ok := x.(*ast.StarExpr) if !ok { return } x = p.X } if !isPkgDot(x, opkg, onam) { return } if t.NewImport != "" && !added[t.NewImport] { addImport(f, t.NewImport) added[t.NewImport] = true } *np = expr(t.New) check[t.OldImport] = true fixed = true }) } for ipath := range check { if !usesImport(f, ipath) { deleteImport(f, ipath) } } return fixed } ================================================ FILE: gozmqfix/main.go ================================================ // Copyright 2011 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package main import ( "bytes" "flag" "fmt" "go/ast" "go/parser" "go/printer" "go/scanner" "go/token" "io/ioutil" "os" "os/exec" "path/filepath" "sort" "strings" ) var ( fset = token.NewFileSet() exitCode = 0 ) var allowedRewrites = flag.String("r", "", "restrict the rewrites to this comma-separated list") var forceRewrites = flag.String("force", "", "force these fixes to run even if the code looks updated") var allowed, force map[string]bool var doDiff = flag.Bool("diff", false, "display diffs instead of rewriting files") // enable for debugging fix failures const debug = false // display incorrectly reformatted source and exit func usage() { fmt.Fprintf(os.Stderr, "usage: go tool fix [-diff] [-r fixname,...] [-force fixname,...] [path ...]\n") flag.PrintDefaults() fmt.Fprintf(os.Stderr, "\nAvailable rewrites are:\n") sort.Sort(byName(fixes)) for _, f := range fixes { fmt.Fprintf(os.Stderr, "\n%s\n", f.name) desc := strings.TrimSpace(f.desc) desc = strings.Replace(desc, "\n", "\n\t", -1) fmt.Fprintf(os.Stderr, "\t%s\n", desc) } os.Exit(2) } func main() { flag.Usage = usage flag.Parse() sort.Sort(byDate(fixes)) if *allowedRewrites != "" { allowed = make(map[string]bool) for _, f := range strings.Split(*allowedRewrites, ",") { allowed[f] = true } } if *forceRewrites != "" { force = make(map[string]bool) for _, f := range strings.Split(*forceRewrites, ",") { force[f] = true } } if flag.NArg() == 0 { if err := processFile("standard input", true); err != nil { report(err) } os.Exit(exitCode) } for i := 0; i < flag.NArg(); i++ { path := flag.Arg(i) switch dir, err := os.Stat(path); { case err != nil: report(err) case dir.IsDir(): walkDir(path) default: if err := processFile(path, false); err != nil { report(err) } } } os.Exit(exitCode) } const ( tabWidth = 8 parserMode = parser.ParseComments printerMode = printer.TabIndent | printer.UseSpaces ) var printConfig = &printer.Config{ Mode: printerMode, Tabwidth: tabWidth, } func gofmtFile(f *ast.File) ([]byte, error) { var buf bytes.Buffer ast.SortImports(fset, f) err := printConfig.Fprint(&buf, fset, f) if err != nil { return nil, err } return buf.Bytes(), nil } func processFile(filename string, useStdin bool) error { var f *os.File var err error var fixlog bytes.Buffer if useStdin { f = os.Stdin } else { f, err = os.Open(filename) if err != nil { return err } defer f.Close() } src, err := ioutil.ReadAll(f) if err != nil { return err } file, err := parser.ParseFile(fset, filename, src, parserMode) if err != nil { return err } // Apply all fixes to file. newFile := file fixed := false for _, fix := range fixes { if allowed != nil && !allowed[fix.name] { continue } if fix.f(newFile) { fixed = true fmt.Fprintf(&fixlog, " %s", fix.name) // AST changed. // Print and parse, to update any missing scoping // or position information for subsequent fixers. newSrc, err := gofmtFile(newFile) if err != nil { return err } newFile, err = parser.ParseFile(fset, filename, newSrc, parserMode) if err != nil { if debug { fmt.Printf("%s", newSrc) report(err) os.Exit(exitCode) } return err } } } if !fixed { return nil } fmt.Fprintf(os.Stderr, "%s: fixed %s\n", filename, fixlog.String()[1:]) // Print AST. We did that after each fix, so this appears // redundant, but it is necessary to generate gofmt-compatible // source code in a few cases. The official gofmt style is the // output of the printer run on a standard AST generated by the parser, // but the source we generated inside the loop above is the // output of the printer run on a mangled AST generated by a fixer. newSrc, err := gofmtFile(newFile) if err != nil { return err } if *doDiff { data, err := diff(src, newSrc) if err != nil { return fmt.Errorf("computing diff: %s", err) } fmt.Printf("diff %s fixed/%s\n", filename, filename) os.Stdout.Write(data) return nil } if useStdin { os.Stdout.Write(newSrc) return nil } return ioutil.WriteFile(f.Name(), newSrc, 0) } var gofmtBuf bytes.Buffer func gofmt(n interface{}) string { gofmtBuf.Reset() err := printConfig.Fprint(&gofmtBuf, fset, n) if err != nil { return "<" + err.Error() + ">" } return gofmtBuf.String() } func report(err error) { scanner.PrintError(os.Stderr, err) exitCode = 2 } func walkDir(path string) { filepath.Walk(path, visitFile) } func visitFile(path string, f os.FileInfo, err error) error { if err == nil && isGoFile(f) { err = processFile(path, false) } if err != nil { report(err) } return nil } func isGoFile(f os.FileInfo) bool { // ignore non-Go files name := f.Name() return !f.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go") } func diff(b1, b2 []byte) (data []byte, err error) { f1, err := ioutil.TempFile("", "go-fix") if err != nil { return nil, err } defer os.Remove(f1.Name()) defer f1.Close() f2, err := ioutil.TempFile("", "go-fix") if err != nil { return nil, err } defer os.Remove(f2.Name()) defer f2.Close() f1.Write(b1) f2.Write(b2) data, err = exec.Command("diff", "-u", f1.Name(), f2.Name()).CombinedOutput() if len(data) > 0 { // diff exits with a non-zero status when the files don't match. // Ignore that failure as long as we get output. err = nil } return } ================================================ FILE: gozmqfix/main_test.go ================================================ // Copyright 2011 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package main import ( "go/ast" "go/parser" "strings" "testing" ) type testCase struct { Name string Fn func(*ast.File) bool In string Out string } var testCases []testCase func addTestCases(t []testCase, fn func(*ast.File) bool) { // Fill in fn to avoid repetition in definitions. if fn != nil { for i := range t { if t[i].Fn == nil { t[i].Fn = fn } } } testCases = append(testCases, t...) } func fnop(*ast.File) bool { return false } func parseFixPrint(t *testing.T, fn func(*ast.File) bool, desc, in string, mustBeGofmt bool) (out string, fixed, ok bool) { file, err := parser.ParseFile(fset, desc, in, parserMode) if err != nil { t.Errorf("%s: parsing: %v", desc, err) return } outb, err := gofmtFile(file) if err != nil { t.Errorf("%s: printing: %v", desc, err) return } if s := string(outb); in != s && mustBeGofmt { t.Errorf("%s: not gofmt-formatted.\n--- %s\n%s\n--- %s | gofmt\n%s", desc, desc, in, desc, s) tdiff(t, in, s) return } if fn == nil { for _, fix := range fixes { if fix.f(file) { fixed = true } } } else { fixed = fn(file) } outb, err = gofmtFile(file) if err != nil { t.Errorf("%s: printing: %v", desc, err) return } return string(outb), fixed, true } func TestRewrite(t *testing.T) { for _, tt := range testCases { // Apply fix: should get tt.Out. out, fixed, ok := parseFixPrint(t, tt.Fn, tt.Name, tt.In, true) if !ok { continue } // reformat to get printing right out, _, ok = parseFixPrint(t, fnop, tt.Name, out, false) if !ok { continue } if out != tt.Out { t.Errorf("%s: incorrect output.\n", tt.Name) if !strings.HasPrefix(tt.Name, "testdata/") { t.Errorf("--- have\n%s\n--- want\n%s", out, tt.Out) } tdiff(t, out, tt.Out) continue } if changed := out != tt.In; changed != fixed { t.Errorf("%s: changed=%v != fixed=%v", tt.Name, changed, fixed) continue } // Should not change if run again. out2, fixed2, ok := parseFixPrint(t, tt.Fn, tt.Name+" output", out, true) if !ok { continue } if fixed2 { t.Errorf("%s: applied fixes during second round", tt.Name) continue } if out2 != out { t.Errorf("%s: changed output after second round of fixes.\n--- output after first round\n%s\n--- output after second round\n%s", tt.Name, out, out2) tdiff(t, out, out2) } } } func tdiff(t *testing.T, a, b string) { data, err := diff([]byte(a), []byte(b)) if err != nil { t.Error(err) return } t.Error(string(data)) } ================================================ FILE: gozmqfix/zmqstruct.go ================================================ // Copyright 2013 Joshua Tacoma. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package main import ( "go/ast" ) func init() { register(zmqstructFix) } var zmqstructFix = fix{ "zmqstruct", "2013-03-20", zmqstruct, ` Make github.com/alecthomas/gozmq use structs instead of interfaces. `, } func zmqstruct(f *ast.File) bool { spec := importSpec(f, "github.com/alecthomas/gozmq") if spec == nil { return false } zmq := "gozmq" if spec.Name != nil { zmq = spec.Name.Name } fixed := false walk(f, func(n interface{}) { switch node := n.(type) { case *ast.ArrayType: t := zmqstructtype(zmq, node.Elt) if t != nil { node.Elt = t fixed = true } case *ast.CompositeLit: // This is irrelevant only because the original type is an // interface i.e. cannot be the type of a composite literal. case *ast.Ellipsis: t := zmqstructtype(zmq, node.Elt) if t != nil { node.Elt = t fixed = true } case *ast.Field: t := zmqstructtype(zmq, node.Type) if t != nil { node.Type = t fixed = true } case *ast.MapType: t := zmqstructtype(zmq, node.Key) if t != nil { node.Key = t fixed = true } t = zmqstructtype(zmq, node.Value) if t != nil { node.Value = t fixed = true } case *ast.Object: // Does something need to be done here with node.Type? // What does it take to trigger this case? case *ast.TypeAssertExpr: t := zmqstructtype(zmq, node.Type) if t != nil { node.Type = t fixed = true } case *ast.TypeSpec: t := zmqstructtype(zmq, node.Type) if t != nil { node.Type = t fixed = true } case *ast.ValueSpec: t := zmqstructtype(zmq, node.Type) if t != nil { node.Type = t fixed = true } } }) return fixed } func zmqstructtype(zmq string, n ast.Expr) ast.Expr { s, ok := n.(*ast.SelectorExpr) if ok { p, ok := s.X.(*ast.Ident) if ok && p.Name == zmq { if s.Sel.Name == "Context" || s.Sel.Name == "Socket" { return &ast.StarExpr{ X: &ast.SelectorExpr{ X: ast.NewIdent(zmq), Sel: ast.NewIdent(s.Sel.Name), }, } } } } return nil } ================================================ FILE: gozmqfix/zmqstruct_test.go ================================================ // Copyright 2013 Joshua Tacoma. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package main func init() { addTestCases(zmqstructTests, zmqstruct) } var zmqstructTests = []testCase{ { Name: "zmqstruct.0", In: `package main import zmq "github.com/alecthomas/gozmq" type M struct { c zmq.Context s zmq.Socket ss []zmq.Socket m map[zmq.Context]zmq.Socket } type S0 zmq.Socket func newM(c zmq.Context, s zmq.Socket, ss ...zmq.Socket) *M { if s == nil { s = c.NewSocket(zmq.PUB) } return &M{ c: c, s: s, ss: ss, } } var GlobalM = newM(c.NewContext(), nil.(zmq.Socket)) type Socket zmq.Socket var S Socket = Socket(M.s) `, Out: `package main import zmq "github.com/alecthomas/gozmq" type M struct { c *zmq.Context s *zmq.Socket ss []*zmq.Socket m map[*zmq.Context]*zmq.Socket } type S0 *zmq.Socket func newM(c *zmq.Context, s *zmq.Socket, ss ...*zmq.Socket) *M { if s == nil { s = c.NewSocket(zmq.PUB) } return &M{ c: c, s: s, ss: ss, } } var GlobalM = newM(c.NewContext(), nil.(*zmq.Socket)) type Socket *zmq.Socket var S Socket = Socket(M.s) `, }, { Name: "zmqstruct.1", In: `package main import "github.com/alecthomas/gozmq" type Socket *gozmq.Socket `, Out: `package main import "github.com/alecthomas/gozmq" type Socket *gozmq.Socket `, }, } ================================================ FILE: gozmqgen/README.md ================================================ # gozmqgen Intended use is: cd gozmq go run ./gozmqgen/main.go In case the template isn't quite right, you should also: go fmt *.go ================================================ FILE: gozmqgen/header.txt ================================================ ================================================ FILE: gozmqgen/main.go ================================================ package main import ( "encoding/xml" "flag" "fmt" "io" "io/ioutil" "net/http" "os" "path" "strings" "text/template" ) type Args struct { zversion string pages string comment_width uint templsource string headersource string } var args = Args{ zversion: "2.1,2.2,3.2,4.0", pages: "getsockopt,setsockopt", comment_width: 72, templsource: "./gozmqgen/template.txt", headersource: "./gozmqgen/header.txt", } func main() { flag.StringVar(&args.zversion, "zversion", args.zversion, "version of zmq") flag.StringVar(&args.pages, "pages", args.pages, "comma-delimited man page names") flag.UintVar(&args.comment_width, "comment-width", args.comment_width, "maximum width of comment text") flag.StringVar(&args.templsource, "template", args.templsource, "Name of template file or - to read STDIN.") flag.StringVar(&args.headersource, "header", args.headersource, "Name of header file.") flag.Parse() if len(args.templsource) == 0 { panic("'template' is required.") } data := map[string]interface{}{ "copyright": string(mustRead(args.headersource)), } for _, version := range strings.Split(args.zversion, ",") { data["build"] = buildtags[version] data["version"] = version for _, page := range strings.Split(args.pages, ",") { manual, err := LoadManual(version, "zmq_"+page) if err != nil { panic(err.Error()) } defer manual.Close() cite := "http://api.zeromq.org/" + version + ":zmq-" + page var options []map[string]interface{} optlist, err := ParseOptions(version, manual) if err != nil { panic(err.Error()) } for _, o := range optlist { o.SetCitation(cite + "#" + o.anchor) if !ignore[""][o.shortname] && !ignore[version][o.shortname] { options = append(options, o.Pod()) } } data[page] = map[string]interface{}{ "cite": cite, "options": options, } } raw_template := mustRead(args.templsource) t, err := template.New("main").Parse(string(raw_template)) if err != nil { panic(err.Error()) } out, err := os.Create("zmqgen_" + strings.Replace(version, ".", "_", -1) + ".go") if err != nil { panic(err.Error()) } else if err = t.Execute(out, data); err != nil { panic(err.Error()) } } } var ( gotypes = map[string]map[string]string{ "binary data": map[string]string{ "": "string", }, "binary data or Z85 text string": map[string]string{ "": "string", }, "character string": map[string]string{ "": "string", }, "int": map[string]string{ "": "int", "boolean": "bool", "milliseconds": "time.Duration", }, "int on POSIX systems, SOCKET on Windows": map[string]string{ "": "int", }, "int64_t": map[string]string{ "": "int64", "boolean": "bool", "milliseconds": "time.Duration", }, "NULL-terminated character string": map[string]string{ "": "string", }, "uint32_t": map[string]string{ "": "uint32", }, "uint64_t": map[string]string{ "": "uint64", "boolean": "bool", }, } ztypes = map[string]map[string]string{ "binary data": map[string]string{"": "String"}, "binary data or Z85 text string": map[string]string{"": "String"}, "character string": map[string]string{"": "String"}, "int": map[string]string{"": "Int"}, "int on POSIX systems, SOCKET on Windows": map[string]string{"": "Int"}, "int64_t": map[string]string{"": "Int64"}, "NULL-terminated character string": map[string]string{"": "String"}, "uint32_t": map[string]string{"": "UInt32"}, "uint64_t": map[string]string{"": "UInt64"}, } lowtypes = map[string]string{ "int32_t": "int32", "int64_t": "int64", "uint32_t": "uint32", "uint64_t": "uint64", } replacements = map[string]string{ "buf": "Buf", "Hwm": "HWM", "hwm": "HWM", "Ipv4only": "IPv4Only", "more": "More", "msg": "Msg", "pub": "PUB", "Router": "ROUTER", "size": "Size", "Tcp": "TCP", "timeo": "Timeout", } cachedir = path.Join(".cache", "codegen") // version : shortname : C type fixedtypes = map[string]map[string]string{ "": map[string]string{ "EVENTS": "uint64_t", "FD": "int", "RATE": "int64_t", "RCVBUF": "uint64_t", "RECOVERY_IVL": "int64_t", "SNDBUF": "uint64_t", "TYPE": "uint64_t", }, "2.1": map[string]string{ "RCVMORE": "uint64_t", }, "2.2": map[string]string{ "RCVMORE": "uint64_t", }, } fixedgotypes = map[string]string{ "TYPE": "SocketType", } // shortname : unit fixedunits = map[string]string{ "DELAY_ATTACH_ON_CONNECT": "boolean", "ROUTER_MANDATORY": "boolean", "XPUB_VERBOSE": "boolean", } // version : shortname ignore = map[string]map[string]bool{ "": map[string]bool{ "FD": true, "LAST_ENDPOINT": true, "MULTICAST_HOPS": true, }, "2.1": map[string]bool{ "RECOVERY_IVL": true, }, "2.2": map[string]bool{ "RECOVERY_IVL": true, }, "3.2": map[string]bool{}, } // shortname : shortname rename = map[string]string{ "RECOVERY_IVL_MSEC": "RECOVERY_IVL", } buildtags = map[string]string{ "2.1": "zmq_2_1", "2.2": "!zmq_2_1,!zmq_3_x,!zmq_4_x", "3.2": "zmq_3_x", "4.0": "zmq_4_x", } ) func fix(s string) string { for key, value := range replacements { s = strings.Replace(s, key, value, -1) } return s } func LoadManual(version string, funcname string) (io.ReadCloser, error) { pagename := version + ":" + funcname pagename = strings.Replace(pagename, ".", "-", -1) pagename = strings.Replace(pagename, "_", "-", -1) cachepath := path.Join(cachedir, pagename) cachefile, err := os.Open(cachepath) if err == nil { return cachefile, nil } os.MkdirAll(cachedir, 0755) url := "http://api.zeromq.org/" + pagename resp, err := http.Get(url) if err != nil { return nil, err } defer resp.Body.Close() if resp.StatusCode != 200 { return nil, fmt.Errorf("%s -> %s", url, resp.Status) } if cachefile, err = os.Create(cachepath); err != nil { return nil, err } if _, err := io.Copy(cachefile, resp.Body); err != nil { return nil, err } return os.Open(cachepath) } type Option struct { typ string // type as listed in source documentation unit string // unit as listed source documentation fullname string // e.g. "ZMQ_RCVMORE" shortname string // e.g. "RCVMORE" desc []string // one or more paragraphs cite string // URL to source documentation ctype string // C type e.g. "uint64_t" gotype string // Go type e.g. "SocketType" ztype string // option method suffix e.g. "Int64" lowtype string // go equivalent of C type e.g. "uint64" anchor string // id in source documentation duration bool // true if gotype=="time.Duration" gounit string // e.g. "time.Millisecond" cast bool // true if gotype needs casting } func NewOption(fullname string) *Option { return &Option{ fullname: fullname, shortname: fullname[4:], } } func (o *Option) Name() (name string) { shortname, ok := rename[o.shortname] if !ok { shortname = o.shortname } for _, part := range strings.Split(shortname, "_") { name = name + string(part[0]) + strings.ToLower(part[1:]) } return fix(name) } func (o *Option) AppendDescription(line string) { line = strings.TrimSpace(line) if len(line) > 0 { o.desc = append(o.desc, line) } } func (o *Option) SetCitation(cite string) { o.cite = cite } func (o *Option) Comment() (comment string) { desc := o.desc[1:] if len(o.cite) > 0 { desc = append([]string{o.cite, ""}, desc...) } for _, line := range desc { if len(line) > 0 && line[0] == ' ' { comment = comment + strings.TrimRight(line, "\n") + "\n" } else { // TODO: wrap line to width chars //wrapped = textwrap.wrap(line, width) //"\n".join(wrapped) + "\n%s\n" % wrapped comment = comment + line } } return } func (o *Option) Summary() string { return o.fullname + ": " + o.desc[0] + "." } func (o *Option) Pod() map[string]interface{} { return map[string]interface{}{ "fullname": o.fullname, "shortname": o.shortname, "nicename": o.Name(), "summary": o.Summary(), "description": strings.Split(o.Comment(), "\n"), "ctype": o.typ, "gotype": o.gotype, "ztype": o.ztype, "lowtype": o.lowtype, "anchor": o.anchor, "duration": o.duration, "citation": o.cite, "boolean": o.gotype == "bool", "gounit": o.gounit, "cast": o.cast, } } func (o *Option) String() string { return o.Name() } type OptionsBuilder struct { options []*Option version string } func (b *OptionsBuilder) Add(name string, info string) bool { if !strings.HasPrefix(name, "ZMQ_") { return false } option := NewOption(name) b.options = append(b.options, option) option.AppendDescription(info) return true } func (b *OptionsBuilder) Describe(info string) { if len(b.options) > 0 { b.options[len(b.options)-1].AppendDescription(info) } } func (b *OptionsBuilder) SetAnchor(anchor string) { if len(b.options) > 0 { b.options[len(b.options)-1].anchor = anchor } } func (b *OptionsBuilder) SetProperty(name string, value string) { if len(b.options) > 0 { option := b.options[len(b.options)-1] name = strings.TrimSpace(name) switch name { case "Option value type": option.typ = value break case "Option value unit": option.unit = value break case "Option value size": option.unit = "Z85" break } if len(option.typ) > 0 && len(option.unit) > 0 { if val, ok := fixedtypes[""][option.shortname]; ok { option.typ = val } else if val, ok := fixedtypes[b.version][option.shortname]; ok { option.typ = val } if val, ok := lowtypes[option.typ]; ok { option.lowtype = val } else { option.lowtype = option.typ } if val, ok := fixedunits[option.shortname]; ok { option.unit = val } gomap := gotypes[option.typ] if val, ok := gomap[option.unit]; ok { option.gotype = val } else { option.gotype = gomap[""] } if val, ok := fixedgotypes[option.shortname]; ok { option.gotype = val option.cast = true } zmap := ztypes[option.typ] if val, ok := zmap[option.unit]; ok { option.ztype = val } else { option.ztype = zmap[""] } if option.gotype == "time.Duration" { option.duration = true switch option.unit { case "milliseconds": option.gounit = "time.Millisecond" case "seconds": option.gounit = "time.Second" } } } option.AppendDescription(fmt.Sprintf(" %-25s %s\n", name, value)) } } func ParseOptions(version string, r io.Reader) ([]*Option, error) { d := xml.NewDecoder(r) d.Strict = false d.AutoClose = xml.HTMLAutoClose d.Entity = xml.HTMLEntity b := &OptionsBuilder{version: version} var state, text, text2 string for { t, err := d.Token() if err == io.EOF { break } else if err != nil { return nil, err } else { switch token := t.(type) { case xml.StartElement: switch token.Name.Local { case "h3": state = "title" text = "" text2 = "unknown" for _, attr := range token.Attr { switch attr.Name.Local { case "id": text2 = attr.Value } } case "table": switch state { case "describing": for _, attr := range token.Attr { switch attr.Name.Local { case "class": if attr.Value == "wiki-content-table" { b.Describe(text) text = "" state = "properties" } } } } case "td": switch state { case "properties": state = "property-name" case "property-name": state = "property-value" } } case xml.EndElement: switch state { case "title": switch token.Name.Local { case "h3": parts := strings.SplitN(text, ": ", 2) if b.Add(parts[0], parts[1]) { state = "describing" b.SetAnchor(text2) } else { state = "" } text = "" text2 = "" } case "describing": switch token.Name.Local { case "p", "li": b.Describe(text) text = "" } case "properties": switch token.Name.Local { case "table": state = "" } case "property-value": switch token.Name.Local { case "td": b.SetProperty(text, text2) state = "properties" text = "" text2 = "" } } case xml.CharData: switch state { case "title": text += string(token) case "describing": text += string(token) case "property-name": text += string(token) case "property-value": text2 += string(token) } } } } return b.options, nil } func mustRead(name string) []byte { var raw []byte var err error if name == "-" { raw, err = ioutil.ReadAll(os.Stdin) } else { raw, err = ioutil.ReadFile(name) } if err != nil { panic(err.Error()) } return raw } ================================================ FILE: gozmqgen/main_test.go ================================================ package main import ( "testing" ) // This test depends on a remote HTTP service that may not even be available. func TestLoadManual(t *testing.T) { if m, err := LoadManual("3.2", "zmq-setsockopt"); err != nil { t.Errorf(err.Error()) } else if m == nil { t.Errorf("no error yet nil reader.") } } ================================================ FILE: gozmqgen/template.txt ================================================ // +build {{.build}} // {{if .copyright}}{{.copyright}} {{end}} package gozmq import ( "time" ) // This file was {{/*NOT */}}generated automatically. Changes made here will {{/*NOT */}}be lost. // Socket Option Getters{{with .getsockopt}}{{range .options}} // {{.summary}} // // See: {{.citation}} // func (s *Socket) {{.nicename}}() ({{.gotype}}, error) { {{if .duration}}ms, err := s.GetSockOpt{{.ztype}}({{.shortname}}) return time.Duration(ms) * {{.gounit}}, err{{else}}{{if .boolean}}value, err := s.GetSockOpt{{.ztype}}({{.shortname}}) return value != 0, err{{else}}{{if .cast}}value, err := s.GetSockOpt{{.ztype}}({{.shortname}}) return {{.gotype}}(value), err{{else}}return s.GetSockOpt{{.ztype}}({{.shortname}}){{end}}{{end}}{{end}} }{{end}}{{end}} // Socket Option Setters{{with .setsockopt}}{{range .options}} // {{.summary}} // // See: {{.citation}} // func (s *Socket) Set{{.nicename}}(value {{.gotype}}) error { {{if .duration}}return s.SetSockOpt{{.ztype}}({{.shortname}}, {{.lowtype}}(value/{{.gounit}})){{else}}{{if .boolean}}if value { return s.SetSockOpt{{.ztype}}({{.shortname}}, 1) } return s.SetSockOpt{{.ztype}}({{.shortname}}, 0){{else}}return s.SetSockOpt{{.ztype}}({{.shortname}}, {{if .cast}}{{.lowtype}}({{end}}value{{if .cast}}){{end}}){{end}}{{end}} }{{end}}{{end}} ================================================ FILE: zmq.go ================================================ /* Copyright 2010-2012 Alec Thomas Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // Go (golang) Bindings for 0mq (zmq, zeromq) package gozmq /* #cgo pkg-config: libzmq #include #include #include */ import "C" import ( "errors" "sync" "syscall" "time" "unsafe" ) type SocketType int type IntSocketOption int type Int64SocketOption int type UInt64SocketOption int type StringSocketOption int type BoolSocketOption int type MessageOption int type SendRecvOption int const ( // NewSocket types PAIR = SocketType(C.ZMQ_PAIR) PUB = SocketType(C.ZMQ_PUB) SUB = SocketType(C.ZMQ_SUB) REQ = SocketType(C.ZMQ_REQ) REP = SocketType(C.ZMQ_REP) DEALER = SocketType(C.ZMQ_DEALER) ROUTER = SocketType(C.ZMQ_ROUTER) PULL = SocketType(C.ZMQ_PULL) PUSH = SocketType(C.ZMQ_PUSH) XPUB = SocketType(C.ZMQ_XPUB) XSUB = SocketType(C.ZMQ_XSUB) // Deprecated aliases XREQ = DEALER XREP = ROUTER UPSTREAM = PULL DOWNSTREAM = PUSH // NewSocket options AFFINITY = UInt64SocketOption(C.ZMQ_AFFINITY) IDENTITY = StringSocketOption(C.ZMQ_IDENTITY) SUBSCRIBE = StringSocketOption(C.ZMQ_SUBSCRIBE) UNSUBSCRIBE = StringSocketOption(C.ZMQ_UNSUBSCRIBE) RATE = Int64SocketOption(C.ZMQ_RATE) RECOVERY_IVL = Int64SocketOption(C.ZMQ_RECOVERY_IVL) SNDBUF = UInt64SocketOption(C.ZMQ_SNDBUF) RCVBUF = UInt64SocketOption(C.ZMQ_RCVBUF) FD = Int64SocketOption(C.ZMQ_FD) EVENTS = UInt64SocketOption(C.ZMQ_EVENTS) TYPE = UInt64SocketOption(C.ZMQ_TYPE) LINGER = IntSocketOption(C.ZMQ_LINGER) RECONNECT_IVL = IntSocketOption(C.ZMQ_RECONNECT_IVL) RECONNECT_IVL_MAX = IntSocketOption(C.ZMQ_RECONNECT_IVL_MAX) BACKLOG = IntSocketOption(C.ZMQ_BACKLOG) // Send/recv options SNDMORE = SendRecvOption(C.ZMQ_SNDMORE) ) type zmqErrno syscall.Errno var ( // Additional ZMQ errors ENOTSOCK error = zmqErrno(C.ENOTSOCK) EFSM error = zmqErrno(C.EFSM) EINVAL error = syscall.EINVAL ENOCOMPATPROTO error = zmqErrno(C.ENOCOMPATPROTO) ETERM error = zmqErrno(C.ETERM) EMTHREAD error = zmqErrno(C.EMTHREAD) ) type PollEvents C.short const ( POLLIN = PollEvents(C.ZMQ_POLLIN) POLLOUT = PollEvents(C.ZMQ_POLLOUT) POLLERR = PollEvents(C.ZMQ_POLLERR) ) type DeviceType int const ( STREAMER = DeviceType(C.ZMQ_STREAMER) FORWARDER = DeviceType(C.ZMQ_FORWARDER) QUEUE = DeviceType(C.ZMQ_QUEUE) ) var ( pollunit time.Duration ) func init() { if v, _, _ := Version(); v < 3 { pollunit = time.Microsecond } else { pollunit = time.Millisecond } } // void zmq_version (int *major, int *minor, int *patch); func Version() (int, int, int) { var major, minor, patch C.int C.zmq_version(&major, &minor, &patch) return int(major), int(minor), int(patch) } func (e zmqErrno) Error() string { return C.GoString(C.zmq_strerror(C.int(e))) } // If possible, convert a syscall.Errno to a zmqErrno. func casterr(fromcgo error) error { errno, ok := fromcgo.(syscall.Errno) if !ok { return fromcgo } zmqerrno := zmqErrno(errno) switch zmqerrno { case ENOTSOCK: return zmqerrno } if zmqerrno >= C.ZMQ_HAUSNUMERO { return zmqerrno } return errno } func getErrorForTesting() error { return zmqErrno(C.EFSM) } /* * A context handles socket creation and asynchronous message delivery. * There should generally be one context per application. */ type Context struct { c unsafe.Pointer mutex sync.Mutex // ensure init is only called once init func() // func that calls zmq_init err error // error returned from zmq_init iothreads int // hold the iothreads option until zmq_init time } // Create a new context. func NewContext() (*Context, error) { c := &Context{iothreads: 1} c.init = func() { c.mutex.Lock() defer c.mutex.Unlock() if c.c == nil && c.err == nil { // C.NULL is correct but causes a runtime failure on darwin at present if ptr, err := C.zmq_init(C.int(c.iothreads)); ptr != nil /*C.NULL*/ { c.c = ptr } else { c.err = casterr(err) } } } return c, nil } func (c *Context) Close() { // C.NULL is correct but causes a runtime failure on darwin at present if c.c != nil /*C.NULL*/ { C.zmq_term(c.c) } } // Create a new socket. // void *zmq_socket (void *context, int type); func (c *Context) NewSocket(t SocketType) (*Socket, error) { if c.init(); c.err != nil { return nil, c.err } s, err := C.zmq_socket(c.c, C.int(t)) // C.NULL is correct but causes a runtime failure on darwin at present if s != nil /*C.NULL*/ { return &Socket{c: c, s: s}, nil } return nil, casterr(err) } type Socket struct { // XXX Ensure the zmq context doesn't get destroyed underneath us. c *Context s unsafe.Pointer } // Shutdown the socket. // int zmq_close (void *s); func (s *Socket) Close() error { if s.c == nil { return ENOTSOCK } if rc, err := C.zmq_close(s.s); rc != 0 { return casterr(err) } s.c = nil return nil } // Set an int option on the socket. // int zmq_setsockopt (void *s, int option, const void *optval, size_t optvallen); func (s *Socket) SetSockOptInt(option IntSocketOption, value int) error { val := C.int(value) if rc, err := C.zmq_setsockopt(s.s, C.int(option), unsafe.Pointer(&val), C.size_t(unsafe.Sizeof(val))); rc != 0 { return casterr(err) } return nil } // Set an int64 option on the socket. // int zmq_setsockopt (void *s, int option, const void *optval, size_t optvallen); func (s *Socket) SetSockOptInt64(option Int64SocketOption, value int64) error { if rc, err := C.zmq_setsockopt(s.s, C.int(option), unsafe.Pointer(&value), C.size_t(unsafe.Sizeof(value))); rc != 0 { return casterr(err) } return nil } // Set a uint64 option on the socket. // int zmq_setsockopt (void *s, int option, const void *optval, size_t optvallen); func (s *Socket) SetSockOptUInt64(option UInt64SocketOption, value uint64) error { if rc, err := C.zmq_setsockopt(s.s, C.int(option), unsafe.Pointer(&value), C.size_t(unsafe.Sizeof(value))); rc != 0 { return casterr(err) } return nil } // Set a string option on the socket. // int zmq_setsockopt (void *s, int option, const void *optval, size_t optvallen); func (s *Socket) SetSockOptString(option StringSocketOption, value string) error { v := C.CString(value) defer C.free(unsafe.Pointer(v)) if rc, err := C.zmq_setsockopt(s.s, C.int(option), unsafe.Pointer(v), C.size_t(len(value))); rc != 0 { return casterr(err) } return nil } // Set a string option on the socket to nil. // int zmq_setsockopt (void *s, int option, const void *optval, size_t optvallen); func (s *Socket) SetSockOptStringNil(option StringSocketOption) error { if rc, err := C.zmq_setsockopt(s.s, C.int(option), nil, 0); rc != 0 { return casterr(err) } return nil } // Get an int option from the socket. // int zmq_getsockopt (void *s, int option, void *optval, size_t *optvallen); func (s *Socket) GetSockOptInt(option IntSocketOption) (value int, err error) { size := C.size_t(unsafe.Sizeof(value)) var rc C.int if rc, err = C.zmq_getsockopt(s.s, C.int(option), unsafe.Pointer(&value), &size); rc != 0 { err = casterr(err) return } return } // Get an int64 option from the socket. // int zmq_getsockopt (void *s, int option, void *optval, size_t *optvallen); func (s *Socket) GetSockOptInt64(option Int64SocketOption) (value int64, err error) { size := C.size_t(unsafe.Sizeof(value)) var rc C.int if rc, err = C.zmq_getsockopt(s.s, C.int(option), unsafe.Pointer(&value), &size); rc != 0 { err = casterr(err) return } return } // Get a uint64 option from the socket. // int zmq_getsockopt (void *s, int option, void *optval, size_t *optvallen); func (s *Socket) GetSockOptUInt64(option UInt64SocketOption) (value uint64, err error) { size := C.size_t(unsafe.Sizeof(value)) var rc C.int if rc, err = C.zmq_getsockopt(s.s, C.int(option), unsafe.Pointer(&value), &size); rc != 0 { println("GetSockOptUInt64:", err.Error()) err = casterr(err) return } return } // Get a string option from the socket. // int zmq_getsockopt (void *s, int option, void *optval, size_t *optvallen); func (s *Socket) GetSockOptString(option StringSocketOption) (value string, err error) { var buffer [1024]byte var size C.size_t = 1024 var rc C.int if rc, err = C.zmq_getsockopt(s.s, C.int(option), unsafe.Pointer(&buffer), &size); rc != 0 { err = casterr(err) return } value = string(buffer[:size]) return } func (s *Socket) GetSockOptBool(option BoolSocketOption) (value bool, err error) { size := C.size_t(unsafe.Sizeof(value)) var rc C.int if rc, err = C.zmq_getsockopt(s.s, C.int(option), unsafe.Pointer(&value), &size); rc != 0 { err = casterr(err) return } return } // Bind the socket to a listening address. // int zmq_bind (void *s, const char *addr); func (s *Socket) Bind(address string) error { a := C.CString(address) defer C.free(unsafe.Pointer(a)) if rc, err := C.zmq_bind(s.s, a); rc != 0 { return casterr(err) } return nil } // Connect the socket to an address. // int zmq_connect (void *s, const char *addr); func (s *Socket) Connect(address string) error { if s.c == nil { return ENOTSOCK } a := C.CString(address) defer C.free(unsafe.Pointer(a)) if rc, err := C.zmq_connect(s.s, a); rc != 0 { return casterr(err) } return nil } // Send a multipart message. func (s *Socket) SendMultipart(parts [][]byte, flags SendRecvOption) (err error) { for i := 0; i < len(parts)-1; i++ { if err = s.Send(parts[i], SNDMORE|flags); err != nil { return } } err = s.Send(parts[(len(parts)-1)], flags) return } // Receive a multipart message. func (s *Socket) RecvMultipart(flags SendRecvOption) (parts [][]byte, err error) { parts = make([][]byte, 0) for { var data []byte var more bool data, err = s.Recv(flags) if err != nil { return } parts = append(parts, data) more, err = s.getRcvmore() if err != nil { return } if !more { break } } return } // return the func (s *Socket) apiSocket() unsafe.Pointer { return s.s } // Item to poll for read/write events on, either a *Socket or a file descriptor type PollItem struct { Socket *Socket // socket to poll for events on Fd ZmqOsSocketType // fd to poll for events on as returned from os.File.Fd() Events PollEvents // event set to poll for REvents PollEvents // events that were present } // a set of items to poll for events on type PollItems []PollItem // Poll ZmqSockets and file descriptors for I/O readiness. Timeout is in // time.Duration. The smallest possible timeout is time.Millisecond for // ZeroMQ version 3 and above, and time.Microsecond for earlier versions. func Poll(items []PollItem, timeout time.Duration) (count int, err error) { zitems := make([]C.zmq_pollitem_t, len(items)) for i, pi := range items { zitems[i].socket = pi.Socket.apiSocket() zitems[i].fd = pi.Fd.ToRaw() zitems[i].events = C.short(pi.Events) } ztimeout := C.long(-1) if timeout >= 0 { ztimeout = C.long(uint64(timeout / pollunit)) } rc, err := C.zmq_poll(&zitems[0], C.int(len(zitems)), ztimeout) if rc == -1 { return 0, casterr(err) } for i, zi := range zitems { items[i].REvents = PollEvents(zi.revents) } return int(rc), nil } // run a zmq_device passing messages between in and out func Device(t DeviceType, in, out *Socket) error { if rc, err := C.zmq_device(C.int(t), in.apiSocket(), out.apiSocket()); rc != 0 { return casterr(err) } return errors.New("zmq_device() returned unexpectedly.") } // XXX For now, this library abstracts zmq_msg_t out of the API. // int zmq_msg_init (zmq_msg_t *msg); // int zmq_msg_init_size (zmq_msg_t *msg, size_t size); // int zmq_msg_close (zmq_msg_t *msg); // size_t zmq_msg_size (zmq_msg_t *msg); // void *zmq_msg_data (zmq_msg_t *msg); // int zmq_msg_copy (zmq_msg_t *dest, zmq_msg_t *src); // int zmq_msg_move (zmq_msg_t *dest, zmq_msg_t *src); ================================================ FILE: zmq_2_2.go ================================================ // +build !zmq_2_1 /* Copyright 2010-2012 Alec Thomas Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package gozmq /* #cgo pkg-config: libzmq #include */ import "C" const ( RCVTIMEO = IntSocketOption(C.ZMQ_RCVTIMEO) SNDTIMEO = IntSocketOption(C.ZMQ_SNDTIMEO) ) ================================================ FILE: zmq_2_x.go ================================================ // +build !zmq_3_x,!zmq_4_x /* Copyright 2010-2012 Alec Thomas Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package gozmq /* #cgo pkg-config: libzmq #include #include #include */ import "C" import "unsafe" const ( RCVMORE = UInt64SocketOption(C.ZMQ_RCVMORE) RECOVERY_IVL_MSEC = Int64SocketOption(C.ZMQ_RECOVERY_IVL_MSEC) SWAP = Int64SocketOption(C.ZMQ_SWAP) MCAST_LOOP = Int64SocketOption(C.ZMQ_MCAST_LOOP) HWM = UInt64SocketOption(C.ZMQ_HWM) NOBLOCK = SendRecvOption(C.ZMQ_NOBLOCK) // Forwards-compatible aliases: DONTWAIT = NOBLOCK ) // Get a context option. func (c *Context) IOThreads() (int, error) { return c.iothreads, nil } // Set a context option. func (c *Context) SetIOThreads(value int) error { c.iothreads = value return nil } // Send a message to the socket. // int zmq_send (void *s, zmq_msg_t *msg, int flags); func (s *Socket) Send(data []byte, flags SendRecvOption) error { var m C.zmq_msg_t // Copy data array into C-allocated buffer. size := C.size_t(len(data)) if rc, err := C.zmq_msg_init_size(&m, size); rc != 0 { return casterr(err) } if size > 0 { // FIXME Ideally this wouldn't require a copy. C.memcpy(C.zmq_msg_data(&m), unsafe.Pointer(&data[0]), size) // XXX I hope this works...(seems to) } if rc, err := C.zmq_send(s.s, &m, C.int(flags)); rc != 0 { // zmq_send did not take ownership, free message C.zmq_msg_close(&m) return casterr(err) } return nil } // Receive a message from the socket. // int zmq_recv (void *s, zmq_msg_t *msg, int flags); func (s *Socket) Recv(flags SendRecvOption) (data []byte, err error) { // Allocate and initialise a new zmq_msg_t var m C.zmq_msg_t var rc C.int if rc, err = C.zmq_msg_init(&m); rc != 0 { err = casterr(err) return } defer C.zmq_msg_close(&m) // Receive into message if rc, err = C.zmq_recv(s.s, &m, C.int(flags)); rc != 0 { err = casterr(err) return } err = nil // Copy message data into a byte array // FIXME Ideally this wouldn't require a copy. size := C.zmq_msg_size(&m) if size > 0 { data = C.GoBytes(C.zmq_msg_data(&m), C.int(size)) } else { data = nil } return } // Portability helper func (s *Socket) getRcvmore() (more bool, err error) { value, err := s.GetSockOptUInt64(RCVMORE) more = value != 0 return } ================================================ FILE: zmq_3_x.go ================================================ // +build zmq_3_x zmq_4_x /* Copyright 2010-2012 Alec Thomas Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package gozmq /* #cgo pkg-config: libzmq #include #include #include */ import "C" import ( "errors" "unsafe" ) const ( RCVMORE = IntSocketOption(C.ZMQ_RCVMORE) SNDHWM = IntSocketOption(C.ZMQ_SNDHWM) RCVHWM = IntSocketOption(C.ZMQ_RCVHWM) // TODO Not documented in the man page... //LAST_ENDPOINT = UInt64SocketOption(C.ZMQ_LAST_ENDPOINT) DELAY_ATTACH_ON_CONNECT = IntSocketOption(C.ZMQ_DELAY_ATTACH_ON_CONNECT) FAIL_UNROUTABLE = BoolSocketOption(C.ZMQ_FAIL_UNROUTABLE) IPV4ONLY = IntSocketOption(C.ZMQ_IPV4ONLY) MAXMSGSIZE = Int64SocketOption(C.ZMQ_MAXMSGSIZE) ROUTER_MANDATORY = IntSocketOption(C.ZMQ_ROUTER_MANDATORY) TCP_KEEPALIVE = IntSocketOption(C.ZMQ_TCP_KEEPALIVE) TCP_KEEPALIVE_CNT = IntSocketOption(C.ZMQ_TCP_KEEPALIVE_CNT) TCP_KEEPALIVE_IDLE = IntSocketOption(C.ZMQ_TCP_KEEPALIVE_IDLE) TCP_KEEPALIVE_INTVL = IntSocketOption(C.ZMQ_TCP_KEEPALIVE_INTVL) TCP_ACCEPT_FILTER = StringSocketOption(C.ZMQ_TCP_ACCEPT_FILTER) XPUB_VERBOSE = IntSocketOption(C.ZMQ_XPUB_VERBOSE) // Message options MORE = MessageOption(C.ZMQ_MORE) // Send/recv options DONTWAIT = SendRecvOption(C.ZMQ_DONTWAIT) // Deprecated aliases NOBLOCK = DONTWAIT ) // Socket transport events type Event int const ( EVENT_CONNECTED = Event(C.ZMQ_EVENT_CONNECTED) EVENT_CONNECT_DELAYED = Event(C.ZMQ_EVENT_CONNECT_DELAYED) EVENT_CONNECT_RETRIED = Event(C.ZMQ_EVENT_CONNECT_RETRIED) EVENT_LISTENING = Event(C.ZMQ_EVENT_LISTENING) EVENT_BIND_FAILED = Event(C.ZMQ_EVENT_BIND_FAILED) EVENT_ACCEPTED = Event(C.ZMQ_EVENT_ACCEPTED) EVENT_ACCEPT_FAILED = Event(C.ZMQ_EVENT_ACCEPT_FAILED) EVENT_CLOSED = Event(C.ZMQ_EVENT_CLOSED) EVENT_CLOSE_FAILED = Event(C.ZMQ_EVENT_CLOSE_FAILED) EVENT_DISCONNECTED = Event(C.ZMQ_EVENT_DISCONNECTED) EVENT_ALL = EVENT_CONNECTED | EVENT_CONNECT_DELAYED | EVENT_CONNECT_RETRIED | EVENT_LISTENING | EVENT_BIND_FAILED | EVENT_ACCEPTED | EVENT_ACCEPT_FAILED | EVENT_CLOSED | EVENT_CLOSE_FAILED | EVENT_DISCONNECTED ) // Get a context option. // int zmq_ctx_get (void *c, int); func (c *Context) get(option C.int) (int, error) { if c.init(); c.err != nil { return -1, c.err } var value C.int var err error if value, err = C.zmq_ctx_get(c.c, option); err != nil { return -1, casterr(err) } return int(value), nil } // Set a context option. // int zmq_ctx_set (void *c, int, int); func (c *Context) set(option C.int, value int) error { if c.init(); c.err != nil { return c.err } if rc, err := C.zmq_ctx_set(c.c, option, C.int(value)); rc == -1 { return casterr(err) } return nil } func (c *Context) IOThreads() (int, error) { return c.get(C.ZMQ_IO_THREADS) } func (c *Context) MaxSockets() (int, error) { return c.get(C.ZMQ_MAX_SOCKETS) } func (c *Context) SetIOThreads(value int) error { return c.set(C.ZMQ_IO_THREADS, value) } func (c *Context) SetMaxSockets(value int) error { return c.set(C.ZMQ_MAX_SOCKETS, value) } func (s *Socket) SetHWM(value int) error { snd := s.SetSndHWM(value) rcv := s.SetRcvHWM(value) if snd != nil { return snd } return rcv } func (s *Socket) SetTCPAcceptFilterNil() error { return s.SetSockOptStringNil(TCP_ACCEPT_FILTER) } // Disconnect the socket from the address. // int zmq_disconnect (void *s, const char *addr); func (s *Socket) Disconnect(address string) error { if s.c == nil { return ENOTSOCK } a := C.CString(address) defer C.free(unsafe.Pointer(a)) if rc, err := C.zmq_disconnect(s.s, a); rc != 0 { return casterr(err) } return nil } // Send a message to the socket. // int zmq_send (void *s, zmq_msg_t *msg, int flags); func (s *Socket) Send(data []byte, flags SendRecvOption) error { var m C.zmq_msg_t // Copy data array into C-allocated buffer. size := C.size_t(len(data)) if rc, err := C.zmq_msg_init_size(&m, size); rc != 0 { return casterr(err) } if size > 0 { // FIXME Ideally this wouldn't require a copy. C.memcpy(C.zmq_msg_data(&m), unsafe.Pointer(&data[0]), size) // XXX I hope this works...(seems to) } if rc, err := C.zmq_sendmsg(s.s, &m, C.int(flags)); rc == -1 { // zmq_send did not take ownership, free message C.zmq_msg_close(&m) return casterr(err) } return nil } // Receive a message from the socket. // int zmq_recv (void *s, zmq_msg_t *msg, int flags); func (s *Socket) Recv(flags SendRecvOption) (data []byte, err error) { // Allocate and initialise a new zmq_msg_t var m C.zmq_msg_t var rc C.int if rc, err = C.zmq_msg_init(&m); rc != 0 { err = casterr(err) return } defer C.zmq_msg_close(&m) // Receive into message if rc, err = C.zmq_recvmsg(s.s, &m, C.int(flags)); rc == -1 { err = casterr(err) return } err = nil // Copy message data into a byte array // FIXME Ideally this wouldn't require a copy. size := C.zmq_msg_size(&m) if size > 0 { data = C.GoBytes(C.zmq_msg_data(&m), C.int(size)) } else { data = nil } return } // Register a monitoring callback endpoint. // int zmq_socket_monitor (void *s, const char *addr, int events); func (s *Socket) Monitor(address string, events Event) error { a := C.CString(address) defer C.free(unsafe.Pointer(a)) rc, err := C.zmq_socket_monitor(s.apiSocket(), a, C.int(events)) if rc == -1 { return casterr(err) } return nil } // Portability helper func (s *Socket) getRcvmore() (more bool, err error) { value, err := s.GetSockOptInt(RCVMORE) more = value != 0 return } // run a zmq_proxy with in, out and capture sockets func Proxy(in, out, capture *Socket) error { var c unsafe.Pointer if capture != nil { c = capture.apiSocket() } if rc, err := C.zmq_proxy(in.apiSocket(), out.apiSocket(), c); rc != 0 { return casterr(err) } return errors.New("zmq_proxy() returned unexpectedly.") } ================================================ FILE: zmq_3_x_test.go ================================================ // +build zmq_3_x zmq_4_x /* Copyright 2010 Alec Thomas Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package gozmq import ( "errors" "testing" "time" ) const ADDR_PROXY_IN = "tcp://127.0.0.1:24114" const ADDR_PROXY_OUT = "tcp://127.0.0.1:24115" const ADDR_PROXY_CAP = "tcp://127.0.0.1:24116" func TestProxy(t *testing.T) { te1, te2 := NewTestEnv(t), NewTestEnv(t) exitOk := make(chan bool, 1) go func() { in := te1.NewBoundSocket(ROUTER, ADDR_PROXY_IN) out := te1.NewBoundSocket(DEALER, ADDR_PROXY_OUT) capture := te1.NewBoundSocket(PUSH, ADDR_PROXY_CAP) err := Proxy(in, out, capture) select { case <-exitOk: default: t.Error("Proxy() failed: ", err) } }() in := te2.NewConnectedSocket(REQ, ADDR_PROXY_IN) out := te2.NewConnectedSocket(REP, ADDR_PROXY_OUT) capture := te2.NewConnectedSocket(PULL, ADDR_PROXY_CAP) time.Sleep(1e8) te2.Send(in, nil, 0) te2.Recv(out, 0) te2.Recv(capture, 0) te2.Close() exitOk <- true te1.Close() } func TestProxyNoCapture(t *testing.T) { te1, te2 := NewTestEnv(t), NewTestEnv(t) exitOk := make(chan bool, 1) go func() { in := te1.NewBoundSocket(ROUTER, ADDR_PROXY_IN) out := te1.NewBoundSocket(DEALER, ADDR_PROXY_OUT) err := Proxy(in, out, nil) select { case <-exitOk: default: t.Error("Proxy() failed: ", err) } }() in := te2.NewConnectedSocket(REQ, ADDR_PROXY_IN) out := te2.NewConnectedSocket(REP, ADDR_PROXY_OUT) time.Sleep(1e8) te2.Send(in, nil, 0) te2.Recv(out, 0) te2.Close() exitOk <- true te1.Close() } func TestSocket_SetSockOptStringNil(t *testing.T) { failed := make(chan bool, 2) c, _ := NewContext() defer c.Close() go func() { srv, _ := c.NewSocket(REP) defer srv.Close() srv.SetSockOptString(TCP_ACCEPT_FILTER, "127.0.0.1") srv.SetSockOptString(TCP_ACCEPT_FILTER, "192.0.2.1") srv.Bind(ADDRESS1) // 127.0.0.1 and 192.0.2.1 are allowed here. // The test will fail if the following line is removed: srv.SetSockOptStringNil(TCP_ACCEPT_FILTER) srv.SetSockOptString(TCP_ACCEPT_FILTER, "192.0.2.2") srv.Bind(ADDRESS2) // Only 192.0.2.1 is allowed here. for { if _, err := srv.Recv(0); err != nil { break } srv.Send(nil, 0) } }() go func() { s2, _ := c.NewSocket(REQ) defer s2.Close() s2.SetSockOptInt(LINGER, 0) s2.Connect(ADDRESS2) s2.Send(nil, 0) if _, err := s2.Recv(0); err == nil { // 127.0.0.1 is supposed to be ignored by ADDRESS2: t.Error("SetSockOptStringNil did not clear TCP_ACCEPT_FILTER.") } failed <- true }() s1, _ := c.NewSocket(REQ) defer s1.Close() s1.Connect(ADDRESS1) s1.Send(nil, 0) s1.Recv(0) select { case <-failed: case <-time.After(50 * time.Millisecond): } } const ( TESTMONITOR_ADDR_SINK = "tcp://127.0.0.1:24117" TESTMONITOR_ADDR_EVENTS = "inproc://TestMonitorEvents" ) func TestMonitor(t *testing.T) { te := NewTestEnv(t) defer te.Close() // Prepare the sink socket. out := te.NewSocket(PULL) err := out.Bind(TESTMONITOR_ADDR_SINK) if err != nil { t.Fatal(err) } // Prepare the source socket, do not connect yet. in := te.NewSocket(PUSH) defer in.Close() // Attach the monitor. err = in.Monitor(TESTMONITOR_ADDR_EVENTS, EVENT_CONNECTED|EVENT_DISCONNECTED) if err != nil { out.Close() t.Fatal(err) } monitor := te.NewConnectedSocket(PAIR, TESTMONITOR_ADDR_EVENTS) // Connect the client to the server, wait for EVENT_CONNECTED. err = in.Connect(TESTMONITOR_ADDR_SINK) if err != nil { out.Close() t.Fatal(err) } err = waitForEvent(t, monitor) if err != nil { out.Close() t.Fatal(err) } // Close the sink socket, wait for EVENT_DISCONNECTED. err = out.Close() if err != nil { t.Fatal(err) } err = waitForEvent(t, monitor) if err != nil { t.Fatal(err) } } func waitForEvent(t *testing.T, monitor *Socket) error { exit := make(chan error, 1) // This goroutine will return either when an event is received // or the context is closed. go func() { // RecvMultipart should work for both zeromq3-x and libzmq API. _, ex := monitor.RecvMultipart(0) exit <- ex }() timeout := time.After(time.Second) select { case err := <-exit: return err case <-timeout: return errors.New("Test timed out") } return nil } ================================================ FILE: zmq_4_x.go ================================================ // +build zmq_4_x /* Copyright 2010-2012 Alec Thomas Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package gozmq /* #cgo pkg-config: libzmq #include #include #include */ import "C" const ( IPV6 = IntSocketOption(C.ZMQ_IPV6) IMMEDIATE = IntSocketOption(C.ZMQ_IMMEDIATE) MECHANISM = IntSocketOption(C.ZMQ_MECHANISM) PLAIN_SERVER = IntSocketOption(C.ZMQ_PLAIN_SERVER) PLAIN_USERNAME = StringSocketOption(C.ZMQ_PLAIN_USERNAME) PLAIN_PASSWORD = StringSocketOption(C.ZMQ_PLAIN_PASSWORD) CURVE_PUBLICKEY = StringSocketOption(C.ZMQ_CURVE_PUBLICKEY) CURVE_SECRETKEY = StringSocketOption(C.ZMQ_CURVE_SECRETKEY) CURVE_SERVERKEY = StringSocketOption(C.ZMQ_CURVE_SERVERKEY) ZAP_DOMAIN = StringSocketOption(C.ZMQ_ZAP_DOMAIN) ROUTER_RAW = IntSocketOption(C.ZMQ_ROUTER_RAW) PROBE_ROUTER = IntSocketOption(C.ZMQ_PROBE_ROUTER) REQ_CORRELATE = IntSocketOption(C.ZMQ_REQ_CORRELATE) REQ_RELAXED = IntSocketOption(C.ZMQ_REQ_RELAXED) CURVE_SERVER = IntSocketOption(C.ZMQ_CURVE_SERVER) CONFLATE = IntSocketOption(C.ZMQ_CONFLATE) ) ================================================ FILE: zmq_test.go ================================================ /* Copyright 2010 Alec Thomas Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package gozmq import ( "log" "runtime" "syscall" "testing" "time" ) const ADDRESS1 = "tcp://127.0.0.1:23456" const ADDRESS2 = "tcp://127.0.0.1:23457" const ADDRESS3 = "tcp://127.0.0.1:23458" // Addresses for the device test. These cannot be reused since the device // will keep running after the test terminates const ADDR_DEV_IN = "tcp://127.0.0.1:24111" const ADDR_DEV_OUT = "tcp://127.0.0.1:24112" // a process local address const ADDRESS_INPROC = "inproc://test" const SERVER_READY = "SERVER READY" func runServer(t *testing.T, c *Context, callback func(s *Socket)) chan bool { finished := make(chan bool) go func() { runtime.LockOSThread() defer runtime.UnlockOSThread() s, _ := c.NewSocket(REP) defer s.Close() if rc := s.Bind(ADDRESS1); rc != nil { t.Errorf("Failed to bind to %s; %s", ADDRESS1, rc.Error()) } callback(s) finished <- true }() return finished } func runPollServer(t *testing.T) (done, bound chan bool) { done = make(chan bool) bound = make(chan bool) go func() { te := NewTestEnv(t) defer te.Close() s1 := te.NewBoundSocket(REP, ADDRESS1) s2 := te.NewBoundSocket(REP, ADDRESS2) s3 := te.NewBoundSocket(REP, ADDRESS3) pi := PollItems{ PollItem{Socket: s1, Events: POLLIN}, PollItem{Socket: s2, Events: POLLIN}, PollItem{Socket: s3, Events: POLLIN}, } bound <- true sent := 0 for { _, err := Poll(pi, -1) if err != nil { done <- false return } switch { case pi[0].REvents&POLLIN != 0: pi[0].Socket.Recv(0) // eat the incoming message pi[0].Socket.Send(nil, 0) sent++ case pi[1].REvents&POLLIN != 0: pi[1].Socket.Recv(0) // eat the incoming message pi[1].Socket.Send(nil, 0) sent++ case pi[2].REvents&POLLIN != 0: pi[2].Socket.Recv(0) // eat the incoming message pi[2].Socket.Send(nil, 0) sent++ } if sent == 3 { break } } done <- true }() return } func TestVersion(t *testing.T) { major, minor, patch := Version() // Require at least 2.0.9 if major > 2 && minor >= 0 && patch >= 9 { t.Errorf("expected at least 0mq version 2.0.9") } } func TestCreateDestroyContext(t *testing.T) { c, _ := NewContext() c.Close() c, _ = NewContext() c.Close() } func TestContext_IOThreads(t *testing.T) { c, _ := NewContext() defer c.Close() if iothreads, err := c.IOThreads(); err != nil { t.Fatalf("Failed to get IO_THREADS: %s", err.Error()) } else if iothreads != 1 { t.Fatalf("Got IO_THREADS = %s", iothreads) } } func TestContext_SetIOThreads(t *testing.T) { c, _ := NewContext() defer c.Close() if err := c.SetIOThreads(2); err != nil { t.Fatalf("Failed to set IO_THREADS: %s", err.Error()) } if iothreads, err := c.IOThreads(); err != nil { t.Fatalf("Failed to get IO_THREADS: %s", err.Error()) } else if iothreads != 2 { t.Fatalf("Got IO_THREADS = %s", iothreads) } } func TestSocket_Connect(t *testing.T) { c, _ := NewContext() defer c.Close() s, _ := c.NewSocket(REP) defer s.Close() if rc := s.Connect(ADDRESS1); rc != nil { t.Errorf("Failed to bind to %s; %s", ADDRESS1, rc.Error()) } bad_address := "a malformed address" rc := s.Connect(bad_address) switch rc { case syscall.EINVAL: //pass case nil: t.Errorf("Connected to %s", bad_address) default: t.Errorf("Received incorrect error connecting to %s; %s", bad_address, rc.Error()) } s.Close() rc = s.Connect(ADDRESS1) switch rc { case ENOTSOCK: //pass case nil: t.Errorf("Connected a closed socket") default: t.Errorf("Expected ENOTSOCK, got %T(%d); %s", rc, rc, rc.Error()) } } func TestBindToLoopBack(t *testing.T) { c, _ := NewContext() defer c.Close() s, _ := c.NewSocket(REP) defer s.Close() if rc := s.Bind(ADDRESS1); rc != nil { t.Errorf("Failed to bind to %s; %s", ADDRESS1, rc.Error()) } } func TestSetSockOptInt(t *testing.T) { c, _ := NewContext() defer c.Close() s, _ := c.NewSocket(REQ) defer s.Close() var linger int = 42 if rc := s.SetSockOptInt(LINGER, linger); rc != nil { t.Errorf("Failed to set linger; %v", rc) } if val, rc := s.GetSockOptInt(LINGER); rc != nil { t.Errorf("Failed to get linger; %v", rc) } else if val != linger { t.Errorf("Expected %d, got %d", linger, val) } } func TestSetSockOptString(t *testing.T) { c, _ := NewContext() defer c.Close() s, _ := c.NewSocket(SUB) defer s.Close() if rc := s.Bind(ADDRESS1); rc != nil { t.Errorf("Failed to bind to %s; %s", ADDRESS1, rc.Error()) } if rc := s.SetSockOptString(SUBSCRIBE, "TEST"); rc != nil { t.Errorf("Failed to subscribe; %v", rc) } if rc := s.SetSubscribe("TEST"); rc != nil { t.Errorf("Failed to subscribe; %v", rc) } if rc := s.SetUnsubscribe("TEST"); rc != nil { t.Errorf("Failed to unsubscribe; %v", rc) } } func TestMultipart(t *testing.T) { c, _ := NewContext() defer c.Close() finished := runServer(t, c, func(s *Socket) { parts, rc := s.RecvMultipart(0) if rc != nil { t.Errorf("Failed to receive multipart message; %s", rc.Error()) } if len(parts) != 2 { t.Errorf("Invalid multipart message, not enough parts; %d", len(parts)) } if string(parts[0]) != "part1" || string(parts[1]) != "part2" { t.Errorf("Invalid multipart message.") } }) s, _ := c.NewSocket(REQ) defer s.Close() if rc := s.Connect(ADDRESS1); rc != nil { t.Errorf("Failed to connect to %s; %s", ADDRESS1, rc.Error()) } if rc := s.SendMultipart([][]byte{[]byte("part1"), []byte("part2")}, 0); rc != nil { t.Errorf("Failed to send multipart message; %s", rc.Error()) } <-finished } func TestPoll(t *testing.T) { te := NewTestEnv(t) defer te.Close() finished, bound := runPollServer(t) // wait for sockets to bind <-bound for _, addr := range []string{ADDRESS2, ADDRESS3, ADDRESS1} { sock := te.NewConnectedSocket(REQ, addr) te.Send(sock, []byte("request data"), 0) te.Recv(sock, 0) } <-finished } func TestDevice(t *testing.T) { go func() { // the device will never exit so this goroutine will never terminate te := NewTestEnv(t) defer te.Close() in := te.NewBoundSocket(PULL, ADDR_DEV_IN) out := te.NewBoundSocket(PUSH, ADDR_DEV_OUT) err := Device(STREAMER, in, out) // Should never get to here t.Error("Device() failed: ", err) }() te := NewTestEnv(t) defer te.Close() out := te.NewConnectedSocket(PUSH, ADDR_DEV_IN) in := te.NewConnectedSocket(PULL, ADDR_DEV_OUT) time.Sleep(1e8) te.Send(out, nil, 0) te.Recv(in, 0) } func TestZmqErrorStr(t *testing.T) { var e error = EFSM es := e.Error() if es != "Operation cannot be accomplished in current state" { t.Errorf("EFSM.String() returned unexpected result: %s", e) } } func TestZmqErrorComparison(t *testing.T) { var e error = getErrorForTesting() if e != EFSM { t.Errorf("EFSM did not compare correctly. This should not happen.") } } // expensive test - send a huge amount of data. should be enough to // trash a current machine if Send or Recv are leaking. /* func TestMessageMemory(t *testing.T) { // primarily to see if Send or Recv are leaking memory const MSG_SIZE = 1e6 const MSG_COUNT = 100 * 1000 te := NewTestEnv(nil) defer te.Close() data := make([]byte, MSG_SIZE) out := te.NewBoundSocket(PUSH, ADDRESS1) in := te.NewConnectedSocket(PULL, ADDRESS1) for i := 0; i < MSG_COUNT; i++ { te.Send(out, data, 0) d2 := te.Recv(in, 0) if len(d2) != MSG_SIZE { t.Errorf("Bad message size received") } } } */ func doBenchmarkSendReceive(b *testing.B, size int, addr string) { // since this is a benchmark it should probably call // this package's api functions directly rather than // using the testEnv wrappers b.StopTimer() data := make([]byte, size) te := NewTestEnv(nil) defer te.Close() b.StartTimer() out := te.NewBoundSocket(PUSH, ADDRESS1) in := te.NewConnectedSocket(PULL, ADDRESS1) for i := 0; i < b.N; i++ { te.Send(out, data, 0) d2 := te.Recv(in, 0) if len(d2) != size { panic("Bad message size received") } } } func BenchmarkSendReceive1Btcp(b *testing.B) { doBenchmarkSendReceive(b, 1, ADDRESS1) } func BenchmarkSendReceive1KBtcp(b *testing.B) { doBenchmarkSendReceive(b, 1e3, ADDRESS1) } func BenchmarkSendReceive1MBtcp(b *testing.B) { doBenchmarkSendReceive(b, 1e6, ADDRESS1) } func BenchmarkSendReceive1Binproc(b *testing.B) { doBenchmarkSendReceive(b, 1, ADDRESS_INPROC) } func BenchmarkSendReceive1KBinproc(b *testing.B) { doBenchmarkSendReceive(b, 1e3, ADDRESS_INPROC) } func BenchmarkSendReceive1MBinproc(b *testing.B) { doBenchmarkSendReceive(b, 1e6, ADDRESS_INPROC) } // A helper to make tests less verbose type testEnv struct { context *Context sockets []*Socket t *testing.T } func NewTestEnv(t *testing.T) *testEnv { // Encapsulate everything, including (unnecessarily) the context // in the same thread. runtime.LockOSThread() c, err := NewContext() if err != nil { t.Errorf("failed to create context in testEnv: %v", err) t.FailNow() } return &testEnv{context: c, t: t} } func (te *testEnv) NewSocket(t SocketType) *Socket { s, err := te.context.NewSocket(t) if err != nil { log.Panicf("Failed to Create socket of type %v: %v", t, err) } return s } func (te *testEnv) NewBoundSocket(t SocketType, bindAddr string) *Socket { s := te.NewSocket(t) if err := s.Bind(bindAddr); err != nil { log.Panicf("Failed to connect to %v: %v", bindAddr, err) } te.pushSocket(s) return s } func (te *testEnv) NewConnectedSocket(t SocketType, connectAddr string) *Socket { s := te.NewSocket(t) if err := s.Connect(connectAddr); err != nil { log.Panicf("Failed to connect to %v: %v", connectAddr, err) } te.pushSocket(s) return s } func (te *testEnv) pushSocket(s *Socket) { te.sockets = append(te.sockets, s) } func (te *testEnv) Close() { if err := recover(); err != nil { te.t.Errorf("failed in testEnv: %v", err) } for _, s := range te.sockets { s.Close() } if te.context != nil { te.context.Close() } runtime.UnlockOSThread() } func (te *testEnv) Send(sock *Socket, data []byte, flags SendRecvOption) { if err := sock.Send(data, flags); err != nil { te.t.Errorf("Send failed") } } func (te *testEnv) Recv(sock *Socket, flags SendRecvOption) []byte { data, err := sock.Recv(flags) if err != nil { te.t.Errorf("Receive failed") } return data } // TODO Test various socket types. UDP, TCP, etc. // TODO Test NOBLOCK mode. // TODO Test getting/setting socket options. Probably sufficient to do just one // int and one string test. // TODO Test that closing a context underneath a socket behaves "reasonably" (ie. doesnt' crash). ================================================ FILE: zmq_unix.go ================================================ // +build darwin freebsd linux netbsd openbsd /* Copyright 2012 Alec Thomas Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package gozmq /* #cgo pkg-config: libzmq #include */ import "C" type ZmqOsSocketType C.int func (self ZmqOsSocketType) ToRaw() C.int { return C.int(self) } ================================================ FILE: zmq_windows.go ================================================ /* Copyright 2012 Alec Thomas Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package gozmq /* #cgo pkg-config: libzmq #include */ import "C" type ZmqOsSocketType C.SOCKET func (self ZmqOsSocketType) ToRaw() C.SOCKET { return C.SOCKET(self) } ================================================ FILE: zmqgen_2_1.go ================================================ // +build zmq_2_1 // package gozmq import ( "time" ) // This file was generated automatically. Changes made here will be lost. // Socket Option Getters // ZMQ_TYPE: Retrieve socket type. // // See: http://api.zeromq.org/2.1:zmq-getsockopt#toc3 // func (s *Socket) Type() (SocketType, error) { value, err := s.GetSockOptUInt64(TYPE) return SocketType(value), err } // ZMQ_RCVMORE: More message parts to follow. // // See: http://api.zeromq.org/2.1:zmq-getsockopt#toc4 // func (s *Socket) RcvMore() (bool, error) { value, err := s.GetSockOptUInt64(RCVMORE) return value != 0, err } // ZMQ_HWM: Retrieve high water mark. // // See: http://api.zeromq.org/2.1:zmq-getsockopt#toc5 // func (s *Socket) HWM() (uint64, error) { return s.GetSockOptUInt64(HWM) } // ZMQ_SWAP: Retrieve disk offload size. // // See: http://api.zeromq.org/2.1:zmq-getsockopt#toc6 // func (s *Socket) Swap() (int64, error) { return s.GetSockOptInt64(SWAP) } // ZMQ_AFFINITY: Retrieve I/O thread affinity. // // See: http://api.zeromq.org/2.1:zmq-getsockopt#toc7 // func (s *Socket) Affinity() (uint64, error) { return s.GetSockOptUInt64(AFFINITY) } // ZMQ_IDENTITY: Retrieve socket identity. // // See: http://api.zeromq.org/2.1:zmq-getsockopt#toc8 // func (s *Socket) Identity() (string, error) { return s.GetSockOptString(IDENTITY) } // ZMQ_RATE: Retrieve multicast data rate. // // See: http://api.zeromq.org/2.1:zmq-getsockopt#toc9 // func (s *Socket) Rate() (int64, error) { return s.GetSockOptInt64(RATE) } // ZMQ_RECOVERY_IVL_MSEC: Get multicast recovery interval in milliseconds. // // See: http://api.zeromq.org/2.1:zmq-getsockopt#toc11 // func (s *Socket) RecoveryIvl() (time.Duration, error) { ms, err := s.GetSockOptInt64(RECOVERY_IVL_MSEC) return time.Duration(ms) * time.Millisecond, err } // ZMQ_MCAST_LOOP: Control multicast loop-back. // // See: http://api.zeromq.org/2.1:zmq-getsockopt#toc12 // func (s *Socket) McastLoop() (bool, error) { value, err := s.GetSockOptInt64(MCAST_LOOP) return value != 0, err } // ZMQ_SNDBUF: Retrieve kernel transmit buffer size. // // See: http://api.zeromq.org/2.1:zmq-getsockopt#toc13 // func (s *Socket) SndBuf() (uint64, error) { return s.GetSockOptUInt64(SNDBUF) } // ZMQ_RCVBUF: Retrieve kernel receive buffer size. // // See: http://api.zeromq.org/2.1:zmq-getsockopt#toc14 // func (s *Socket) RcvBuf() (uint64, error) { return s.GetSockOptUInt64(RCVBUF) } // ZMQ_LINGER: Retrieve linger period for socket shutdown. // // See: http://api.zeromq.org/2.1:zmq-getsockopt#toc15 // func (s *Socket) Linger() (time.Duration, error) { ms, err := s.GetSockOptInt(LINGER) return time.Duration(ms) * time.Millisecond, err } // ZMQ_RECONNECT_IVL: Retrieve reconnection interval. // // See: http://api.zeromq.org/2.1:zmq-getsockopt#toc16 // func (s *Socket) ReconnectIvl() (time.Duration, error) { ms, err := s.GetSockOptInt(RECONNECT_IVL) return time.Duration(ms) * time.Millisecond, err } // ZMQ_RECONNECT_IVL_MAX: Retrieve maximum reconnection interval. // // See: http://api.zeromq.org/2.1:zmq-getsockopt#toc17 // func (s *Socket) ReconnectIvlMax() (time.Duration, error) { ms, err := s.GetSockOptInt(RECONNECT_IVL_MAX) return time.Duration(ms) * time.Millisecond, err } // ZMQ_BACKLOG: Retrieve maximum length of the queue of outstanding connections. // // See: http://api.zeromq.org/2.1:zmq-getsockopt#toc18 // func (s *Socket) Backlog() (int, error) { return s.GetSockOptInt(BACKLOG) } // ZMQ_EVENTS: Retrieve socket event state. // // See: http://api.zeromq.org/2.1:zmq-getsockopt#toc20 // func (s *Socket) Events() (uint64, error) { return s.GetSockOptUInt64(EVENTS) } // Socket Option Setters // ZMQ_HWM: Set high water mark. // // See: http://api.zeromq.org/2.1:zmq-setsockopt#toc3 // func (s *Socket) SetHWM(value uint64) error { return s.SetSockOptUInt64(HWM, value) } // ZMQ_SWAP: Set disk offload size. // // See: http://api.zeromq.org/2.1:zmq-setsockopt#toc4 // func (s *Socket) SetSwap(value int64) error { return s.SetSockOptInt64(SWAP, value) } // ZMQ_AFFINITY: Set I/O thread affinity. // // See: http://api.zeromq.org/2.1:zmq-setsockopt#toc5 // func (s *Socket) SetAffinity(value uint64) error { return s.SetSockOptUInt64(AFFINITY, value) } // ZMQ_IDENTITY: Set socket identity. // // See: http://api.zeromq.org/2.1:zmq-setsockopt#toc6 // func (s *Socket) SetIdentity(value string) error { return s.SetSockOptString(IDENTITY, value) } // ZMQ_SUBSCRIBE: Establish message filter. // // See: http://api.zeromq.org/2.1:zmq-setsockopt#toc7 // func (s *Socket) SetSubscribe(value string) error { return s.SetSockOptString(SUBSCRIBE, value) } // ZMQ_UNSUBSCRIBE: Remove message filter. // // See: http://api.zeromq.org/2.1:zmq-setsockopt#toc8 // func (s *Socket) SetUnsubscribe(value string) error { return s.SetSockOptString(UNSUBSCRIBE, value) } // ZMQ_RATE: Set multicast data rate. // // See: http://api.zeromq.org/2.1:zmq-setsockopt#toc9 // func (s *Socket) SetRate(value int64) error { return s.SetSockOptInt64(RATE, value) } // ZMQ_RECOVERY_IVL_MSEC: Set multicast recovery interval in milliseconds. // // See: http://api.zeromq.org/2.1:zmq-setsockopt#toc11 // func (s *Socket) SetRecoveryIvl(value time.Duration) error { return s.SetSockOptInt64(RECOVERY_IVL_MSEC, int64(value/time.Millisecond)) } // ZMQ_MCAST_LOOP: Control multicast loop-back. // // See: http://api.zeromq.org/2.1:zmq-setsockopt#toc12 // func (s *Socket) SetMcastLoop(value bool) error { if value { return s.SetSockOptInt64(MCAST_LOOP, 1) } return s.SetSockOptInt64(MCAST_LOOP, 0) } // ZMQ_SNDBUF: Set kernel transmit buffer size. // // See: http://api.zeromq.org/2.1:zmq-setsockopt#toc13 // func (s *Socket) SetSndBuf(value uint64) error { return s.SetSockOptUInt64(SNDBUF, value) } // ZMQ_RCVBUF: Set kernel receive buffer size. // // See: http://api.zeromq.org/2.1:zmq-setsockopt#toc14 // func (s *Socket) SetRcvBuf(value uint64) error { return s.SetSockOptUInt64(RCVBUF, value) } // ZMQ_LINGER: Set linger period for socket shutdown. // // See: http://api.zeromq.org/2.1:zmq-setsockopt#toc15 // func (s *Socket) SetLinger(value time.Duration) error { return s.SetSockOptInt(LINGER, int(value/time.Millisecond)) } // ZMQ_RECONNECT_IVL: Set reconnection interval. // // See: http://api.zeromq.org/2.1:zmq-setsockopt#toc16 // func (s *Socket) SetReconnectIvl(value time.Duration) error { return s.SetSockOptInt(RECONNECT_IVL, int(value/time.Millisecond)) } // ZMQ_RECONNECT_IVL_MAX: Set maximum reconnection interval. // // See: http://api.zeromq.org/2.1:zmq-setsockopt#toc17 // func (s *Socket) SetReconnectIvlMax(value time.Duration) error { return s.SetSockOptInt(RECONNECT_IVL_MAX, int(value/time.Millisecond)) } // ZMQ_BACKLOG: Set maximum length of the queue of outstanding connections. // // See: http://api.zeromq.org/2.1:zmq-setsockopt#toc18 // func (s *Socket) SetBacklog(value int) error { return s.SetSockOptInt(BACKLOG, value) } ================================================ FILE: zmqgen_2_2.go ================================================ // +build !zmq_2_1,!zmq_3_x,!zmq_4_x // package gozmq import ( "time" ) // This file was generated automatically. Changes made here will be lost. // Socket Option Getters // ZMQ_TYPE: Retrieve socket type. // // See: http://api.zeromq.org/2.2:zmq-getsockopt#toc3 // func (s *Socket) Type() (SocketType, error) { value, err := s.GetSockOptUInt64(TYPE) return SocketType(value), err } // ZMQ_RCVMORE: More message parts to follow. // // See: http://api.zeromq.org/2.2:zmq-getsockopt#toc4 // func (s *Socket) RcvMore() (bool, error) { value, err := s.GetSockOptUInt64(RCVMORE) return value != 0, err } // ZMQ_HWM: Retrieve high water mark. // // See: http://api.zeromq.org/2.2:zmq-getsockopt#toc5 // func (s *Socket) HWM() (uint64, error) { return s.GetSockOptUInt64(HWM) } // ZMQ_RCVTIMEO: Maximum time before a socket operation returns with EAGAIN. // // See: http://api.zeromq.org/2.2:zmq-getsockopt#toc6 // func (s *Socket) RcvTimeout() (time.Duration, error) { ms, err := s.GetSockOptInt(RCVTIMEO) return time.Duration(ms) * time.Millisecond, err } // ZMQ_SNDTIMEO: Maximum time before a socket operation returns with EAGAIN. // // See: http://api.zeromq.org/2.2:zmq-getsockopt#toc7 // func (s *Socket) SndTimeout() (time.Duration, error) { ms, err := s.GetSockOptInt(SNDTIMEO) return time.Duration(ms) * time.Millisecond, err } // ZMQ_SWAP: Retrieve disk offload size. // // See: http://api.zeromq.org/2.2:zmq-getsockopt#toc8 // func (s *Socket) Swap() (int64, error) { return s.GetSockOptInt64(SWAP) } // ZMQ_AFFINITY: Retrieve I/O thread affinity. // // See: http://api.zeromq.org/2.2:zmq-getsockopt#toc9 // func (s *Socket) Affinity() (uint64, error) { return s.GetSockOptUInt64(AFFINITY) } // ZMQ_IDENTITY: Retrieve socket identity. // // See: http://api.zeromq.org/2.2:zmq-getsockopt#toc10 // func (s *Socket) Identity() (string, error) { return s.GetSockOptString(IDENTITY) } // ZMQ_RATE: Retrieve multicast data rate. // // See: http://api.zeromq.org/2.2:zmq-getsockopt#toc11 // func (s *Socket) Rate() (int64, error) { return s.GetSockOptInt64(RATE) } // ZMQ_RECOVERY_IVL_MSEC: Get multicast recovery interval in milliseconds. // // See: http://api.zeromq.org/2.2:zmq-getsockopt#toc13 // func (s *Socket) RecoveryIvl() (time.Duration, error) { ms, err := s.GetSockOptInt64(RECOVERY_IVL_MSEC) return time.Duration(ms) * time.Millisecond, err } // ZMQ_MCAST_LOOP: Control multicast loop-back. // // See: http://api.zeromq.org/2.2:zmq-getsockopt#toc14 // func (s *Socket) McastLoop() (bool, error) { value, err := s.GetSockOptInt64(MCAST_LOOP) return value != 0, err } // ZMQ_SNDBUF: Retrieve kernel transmit buffer size. // // See: http://api.zeromq.org/2.2:zmq-getsockopt#toc15 // func (s *Socket) SndBuf() (uint64, error) { return s.GetSockOptUInt64(SNDBUF) } // ZMQ_RCVBUF: Retrieve kernel receive buffer size. // // See: http://api.zeromq.org/2.2:zmq-getsockopt#toc16 // func (s *Socket) RcvBuf() (uint64, error) { return s.GetSockOptUInt64(RCVBUF) } // ZMQ_LINGER: Retrieve linger period for socket shutdown. // // See: http://api.zeromq.org/2.2:zmq-getsockopt#toc17 // func (s *Socket) Linger() (time.Duration, error) { ms, err := s.GetSockOptInt(LINGER) return time.Duration(ms) * time.Millisecond, err } // ZMQ_RECONNECT_IVL: Retrieve reconnection interval. // // See: http://api.zeromq.org/2.2:zmq-getsockopt#toc18 // func (s *Socket) ReconnectIvl() (time.Duration, error) { ms, err := s.GetSockOptInt(RECONNECT_IVL) return time.Duration(ms) * time.Millisecond, err } // ZMQ_RECONNECT_IVL_MAX: Retrieve maximum reconnection interval. // // See: http://api.zeromq.org/2.2:zmq-getsockopt#toc19 // func (s *Socket) ReconnectIvlMax() (time.Duration, error) { ms, err := s.GetSockOptInt(RECONNECT_IVL_MAX) return time.Duration(ms) * time.Millisecond, err } // ZMQ_BACKLOG: Retrieve maximum length of the queue of outstanding connections. // // See: http://api.zeromq.org/2.2:zmq-getsockopt#toc20 // func (s *Socket) Backlog() (int, error) { return s.GetSockOptInt(BACKLOG) } // ZMQ_EVENTS: Retrieve socket event state. // // See: http://api.zeromq.org/2.2:zmq-getsockopt#toc22 // func (s *Socket) Events() (uint64, error) { return s.GetSockOptUInt64(EVENTS) } // Socket Option Setters // ZMQ_HWM: Set high water mark. // // See: http://api.zeromq.org/2.2:zmq-setsockopt#toc3 // func (s *Socket) SetHWM(value uint64) error { return s.SetSockOptUInt64(HWM, value) } // ZMQ_SWAP: Set disk offload size. // // See: http://api.zeromq.org/2.2:zmq-setsockopt#toc4 // func (s *Socket) SetSwap(value int64) error { return s.SetSockOptInt64(SWAP, value) } // ZMQ_AFFINITY: Set I/O thread affinity. // // See: http://api.zeromq.org/2.2:zmq-setsockopt#toc5 // func (s *Socket) SetAffinity(value uint64) error { return s.SetSockOptUInt64(AFFINITY, value) } // ZMQ_IDENTITY: Set socket identity. // // See: http://api.zeromq.org/2.2:zmq-setsockopt#toc6 // func (s *Socket) SetIdentity(value string) error { return s.SetSockOptString(IDENTITY, value) } // ZMQ_SUBSCRIBE: Establish message filter. // // See: http://api.zeromq.org/2.2:zmq-setsockopt#toc7 // func (s *Socket) SetSubscribe(value string) error { return s.SetSockOptString(SUBSCRIBE, value) } // ZMQ_UNSUBSCRIBE: Remove message filter. // // See: http://api.zeromq.org/2.2:zmq-setsockopt#toc8 // func (s *Socket) SetUnsubscribe(value string) error { return s.SetSockOptString(UNSUBSCRIBE, value) } // ZMQ_RCVTIMEO: Maximum time before a recv operation returns with EAGAIN. // // See: http://api.zeromq.org/2.2:zmq-setsockopt#toc9 // func (s *Socket) SetRcvTimeout(value time.Duration) error { return s.SetSockOptInt(RCVTIMEO, int(value/time.Millisecond)) } // ZMQ_SNDTIMEO: Maximum time before a send operation returns with EAGAIN. // // See: http://api.zeromq.org/2.2:zmq-setsockopt#toc10 // func (s *Socket) SetSndTimeout(value time.Duration) error { return s.SetSockOptInt(SNDTIMEO, int(value/time.Millisecond)) } // ZMQ_RATE: Set multicast data rate. // // See: http://api.zeromq.org/2.2:zmq-setsockopt#toc11 // func (s *Socket) SetRate(value int64) error { return s.SetSockOptInt64(RATE, value) } // ZMQ_RECOVERY_IVL_MSEC: Set multicast recovery interval in milliseconds. // // See: http://api.zeromq.org/2.2:zmq-setsockopt#toc13 // func (s *Socket) SetRecoveryIvl(value time.Duration) error { return s.SetSockOptInt64(RECOVERY_IVL_MSEC, int64(value/time.Millisecond)) } // ZMQ_MCAST_LOOP: Control multicast loop-back. // // See: http://api.zeromq.org/2.2:zmq-setsockopt#toc14 // func (s *Socket) SetMcastLoop(value bool) error { if value { return s.SetSockOptInt64(MCAST_LOOP, 1) } return s.SetSockOptInt64(MCAST_LOOP, 0) } // ZMQ_SNDBUF: Set kernel transmit buffer size. // // See: http://api.zeromq.org/2.2:zmq-setsockopt#toc15 // func (s *Socket) SetSndBuf(value uint64) error { return s.SetSockOptUInt64(SNDBUF, value) } // ZMQ_RCVBUF: Set kernel receive buffer size. // // See: http://api.zeromq.org/2.2:zmq-setsockopt#toc16 // func (s *Socket) SetRcvBuf(value uint64) error { return s.SetSockOptUInt64(RCVBUF, value) } // ZMQ_LINGER: Set linger period for socket shutdown. // // See: http://api.zeromq.org/2.2:zmq-setsockopt#toc17 // func (s *Socket) SetLinger(value time.Duration) error { return s.SetSockOptInt(LINGER, int(value/time.Millisecond)) } // ZMQ_RECONNECT_IVL: Set reconnection interval. // // See: http://api.zeromq.org/2.2:zmq-setsockopt#toc18 // func (s *Socket) SetReconnectIvl(value time.Duration) error { return s.SetSockOptInt(RECONNECT_IVL, int(value/time.Millisecond)) } // ZMQ_RECONNECT_IVL_MAX: Set maximum reconnection interval. // // See: http://api.zeromq.org/2.2:zmq-setsockopt#toc19 // func (s *Socket) SetReconnectIvlMax(value time.Duration) error { return s.SetSockOptInt(RECONNECT_IVL_MAX, int(value/time.Millisecond)) } // ZMQ_BACKLOG: Set maximum length of the queue of outstanding connections. // // See: http://api.zeromq.org/2.2:zmq-setsockopt#toc20 // func (s *Socket) SetBacklog(value int) error { return s.SetSockOptInt(BACKLOG, value) } ================================================ FILE: zmqgen_3_2.go ================================================ // +build zmq_3_x // package gozmq import ( "time" ) // This file was generated automatically. Changes made here will be lost. // Socket Option Getters // ZMQ_TYPE: Retrieve socket type. // // See: http://api.zeromq.org/3.2:zmq-getsockopt#toc3 // func (s *Socket) Type() (SocketType, error) { value, err := s.GetSockOptUInt64(TYPE) return SocketType(value), err } // ZMQ_RCVMORE: More message data parts to follow. // // See: http://api.zeromq.org/3.2:zmq-getsockopt#toc4 // func (s *Socket) RcvMore() (bool, error) { value, err := s.GetSockOptInt(RCVMORE) return value != 0, err } // ZMQ_SNDHWM: Retrieves high water mark for outbound messages. // // See: http://api.zeromq.org/3.2:zmq-getsockopt#toc5 // func (s *Socket) SndHWM() (int, error) { return s.GetSockOptInt(SNDHWM) } // ZMQ_RCVHWM: Retrieve high water mark for inbound messages. // // See: http://api.zeromq.org/3.2:zmq-getsockopt#toc6 // func (s *Socket) RcvHWM() (int, error) { return s.GetSockOptInt(RCVHWM) } // ZMQ_AFFINITY: Retrieve I/O thread affinity. // // See: http://api.zeromq.org/3.2:zmq-getsockopt#toc7 // func (s *Socket) Affinity() (uint64, error) { return s.GetSockOptUInt64(AFFINITY) } // ZMQ_IDENTITY: Set socket identity. // // See: http://api.zeromq.org/3.2:zmq-getsockopt#toc8 // func (s *Socket) Identity() (string, error) { return s.GetSockOptString(IDENTITY) } // ZMQ_RATE: Retrieve multicast data rate. // // See: http://api.zeromq.org/3.2:zmq-getsockopt#toc9 // func (s *Socket) Rate() (int64, error) { return s.GetSockOptInt64(RATE) } // ZMQ_RECOVERY_IVL: Get multicast recovery interval. // // See: http://api.zeromq.org/3.2:zmq-getsockopt#toc10 // func (s *Socket) RecoveryIvl() (time.Duration, error) { ms, err := s.GetSockOptInt64(RECOVERY_IVL) return time.Duration(ms) * time.Millisecond, err } // ZMQ_SNDBUF: Retrieve kernel transmit buffer size. // // See: http://api.zeromq.org/3.2:zmq-getsockopt#toc11 // func (s *Socket) SndBuf() (uint64, error) { return s.GetSockOptUInt64(SNDBUF) } // ZMQ_RCVBUF: Retrieve kernel receive buffer size. // // See: http://api.zeromq.org/3.2:zmq-getsockopt#toc12 // func (s *Socket) RcvBuf() (uint64, error) { return s.GetSockOptUInt64(RCVBUF) } // ZMQ_LINGER: Retrieve linger period for socket shutdown. // // See: http://api.zeromq.org/3.2:zmq-getsockopt#toc13 // func (s *Socket) Linger() (time.Duration, error) { ms, err := s.GetSockOptInt(LINGER) return time.Duration(ms) * time.Millisecond, err } // ZMQ_RECONNECT_IVL: Retrieve reconnection interval. // // See: http://api.zeromq.org/3.2:zmq-getsockopt#toc14 // func (s *Socket) ReconnectIvl() (time.Duration, error) { ms, err := s.GetSockOptInt(RECONNECT_IVL) return time.Duration(ms) * time.Millisecond, err } // ZMQ_RECONNECT_IVL_MAX: Retrieve maximum reconnection interval. // // See: http://api.zeromq.org/3.2:zmq-getsockopt#toc15 // func (s *Socket) ReconnectIvlMax() (time.Duration, error) { ms, err := s.GetSockOptInt(RECONNECT_IVL_MAX) return time.Duration(ms) * time.Millisecond, err } // ZMQ_BACKLOG: Retrieve maximum length of the queue of outstanding connections. // // See: http://api.zeromq.org/3.2:zmq-getsockopt#toc16 // func (s *Socket) Backlog() (int, error) { return s.GetSockOptInt(BACKLOG) } // ZMQ_MAXMSGSIZE: Maximum acceptable inbound message size. // // See: http://api.zeromq.org/3.2:zmq-getsockopt#toc17 // func (s *Socket) MaxMsgSize() (int64, error) { return s.GetSockOptInt64(MAXMSGSIZE) } // ZMQ_RCVTIMEO: Maximum time before a socket operation returns with EAGAIN. // // See: http://api.zeromq.org/3.2:zmq-getsockopt#toc19 // func (s *Socket) RcvTimeout() (time.Duration, error) { ms, err := s.GetSockOptInt(RCVTIMEO) return time.Duration(ms) * time.Millisecond, err } // ZMQ_SNDTIMEO: Maximum time before a socket operation returns with EAGAIN. // // See: http://api.zeromq.org/3.2:zmq-getsockopt#toc20 // func (s *Socket) SndTimeout() (time.Duration, error) { ms, err := s.GetSockOptInt(SNDTIMEO) return time.Duration(ms) * time.Millisecond, err } // ZMQ_IPV4ONLY: Retrieve IPv4-only socket override status. // // See: http://api.zeromq.org/3.2:zmq-getsockopt#toc21 // func (s *Socket) IPv4Only() (bool, error) { value, err := s.GetSockOptInt(IPV4ONLY) return value != 0, err } // ZMQ_DELAY_ATTACH_ON_CONNECT: Retrieve attach-on-connect value. // // See: http://api.zeromq.org/3.2:zmq-getsockopt#toc22 // func (s *Socket) DelayAttachOnConnect() (bool, error) { value, err := s.GetSockOptInt(DELAY_ATTACH_ON_CONNECT) return value != 0, err } // ZMQ_EVENTS: Retrieve socket event state. // // See: http://api.zeromq.org/3.2:zmq-getsockopt#toc24 // func (s *Socket) Events() (uint64, error) { return s.GetSockOptUInt64(EVENTS) } // ZMQ_TCP_KEEPALIVE: Override SO_KEEPALIVE socket option. // // See: http://api.zeromq.org/3.2:zmq-getsockopt#toc26 // func (s *Socket) TCPKeepalive() (int, error) { return s.GetSockOptInt(TCP_KEEPALIVE) } // ZMQ_TCP_KEEPALIVE_IDLE: Override TCP_KEEPCNT(or TCP_KEEPALIVE on some OS). // // See: http://api.zeromq.org/3.2:zmq-getsockopt#toc27 // func (s *Socket) TCPKeepaliveIdle() (int, error) { return s.GetSockOptInt(TCP_KEEPALIVE_IDLE) } // ZMQ_TCP_KEEPALIVE_CNT: Override TCP_KEEPCNT socket option. // // See: http://api.zeromq.org/3.2:zmq-getsockopt#toc28 // func (s *Socket) TCPKeepaliveCnt() (int, error) { return s.GetSockOptInt(TCP_KEEPALIVE_CNT) } // ZMQ_TCP_KEEPALIVE_INTVL: Override TCP_KEEPINTVL socket option. // // See: http://api.zeromq.org/3.2:zmq-getsockopt#toc29 // func (s *Socket) TCPKeepaliveIntvl() (int, error) { return s.GetSockOptInt(TCP_KEEPALIVE_INTVL) } // Socket Option Setters // ZMQ_SNDHWM: Set high water mark for outbound messages. // // See: http://api.zeromq.org/3.2:zmq-setsockopt#toc3 // func (s *Socket) SetSndHWM(value int) error { return s.SetSockOptInt(SNDHWM, value) } // ZMQ_RCVHWM: Set high water mark for inbound messages. // // See: http://api.zeromq.org/3.2:zmq-setsockopt#toc4 // func (s *Socket) SetRcvHWM(value int) error { return s.SetSockOptInt(RCVHWM, value) } // ZMQ_AFFINITY: Set I/O thread affinity. // // See: http://api.zeromq.org/3.2:zmq-setsockopt#toc5 // func (s *Socket) SetAffinity(value uint64) error { return s.SetSockOptUInt64(AFFINITY, value) } // ZMQ_SUBSCRIBE: Establish message filter. // // See: http://api.zeromq.org/3.2:zmq-setsockopt#toc6 // func (s *Socket) SetSubscribe(value string) error { return s.SetSockOptString(SUBSCRIBE, value) } // ZMQ_UNSUBSCRIBE: Remove message filter. // // See: http://api.zeromq.org/3.2:zmq-setsockopt#toc7 // func (s *Socket) SetUnsubscribe(value string) error { return s.SetSockOptString(UNSUBSCRIBE, value) } // ZMQ_IDENTITY: Set socket identity. // // See: http://api.zeromq.org/3.2:zmq-setsockopt#toc8 // func (s *Socket) SetIdentity(value string) error { return s.SetSockOptString(IDENTITY, value) } // ZMQ_RATE: Set multicast data rate. // // See: http://api.zeromq.org/3.2:zmq-setsockopt#toc9 // func (s *Socket) SetRate(value int64) error { return s.SetSockOptInt64(RATE, value) } // ZMQ_RECOVERY_IVL: Set multicast recovery interval. // // See: http://api.zeromq.org/3.2:zmq-setsockopt#toc10 // func (s *Socket) SetRecoveryIvl(value time.Duration) error { return s.SetSockOptInt64(RECOVERY_IVL, int64(value/time.Millisecond)) } // ZMQ_SNDBUF: Set kernel transmit buffer size. // // See: http://api.zeromq.org/3.2:zmq-setsockopt#toc11 // func (s *Socket) SetSndBuf(value uint64) error { return s.SetSockOptUInt64(SNDBUF, value) } // ZMQ_RCVBUF: Set kernel receive buffer size. // // See: http://api.zeromq.org/3.2:zmq-setsockopt#toc12 // func (s *Socket) SetRcvBuf(value uint64) error { return s.SetSockOptUInt64(RCVBUF, value) } // ZMQ_LINGER: Set linger period for socket shutdown. // // See: http://api.zeromq.org/3.2:zmq-setsockopt#toc13 // func (s *Socket) SetLinger(value time.Duration) error { return s.SetSockOptInt(LINGER, int(value/time.Millisecond)) } // ZMQ_RECONNECT_IVL: Set reconnection interval. // // See: http://api.zeromq.org/3.2:zmq-setsockopt#toc14 // func (s *Socket) SetReconnectIvl(value time.Duration) error { return s.SetSockOptInt(RECONNECT_IVL, int(value/time.Millisecond)) } // ZMQ_RECONNECT_IVL_MAX: Set maximum reconnection interval. // // See: http://api.zeromq.org/3.2:zmq-setsockopt#toc15 // func (s *Socket) SetReconnectIvlMax(value time.Duration) error { return s.SetSockOptInt(RECONNECT_IVL_MAX, int(value/time.Millisecond)) } // ZMQ_BACKLOG: Set maximum length of the queue of outstanding connections. // // See: http://api.zeromq.org/3.2:zmq-setsockopt#toc16 // func (s *Socket) SetBacklog(value int) error { return s.SetSockOptInt(BACKLOG, value) } // ZMQ_MAXMSGSIZE: Maximum acceptable inbound message size. // // See: http://api.zeromq.org/3.2:zmq-setsockopt#toc17 // func (s *Socket) SetMaxMsgSize(value int64) error { return s.SetSockOptInt64(MAXMSGSIZE, value) } // ZMQ_RCVTIMEO: Maximum time before a recv operation returns with EAGAIN. // // See: http://api.zeromq.org/3.2:zmq-setsockopt#toc19 // func (s *Socket) SetRcvTimeout(value time.Duration) error { return s.SetSockOptInt(RCVTIMEO, int(value/time.Millisecond)) } // ZMQ_SNDTIMEO: Maximum time before a send operation returns with EAGAIN. // // See: http://api.zeromq.org/3.2:zmq-setsockopt#toc20 // func (s *Socket) SetSndTimeout(value time.Duration) error { return s.SetSockOptInt(SNDTIMEO, int(value/time.Millisecond)) } // ZMQ_IPV4ONLY: Use IPv4-only sockets. // // See: http://api.zeromq.org/3.2:zmq-setsockopt#toc21 // func (s *Socket) SetIPv4Only(value bool) error { if value { return s.SetSockOptInt(IPV4ONLY, 1) } return s.SetSockOptInt(IPV4ONLY, 0) } // ZMQ_DELAY_ATTACH_ON_CONNECT: Accept messages only when connections are made. // // See: http://api.zeromq.org/3.2:zmq-setsockopt#toc22 // func (s *Socket) SetDelayAttachOnConnect(value bool) error { if value { return s.SetSockOptInt(DELAY_ATTACH_ON_CONNECT, 1) } return s.SetSockOptInt(DELAY_ATTACH_ON_CONNECT, 0) } // ZMQ_ROUTER_MANDATORY: accept only routable messages on ROUTER sockets. // // See: http://api.zeromq.org/3.2:zmq-setsockopt#toc23 // func (s *Socket) SetROUTERMandatory(value bool) error { if value { return s.SetSockOptInt(ROUTER_MANDATORY, 1) } return s.SetSockOptInt(ROUTER_MANDATORY, 0) } // ZMQ_XPUB_VERBOSE: provide all subscription messages on XPUB sockets. // // See: http://api.zeromq.org/3.2:zmq-setsockopt#toc24 // func (s *Socket) SetXPUBVerbose(value bool) error { if value { return s.SetSockOptInt(XPUB_VERBOSE, 1) } return s.SetSockOptInt(XPUB_VERBOSE, 0) } // ZMQ_TCP_KEEPALIVE: Override SO_KEEPALIVE socket option. // // See: http://api.zeromq.org/3.2:zmq-setsockopt#toc25 // func (s *Socket) SetTCPKeepalive(value int) error { return s.SetSockOptInt(TCP_KEEPALIVE, value) } // ZMQ_TCP_KEEPALIVE_IDLE: Override TCP_KEEPCNT(or TCP_KEEPALIVE on some OS). // // See: http://api.zeromq.org/3.2:zmq-setsockopt#toc26 // func (s *Socket) SetTCPKeepaliveIdle(value int) error { return s.SetSockOptInt(TCP_KEEPALIVE_IDLE, value) } // ZMQ_TCP_KEEPALIVE_CNT: Override TCP_KEEPCNT socket option. // // See: http://api.zeromq.org/3.2:zmq-setsockopt#toc27 // func (s *Socket) SetTCPKeepaliveCnt(value int) error { return s.SetSockOptInt(TCP_KEEPALIVE_CNT, value) } // ZMQ_TCP_KEEPALIVE_INTVL: Override TCP_KEEPINTVL socket option. // // See: http://api.zeromq.org/3.2:zmq-setsockopt#toc28 // func (s *Socket) SetTCPKeepaliveIntvl(value int) error { return s.SetSockOptInt(TCP_KEEPALIVE_INTVL, value) } // ZMQ_TCP_ACCEPT_FILTER: Assign filters to allow new TCP connections. // // See: http://api.zeromq.org/3.2:zmq-setsockopt#toc29 // func (s *Socket) SetTCPAcceptFilter(value string) error { return s.SetSockOptString(TCP_ACCEPT_FILTER, value) } ================================================ FILE: zmqgen_4_0.go ================================================ // +build zmq_4_x // package gozmq import ( "time" ) // This file was generated automatically. Changes made here will be lost. // Socket Option Getters // ZMQ_TYPE: Retrieve socket type. // // See: http://api.zeromq.org/4.0:zmq-getsockopt#toc3 // func (s *Socket) Type() (SocketType, error) { value, err := s.GetSockOptUInt64(TYPE) return SocketType(value), err } // ZMQ_RCVMORE: More message data parts to follow. // // See: http://api.zeromq.org/4.0:zmq-getsockopt#toc4 // func (s *Socket) RcvMore() (bool, error) { value, err := s.GetSockOptInt(RCVMORE) return value != 0, err } // ZMQ_SNDHWM: Retrieves high water mark for outbound messages. // // See: http://api.zeromq.org/4.0:zmq-getsockopt#toc5 // func (s *Socket) SndHWM() (int, error) { return s.GetSockOptInt(SNDHWM) } // ZMQ_RCVHWM: Retrieve high water mark for inbound messages. // // See: http://api.zeromq.org/4.0:zmq-getsockopt#toc6 // func (s *Socket) RcvHWM() (int, error) { return s.GetSockOptInt(RCVHWM) } // ZMQ_AFFINITY: Retrieve I/O thread affinity. // // See: http://api.zeromq.org/4.0:zmq-getsockopt#toc7 // func (s *Socket) Affinity() (uint64, error) { return s.GetSockOptUInt64(AFFINITY) } // ZMQ_IDENTITY: Retrieve socket identity. // // See: http://api.zeromq.org/4.0:zmq-getsockopt#toc8 // func (s *Socket) Identity() (string, error) { return s.GetSockOptString(IDENTITY) } // ZMQ_RATE: Retrieve multicast data rate. // // See: http://api.zeromq.org/4.0:zmq-getsockopt#toc9 // func (s *Socket) Rate() (int64, error) { return s.GetSockOptInt64(RATE) } // ZMQ_RECOVERY_IVL: Get multicast recovery interval. // // See: http://api.zeromq.org/4.0:zmq-getsockopt#toc10 // func (s *Socket) RecoveryIvl() (time.Duration, error) { ms, err := s.GetSockOptInt64(RECOVERY_IVL) return time.Duration(ms) * time.Millisecond, err } // ZMQ_SNDBUF: Retrieve kernel transmit buffer size. // // See: http://api.zeromq.org/4.0:zmq-getsockopt#toc11 // func (s *Socket) SndBuf() (uint64, error) { return s.GetSockOptUInt64(SNDBUF) } // ZMQ_RCVBUF: Retrieve kernel receive buffer size. // // See: http://api.zeromq.org/4.0:zmq-getsockopt#toc12 // func (s *Socket) RcvBuf() (uint64, error) { return s.GetSockOptUInt64(RCVBUF) } // ZMQ_LINGER: Retrieve linger period for socket shutdown. // // See: http://api.zeromq.org/4.0:zmq-getsockopt#toc13 // func (s *Socket) Linger() (time.Duration, error) { ms, err := s.GetSockOptInt(LINGER) return time.Duration(ms) * time.Millisecond, err } // ZMQ_RECONNECT_IVL: Retrieve reconnection interval. // // See: http://api.zeromq.org/4.0:zmq-getsockopt#toc14 // func (s *Socket) ReconnectIvl() (time.Duration, error) { ms, err := s.GetSockOptInt(RECONNECT_IVL) return time.Duration(ms) * time.Millisecond, err } // ZMQ_RECONNECT_IVL_MAX: Retrieve maximum reconnection interval. // // See: http://api.zeromq.org/4.0:zmq-getsockopt#toc15 // func (s *Socket) ReconnectIvlMax() (time.Duration, error) { ms, err := s.GetSockOptInt(RECONNECT_IVL_MAX) return time.Duration(ms) * time.Millisecond, err } // ZMQ_BACKLOG: Retrieve maximum length of the queue of outstanding connections. // // See: http://api.zeromq.org/4.0:zmq-getsockopt#toc16 // func (s *Socket) Backlog() (int, error) { return s.GetSockOptInt(BACKLOG) } // ZMQ_MAXMSGSIZE: Maximum acceptable inbound message size. // // See: http://api.zeromq.org/4.0:zmq-getsockopt#toc17 // func (s *Socket) MaxMsgSize() (int64, error) { return s.GetSockOptInt64(MAXMSGSIZE) } // ZMQ_RCVTIMEO: Maximum time before a socket operation returns with EAGAIN. // // See: http://api.zeromq.org/4.0:zmq-getsockopt#toc19 // func (s *Socket) RcvTimeout() (time.Duration, error) { ms, err := s.GetSockOptInt(RCVTIMEO) return time.Duration(ms) * time.Millisecond, err } // ZMQ_SNDTIMEO: Maximum time before a socket operation returns with EAGAIN. // // See: http://api.zeromq.org/4.0:zmq-getsockopt#toc20 // func (s *Socket) SndTimeout() (time.Duration, error) { ms, err := s.GetSockOptInt(SNDTIMEO) return time.Duration(ms) * time.Millisecond, err } // ZMQ_IPV6: Retrieve IPv6 socket status. // // See: http://api.zeromq.org/4.0:zmq-getsockopt#toc21 // func (s *Socket) Ipv6() (bool, error) { value, err := s.GetSockOptInt(IPV6) return value != 0, err } // ZMQ_IPV4ONLY: Retrieve IPv4-only socket override status. // // See: http://api.zeromq.org/4.0:zmq-getsockopt#toc22 // func (s *Socket) IPv4Only() (bool, error) { value, err := s.GetSockOptInt(IPV4ONLY) return value != 0, err } // ZMQ_IMMEDIATE: Retrieve attach-on-connect value. // // See: http://api.zeromq.org/4.0:zmq-getsockopt#toc23 // func (s *Socket) Immediate() (bool, error) { value, err := s.GetSockOptInt(IMMEDIATE) return value != 0, err } // ZMQ_EVENTS: Retrieve socket event state. // // See: http://api.zeromq.org/4.0:zmq-getsockopt#toc25 // func (s *Socket) Events() (uint64, error) { return s.GetSockOptUInt64(EVENTS) } // ZMQ_TCP_KEEPALIVE: Override SO_KEEPALIVE socket option. // // See: http://api.zeromq.org/4.0:zmq-getsockopt#toc27 // func (s *Socket) TCPKeepalive() (int, error) { return s.GetSockOptInt(TCP_KEEPALIVE) } // ZMQ_TCP_KEEPALIVE_IDLE: Override TCP_KEEPCNT(or TCP_KEEPALIVE on some OS). // // See: http://api.zeromq.org/4.0:zmq-getsockopt#toc28 // func (s *Socket) TCPKeepaliveIdle() (int, error) { return s.GetSockOptInt(TCP_KEEPALIVE_IDLE) } // ZMQ_TCP_KEEPALIVE_CNT: Override TCP_KEEPCNT socket option. // // See: http://api.zeromq.org/4.0:zmq-getsockopt#toc29 // func (s *Socket) TCPKeepaliveCnt() (int, error) { return s.GetSockOptInt(TCP_KEEPALIVE_CNT) } // ZMQ_TCP_KEEPALIVE_INTVL: Override TCP_KEEPINTVL socket option. // // See: http://api.zeromq.org/4.0:zmq-getsockopt#toc30 // func (s *Socket) TCPKeepaliveIntvl() (int, error) { return s.GetSockOptInt(TCP_KEEPALIVE_INTVL) } // ZMQ_MECHANISM: Retrieve current security mechanism. // // See: http://api.zeromq.org/4.0:zmq-getsockopt#toc31 // func (s *Socket) Mechanism() (int, error) { return s.GetSockOptInt(MECHANISM) } // ZMQ_PLAIN_SERVER: Retrieve current PLAIN server role. // // See: http://api.zeromq.org/4.0:zmq-getsockopt#toc32 // func (s *Socket) PlainServer() (int, error) { return s.GetSockOptInt(PLAIN_SERVER) } // ZMQ_PLAIN_USERNAME: Retrieve current PLAIN username. // // See: http://api.zeromq.org/4.0:zmq-getsockopt#toc33 // func (s *Socket) PlainUsername() (string, error) { return s.GetSockOptString(PLAIN_USERNAME) } // ZMQ_PLAIN_PASSWORD: Retrieve current password. // // See: http://api.zeromq.org/4.0:zmq-getsockopt#toc34 // func (s *Socket) PlainPassword() (string, error) { return s.GetSockOptString(PLAIN_PASSWORD) } // ZMQ_CURVE_PUBLICKEY: Retrieve current CURVE public key. // // See: http://api.zeromq.org/4.0:zmq-getsockopt#toc35 // func (s *Socket) CurvePublickey() (string, error) { return s.GetSockOptString(CURVE_PUBLICKEY) } // ZMQ_CURVE_SECRETKEY: Retrieve current CURVE secret key. // // See: http://api.zeromq.org/4.0:zmq-getsockopt#toc36 // func (s *Socket) CurveSecretkey() (string, error) { return s.GetSockOptString(CURVE_SECRETKEY) } // ZMQ_CURVE_SERVERKEY: Retrieve current CURVE server key. // // See: http://api.zeromq.org/4.0:zmq-getsockopt#toc37 // func (s *Socket) CurveServerkey() (string, error) { return s.GetSockOptString(CURVE_SERVERKEY) } // ZMQ_ZAP_DOMAIN: Retrieve RFC 27 authentication domain. // // See: http://api.zeromq.org/4.0:zmq-getsockopt#toc38 // func (s *Socket) ZapDomain() (string, error) { return s.GetSockOptString(ZAP_DOMAIN) } // Socket Option Setters // ZMQ_SNDHWM: Set high water mark for outbound messages. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc3 // func (s *Socket) SetSndHWM(value int) error { return s.SetSockOptInt(SNDHWM, value) } // ZMQ_RCVHWM: Set high water mark for inbound messages. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc4 // func (s *Socket) SetRcvHWM(value int) error { return s.SetSockOptInt(RCVHWM, value) } // ZMQ_AFFINITY: Set I/O thread affinity. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc5 // func (s *Socket) SetAffinity(value uint64) error { return s.SetSockOptUInt64(AFFINITY, value) } // ZMQ_SUBSCRIBE: Establish message filter. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc6 // func (s *Socket) SetSubscribe(value string) error { return s.SetSockOptString(SUBSCRIBE, value) } // ZMQ_UNSUBSCRIBE: Remove message filter. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc7 // func (s *Socket) SetUnsubscribe(value string) error { return s.SetSockOptString(UNSUBSCRIBE, value) } // ZMQ_IDENTITY: Set socket identity. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc8 // func (s *Socket) SetIdentity(value string) error { return s.SetSockOptString(IDENTITY, value) } // ZMQ_RATE: Set multicast data rate. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc9 // func (s *Socket) SetRate(value int64) error { return s.SetSockOptInt64(RATE, value) } // ZMQ_RECOVERY_IVL: Set multicast recovery interval. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc10 // func (s *Socket) SetRecoveryIvl(value time.Duration) error { return s.SetSockOptInt64(RECOVERY_IVL, int64(value/time.Millisecond)) } // ZMQ_SNDBUF: Set kernel transmit buffer size. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc11 // func (s *Socket) SetSndBuf(value uint64) error { return s.SetSockOptUInt64(SNDBUF, value) } // ZMQ_RCVBUF: Set kernel receive buffer size. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc12 // func (s *Socket) SetRcvBuf(value uint64) error { return s.SetSockOptUInt64(RCVBUF, value) } // ZMQ_LINGER: Set linger period for socket shutdown. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc13 // func (s *Socket) SetLinger(value time.Duration) error { return s.SetSockOptInt(LINGER, int(value/time.Millisecond)) } // ZMQ_RECONNECT_IVL: Set reconnection interval. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc14 // func (s *Socket) SetReconnectIvl(value time.Duration) error { return s.SetSockOptInt(RECONNECT_IVL, int(value/time.Millisecond)) } // ZMQ_RECONNECT_IVL_MAX: Set maximum reconnection interval. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc15 // func (s *Socket) SetReconnectIvlMax(value time.Duration) error { return s.SetSockOptInt(RECONNECT_IVL_MAX, int(value/time.Millisecond)) } // ZMQ_BACKLOG: Set maximum length of the queue of outstanding connections. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc16 // func (s *Socket) SetBacklog(value int) error { return s.SetSockOptInt(BACKLOG, value) } // ZMQ_MAXMSGSIZE: Maximum acceptable inbound message size. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc17 // func (s *Socket) SetMaxMsgSize(value int64) error { return s.SetSockOptInt64(MAXMSGSIZE, value) } // ZMQ_RCVTIMEO: Maximum time before a recv operation returns with EAGAIN. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc19 // func (s *Socket) SetRcvTimeout(value time.Duration) error { return s.SetSockOptInt(RCVTIMEO, int(value/time.Millisecond)) } // ZMQ_SNDTIMEO: Maximum time before a send operation returns with EAGAIN. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc20 // func (s *Socket) SetSndTimeout(value time.Duration) error { return s.SetSockOptInt(SNDTIMEO, int(value/time.Millisecond)) } // ZMQ_IPV6: Enable IPv6 on socket. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc21 // func (s *Socket) SetIpv6(value bool) error { if value { return s.SetSockOptInt(IPV6, 1) } return s.SetSockOptInt(IPV6, 0) } // ZMQ_IPV4ONLY: Use IPv4-only on socket. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc22 // func (s *Socket) SetIPv4Only(value bool) error { if value { return s.SetSockOptInt(IPV4ONLY, 1) } return s.SetSockOptInt(IPV4ONLY, 0) } // ZMQ_IMMEDIATE: Queue messages only to completed connections. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc23 // func (s *Socket) SetImmediate(value bool) error { if value { return s.SetSockOptInt(IMMEDIATE, 1) } return s.SetSockOptInt(IMMEDIATE, 0) } // ZMQ_ROUTER_MANDATORY: accept only routable messages on ROUTER sockets. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc24 // func (s *Socket) SetROUTERMandatory(value bool) error { if value { return s.SetSockOptInt(ROUTER_MANDATORY, 1) } return s.SetSockOptInt(ROUTER_MANDATORY, 0) } // ZMQ_ROUTER_RAW: switch ROUTER socket to raw mode. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc25 // func (s *Socket) SetROUTERRaw(value int) error { return s.SetSockOptInt(ROUTER_RAW, value) } // ZMQ_PROBE_ROUTER: bootstrap connections to ROUTER sockets. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc26 // func (s *Socket) SetProbeROUTER(value int) error { return s.SetSockOptInt(PROBE_ROUTER, value) } // ZMQ_XPUB_VERBOSE: provide all subscription messages on XPUB sockets. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc27 // func (s *Socket) SetXPUBVerbose(value bool) error { if value { return s.SetSockOptInt(XPUB_VERBOSE, 1) } return s.SetSockOptInt(XPUB_VERBOSE, 0) } // ZMQ_REQ_CORRELATE: match replies with requests. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc28 // func (s *Socket) SetReqCorrelate(value int) error { return s.SetSockOptInt(REQ_CORRELATE, value) } // ZMQ_REQ_RELAXED: relax strict alternation between request and reply. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc29 // func (s *Socket) SetReqRelaxed(value int) error { return s.SetSockOptInt(REQ_RELAXED, value) } // ZMQ_TCP_KEEPALIVE: Override SO_KEEPALIVE socket option. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc30 // func (s *Socket) SetTCPKeepalive(value int) error { return s.SetSockOptInt(TCP_KEEPALIVE, value) } // ZMQ_TCP_KEEPALIVE_IDLE: Override TCP_KEEPCNT (or TCP_KEEPALIVE on some OS). // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc31 // func (s *Socket) SetTCPKeepaliveIdle(value int) error { return s.SetSockOptInt(TCP_KEEPALIVE_IDLE, value) } // ZMQ_TCP_KEEPALIVE_CNT: Override TCP_KEEPCNT socket option. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc32 // func (s *Socket) SetTCPKeepaliveCnt(value int) error { return s.SetSockOptInt(TCP_KEEPALIVE_CNT, value) } // ZMQ_TCP_KEEPALIVE_INTVL: Override TCP_KEEPINTVL socket option. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc33 // func (s *Socket) SetTCPKeepaliveIntvl(value int) error { return s.SetSockOptInt(TCP_KEEPALIVE_INTVL, value) } // ZMQ_TCP_ACCEPT_FILTER: Assign filters to allow new TCP connections. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc34 // func (s *Socket) SetTCPAcceptFilter(value string) error { return s.SetSockOptString(TCP_ACCEPT_FILTER, value) } // ZMQ_PLAIN_SERVER: Set PLAIN server role. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc35 // func (s *Socket) SetPlainServer(value int) error { return s.SetSockOptInt(PLAIN_SERVER, value) } // ZMQ_PLAIN_USERNAME: Set PLAIN security username. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc36 // func (s *Socket) SetPlainUsername(value string) error { return s.SetSockOptString(PLAIN_USERNAME, value) } // ZMQ_PLAIN_PASSWORD: Set PLAIN security password. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc37 // func (s *Socket) SetPlainPassword(value string) error { return s.SetSockOptString(PLAIN_PASSWORD, value) } // ZMQ_CURVE_SERVER: Set CURVE server role. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc38 // func (s *Socket) SetCurveServer(value int) error { return s.SetSockOptInt(CURVE_SERVER, value) } // ZMQ_CURVE_PUBLICKEY: Set CURVE public key. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc39 // func (s *Socket) SetCurvePublickey(value string) error { return s.SetSockOptString(CURVE_PUBLICKEY, value) } // ZMQ_CURVE_SECRETKEY: Set CURVE secret key. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc40 // func (s *Socket) SetCurveSecretkey(value string) error { return s.SetSockOptString(CURVE_SECRETKEY, value) } // ZMQ_CURVE_SERVERKEY: Set CURVE server key. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc41 // func (s *Socket) SetCurveServerkey(value string) error { return s.SetSockOptString(CURVE_SERVERKEY, value) } // ZMQ_ZAP_DOMAIN: Set RFC 27 authentication domain. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc42 // func (s *Socket) SetZapDomain(value string) error { return s.SetSockOptString(ZAP_DOMAIN, value) } // ZMQ_CONFLATE: Keep only last message. // // See: http://api.zeromq.org/4.0:zmq-setsockopt#toc43 // func (s *Socket) SetConflate(value bool) error { if value { return s.SetSockOptInt(CONFLATE, 1) } return s.SetSockOptInt(CONFLATE, 0) }