package main
import "C"
import (
"bytes"
"fmt"
"sync"
"unsafe"
)
type UintPtrT = C.uintptr_t
type MessageCb = C.MessageCb
func VoidStarToPtrT(v unsafe.Pointer) UintPtrT {
return C.void_star_to_ptr_t(v)
}
func PtrToVoidStar(ptr UintPtrT) unsafe.Pointer {
return C.ptr_to_void_star(ptr)
}
func PtrToCharStar(ptr UintPtrT) *byte {
return (*byte)(C.ptr_to_void_star(ptr))
}
func LoadBytesSafe(ptr UintPtrT, length UintPtrT) *bytes.Buffer {
raw := unsafe.Slice(PtrToCharStar(ptr), length)
buf := new(bytes.Buffer)
buf.Grow(len(raw))
buf.Write(raw)
return buf
}
func MessageCbInvoke(
cb MessageCb,
usr unsafe.Pointer,
message_type UintPtrT,
slot_a UintPtrT,
slot_b UintPtrT,
slot_c UintPtrT,
slot_d UintPtrT,
) {
C.MessageCbInvoke(cb, usr, message_type, slot_a, slot_b, slot_c, slot_d)
}
type eventReg struct {
mu sync.Mutex
event_cb C.MessageCb
event_usr unsafe.Pointer
}
var globalEventReg eventReg
func EmitEvent(
message_type UintPtrT,
slot_a UintPtrT,
slot_b UintPtrT,
slot_c UintPtrT,
slot_d UintPtrT,
) {
globalEventReg.mu.Lock()
defer globalEventReg.mu.Unlock()
if globalEventReg.event_cb == nil {
return
}
C.MessageCbInvoke(
globalEventReg.event_cb,
globalEventReg.event_usr,
message_type,
slot_a,
slot_b,
slot_c,
slot_d,
)
}
func OnEvent(
event_cb C.MessageCb,
event_usr unsafe.Pointer,
) unsafe.Pointer {
globalEventReg.mu.Lock()
defer globalEventReg.mu.Unlock()
prev := globalEventReg.event_usr
globalEventReg.event_cb = event_cb
globalEventReg.event_usr = event_usr
return prev
}
const (
LvlTrace UintPtrT = 0x01
LvlDebug UintPtrT = 0x02
LvlInfo UintPtrT = 0x03
LvlWarn UintPtrT = 0x04
LvlError UintPtrT = 0x05
)
func EmitTrace(
lvl UintPtrT,
msg string,
) {
buf := []byte(msg)
EmitEvent(
TyOnTrace,
lvl,
C.void_star_to_ptr_t(unsafe.Pointer(&buf[0])),
UintPtrT(len(buf)),
0,
)
}
func Call(
call_type UintPtrT,
slot_a UintPtrT,
slot_b UintPtrT,
slot_c UintPtrT,
slot_d UintPtrT,
response_cb C.MessageCb,
response_usr unsafe.Pointer,
) {
defer func() {
if err := recover(); err != nil {
if response_cb == nil {
return
}
bytes := ([]byte)(fmt.Sprintf("%s", err))
C.MessageCbInvoke(
response_cb,
response_usr,
TyErr,
C.void_star_to_ptr_t(unsafe.Pointer(&([]byte)("Error")[0])),
UintPtrT(5),
C.void_star_to_ptr_t(unsafe.Pointer(&bytes[0])),
UintPtrT(len(bytes)),
)
}
}()
callInner(call_type, slot_a, slot_b, slot_c, slot_d, response_cb, response_usr)
}
func callInner(
call_type UintPtrT,
slot_a UintPtrT,
slot_b UintPtrT,
slot_c UintPtrT,
slot_d UintPtrT,
response_cb C.MessageCb,
response_usr unsafe.Pointer,
) {
switch call_type {
case TyBufferFree:
CallBufferFree(slot_a)
return
case TyPeerConFree:
CallPeerConFree(slot_a)
return
case TyDataChanFree:
CallDataChanFree(slot_a)
return
}
if response_cb == nil {
panic(fmt.Errorf("response_cb cannot be nil for call_type: %d", call_type))
}
switch call_type {
case TyBufferAlloc:
CallBufferAlloc(response_cb, response_usr)
case TyBufferAccess:
CallBufferAccess(slot_a, response_cb, response_usr)
case TyBufferReserve:
CallBufferReserve(slot_a, slot_b, response_cb, response_usr)
case TyBufferExtend:
CallBufferExtend(slot_a, slot_b, slot_c, response_cb, response_usr)
case TyBufferRead:
CallBufferRead(slot_a, slot_b, response_cb, response_usr)
case TyPeerConAlloc:
CallPeerConAlloc(slot_a, response_cb, response_usr)
case TyPeerConCreateOffer:
CallPeerConCreateOffer(slot_a, slot_b, response_cb, response_usr)
case TyPeerConCreateAnswer:
CallPeerConCreateAnswer(slot_a, slot_b, response_cb, response_usr)
case TyPeerConSetLocalDesc:
CallPeerConSetLocalDesc(slot_a, slot_b, response_cb, response_usr)
case TyPeerConSetRemDesc:
CallPeerConSetRemDesc(slot_a, slot_b, response_cb, response_usr)
case TyPeerConAddICECandidate:
CallPeerConAddICECandidate(slot_a, slot_b, response_cb, response_usr)
case TyPeerConCreateDataChan:
CallPeerConCreateDataChan(slot_a, slot_b, response_cb, response_usr)
case TyDataChanLabel:
CallDataChanLabel(slot_a, response_cb, response_usr)
case TyDataChanReadyState:
CallDataChanReadyState(slot_a, response_cb, response_usr)
case TyDataChanSend:
CallDataChanSend(slot_a, slot_b, response_cb, response_usr)
default:
panic(fmt.Errorf("invalid call_type: %d", call_type))
}
}
func main() {}