diff options
author | Determinant <[email protected]> | 2019-06-07 19:32:54 -0400 |
---|---|---|
committer | Determinant <[email protected]> | 2019-06-07 19:32:54 -0400 |
commit | 4a37b259717e545c090fb11b6a36f7e75118c2f9 (patch) | |
tree | 7bc20ad884e53c59f4a99bc2240159142cfb816f | |
parent | 316b61a15ff334a27462715ed4c99cf244a25701 (diff) |
...
-rw-r--r-- | salticidae.go | 75 | ||||
-rw-r--r-- | stream.go | 88 | ||||
-rw-r--r-- | test_msgnet/main.go | 145 | ||||
-rw-r--r-- | test_msgnet/main_.go | 7 |
4 files changed, 309 insertions, 6 deletions
diff --git a/salticidae.go b/salticidae.go index 1dce21e..ad80b88 100644 --- a/salticidae.go +++ b/salticidae.go @@ -13,6 +13,7 @@ import "unsafe" type rawptr_t = unsafe.Pointer + type NetAddr = *C.struct_netaddr_t func NewAddrFromIPPortString(addr string) (res NetAddr) { @@ -22,26 +23,88 @@ func NewAddrFromIPPortString(addr string) (res NetAddr) { return } -type MsgNetwork = *C.struct_msgnetwork_t +func (self NetAddr) Free() { C.netaddr_free(self) } type EventContext = *C.struct_eventcontext_t func NewEventContext() EventContext { return C.eventcontext_new() } +func (self EventContext) Free() { C.eventcontext_free(self) } func (self EventContext) Dispatch() { C.eventcontext_dispatch(self) } func (self EventContext) Stop() { C.eventcontext_stop(self) } +type Opcode = uint8 + +type Msg = *C.struct_msg_t + +func NewMsg(opcode Opcode, _moved_payload ByteArray) Msg { + return C.msg_new(C._opcode_t(opcode), _moved_payload) +} + +func (self Msg) Free() { C.msg_free(self) } + +func (self Msg) GetPayload() DataStream { + return C.msg_get_payload(self) +} + +func (self Msg) GetOpcode() Opcode { + return Opcode(C.msg_get_opcode(self)) +} + +type MsgNetworkInner = *C.struct_msgnetwork_t + +type MsgNetwork struct { + inner MsgNetworkInner +} + +type MsgNetworkConn = *C.struct_msgnetwork_conn_t + +type MsgNetworkConnMode = C.msgnetwork_conn_mode_t + + +func (self MsgNetworkConn) GetNet() MsgNetworkInner { + return C.msgnetwork_conn_get_net(self) +} + +var ( + CONN_MODE_ACTIVE = MsgNetworkConnMode(C.CONN_MODE_ACTIVE) + CONN_MODE_PASSIVE = MsgNetworkConnMode(C.CONN_MODE_PASSIVE) + CONN_MODE_DEAD = MsgNetworkConnMode(C.CONN_MODE_DEAD) +) + +func (self MsgNetworkConn) GetMode() MsgNetworkConnMode { + return C.msgnetwork_conn_get_mode(self) +} + +func (self MsgNetworkConn) GetAddr() NetAddr { + return C.msgnetwork_conn_get_addr(self) +} + type MsgNetworkConfig = *C.struct_msgnetwork_config_t func NewMsgNetworkConfig() MsgNetworkConfig { return C.msgnetwork_config_new() } +func (self MsgNetworkConfig) Free() { C.msgnetwork_config_free(self) } + func NewMsgNetwork(ec EventContext, config MsgNetworkConfig) MsgNetwork { - return C.msgnetwork_new(ec, config) + return MsgNetwork { + inner: C.msgnetwork_new(ec, config), + } } -func (self MsgNetwork) Start() { C.msgnetwork_start(self) } -func (self MsgNetwork) Listen(addr NetAddr) { C.msgnetwork_listen(self, addr) } -func (self MsgNetwork) Connect(addr NetAddr) { C.msgnetwork_connect(self, addr) } -func (self MsgNetwork) Free() { C.msgnetwork_free(self) } +func (self MsgNetwork) Free() { C.msgnetwork_free(self.inner) } +func (self MsgNetwork) SendMsg(msg Msg, conn MsgNetworkConn) { self.inner.SendMsg(msg, conn) } +func (self MsgNetwork) Connect(addr NetAddr) { self.inner.Connect(addr) } +func (self MsgNetwork) Listen(addr NetAddr) { C.msgnetwork_listen(self.inner, addr) } +func (self MsgNetwork) Start() { C.msgnetwork_start(self.inner) } +func (self MsgNetwork) GetInner() MsgNetworkInner { return self.inner } + +func (self MsgNetworkInner) SendMsg(msg Msg, conn MsgNetworkConn) { + C.msgnetwork_send_msg(self, msg, conn) +} + +func (self MsgNetworkInner) Connect(addr NetAddr) { + C.msgnetwork_connect(self, addr) +} type SigEvent = *C.sigev_t type SigEventCallback = C.sigev_callback_t diff --git a/stream.go b/stream.go new file mode 100644 index 0000000..2727565 --- /dev/null +++ b/stream.go @@ -0,0 +1,88 @@ +package salticidae + +// #include "salticidae/stream.h" +import "C" + +type ByteArray = *C.struct_bytearray_t + +func NewByteArray() ByteArray { return C.bytearray_new() } +func (self ByteArray) Free() { C.bytearray_free(self) } + +type DataStream = *C.struct_datastream_t + +func NewDataStream() DataStream { return C.datastream_new() } +func NewDataStreamFromBytes(bytes []byte) DataStream { + base := uintptr(rawptr_t(&bytes[0])) + return C.datastream_new_from_bytes( + (*C.uint8_t)(rawptr_t(base)), + (*C.uint8_t)(rawptr_t(base + uintptr(len(bytes))))) +} + +func (self DataStream) Free() { C.datastream_free(self) } + +func (self DataStream) AssignByCopy(src DataStream) { + C.datastream_assign_by_copy(self, src) +} + +func (self DataStream) AssignByMove(src DataStream) { + C.datastream_assign_by_move(self, src) +} + +// TODO: datastream_data + +func (self DataStream) Clear() { C.datastream_clear(self) } + +func (self DataStream) Size() int { return int(C.datastream_size(self)) } + +func (self DataStream) PutU8(v uint8) { C.datastream_put_u8(self, C.uint8_t(v)) } +func (self DataStream) PutU16(v uint16) { C.datastream_put_u16(self, C.uint16_t(v)) } +func (self DataStream) PutU32(v uint32) { C.datastream_put_u32(self, C.uint32_t(v)) } +func (self DataStream) PutU64(v uint32) { C.datastream_put_u64(self, C.uint64_t(v)) } + +func (self DataStream) PutI8(v int8) { C.datastream_put_i8(self, C.int8_t(v)) } +func (self DataStream) PutI16(v int16) { C.datastream_put_i16(self, C.int16_t(v)) } +func (self DataStream) PutI32(v int32) { C.datastream_put_i32(self, C.int32_t(v)) } +func (self DataStream) PutI64(v int32) { C.datastream_put_i64(self, C.int64_t(v)) } + +func (self DataStream) PutData(bytes []byte) { + base := uintptr(rawptr_t(&bytes[0])) + C.datastream_put_data(self, + (*C.uint8_t)(rawptr_t(base)), + (*C.uint8_t)(rawptr_t(base + uintptr(len(bytes))))) + +} + +func (self DataStream) GetU8() uint8 { return uint8(C.datastream_get_u8(self)) } +func (self DataStream) GetU16() uint16 { return uint16(C.datastream_get_u16(self)) } +func (self DataStream) GetU32() uint32 { return uint32(C.datastream_get_u32(self)) } +func (self DataStream) GetU64() uint64 { return uint64(C.datastream_get_u64(self)) } + +func (self DataStream) GetI8() int8 { return int8(C.datastream_get_i8(self)) } +func (self DataStream) GetI16() int16 { return int16(C.datastream_get_i16(self)) } +func (self DataStream) GetI32() int32 { return int32(C.datastream_get_i32(self)) } +func (self DataStream) GetI64() int64 { return int64(C.datastream_get_i64(self)) } + + +func (self DataStream) GetDataInPlace(length int) *C.uint8_t { + return C.datastream_get_data_inplace(self, C.size_t(length)) +} + +func (self DataStream) GetData(length int) []byte { + return C.GoBytes(rawptr_t(self.GetDataInPlace(length)), C.int(length)) +} + +type UInt256 = *C.uint256_t + +func NewUInt256() UInt256 { return C.uint256_new() } +func (self UInt256) UInt256IsNull() bool { return bool(C.uint256_is_null(self)) } +func (self UInt256) UInt256IsEq(other UInt256) bool { return bool(C.uint256_is_eq(self, other)) } +func (self UInt256) Serialize(s DataStream) { C.uint256_serialize(self, s) } +func (self UInt256) Unserialize(s DataStream) { C.uint256_unserialize(self, s) } + +func (self DataStream) GetHash() UInt256 { + return C.datastream_get_hash(self) +} + +func (_moved_self DataStream) ToByteArray() ByteArray { + return C.datastream_to_bytearray(_moved_self) +} diff --git a/test_msgnet/main.go b/test_msgnet/main.go new file mode 100644 index 0000000..b9a5048 --- /dev/null +++ b/test_msgnet/main.go @@ -0,0 +1,145 @@ +package main + +// void onTerm_cgo(int sig); +import "C" + +import ( + "unsafe" + "encoding/binary" + "fmt" + "salticidae-go" +) + +var ec salticidae.EventContext +const ( + MSG_OPCODE_HELLO salticidae.Opcode = iota + MSG_OPCODE_ACK +) + +//export onTerm +func onTerm(_ int) { + ec.Stop() +} + +type MsgHello struct { + name string + text string +} + +func msgHelloSerialize(name string, text string) salticidae.Msg { + serialized := salticidae.NewDataStream() + t := make([]byte, 4) + binary.LittleEndian.PutUint32(t, uint32(len(name))) + serialized.PutData(t) + serialized.PutData([]byte(name)) + serialized.PutData([]byte(text)) + return salticidae.NewMsg(MSG_OPCODE_HELLO, serialized.ToByteArray()) +} + +func msgHelloUnserialize(msg salticidae.Msg) MsgHello { + p := msg.GetPayload() + length := binary.LittleEndian.Uint32(p.GetData(4)) + name := string(p.GetData(int(length))) + text := string(p.GetData(p.Size())) + p.Free() + return MsgHello { name: name, text: text } +} + +func msgAckSerialize() salticidae.Msg { + return salticidae.NewMsg(MSG_OPCODE_ACK, salticidae.NewByteArray()) +} + +type MyNet struct { + net salticidae.MsgNetwork + name string +} + +var alice, bob MyNet + +func onReceiveHello(_msg salticidae.Msg, conn salticidae.MsgNetworkConn) { + net := conn.GetNet() + name := bob.name + if net == alice.net.GetInner() { + name = alice.name + } + msg := msgHelloUnserialize(_msg) + fmt.Printf("[%s] %s says %s\n", name, msg.name, msg.text) + ack := msgAckSerialize() + net.SendMsg(ack, conn) + ack.Free() +} + +func onReceiveAck(msg salticidae.Msg, conn salticidae.MsgNetworkConn) { + net := conn.GetNet() + name := bob.name + if net == alice.net.GetInner() { + name = alice.name + } + fmt.Printf("[%s] the peer knows\n", name) +} + +func connHandler(conn salticidae.MsgNetworkConn, connected bool) { + net := conn.GetNet() + n := &bob + if net == alice.net.GetInner() { + n = &alice + } + name := n.name + if connected { + if conn.GetMode() == salticidae.CONN_MODE_ACTIVE { + fmt.Printf("[%s] Connected, sending hello.", name) + hello := msgHelloSerialize(name, "Hello there!") + n.net.SendMsg(hello, conn) + hello.Free() + } else { + fmt.Printf("[%s] Accepted, waiting for greetings.\n", name) + } + } else { + fmt.Printf("[%s] Disconnected, retrying.\n", name) + net.Connect(conn.GetAddr()) + } +} + +func genMyNet(ec salticidae.EventContext, name string) MyNet { + netconfig := salticidae.NewMsgNetworkConfig() + n := MyNet { + net: salticidae.NewMsgNetwork(ec, netconfig), + name: name, + } + netconfig.Free() + return n +} + +func main() { + ec = salticidae.NewEventContext() + alice_addr := salticidae.NewAddrFromIPPortString("127.0.0.1:12345") + bob_addr := salticidae.NewAddrFromIPPortString("127.0.0.1:12346") + + alice := genMyNet(ec, "Alice") + bob := genMyNet(ec, "Bob") + + alice.net.Start() + bob.net.Start() + + alice.net.Listen(alice_addr) + bob.net.Listen(bob_addr) + + alice.net.Connect(bob_addr) + bob.net.Connect(alice_addr) + + alice_addr.Free() + bob_addr.Free() + + ev_int := salticidae.NewSigEvent(ec, salticidae.SigEventCallback(unsafe.Pointer(C.onTerm_cgo))) + ev_int.Add(salticidae.SIGINT) + ev_term := salticidae.NewSigEvent(ec, salticidae.SigEventCallback(unsafe.Pointer(C.onTerm_cgo))) + ev_term.Add(salticidae.SIGTERM) + + ec.Dispatch() + + ev_int.Free() + ev_term.Free() + alice.net.Free() + bob.net.Free() + ec.Free() +} diff --git a/test_msgnet/main_.go b/test_msgnet/main_.go new file mode 100644 index 0000000..2f53d93 --- /dev/null +++ b/test_msgnet/main_.go @@ -0,0 +1,7 @@ +package main + +// void onTerm_cgo(int sig) { +// void onTerm(int); +// onTerm(sig); +// } +import "C" |