diff options
-rw-r--r-- | crypto.go | 108 | ||||
-rw-r--r-- | event.go | 118 | ||||
-rw-r--r-- | msg.go | 41 | ||||
-rw-r--r-- | netaddr.go | 94 | ||||
-rw-r--r-- | network.go | 311 | ||||
-rw-r--r-- | salticidae.go | 5 | ||||
-rw-r--r-- | stream.go | 336 |
7 files changed, 537 insertions, 476 deletions
@@ -7,92 +7,94 @@ import "runtime" // The C pointer type for a X509 handle. type CX509 = *C.x509_t -type x509 struct { inner CX509 } +type x509 struct{ inner CX509 } + // The handle for a X509 certificate. type X509 = *x509 func X509FromC(ptr CX509) X509 { - return &x509{ inner: ptr } + return &x509{inner: ptr} } func NewX509FromPemFile(fname string, passwd *string, err *Error) X509 { - fname_c_str := C.CString(fname) - passwd_c_str := (*C.char)(nil) - if passwd != nil { - passwd_c_str = C.CString(*passwd) - } - res := X509FromC(C.x509_new_from_pem_file(fname_c_str, passwd_c_str, err)) - if res != nil { - runtime.SetFinalizer(res, func(self X509) { self.free() }) - } - C.free(rawptr_t(fname_c_str)) - if passwd_c_str != nil { - C.free(rawptr_t(passwd_c_str)) - } - return res + fname_c_str := C.CString(fname) + passwd_c_str := (*C.char)(nil) + if passwd != nil { + passwd_c_str = C.CString(*passwd) + } + res := X509FromC(C.x509_new_from_pem_file(fname_c_str, passwd_c_str, err)) + if res != nil { + runtime.SetFinalizer(res, func(self X509) { self.free() }) + } + C.free(rawptr_t(fname_c_str)) + if passwd_c_str != nil { + C.free(rawptr_t(passwd_c_str)) + } + return res } func NewX509FromDer(der ByteArray, err *Error) X509 { - res := X509FromC(C.x509_new_from_der(der.inner, err)) - if res != nil { - runtime.SetFinalizer(res, func(self X509) { self.free() }) - } - return res + res := X509FromC(C.x509_new_from_der(der.inner, err)) + if res != nil { + runtime.SetFinalizer(res, func(self X509) { self.free() }) + } + return res } func (self X509) free() { C.x509_free(self.inner) } func (self X509) GetPubKey() PKey { - res := &pKey{ inner: C.x509_get_pubkey(self.inner) } - runtime.SetFinalizer(res, func(self PKey) { self.free() }) - return res + res := &pKey{inner: C.x509_get_pubkey(self.inner)} + runtime.SetFinalizer(res, func(self PKey) { self.free() }) + return res } func (self X509) GetDer(autoFree bool) ByteArray { - res := ByteArrayFromC(C.x509_get_der(self.inner)) - byteArraySetFinalizer(res, autoFree) - return res + res := ByteArrayFromC(C.x509_get_der(self.inner)) + byteArraySetFinalizer(res, autoFree) + return res } // The C pointer type for a PKey handle. type CPKey = *C.pkey_t -type pKey struct { inner CPKey } +type pKey struct{ inner CPKey } + // The handle for an OpenSSL EVP_PKEY. type PKey = *pKey func NewPrivKeyFromPemFile(fname string, passwd *string, err *Error) PKey { - fname_c_str := C.CString(fname) - passwd_c_str := (*C.char)(nil) - if passwd != nil { - passwd_c_str = C.CString(*passwd) - } - res := &pKey{ inner: C.pkey_new_privkey_from_pem_file(fname_c_str, passwd_c_str, err) } - if res != nil { - runtime.SetFinalizer(res, func(self PKey) { self.free() }) - } - C.free(rawptr_t(fname_c_str)) - if passwd_c_str != nil { - C.free(rawptr_t(passwd_c_str)) - } - return res + fname_c_str := C.CString(fname) + passwd_c_str := (*C.char)(nil) + if passwd != nil { + passwd_c_str = C.CString(*passwd) + } + res := &pKey{inner: C.pkey_new_privkey_from_pem_file(fname_c_str, passwd_c_str, err)} + if res != nil { + runtime.SetFinalizer(res, func(self PKey) { self.free() }) + } + C.free(rawptr_t(fname_c_str)) + if passwd_c_str != nil { + C.free(rawptr_t(passwd_c_str)) + } + return res } func NewPrivKeyFromDer(der ByteArray, err *Error) PKey { - res := &pKey{ inner: C.pkey_new_privkey_from_der(der.inner, err) } - if res != nil { - runtime.SetFinalizer(res, func(self PKey) { self.free() }) - } - return res + res := &pKey{inner: C.pkey_new_privkey_from_der(der.inner, err)} + if res != nil { + runtime.SetFinalizer(res, func(self PKey) { self.free() }) + } + return res } func (self PKey) free() { C.pkey_free(self.inner) } func (self PKey) GetPubKeyDer(autoFree bool) ByteArray { - res := ByteArrayFromC(C.pkey_get_pubkey_der(self.inner)) - byteArraySetFinalizer(res, autoFree) - return res + res := ByteArrayFromC(C.pkey_get_pubkey_der(self.inner)) + byteArraySetFinalizer(res, autoFree) + return res } func (self PKey) GetPrivKeyDer(autoFree bool) ByteArray { - res := ByteArrayFromC(C.pkey_get_privkey_der(self.inner)) - byteArraySetFinalizer(res, autoFree) - return res + res := ByteArrayFromC(C.pkey_get_privkey_der(self.inner)) + byteArraySetFinalizer(res, autoFree) + return res } @@ -8,24 +8,25 @@ import "runtime" // The C pointer type for an EventContext handle. type CEventContext = *C.eventcontext_t type eventContext struct { - inner CEventContext - attached map[uintptr]interface{} + inner CEventContext + attached map[uintptr]interface{} } + // The handle for an event loop. type EventContext = *eventContext func NewEventContext() EventContext { - res := &eventContext{ - inner: C.eventcontext_new(), - attached: make(map[uintptr]interface{}), - } - runtime.SetFinalizer(res, func(self EventContext) { self.free() }) - return res + res := &eventContext{ + inner: C.eventcontext_new(), + attached: make(map[uintptr]interface{}), + } + runtime.SetFinalizer(res, func(self EventContext) { self.free() }) + return res } func (self EventContext) attach(ptr rawptr_t, x interface{}) { self.attached[uintptr(ptr)] = x } -func (self EventContext) detach(ptr rawptr_t) { delete(self.attached, uintptr(ptr)) } -func (self EventContext) free() { C.eventcontext_free(self.inner) } +func (self EventContext) detach(ptr rawptr_t) { delete(self.attached, uintptr(ptr)) } +func (self EventContext) free() { C.eventcontext_free(self.inner) } // Start the event loop. This is a blocking call that will hand over the // control flow to the infinite loop which triggers callbacks upon new events. @@ -40,7 +41,8 @@ func (self EventContext) Stop() { C.eventcontext_stop(self.inner) } // The C pointer type for a ThreadCall handle. type CThreadCall = *C.threadcall_t -type threadCall struct { inner CThreadCall } +type threadCall struct{ inner CThreadCall } + // The handle for scheduling a function call executed by a particular // EventContext event loop. type ThreadCall = *threadCall @@ -53,23 +55,23 @@ type ThreadCallCallback = C.threadcall_callback_t // invokcation of AsyncCall() will schedule a function call executed in the // given EventContext event loop. func NewThreadCall(ec EventContext) ThreadCall { - res := &threadCall{ inner: C.threadcall_new(ec.inner) } - runtime.SetFinalizer(res, func(self ThreadCall) { self.free() }) - return res + res := &threadCall{inner: C.threadcall_new(ec.inner)} + runtime.SetFinalizer(res, func(self ThreadCall) { self.free() }) + return res } func (self ThreadCall) free() { C.threadcall_free(self.inner) } // Schedule a function to be executed in the target event loop. func (self ThreadCall) AsyncCall(callback ThreadCallCallback, userdata rawptr_t) { - C.threadcall_async_call(self.inner, callback, userdata) + C.threadcall_async_call(self.inner, callback, userdata) } // The C pointer type for TimerEvent handle. type CTimerEvent = *C.timerev_t type timerEvent struct { - inner CTimerEvent - ec EventContext + inner CTimerEvent + ec EventContext } // The handle for a timed event. @@ -82,45 +84,44 @@ type TimerEventCallback = C.timerev_callback_t // Create a TimerEvent handle attached to the given EventContext, with a // registered callback. func NewTimerEvent(_ec EventContext, cb TimerEventCallback, userdata rawptr_t) TimerEvent { - res := &timerEvent{ - inner: C.timerev_new(_ec.inner, cb, userdata), - ec: _ec, - } - _ec.attach(rawptr_t(res.inner), res) - runtime.SetFinalizer(res, func(self TimerEvent) { self.free() }) - return res + res := &timerEvent{ + inner: C.timerev_new(_ec.inner, cb, userdata), + ec: _ec, + } + _ec.attach(rawptr_t(res.inner), res) + runtime.SetFinalizer(res, func(self TimerEvent) { self.free() }) + return res } func (self TimerEvent) free() { C.timerev_free(self.inner) } // Change the callback. func (self TimerEvent) SetCallback(callback TimerEventCallback, userdata rawptr_t) { - C.timerev_set_callback(self.inner, callback, userdata) + C.timerev_set_callback(self.inner, callback, userdata) } // Schedule the timer to go off after t_sec seconds. func (self TimerEvent) Add(t_sec float64) { C.timerev_add(self.inner, C.double(t_sec)) } - // Unschedule the timer if it was scheduled. The timer could still be rescheduled // by calling Add() afterwards. func (self TimerEvent) Del() { - self.ec.detach(rawptr_t(self.inner)) - C.timerev_del(self.inner) + self.ec.detach(rawptr_t(self.inner)) + C.timerev_del(self.inner) } // Empty the timer. It will be unscheduled and deallocated and its methods // should never be called again. func (self TimerEvent) Clear() { - self.ec.detach(rawptr_t(self.inner)) - C.timerev_clear(self.inner) + self.ec.detach(rawptr_t(self.inner)) + C.timerev_clear(self.inner) } // The C pointer type for a SigEvent. type CSigEvent = *C.sigev_t type sigEvent struct { - inner CSigEvent - ec EventContext + inner CSigEvent + ec EventContext } // The handle for a UNIX signal event. @@ -129,20 +130,20 @@ type SigEvent = *sigEvent type SigEventCallback = C.sigev_callback_t var ( - SIGTERM = C.SIGTERM - SIGINT = C.SIGINT + SIGTERM = C.SIGTERM + SIGINT = C.SIGINT ) // Create a SigEvent handle attached to the given EventContext, with a // registered callback. func NewSigEvent(_ec EventContext, cb SigEventCallback, userdata rawptr_t) SigEvent { - res := &sigEvent{ - inner: C.sigev_new(_ec.inner, cb, userdata), - ec: _ec, - } - _ec.attach(rawptr_t(res.inner), res) - runtime.SetFinalizer(res, func(self SigEvent) { self.free() }) - return res + res := &sigEvent{ + inner: C.sigev_new(_ec.inner, cb, userdata), + ec: _ec, + } + _ec.attach(rawptr_t(res.inner), res) + runtime.SetFinalizer(res, func(self SigEvent) { self.free() }) + return res } func (self SigEvent) free() { C.sigev_free(self.inner) } @@ -150,25 +151,24 @@ func (self SigEvent) free() { C.sigev_free(self.inner) } // Register the handle to listen for UNIX signal sig. func (self SigEvent) Add(sig int) { C.sigev_add(self.inner, C.int(sig)) } - // Unregister the handle. The handle may be re-registered in the future. func (self SigEvent) Del() { - self.ec.detach(rawptr_t(self.inner)) - C.sigev_del(self.inner) + self.ec.detach(rawptr_t(self.inner)) + C.sigev_del(self.inner) } // Unregister the handle. Any methods of the handle should no longer be used // and the handle will be deallocated. func (self SigEvent) Clear() { - self.ec.detach(rawptr_t(self.inner)) - C.sigev_clear(self.inner) + self.ec.detach(rawptr_t(self.inner)) + C.sigev_clear(self.inner) } // The C pointer type for a MPSCQueue object. type CMPSCQueue = *C.mpscqueue_t type mpscQueue struct { - inner CMPSCQueue - ec EventContext + inner CMPSCQueue + ec EventContext } // The object for a Multi-Producer, Single-Consumer queue. @@ -182,41 +182,41 @@ type MPSCQueueCallback = C.mpscqueue_callback_t // Create a MPSCQueue object. func NewMPSCQueue() MPSCQueue { - res := &mpscQueue{ inner: C.mpscqueue_new(), ec: nil } - runtime.SetFinalizer(res, func(self MPSCQueue) { self.free() }) - return res + res := &mpscQueue{inner: C.mpscqueue_new(), ec: nil} + runtime.SetFinalizer(res, func(self MPSCQueue) { self.free() }) + return res } func (self MPSCQueue) free() { C.mpscqueue_free(self.inner) } // Register the callback invoked when there are new elements in the MPSC queue. func (self MPSCQueue) RegHandler(_ec EventContext, callback MPSCQueueCallback, userdata rawptr_t) { - C.mpscqueue_reg_handler(self.inner, _ec.inner, callback, userdata) - self.ec = _ec - _ec.attach(rawptr_t(self.inner), self) + C.mpscqueue_reg_handler(self.inner, _ec.inner, callback, userdata) + self.ec = _ec + _ec.attach(rawptr_t(self.inner), self) } // Unregister the callback. func (self MPSCQueue) UnregHandler() { - self.ec.detach(rawptr_t(self.inner)) - C.mpscqueue_unreg_handler(self.inner) + self.ec.detach(rawptr_t(self.inner)) + C.mpscqueue_unreg_handler(self.inner) } // Enqueue an element (thread-safe). It returns true if successful. If // unbounded is true the queue is expanded when full (and this function will // return true). func (self MPSCQueue) Enqueue(elem rawptr_t, unbounded bool) bool { - return bool(C.mpscqueue_enqueue(self.inner, elem, C.bool(unbounded))) + return bool(C.mpscqueue_enqueue(self.inner, elem, C.bool(unbounded))) } // Try to dequeue an element from the queue (should only be called from one // thread). It returns true if successful. func (self MPSCQueue) TryDequeue(elem *rawptr_t) bool { - return bool(C.mpscqueue_try_dequeue(self.inner, elem)) + return bool(C.mpscqueue_try_dequeue(self.inner, elem)) } // Set the initial capacity of the queue. This should only be called before the // first dequeue/enqueue operation. func (self MPSCQueue) SetCapacity(capacity int) { - C.mpscqueue_set_capacity(self.inner, C.size_t(capacity)) + C.mpscqueue_set_capacity(self.inner, C.size_t(capacity)) } @@ -8,9 +8,10 @@ import "runtime" // The C pointer type for a Msg object. type CMsg = *C.msg_t type msg struct { - inner CMsg - autoFree bool + inner CMsg + autoFree bool } + // Message sent by MsgNetwork. type Msg = *msg @@ -19,29 +20,29 @@ type Msg = *msg // the extent in which the given C pointer is valid. The C memory will not be // deallocated when the go object is finalized by GC. This applies to all other // "FromC" functions. -func MsgFromC(ptr CMsg) Msg { return &msg{ inner: ptr } } +func MsgFromC(ptr CMsg) Msg { return &msg{inner: ptr} } func msgSetFinalizer(res Msg, autoFree bool) { - res.autoFree = autoFree - if res != nil && autoFree { - runtime.SetFinalizer(res, func(self Msg) { self.Free() }) - } + res.autoFree = autoFree + if res != nil && autoFree { + runtime.SetFinalizer(res, func(self Msg) { self.Free() }) + } } // Create a message by taking out all data from src. Notice this is a zero-copy // operation that consumes and invalidates the data in src ("move" semantics) // so that no more operation should be done to src after this function call. func NewMsgMovedFromByteArray(opcode Opcode, src ByteArray, autoFree bool) Msg { - res := MsgFromC(C.msg_new_moved_from_bytearray(C._opcode_t(opcode), src.inner)) - msgSetFinalizer(res, autoFree) - return res + res := MsgFromC(C.msg_new_moved_from_bytearray(C._opcode_t(opcode), src.inner)) + msgSetFinalizer(res, autoFree) + return res } func (self Msg) Free() { - C.msg_free(self.inner) - if self.autoFree { - runtime.SetFinalizer(self, nil) - } + C.msg_free(self.inner) + if self.autoFree { + runtime.SetFinalizer(self, nil) + } } // Get the message payload by taking out all data. Notice this is a zero-copy @@ -49,22 +50,22 @@ func (self Msg) Free() { // semantics) so that no more operation should be done to the payload after // this function call. func (self Msg) GetPayloadByMove() DataStream { - res := DataStreamFromC(C.msg_consume_payload(self.inner)) - runtime.SetFinalizer(res, func(self DataStream) { self.Free() }) - return res + res := DataStreamFromC(C.msg_consume_payload(self.inner)) + runtime.SetFinalizer(res, func(self DataStream) { self.Free() }) + return res } // Get the opcode. func (self Msg) GetOpcode() Opcode { - return Opcode(C.msg_get_opcode(self.inner)) + return Opcode(C.msg_get_opcode(self.inner)) } // Get the magic number. func (self Msg) GetMagic() uint32 { - return uint32(C.msg_get_magic(self.inner)) + return uint32(C.msg_get_magic(self.inner)) } // Set the magic number (the default value is 0x0). func (self Msg) SetMagic(magic uint32) { - C.msg_set_magic(self.inner, C.uint32_t(magic)) + C.msg_set_magic(self.inner, C.uint32_t(magic)) } @@ -8,9 +8,10 @@ import "runtime" // The C pointer type for a NetAddr object type CNetAddr = *C.netaddr_t type netAddr struct { - inner CNetAddr - autoFree bool + inner CNetAddr + autoFree bool } + // Network address object. type NetAddr = *netAddr @@ -20,30 +21,30 @@ type NetAddr = *netAddr // deallocated when the go object is finalized by GC. This applies to all other // "FromC" functions. func NetAddrFromC(ptr CNetAddr) NetAddr { - return &netAddr{ inner: ptr } + return &netAddr{inner: ptr} } func netAddrSetFinalizer(res NetAddr, autoFree bool) { - res.autoFree = autoFree - if res != nil && autoFree { - runtime.SetFinalizer(res, func(self NetAddr) { self.Free() }) - } + res.autoFree = autoFree + if res != nil && autoFree { + runtime.SetFinalizer(res, func(self NetAddr) { self.Free() }) + } } // Create NetAddr from a TCP socket format string (e.g. 127.0.0.1:8888). func NewNetAddrFromIPPortString(addr string, autoFree bool, err *Error) (res NetAddr) { - c_str := C.CString(addr) - res = &netAddr{ inner: C.netaddr_new_from_sipport(c_str, err) } - C.free(rawptr_t(c_str)) - netAddrSetFinalizer(res, autoFree) - return + c_str := C.CString(addr) + res = &netAddr{inner: C.netaddr_new_from_sipport(c_str, err)} + C.free(rawptr_t(c_str)) + netAddrSetFinalizer(res, autoFree) + return } func (self NetAddr) Free() { - C.netaddr_free(self.inner) - if self.autoFree { - runtime.SetFinalizer(self, nil) - } + C.netaddr_free(self.inner) + if self.autoFree { + runtime.SetFinalizer(self, nil) + } } // Check if two addresses are the same. @@ -62,54 +63,55 @@ func (self NetAddr) GetPort() uint16 { return uint16(C.netaddr_get_port(self.inn // returned (or passed as a callback parameter) by other salticidae methods // (such like MsgNetwork/PeerNetwork), unless those method return a moved object. func (self NetAddr) Copy(autoFree bool) NetAddr { - res := &netAddr{ inner: C.netaddr_copy(self.inner) } - netAddrSetFinalizer(res, autoFree) - return res + res := &netAddr{inner: C.netaddr_copy(self.inner)} + netAddrSetFinalizer(res, autoFree) + return res } // The C pointer type for a NetAddrArray object. type CNetAddrArray = *C.netaddr_array_t type netAddrArray struct { - inner CNetAddrArray - autoFree bool + inner CNetAddrArray + autoFree bool } + // An array of network address. type NetAddrArray = *netAddrArray func NetAddrArrayFromC(ptr CNetAddrArray) NetAddrArray { - return &netAddrArray{ inner: ptr } + return &netAddrArray{inner: ptr} } func netAddrArraySetFinalizer(res NetAddrArray, autoFree bool) { - res.autoFree = autoFree - if res != nil && autoFree { - runtime.SetFinalizer(res, func(self NetAddrArray) { self.Free() }) - } + res.autoFree = autoFree + if res != nil && autoFree { + runtime.SetFinalizer(res, func(self NetAddrArray) { self.Free() }) + } } // Convert a Go slice of net addresses to NetAddrArray. func NewNetAddrArrayFromAddrs(arr []NetAddr, autoFree bool) (res NetAddrArray) { - size := len(arr) - _arr := make([]CNetAddr, size) - for i, v := range arr { - _arr[i] = v.inner - } - if size > 0 { - // FIXME: here we assume struct of a single pointer has the same memory - // footprint the pointer - base := (**C.netaddr_t)(rawptr_t(&_arr[0])) - res = NetAddrArrayFromC(C.netaddr_array_new_from_addrs(base, C.size_t(size))) - } else { - res = NetAddrArrayFromC(C.netaddr_array_new()) - } - runtime.KeepAlive(_arr) - netAddrArraySetFinalizer(res, autoFree) - return + size := len(arr) + _arr := make([]CNetAddr, size) + for i, v := range arr { + _arr[i] = v.inner + } + if size > 0 { + // FIXME: here we assume struct of a single pointer has the same memory + // footprint the pointer + base := (**C.netaddr_t)(rawptr_t(&_arr[0])) + res = NetAddrArrayFromC(C.netaddr_array_new_from_addrs(base, C.size_t(size))) + } else { + res = NetAddrArrayFromC(C.netaddr_array_new()) + } + runtime.KeepAlive(_arr) + netAddrArraySetFinalizer(res, autoFree) + return } func (self NetAddrArray) Free() { - C.netaddr_array_free(self.inner) - if self.autoFree { - runtime.SetFinalizer(self, nil) - } + C.netaddr_array_free(self.inner) + if self.autoFree { + runtime.SetFinalizer(self, nil) + } } @@ -7,7 +7,8 @@ import "runtime" // The C pointer type for a MsgNetwork handle. type CMsgNetwork = *C.msgnetwork_t -type msgNetwork struct { inner CMsgNetwork } +type msgNetwork struct{ inner CMsgNetwork } + // The handle for a message network. type MsgNetwork = *msgNetwork @@ -17,25 +18,26 @@ type MsgNetwork = *msgNetwork // deallocated when the go object is finalized by GC. This applies to all other // "FromC" functions. func MsgNetworkFromC(ptr CMsgNetwork) MsgNetwork { - return &msgNetwork{ inner: ptr } + return &msgNetwork{inner: ptr} } // The C pointer type for a MsgNetworkConn handle. type CMsgNetworkConn = *C.msgnetwork_conn_t type msgNetworkConn struct { - inner CMsgNetworkConn - autoFree bool + inner CMsgNetworkConn + autoFree bool } + // The handle for a message network connection. type MsgNetworkConn = *msgNetworkConn func MsgNetworkConnFromC(ptr CMsgNetworkConn) MsgNetworkConn { - return &msgNetworkConn{ inner: ptr } + return &msgNetworkConn{inner: ptr} } var ( - CONN_MODE_ACTIVE = MsgNetworkConnMode(C.CONN_MODE_ACTIVE) - CONN_MODE_PASSIVE = MsgNetworkConnMode(C.CONN_MODE_PASSIVE) + CONN_MODE_ACTIVE = MsgNetworkConnMode(C.CONN_MODE_ACTIVE) + CONN_MODE_PASSIVE = MsgNetworkConnMode(C.CONN_MODE_PASSIVE) ) // The connection mode. CONN_MODE_ACTIVE: a connection established from the @@ -44,73 +46,73 @@ var ( type MsgNetworkConnMode = C.msgnetwork_conn_mode_t func msgNetworkConnSetFinalizer(res MsgNetworkConn, autoFree bool) { - res.autoFree = autoFree - if res != nil && autoFree { - runtime.SetFinalizer(res, func(self MsgNetworkConn) { self.Free() }) - } + res.autoFree = autoFree + if res != nil && autoFree { + runtime.SetFinalizer(res, func(self MsgNetworkConn) { self.Free() }) + } } func (self MsgNetworkConn) Free() { - C.msgnetwork_conn_free(self.inner) - if self.autoFree { - runtime.SetFinalizer(self, nil) - } + C.msgnetwork_conn_free(self.inner) + if self.autoFree { + runtime.SetFinalizer(self, nil) + } } // Get the corresponding MsgNetwork handle that manages this connection. The // returned handle is only valid during the lifetime of this connection. func (self MsgNetworkConn) GetNet() MsgNetwork { - return MsgNetworkFromC(C.msgnetwork_conn_get_net(self.inner)) + return MsgNetworkFromC(C.msgnetwork_conn_get_net(self.inner)) } func (self MsgNetworkConn) GetMode() MsgNetworkConnMode { - return C.msgnetwork_conn_get_mode(self.inner) + return C.msgnetwork_conn_get_mode(self.inner) } // Get the address of the remote end of this connection. Use Copy() to make a // copy of the address if you want to use the address object beyond the // lifetime of the connection. func (self MsgNetworkConn) GetAddr() NetAddr { - return NetAddrFromC(C.msgnetwork_conn_get_addr(self.inner)) + return NetAddrFromC(C.msgnetwork_conn_get_addr(self.inner)) } // Check if the connection has been terminated. func (self MsgNetworkConn) IsTerminated() bool { - return bool(C.msgnetwork_conn_is_terminated(self.inner)) + return bool(C.msgnetwork_conn_is_terminated(self.inner)) } // Get the certificate of the remote end of this connection. Use Copy() to make a // copy of the certificate if you want to use the certificate object beyond the // lifetime of the connection. func (self MsgNetworkConn) GetPeerCert() X509 { - return &x509{ inner: C.msgnetwork_conn_get_peer_cert(self.inner) } + return &x509{inner: C.msgnetwork_conn_get_peer_cert(self.inner)} } // Make a copy of the object. This is required if you want to keep the // connection passed as a callback parameter by other salticidae methods (such // like MsgNetwork/PeerNetwork). func (self MsgNetworkConn) Copy(autoFree bool) MsgNetworkConn { - res := MsgNetworkConnFromC(C.msgnetwork_conn_copy(self.inner)) - msgNetworkConnSetFinalizer(res, autoFree) - return res + res := MsgNetworkConnFromC(C.msgnetwork_conn_copy(self.inner)) + msgNetworkConnSetFinalizer(res, autoFree) + return res } - // The C pointer type for a MsgNetworkConfig object. type CMsgNetworkConfig = *C.msgnetwork_config_t -type msgNetworkConfig struct { inner CMsgNetworkConfig } +type msgNetworkConfig struct{ inner CMsgNetworkConfig } + // Configuration for MsgNetwork. type MsgNetworkConfig = *msgNetworkConfig func MsgNetworkConfigFromC(ptr CMsgNetworkConfig) MsgNetworkConfig { - return &msgNetworkConfig{ inner: ptr } + return &msgNetworkConfig{inner: ptr} } // Create the configuration object with default settings. func NewMsgNetworkConfig() MsgNetworkConfig { - res := MsgNetworkConfigFromC(C.msgnetwork_config_new()) - runtime.SetFinalizer(res, func(self MsgNetworkConfig) { self.free() }) - return res + res := MsgNetworkConfigFromC(C.msgnetwork_config_new()) + runtime.SetFinalizer(res, func(self MsgNetworkConfig) { self.free() }) + return res } func (self MsgNetworkConfig) free() { C.msgnetwork_config_free(self.inner) } @@ -119,62 +121,62 @@ func (self MsgNetworkConfig) free() { C.msgnetwork_config_free(self.inner) } // Usually the default value is good enough. This is used to make the tradeoff // between the event loop fairness and the amortization of syscall cost. func (self MsgNetworkConfig) BurstSize(size int) { - C.msgnetwork_config_burst_size(self.inner, C.size_t(size)) + C.msgnetwork_config_burst_size(self.inner, C.size_t(size)) } // Set the maximum backlogs (see POSIX TCP backlog). func (self MsgNetworkConfig) MaxListenBacklog(backlog int) { - C.msgnetwork_config_max_listen_backlog(self.inner, C.int(backlog)) + C.msgnetwork_config_max_listen_backlog(self.inner, C.int(backlog)) } // Set the timeout for connecting to the remote (in seconds). func (self MsgNetworkConfig) ConnServerTimeout(timeout float64) { - C.msgnetwork_config_conn_server_timeout(self.inner, C.double(timeout)) + C.msgnetwork_config_conn_server_timeout(self.inner, C.double(timeout)) } // Set the size for an inbound data chunk (per read() syscall). func (self MsgNetworkConfig) SegBuffSize(size int) { - C.msgnetwork_config_seg_buff_size(self.inner, C.size_t(size)) + C.msgnetwork_config_seg_buff_size(self.inner, C.size_t(size)) } // Set the number of worker threads. func (self MsgNetworkConfig) NWorker(nworker int) { - C.msgnetwork_config_nworker(self.inner, C.size_t(nworker)) + C.msgnetwork_config_nworker(self.inner, C.size_t(nworker)) } // Set the capacity of the send buffer. func (self MsgNetworkConfig) QueueCapacity(capacity int) { - C.msgnetwork_config_queue_capacity(self.inner, C.size_t(capacity)) + C.msgnetwork_config_queue_capacity(self.inner, C.size_t(capacity)) } // Specify whether to use SSL/TLS. When this flag is enabled, MsgNetwork uses // TLSKey (or TLSKeyFile) or TLSCert (or TLSCertFile) to setup the underlying // OpenSSL. func (self MsgNetworkConfig) EnableTLS(enabled bool) { - C.msgnetwork_config_enable_tls(self.inner, C.bool(enabled)) + C.msgnetwork_config_enable_tls(self.inner, C.bool(enabled)) } // Load the TLS key from a file. The file should be an unencrypted PEM file. // Use TLSKey() instead for more complex usage. func (self MsgNetworkConfig) TLSKeyFile(fname string) { - c_str := C.CString(fname) - C.msgnetwork_config_tls_key_file(self.inner, c_str) - C.free(rawptr_t(c_str)) + c_str := C.CString(fname) + C.msgnetwork_config_tls_key_file(self.inner, c_str) + C.free(rawptr_t(c_str)) } // Load the TLS certificate from a file. The file should be an unencrypted // (X509) PEM file. Use TLSCert() instead for more complex usage. func (self MsgNetworkConfig) TLSCertFile(fname string) { - c_str := C.CString(fname) - C.msgnetwork_config_tls_cert_file(self.inner, c_str) - C.free(rawptr_t(c_str)) + c_str := C.CString(fname) + C.msgnetwork_config_tls_cert_file(self.inner, c_str) + C.free(rawptr_t(c_str)) } // Use the given TLS key. This overrides TLSKeyFile(). pkey will be moved and // kept by the library. Thus, no methods of msg involving the payload should be // called afterwards. func (self MsgNetworkConfig) TLSKeyByMove(pkey PKey) { - C.msgnetwork_config_tls_key_by_move(self.inner, pkey.inner) + C.msgnetwork_config_tls_key_by_move(self.inner, pkey.inner) } //// Load the TLS certificate from a file. The file should be an unencrypted @@ -187,12 +189,12 @@ func (self MsgNetworkConfig) TLSKeyByMove(pkey PKey) { // Create a message network handle which is attached to given event loop. func NewMsgNetwork(ec EventContext, config MsgNetworkConfig, err *Error) MsgNetwork { - res := MsgNetworkFromC(C.msgnetwork_new(ec.inner, config.inner, err)) - if res != nil { - ec.attach(rawptr_t(res.inner), res) - runtime.SetFinalizer(res, func(self MsgNetwork) { self.free() }) - } - return res + res := MsgNetworkFromC(C.msgnetwork_new(ec.inner, config.inner, err)) + if res != nil { + ec.attach(rawptr_t(res.inner), res) + runtime.SetFinalizer(res, func(self MsgNetwork) { self.free() }) + } + return res } func (self MsgNetwork) free() { C.msgnetwork_free(self.inner) } @@ -202,14 +204,16 @@ func (self MsgNetwork) free() { C.msgnetwork_free(self.inner) } func (self MsgNetwork) Start() { C.msgnetwork_start(self.inner) } // Listen to the specified network address. -func (self MsgNetwork) Listen(addr NetAddr, err *Error) { C.msgnetwork_listen(self.inner, addr.inner, err) } +func (self MsgNetwork) Listen(addr NetAddr, err *Error) { + C.msgnetwork_listen(self.inner, addr.inner, err) +} // Stop the message network. No other methods should be called after this. func (self MsgNetwork) Stop() { C.msgnetwork_stop(self.inner) } // Send a message through the given connection. func (self MsgNetwork) SendMsg(msg Msg, conn MsgNetworkConn) bool { - return bool(C.msgnetwork_send_msg(self.inner, msg.inner, conn.inner)) + return bool(C.msgnetwork_send_msg(self.inner, msg.inner, conn.inner)) } // Send a message through the given connection, using a worker thread to @@ -217,21 +221,21 @@ func (self MsgNetwork) SendMsg(msg Msg, conn MsgNetworkConn) bool { // msg will be moved and sent. Thus, no methods of msg involving the payload // should be called afterwards. func (self MsgNetwork) SendMsgDeferredByMove(msg Msg, conn MsgNetworkConn) int32 { - return int32(C.msgnetwork_send_msg_deferred_by_move(self.inner, msg.inner, conn.inner)) + return int32(C.msgnetwork_send_msg_deferred_by_move(self.inner, msg.inner, conn.inner)) } // Try to connect to a remote address. The connection handle is returned. The // returned connection handle could be kept in your program. func (self MsgNetwork) ConnectSync(addr NetAddr, autoFree bool, err *Error) MsgNetworkConn { - res := MsgNetworkConnFromC(C.msgnetwork_connect_sync(self.inner, addr.inner, err)) - msgNetworkConnSetFinalizer(res, autoFree) - return res + res := MsgNetworkConnFromC(C.msgnetwork_connect_sync(self.inner, addr.inner, err)) + msgNetworkConnSetFinalizer(res, autoFree) + return res } // Try to connect to a remote address (async). It returns an id which could be // used to identify the corresponding error in the error callback. func (self MsgNetwork) Connect(addr NetAddr) int32 { - return int32(C.msgnetwork_connect(self.inner, addr.inner)) + return int32(C.msgnetwork_connect(self.inner, addr.inner)) } // Terminate the given connection. @@ -240,10 +244,12 @@ func (self MsgNetwork) Terminate(conn MsgNetworkConn) { C.msgnetwork_terminate(s // The C function pointer type which takes msg_t*, msgnetwork_conn_t* and void* // (passing in the custom user data allocated by C.malloc) as parameters. type MsgNetworkMsgCallback = C.msgnetwork_msg_callback_t + // The C function pointer type which takes msgnetwork_conn_t*, bool (true for // the connection is established, false for the connection is terminated) and // void* as parameters. type MsgNetworkConnCallback = C.msgnetwork_conn_callback_t + // The C function Pointer type which takes SalticidaeCError* and void* as parameters. type MsgNetworkErrorCallback = C.msgnetwork_error_callback_t @@ -251,53 +257,55 @@ type MsgNetworkErrorCallback = C.msgnetwork_error_callback_t // callback function will be invoked upon the delivery of each message with the // given opcode, by the thread of the event loop the MsgNetwork is attached to. func (self MsgNetwork) RegHandler(opcode Opcode, callback MsgNetworkMsgCallback, userdata rawptr_t) { - C.msgnetwork_reg_handler(self.inner, C._opcode_t(opcode), callback, userdata) + C.msgnetwork_reg_handler(self.inner, C._opcode_t(opcode), callback, userdata) } // Register a connection handler invoked when the connection state is changed. func (self MsgNetwork) RegConnHandler(callback MsgNetworkConnCallback, userdata rawptr_t) { - C.msgnetwork_reg_conn_handler(self.inner, callback, userdata) + C.msgnetwork_reg_conn_handler(self.inner, callback, userdata) } // Register an error handler invoked when there is recoverable errors during any // asynchronous call/execution inside the MsgNetwork. func (self MsgNetwork) RegErrorHandler(callback MsgNetworkErrorCallback, userdata rawptr_t) { - C.msgnetwork_reg_error_handler(self.inner, callback, userdata) + C.msgnetwork_reg_error_handler(self.inner, callback, userdata) } // The C pointer type for a PeerNetwork handle. type CPeerNetwork = *C.peernetwork_t -type peerNetwork struct { inner CPeerNetwork } +type peerNetwork struct{ inner CPeerNetwork } + // The handle for a peer-to-peer network. type PeerNetwork = *peerNetwork func PeerNetworkFromC(ptr CPeerNetwork) PeerNetwork { - return &peerNetwork{ inner: ptr } + return &peerNetwork{inner: ptr} } // The C pointer type for a PeerNetworkConn handle. type CPeerNetworkConn = *C.peernetwork_conn_t type peerNetworkConn struct { - inner CPeerNetworkConn - autoFree bool + inner CPeerNetworkConn + autoFree bool } + // The handle for a PeerNetwork connection. type PeerNetworkConn = *peerNetworkConn func PeerNetworkConnFromC(ptr CPeerNetworkConn) PeerNetworkConn { - return &peerNetworkConn{ inner: ptr } + return &peerNetworkConn{inner: ptr} } func peerNetworkConnSetFinalizer(res PeerNetworkConn, autoFree bool) { - res.autoFree = autoFree - if res != nil && autoFree { - runtime.SetFinalizer(res, func(self PeerNetworkConn) { self.Free() }) - } + res.autoFree = autoFree + if res != nil && autoFree { + runtime.SetFinalizer(res, func(self PeerNetworkConn) { self.Free() }) + } } var ( - ADDR_BASED = PeerNetworkIdMode(C.ID_MODE_ADDR_BASED) - CERT_BASED = PeerNetworkIdMode(C.ID_MODE_CERT_BASED) + ADDR_BASED = PeerNetworkIdMode(C.ID_MODE_ADDR_BASED) + CERT_BASED = PeerNetworkIdMode(C.ID_MODE_CERT_BASED) ) // The identity mode. ID_MODE_IP_BASED: a remote peer is identified by the IP @@ -307,58 +315,59 @@ type PeerNetworkIdMode = C.peernetwork_id_mode_t // The C pointer type for a PeerNetworkConfig handle. type CPeerNetworkConfig = *C.peernetwork_config_t -type peerNetworkConfig struct { inner CPeerNetworkConfig } +type peerNetworkConfig struct{ inner CPeerNetworkConfig } + // Configuration for PeerNetwork. type PeerNetworkConfig = *peerNetworkConfig func PeerNetworkConfigFromC(ptr CPeerNetworkConfig) PeerNetworkConfig { - return &peerNetworkConfig{ inner: ptr } + return &peerNetworkConfig{inner: ptr} } // Create the configuration object with default settings. func NewPeerNetworkConfig() PeerNetworkConfig { - res := PeerNetworkConfigFromC(C.peernetwork_config_new()) - runtime.SetFinalizer(res, func(self PeerNetworkConfig) { self.free() }) - return res + res := PeerNetworkConfigFromC(C.peernetwork_config_new()) + runtime.SetFinalizer(res, func(self PeerNetworkConfig) { self.free() }) + return res } func (self PeerNetworkConfig) free() { C.peernetwork_config_free(self.inner) } // Set the connection retry delay (in seconds). func (self PeerNetworkConfig) RetryConnDelay(t_sec float64) { - C.peernetwork_config_retry_conn_delay(self.inner, C.double(t_sec)) + C.peernetwork_config_retry_conn_delay(self.inner, C.double(t_sec)) } // Set the period for sending ping messsages (in seconds). func (self PeerNetworkConfig) PingPeriod(t_sec float64) { - C.peernetwork_config_ping_period(self.inner, C.double(t_sec)) + C.peernetwork_config_ping_period(self.inner, C.double(t_sec)) } // Set the time it takes after sending a ping message before a connection is // considered as broken. func (self PeerNetworkConfig) ConnTimeout(t_sec float64) { - C.peernetwork_config_conn_timeout(self.inner, C.double(t_sec)) + C.peernetwork_config_conn_timeout(self.inner, C.double(t_sec)) } // Set the identity mode. func (self PeerNetworkConfig) IdMode(mode PeerNetworkIdMode) { - C.peernetwork_config_id_mode(self.inner, mode) + C.peernetwork_config_id_mode(self.inner, mode) } // Use the PeerNetworkConfig object as a MsgNetworkConfig object (to invoke the // methods inherited from MsgNetworkConfig, such as NWorker). func (self PeerNetworkConfig) AsMsgNetworkConfig() MsgNetworkConfig { - return MsgNetworkConfigFromC(C.peernetwork_config_as_msgnetwork_config(self.inner)) + return MsgNetworkConfigFromC(C.peernetwork_config_as_msgnetwork_config(self.inner)) } // Create a peer-to-peer message network handle. func NewPeerNetwork(ec EventContext, config PeerNetworkConfig, err *Error) PeerNetwork { - res := PeerNetworkFromC(C.peernetwork_new(ec.inner, config.inner, err)) - if res != nil { - ec.attach(rawptr_t(res.inner), res) - runtime.SetFinalizer(res, func(self PeerNetwork) { self.free() }) - } - return res + res := PeerNetworkFromC(C.peernetwork_new(ec.inner, config.inner, err)) + if res != nil { + ec.attach(rawptr_t(res.inner), res) + runtime.SetFinalizer(res, func(self PeerNetwork) { self.free() }) + } + return res } func (self PeerNetwork) free() { C.peernetwork_free(self.inner) } @@ -373,74 +382,76 @@ func (self PeerNetwork) AddPeer(addr NetAddr) { C.peernetwork_add_peer(self.inne func (self PeerNetwork) DelPeer(addr NetAddr) { C.peernetwork_del_peer(self.inner, addr.inner) } // Test whether a peer is already in the list. -func (self PeerNetwork) HasPeer(addr NetAddr) bool { return bool(C.peernetwork_has_peer(self.inner, addr.inner)) } +func (self PeerNetwork) HasPeer(addr NetAddr) bool { + return bool(C.peernetwork_has_peer(self.inner, addr.inner)) +} // Get the connection of the known peer. The connection handle is returned. The // returned connection handle could be kept in your program. func (self PeerNetwork) GetPeerConn(addr NetAddr, autoFree bool, err *Error) PeerNetworkConn { - res := PeerNetworkConnFromC(C.peernetwork_get_peer_conn(self.inner, addr.inner, err)) - peerNetworkConnSetFinalizer(res, autoFree) - return res + res := PeerNetworkConnFromC(C.peernetwork_get_peer_conn(self.inner, addr.inner, err)) + peerNetworkConnSetFinalizer(res, autoFree) + return res } // Use the PeerNetwork handle as a MsgNetwork handle (to invoke the methods // inherited from MsgNetwork, such as RegHandler). func (self PeerNetwork) AsMsgNetwork() MsgNetwork { - return MsgNetworkFromC(C.peernetwork_as_msgnetwork(self.inner)) + return MsgNetworkFromC(C.peernetwork_as_msgnetwork(self.inner)) } // Use the MsgNetwork handle as a PeerNetwork handle (forcing the conversion). func (self MsgNetwork) AsPeerNetworkUnsafe() PeerNetwork { - return PeerNetworkFromC(C.msgnetwork_as_peernetwork_unsafe(self.inner)) + return PeerNetworkFromC(C.msgnetwork_as_peernetwork_unsafe(self.inner)) } // Create a MsgNetworkConn handle from a PeerNetworkConn (representing the same // connection). func NewMsgNetworkConnFromPeerNetworkConn(conn PeerNetworkConn, autoFree bool) MsgNetworkConn { - res := MsgNetworkConnFromC(C.msgnetwork_conn_new_from_peernetwork_conn(conn.inner)) - msgNetworkConnSetFinalizer(res, autoFree) - return res + res := MsgNetworkConnFromC(C.msgnetwork_conn_new_from_peernetwork_conn(conn.inner)) + msgNetworkConnSetFinalizer(res, autoFree) + return res } // Create a PeerNetworkConn handle from a MsgNetworkConn (representing the same // connection and forcing the conversion). func NewPeerNetworkConnFromMsgNetworkConnUnsafe(conn MsgNetworkConn, autoFree bool) PeerNetworkConn { - res := PeerNetworkConnFromC(C.peernetwork_conn_new_from_msgnetwork_conn_unsafe(conn.inner)) - peerNetworkConnSetFinalizer(res, autoFree) - return res + res := PeerNetworkConnFromC(C.peernetwork_conn_new_from_msgnetwork_conn_unsafe(conn.inner)) + peerNetworkConnSetFinalizer(res, autoFree) + return res } // Make a copy of the connection handle. func (self PeerNetworkConn) Copy(autoFree bool) PeerNetworkConn { - res := PeerNetworkConnFromC(C.peernetwork_conn_copy(self.inner)) - peerNetworkConnSetFinalizer(res, autoFree) - return res + res := PeerNetworkConnFromC(C.peernetwork_conn_copy(self.inner)) + peerNetworkConnSetFinalizer(res, autoFree) + return res } // Get the listening address of the remote peer (no Copy() is needed). func (self PeerNetworkConn) GetPeerAddr(autoFree bool) NetAddr { - res := NetAddrFromC(C.peernetwork_conn_get_peer_addr(self.inner)) - netAddrSetFinalizer(res, autoFree) - return res + res := NetAddrFromC(C.peernetwork_conn_get_peer_addr(self.inner)) + netAddrSetFinalizer(res, autoFree) + return res } func (self PeerNetworkConn) Free() { - C.peernetwork_conn_free(self.inner) - if self.autoFree { - runtime.SetFinalizer(self, nil) - } + C.peernetwork_conn_free(self.inner) + if self.autoFree { + runtime.SetFinalizer(self, nil) + } } // Listen to the specified network address. Notice that this method overrides // Listen() in MsgNetwork, so you should always call this one instead of // AsMsgNetwork().Listen(). func (self PeerNetwork) Listen(listenAddr NetAddr, err *Error) { - C.peernetwork_listen(self.inner, listenAddr.inner, err) + C.peernetwork_listen(self.inner, listenAddr.inner, err) } // Send a message to the given peer. func (self PeerNetwork) SendMsg(msg Msg, addr NetAddr) bool { - return bool(C.peernetwork_send_msg(self.inner, msg.inner, addr.inner)) + return bool(C.peernetwork_send_msg(self.inner, msg.inner, addr.inner)) } // Send a message to the given peer, using a worker thread to seralize and put @@ -448,17 +459,17 @@ func (self PeerNetwork) SendMsg(msg Msg, addr NetAddr) bool { // moved and sent. Thus, no methods of msg involving the payload should be // called afterwards. func (self PeerNetwork) SendMsgDeferredByMove(msg Msg, addr NetAddr) int32 { - return int32(C.peernetwork_send_msg_deferred_by_move(self.inner, msg.inner, addr.inner)) + return int32(C.peernetwork_send_msg_deferred_by_move(self.inner, msg.inner, addr.inner)) } // Send a message to the given list of peers. The payload contained in the // given msg will be moved and sent. Thus, no methods of msg involving the // payload should be called afterwards. func (self PeerNetwork) MulticastMsgByMove(msg Msg, addrs []NetAddr) (res int32) { - na := NewNetAddrArrayFromAddrs(addrs, false) - res = int32(C.peernetwork_multicast_msg_by_move(self.inner, msg.inner, na.inner)) - na.Free() - return res + na := NewNetAddrArrayFromAddrs(addrs, false) + res = int32(C.peernetwork_multicast_msg_by_move(self.inner, msg.inner, na.inner)) + na.Free() + return res } // The C function pointer type which takes peernetwork_conn_t*, bool and void* @@ -467,7 +478,7 @@ type PeerNetworkPeerCallback = C.peernetwork_peer_callback_t // Register a connection handler invoked when p2p connection is established/broken. func (self PeerNetwork) RegPeerHandler(callback PeerNetworkPeerCallback, userdata rawptr_t) { - C.peernetwork_reg_peer_handler(self.inner, callback, userdata) + C.peernetwork_reg_peer_handler(self.inner, callback, userdata) } // The C function pointer type which takes netaddr_t*, x509_t* and void* (passing in the @@ -479,47 +490,49 @@ type PeerNetworkUnknownPeerCallback = C.peernetwork_unknown_peer_callback_t // connection was rejected, and you can call AddPeer() to enroll this peer if // you hope to establish the connection soon. func (self PeerNetwork) RegUnknownPeerHandler(callback PeerNetworkUnknownPeerCallback, userdata rawptr_t) { - C.peernetwork_reg_unknown_peer_handler(self.inner, callback, userdata) + C.peernetwork_reg_unknown_peer_handler(self.inner, callback, userdata) } // The C pointer type for a ClientNetwork handle. type CClientNetwork = *C.clientnetwork_t -type clientNetwork struct { inner CClientNetwork } +type clientNetwork struct{ inner CClientNetwork } + // The handle for a client-server network. type ClientNetwork = *clientNetwork func ClientNetworkFromC(ptr CClientNetwork) ClientNetwork { - return &clientNetwork{ inner: ptr } + return &clientNetwork{inner: ptr} } // The C pointer type for a ClientNetworkConn handle. type CClientNetworkConn = *C.clientnetwork_conn_t type clientNetworkConn struct { - inner CClientNetworkConn - autoFree bool + inner CClientNetworkConn + autoFree bool } + // The handle for a ClientNetwork connection. type ClientNetworkConn = *clientNetworkConn func ClientNetworkConnFromC(ptr CClientNetworkConn) ClientNetworkConn { - return &clientNetworkConn{ inner: ptr } + return &clientNetworkConn{inner: ptr} } func clientNetworkConnSetFinalizer(res ClientNetworkConn, autoFree bool) { - res.autoFree = autoFree - if res != nil && autoFree { - runtime.SetFinalizer(res, func(self ClientNetworkConn) { self.Free() }) - } + res.autoFree = autoFree + if res != nil && autoFree { + runtime.SetFinalizer(res, func(self ClientNetworkConn) { self.Free() }) + } } // Create a client-server message network handle. func NewClientNetwork(ec EventContext, config MsgNetworkConfig, err *Error) ClientNetwork { - res := ClientNetworkFromC(C.clientnetwork_new(ec.inner, config.inner, err)) - if res != nil { - ec.attach(rawptr_t(res.inner), res) - runtime.SetFinalizer(res, func(self ClientNetwork) { self.free() }) - } - return res + res := ClientNetworkFromC(C.clientnetwork_new(ec.inner, config.inner, err)) + if res != nil { + ec.attach(rawptr_t(res.inner), res) + runtime.SetFinalizer(res, func(self ClientNetwork) { self.free() }) + } + return res } func (self ClientNetwork) free() { C.clientnetwork_free(self.inner) } @@ -527,47 +540,47 @@ func (self ClientNetwork) free() { C.clientnetwork_free(self.inner) } // Use the ClientNetwork handle as a MsgNetwork handle (to invoke the methods // inherited from MsgNetwork, such as RegHandler). func (self ClientNetwork) AsMsgNetwork() MsgNetwork { - return MsgNetworkFromC(C.clientnetwork_as_msgnetwork(self.inner)) + return MsgNetworkFromC(C.clientnetwork_as_msgnetwork(self.inner)) } // Use the MsgNetwork handle as a ClientNetwork handle (forcing the conversion). func (self MsgNetwork) AsClientNetworkUnsafe() ClientNetwork { - return ClientNetworkFromC(C.msgnetwork_as_clientnetwork_unsafe(self.inner)) + return ClientNetworkFromC(C.msgnetwork_as_clientnetwork_unsafe(self.inner)) } // Create a MsgNetworkConn handle from a ClientNetworkConn (representing the same // connection). func NewMsgNetworkConnFromClientNetworkConn(conn ClientNetworkConn, autoFree bool) MsgNetworkConn { - res := MsgNetworkConnFromC(C.msgnetwork_conn_new_from_clientnetwork_conn(conn.inner)) - msgNetworkConnSetFinalizer(res, autoFree) - return res + res := MsgNetworkConnFromC(C.msgnetwork_conn_new_from_clientnetwork_conn(conn.inner)) + msgNetworkConnSetFinalizer(res, autoFree) + return res } // Create a ClientNetworkConn handle from a MsgNetworkConn (representing the same // connection and forcing the conversion). func NewClientNetworkConnFromMsgNetworkConnUnsafe(conn MsgNetworkConn, autoFree bool) ClientNetworkConn { - res := ClientNetworkConnFromC(C.clientnetwork_conn_new_from_msgnetwork_conn_unsafe(conn.inner)) - clientNetworkConnSetFinalizer(res, autoFree) - return res + res := ClientNetworkConnFromC(C.clientnetwork_conn_new_from_msgnetwork_conn_unsafe(conn.inner)) + clientNetworkConnSetFinalizer(res, autoFree) + return res } // Make a copy of the connection handle. func (self ClientNetworkConn) Copy(autoFree bool) ClientNetworkConn { - res := ClientNetworkConnFromC(C.clientnetwork_conn_copy(self.inner)) - clientNetworkConnSetFinalizer(res, autoFree) - return res + res := ClientNetworkConnFromC(C.clientnetwork_conn_copy(self.inner)) + clientNetworkConnSetFinalizer(res, autoFree) + return res } func (self ClientNetworkConn) Free() { - C.clientnetwork_conn_free(self.inner) - if self.autoFree { - runtime.SetFinalizer(self, nil) - } + C.clientnetwork_conn_free(self.inner) + if self.autoFree { + runtime.SetFinalizer(self, nil) + } } // Send a message to the given client. func (self ClientNetwork) SendMsg(msg Msg, addr NetAddr) bool { - return bool(C.clientnetwork_send_msg(self.inner, msg.inner, addr.inner)) + return bool(C.clientnetwork_send_msg(self.inner, msg.inner, addr.inner)) } // Send a message to the given client, using a worker thread to seralize and put @@ -575,5 +588,5 @@ func (self ClientNetwork) SendMsg(msg Msg, addr NetAddr) bool { // moved and sent. Thus, no methods of msg involving the payload should be // called afterwards. func (self ClientNetwork) SendMsgDeferredByMove(msg Msg, addr NetAddr) int32 { - return int32(C.clientnetwork_send_msg_deferred_by_move(self.inner, msg.inner, addr.inner)) + return int32(C.clientnetwork_send_msg_deferred_by_move(self.inner, msg.inner, addr.inner)) } diff --git a/salticidae.go b/salticidae.go index 0698f39..8676a3d 100644 --- a/salticidae.go +++ b/salticidae.go @@ -1,6 +1,5 @@ package salticidae - // #cgo CFLAGS: -I${SRCDIR}/salticidae/include/ // #cgo LDFLAGS: ${SRCDIR}/salticidae/libsalticidae.so -Wl,-rpath=${SRCDIR}/salticidae/ // #include "salticidae/util.h" @@ -14,9 +13,9 @@ type Error = C.struct_SalticidaeCError func (self *Error) GetCode() int { return int((*C.struct_SalticidaeCError)(self).code) } func NewError() Error { - return C.struct_SalticidaeCError {} + return C.struct_SalticidaeCError{} } func StrError(code int) string { - return C.GoString(C.salticidae_strerror(C.int(code))) + return C.GoString(C.salticidae_strerror(C.int(code))) } @@ -22,39 +22,41 @@ import "C" import "runtime" type CByteArray = *C.bytearray_t + // The C pointer to a ByteArray object. type byteArray struct { - inner CByteArray - autoFree bool + inner CByteArray + autoFree bool } + // Array of binary data. type ByteArray = *byteArray func ByteArrayFromC(ptr CByteArray) ByteArray { - return &byteArray{ inner: ptr } + return &byteArray{inner: ptr} } func byteArraySetFinalizer(res ByteArray, autoFree bool) { - res.autoFree = autoFree - if res != nil && autoFree { - runtime.SetFinalizer(res, func(self ByteArray) { self.Free() }) - } + res.autoFree = autoFree + if res != nil && autoFree { + runtime.SetFinalizer(res, func(self ByteArray) { self.Free() }) + } } // Create an empty byte array (with zero contained bytes). func NewByteArray(autoFree bool) ByteArray { - res := ByteArrayFromC(C.bytearray_new()) - byteArraySetFinalizer(res, autoFree) - return res + res := ByteArrayFromC(C.bytearray_new()) + byteArraySetFinalizer(res, autoFree) + return res } // Free the ByteArray manually. If the object is constructed with autoFree = // true, this will immediately free the object. func (self ByteArray) Free() { - C.bytearray_free(self.inner) - if self.autoFree { - runtime.SetFinalizer(self, nil) - } + C.bytearray_free(self.inner) + if self.autoFree { + runtime.SetFinalizer(self, nil) + } } // Create a byte array by taking out all data from src. Notice this is a @@ -63,112 +65,112 @@ func (self ByteArray) Free() { // function call. Also notice unlike copying, the entire DataStream buffer is // moved (including the possibily consumed part). func NewByteArrayMovedFromDataStream(src DataStream, autoFree bool) (res ByteArray) { - res = ByteArrayFromC(C.bytearray_new_moved_from_datastream(src.inner)) - byteArraySetFinalizer(res, autoFree) - return + res = ByteArrayFromC(C.bytearray_new_moved_from_datastream(src.inner)) + byteArraySetFinalizer(res, autoFree) + return } // Create a byte array by copying the remaining data from src. func NewByteArrayCopiedFromDataStream(src DataStream, autoFree bool) (res ByteArray) { - res = ByteArrayFromC(C.bytearray_new_copied_from_datastream(src.inner)) - byteArraySetFinalizer(res, autoFree) - return + res = ByteArrayFromC(C.bytearray_new_copied_from_datastream(src.inner)) + byteArraySetFinalizer(res, autoFree) + return } func NewByteArrayFromHex(hex string) (res ByteArray, autoFree bool) { - c_str := C.CString(hex) - res = ByteArrayFromC(C.bytearray_new_from_hex(c_str)) - C.free(rawptr_t(c_str)) - byteArraySetFinalizer(res, autoFree) - return + c_str := C.CString(hex) + res = ByteArrayFromC(C.bytearray_new_from_hex(c_str)) + C.free(rawptr_t(c_str)) + byteArraySetFinalizer(res, autoFree) + return } func NewByteArrayFromBytes(bytes []byte, autoFree bool) (res ByteArray) { - size := len(bytes) - if size > 0 { - base := (*C.uint8_t)(&bytes[0]) - res = ByteArrayFromC(C.bytearray_new_from_bytes(base, C.size_t(size))) - } else { - res = ByteArrayFromC(C.bytearray_new()) - } - byteArraySetFinalizer(res, autoFree) - return + size := len(bytes) + if size > 0 { + base := (*C.uint8_t)(&bytes[0]) + res = ByteArrayFromC(C.bytearray_new_from_bytes(base, C.size_t(size))) + } else { + res = ByteArrayFromC(C.bytearray_new()) + } + byteArraySetFinalizer(res, autoFree) + return } // The C pointer to a DataStream object. type CDataStream = *C.datastream_t type dataStream struct { - inner CDataStream - attached map[uintptr]interface{} - autoFree bool + inner CDataStream + attached map[uintptr]interface{} + autoFree bool } // Stream of binary data. type DataStream = *dataStream func DataStreamFromC(ptr CDataStream) DataStream { - return &dataStream{ - inner: ptr, - attached: make(map[uintptr]interface{}), - } + return &dataStream{ + inner: ptr, + attached: make(map[uintptr]interface{}), + } } func dataStreamSetFinalizer(res DataStream, autoFree bool) { - res.autoFree = autoFree - if res != nil && autoFree { - runtime.SetFinalizer(res, func(self DataStream) { self.Free() }) - } + res.autoFree = autoFree + if res != nil && autoFree { + runtime.SetFinalizer(res, func(self DataStream) { self.Free() }) + } } // Create an empty DataStream. func NewDataStream(autoFree bool) DataStream { - res := DataStreamFromC(C.datastream_new()) - dataStreamSetFinalizer(res, autoFree) - return res + res := DataStreamFromC(C.datastream_new()) + dataStreamSetFinalizer(res, autoFree) + return res } // Create a DataStream with data copied from bytes. func NewDataStreamFromBytes(bytes []byte, autoFree bool) (res DataStream) { - size := len(bytes) - if size > 0 { - base := (*C.uint8_t)(&bytes[0]) - res = DataStreamFromC(C.datastream_new_from_bytes(base, C.size_t(size))) - } else { - res = DataStreamFromC(C.datastream_new()) - } - dataStreamSetFinalizer(res, autoFree) - return + size := len(bytes) + if size > 0 { + base := (*C.uint8_t)(&bytes[0]) + res = DataStreamFromC(C.datastream_new_from_bytes(base, C.size_t(size))) + } else { + res = DataStreamFromC(C.datastream_new()) + } + dataStreamSetFinalizer(res, autoFree) + return } // Create a DataStream with content moved from a ByteArray. func NewDataStreamMovedFromByteArray(bytes ByteArray, autoFree bool) (res DataStream) { - res = DataStreamFromC(C.datastream_new_moved_from_bytearray(bytes.inner)) - dataStreamSetFinalizer(res, autoFree) - return + res = DataStreamFromC(C.datastream_new_moved_from_bytearray(bytes.inner)) + dataStreamSetFinalizer(res, autoFree) + return } // Create a DataStream with content copied from a ByteArray. func NewDataStreamFromByteArray(bytes ByteArray, autoFree bool) (res DataStream) { - res = DataStreamFromC(C.datastream_new_from_bytearray(bytes.inner)) - dataStreamSetFinalizer(res, autoFree) - return + res = DataStreamFromC(C.datastream_new_from_bytearray(bytes.inner)) + dataStreamSetFinalizer(res, autoFree) + return } func (self DataStream) Free() { - C.datastream_free(self.inner) - if self.autoFree { - runtime.SetFinalizer(self, nil) - } + C.datastream_free(self.inner) + if self.autoFree { + runtime.SetFinalizer(self, nil) + } } func (self DataStream) attach(ptr rawptr_t, obj interface{}) { self.attached[uintptr(ptr)] = obj } -func (self DataStream) detach(ptr rawptr_t) { delete(self.attached, uintptr(ptr)) } +func (self DataStream) detach(ptr rawptr_t) { delete(self.attached, uintptr(ptr)) } // Make a copy of the object. func (self DataStream) Copy(autoFree bool) (res DataStream) { - res = DataStreamFromC(C.datastream_copy(self.inner)) - dataStreamSetFinalizer(res, autoFree) - return + res = DataStreamFromC(C.datastream_copy(self.inner)) + dataStreamSetFinalizer(res, autoFree) + return } // TODO: datastream_data @@ -180,129 +182,171 @@ func (self DataStream) Size() int { return int(C.datastream_size(self.inner)) } // Write a uint8 integer to the stream (no byte order conversion). func (self DataStream) PutU8(v uint8) bool { return bool(C.datastream_put_u8(self.inner, C.uint8_t(v))) } + // Write a uint16 integer to the stream (no byte order conversion). -func (self DataStream) PutU16(v uint16) bool { return bool(C.datastream_put_u16(self.inner, C.uint16_t(v))) } +func (self DataStream) PutU16(v uint16) bool { + return bool(C.datastream_put_u16(self.inner, C.uint16_t(v))) +} + // Write a uint32 integer to the stream (no byte order conversion). -func (self DataStream) PutU32(v uint32) bool { return bool(C.datastream_put_u32(self.inner, C.uint32_t(v))) } +func (self DataStream) PutU32(v uint32) bool { + return bool(C.datastream_put_u32(self.inner, C.uint32_t(v))) +} + // Write a uint64 integer to the stream (no byte order conversion). -func (self DataStream) PutU64(v uint64) bool { return bool(C.datastream_put_u64(self.inner, C.uint64_t(v))) } +func (self DataStream) PutU64(v uint64) bool { + return bool(C.datastream_put_u64(self.inner, C.uint64_t(v))) +} // Write an int8 integer to the stream (no byte order conversion). func (self DataStream) PutI8(v int8) bool { return bool(C.datastream_put_i8(self.inner, C.int8_t(v))) } + // Write an int16 integer to the stream (no byte order conversion). -func (self DataStream) PutI16(v int16) bool { return bool(C.datastream_put_i16(self.inner, C.int16_t(v))) } +func (self DataStream) PutI16(v int16) bool { + return bool(C.datastream_put_i16(self.inner, C.int16_t(v))) +} + // Write an int32 integer to the stream (no byte order conversion). -func (self DataStream) PutI32(v int32) bool { return bool(C.datastream_put_i32(self.inner, C.int32_t(v))) } +func (self DataStream) PutI32(v int32) bool { + return bool(C.datastream_put_i32(self.inner, C.int32_t(v))) +} + // Write an int64 integer to the stream (no byte order conversion). -func (self DataStream) PutI64(v int32) bool { return bool(C.datastream_put_i64(self.inner, C.int64_t(v))) } +func (self DataStream) PutI64(v int32) bool { + return bool(C.datastream_put_i64(self.inner, C.int64_t(v))) +} // Write arbitrary bytes to the stream. func (self DataStream) PutData(bytes []byte) bool { - size := len(bytes) - if size > 0 { - base := (*C.uint8_t)(&bytes[0]) - return bool(C.datastream_put_data(self.inner, base, C.size_t(size))) - } else { return true } + size := len(bytes) + if size > 0 { + base := (*C.uint8_t)(&bytes[0]) + return bool(C.datastream_put_data(self.inner, base, C.size_t(size))) + } else { + return true + } } // Parse a uint8 integer by consuming the stream (no byte order conversion). -func (self DataStream) GetU8(succ *bool) uint8 { return uint8(C.datastream_get_u8(self.inner, (*C.bool)(succ))) } +func (self DataStream) GetU8(succ *bool) uint8 { + return uint8(C.datastream_get_u8(self.inner, (*C.bool)(succ))) +} + // Parse a uint16 integer by consuming the stream (no byte order conversion). -func (self DataStream) GetU16(succ *bool) uint16 { return uint16(C.datastream_get_u16(self.inner, (*C.bool)(succ))) } +func (self DataStream) GetU16(succ *bool) uint16 { + return uint16(C.datastream_get_u16(self.inner, (*C.bool)(succ))) +} + // Parse a uint32 integer by consuming the stream (no byte order conversion). -func (self DataStream) GetU32(succ *bool) uint32 { return uint32(C.datastream_get_u32(self.inner, (*C.bool)(succ))) } +func (self DataStream) GetU32(succ *bool) uint32 { + return uint32(C.datastream_get_u32(self.inner, (*C.bool)(succ))) +} + // Parse a uint64 integer by consuming the stream (no byte order conversion). -func (self DataStream) GetU64(succ *bool) uint64 { return uint64(C.datastream_get_u64(self.inner, (*C.bool)(succ))) } +func (self DataStream) GetU64(succ *bool) uint64 { + return uint64(C.datastream_get_u64(self.inner, (*C.bool)(succ))) +} // Parse an int8 integer by consuming the stream (no byte order conversion). -func (self DataStream) GetI8(succ *bool) int8 { return int8(C.datastream_get_i8(self.inner, (*C.bool)(succ))) } +func (self DataStream) GetI8(succ *bool) int8 { + return int8(C.datastream_get_i8(self.inner, (*C.bool)(succ))) +} + // Parse an int16 integer by consuming the stream (no byte order conversion). -func (self DataStream) GetI16(succ *bool) int16 { return int16(C.datastream_get_i16(self.inner, (*C.bool)(succ))) } +func (self DataStream) GetI16(succ *bool) int16 { + return int16(C.datastream_get_i16(self.inner, (*C.bool)(succ))) +} + // Parse an int32 integer by consuming the stream (no byte order conversion). -func (self DataStream) GetI32(succ *bool) int32 { return int32(C.datastream_get_i32(self.inner, (*C.bool)(succ))) } -// Parse an int64 integer by consuming the stream (no byte order conversion). -func (self DataStream) GetI64(succ *bool) int64 { return int64(C.datastream_get_i64(self.inner, (*C.bool)(succ))) } +func (self DataStream) GetI32(succ *bool) int32 { + return int32(C.datastream_get_i32(self.inner, (*C.bool)(succ))) +} -func ToLittleEndianU16(x uint16) uint16 { return uint16(C._salti_htole16(C.uint16_t(x))); } -func ToLittleEndianU32(x uint32) uint32 { return uint32(C._salti_htole32(C.uint32_t(x))); } -func ToLittleEndianU64(x uint64) uint64 { return uint64(C._salti_htole64(C.uint64_t(x))); } +// Parse an int64 integer by consuming the stream (no byte order conversion). +func (self DataStream) GetI64(succ *bool) int64 { + return int64(C.datastream_get_i64(self.inner, (*C.bool)(succ))) +} -func FromLittleEndianU16(x uint16) uint16 { return uint16(C._salti_letoh16(C.uint16_t(x))); } -func FromLittleEndianU32(x uint32) uint32 { return uint32(C._salti_letoh32(C.uint32_t(x))); } -func FromLittleEndianU64(x uint64) uint64 { return uint64(C._salti_letoh64(C.uint64_t(x))); } +func ToLittleEndianU16(x uint16) uint16 { return uint16(C._salti_htole16(C.uint16_t(x))) } +func ToLittleEndianU32(x uint32) uint32 { return uint32(C._salti_htole32(C.uint32_t(x))) } +func ToLittleEndianU64(x uint64) uint64 { return uint64(C._salti_htole64(C.uint64_t(x))) } -func ToBigEndianU16(x uint16) uint16 { return uint16(C._salti_htobe16(C.uint16_t(x))); } -func ToBigEndianU32(x uint32) uint32 { return uint32(C._salti_htobe32(C.uint32_t(x))); } -func ToBigEndianU64(x uint64) uint64 { return uint64(C._salti_htobe64(C.uint64_t(x))); } +func FromLittleEndianU16(x uint16) uint16 { return uint16(C._salti_letoh16(C.uint16_t(x))) } +func FromLittleEndianU32(x uint32) uint32 { return uint32(C._salti_letoh32(C.uint32_t(x))) } +func FromLittleEndianU64(x uint64) uint64 { return uint64(C._salti_letoh64(C.uint64_t(x))) } -func FromBigEndianU16(x uint16) uint16 { return uint16(C._salti_betoh16(C.uint16_t(x))); } -func FromBigEndianU32(x uint32) uint32 { return uint32(C._salti_betoh32(C.uint32_t(x))); } -func FromBigEndianU64(x uint64) uint64 { return uint64(C._salti_betoh64(C.uint64_t(x))); } +func ToBigEndianU16(x uint16) uint16 { return uint16(C._salti_htobe16(C.uint16_t(x))) } +func ToBigEndianU32(x uint32) uint32 { return uint32(C._salti_htobe32(C.uint32_t(x))) } +func ToBigEndianU64(x uint64) uint64 { return uint64(C._salti_htobe64(C.uint64_t(x))) } +func FromBigEndianU16(x uint16) uint16 { return uint16(C._salti_betoh16(C.uint16_t(x))) } +func FromBigEndianU32(x uint32) uint32 { return uint32(C._salti_betoh32(C.uint32_t(x))) } +func FromBigEndianU64(x uint64) uint64 { return uint64(C._salti_betoh64(C.uint64_t(x))) } // The handle returned by GetDataInPlace. The Go slice returned by Get() is // valid only during the lifetime of the handle. type dataStreamBytes struct { - bytes []byte - ds DataStream + bytes []byte + ds DataStream } type DataStreamBytes = *dataStreamBytes func (self DataStreamBytes) Get() []byte { return self.bytes } -func (self DataStreamBytes) Release() { self.ds.detach(rawptr_t(self)) } +func (self DataStreamBytes) Release() { self.ds.detach(rawptr_t(self)) } // Get the given length of preceeding bytes from the stream as a byte slice by // consuming the stream. Notice this function does not copy the bytes, so the // slice is only valid during the lifetime of DataStreamBytes handle. func (self DataStream) GetDataInPlace(length int) DataStreamBytes { - base := C.datastream_get_data_inplace(self.inner, C.size_t(length)) - res := &dataStreamBytes{ - bytes: C.GoBytes(rawptr_t(base), C.int(length)), - ds: self, - } - self.attach(rawptr_t(res), res) - return res + base := C.datastream_get_data_inplace(self.inner, C.size_t(length)) + res := &dataStreamBytes{ + bytes: C.GoBytes(rawptr_t(base), C.int(length)), + ds: self, + } + self.attach(rawptr_t(res), res) + return res } // The C pointer to a UInt256 object. type CUInt256 = *C.uint256_t type uint256 struct { - inner CUInt256 - autoFree bool + inner CUInt256 + autoFree bool } + // 256-bit integer. type UInt256 = *uint256 func UInt256FromC(ptr CUInt256) UInt256 { - return &uint256{ inner: ptr } + return &uint256{inner: ptr} } func uint256SetFinalizer(res UInt256, autoFree bool) { - res.autoFree = autoFree - if res != nil && autoFree { - runtime.SetFinalizer(res, func(self UInt256) { self.Free() }) - } + res.autoFree = autoFree + if res != nil && autoFree { + runtime.SetFinalizer(res, func(self UInt256) { self.Free() }) + } } // Create a 256-bit integer. func NewUInt256(autoFree bool) UInt256 { - res := &uint256{ inner: C.uint256_new() } - uint256SetFinalizer(res, autoFree) - return res + res := &uint256{inner: C.uint256_new()} + uint256SetFinalizer(res, autoFree) + return res } func NewUInt256FromByteArray(bytes ByteArray, autoFree bool) (res UInt256) { - res = &uint256{ inner: C.uint256_new_from_bytearray(bytes.inner) } - uint256SetFinalizer(res, autoFree) - return + res = &uint256{inner: C.uint256_new_from_bytearray(bytes.inner)} + uint256SetFinalizer(res, autoFree) + return } func (self UInt256) Free() { - C.uint256_free(self.inner) - if self.autoFree { - runtime.SetFinalizer(self, nil) - } + C.uint256_free(self.inner) + if self.autoFree { + runtime.SetFinalizer(self, nil) + } } func (self UInt256) IsNull() bool { return bool(C.uint256_is_null(self.inner)) } @@ -319,33 +363,33 @@ func (self UInt256) Unserialize(s DataStream) { C.uint256_unserialize(self.inner // Get the Sha256 hash of the given DataStream content (without consuming the // stream). func (self DataStream) GetHash(autoFree bool) UInt256 { - res := &uint256{ inner: C.datastream_get_hash(self.inner) } - uint256SetFinalizer(res, autoFree) - return res + res := &uint256{inner: C.datastream_get_hash(self.inner)} + uint256SetFinalizer(res, autoFree) + return res } // Get the Sha256 hash of the given ByteArray content. func (self ByteArray) GetHash(autoFree bool) (res UInt256) { - s := NewDataStreamFromByteArray(self, false) - res = s.GetHash(autoFree) - s.Free() - return + s := NewDataStreamFromByteArray(self, false) + res = s.GetHash(autoFree) + s.Free() + return } // Get hexadicemal string representation of the given DataStream content // (without consuming the stream). func (self DataStream) GetHex() string { - tmp := C.datastream_get_hex(self.inner) - res := C.GoString(tmp) - C.free(rawptr_t(tmp)) - return res + tmp := C.datastream_get_hex(self.inner) + res := C.GoString(tmp) + C.free(rawptr_t(tmp)) + return res } // Get hexadicemal string representation of the 256-bit integer. func (self UInt256) GetHex() (res string) { - s := NewDataStream(false) - self.Serialize(s) - res = s.GetHex() - s.Free() - return + s := NewDataStream(false) + self.Serialize(s) + res = s.GetHex() + s.Free() + return } |