tx4-go-pion-sys 0.0.1

Low level rust bindings to the go pion webrtc library
package main

import (
	"bytes"
	"runtime/cgo"
	"sync"
	"unsafe"
)

type Buffer struct {
	mu     sync.Mutex
	closed bool
	buf    *bytes.Buffer
	handle UintPtrT
}

func BufferFromPtr(id UintPtrT) *Buffer {
	hnd := cgo.Handle(id)
	buf := hnd.Value().(*Buffer)
	return buf
}

// If you invoke this function, you *must* call Free,
// otherwise the buffer will be leaked.
func NewBuffer(initBuf []byte) *Buffer {
	buf := new(Buffer)
	if initBuf != nil {
		buf.buf = bytes.NewBuffer(initBuf)
	} else {
		buf.buf = new(bytes.Buffer)
	}
	buf.handle = UintPtrT(cgo.NewHandle(buf))
	return buf
}

func (buf *Buffer) FreeAlreadyLocked() {
	if buf.closed {
		return
	}

	buf.closed = true
	(cgo.Handle)(buf.handle).Delete()
}

func CallBufferAlloc(
	response_cb MessageCb,
	response_usr unsafe.Pointer,
) {
	buf := NewBuffer(nil)
	MessageCbInvoke(
		response_cb,
		response_usr,
		TyBufferAlloc,
		buf.handle,
		0,
		0,
		0,
	)
}

func CallBufferFree(id UintPtrT) {
	buf := BufferFromPtr(id)
	buf.mu.Lock()
	defer buf.mu.Unlock()

	buf.FreeAlreadyLocked()
}

func CallBufferAccess(
	id UintPtrT,
	response_cb MessageCb,
	response_usr unsafe.Pointer,
) {
	buf := BufferFromPtr(id)
	buf.mu.Lock()
	defer buf.mu.Unlock()

	if buf.closed {
		panic("BufferClosed")
	}

	bytes := buf.buf.Bytes()

	if bytes == nil || len(bytes) == 0 {
		MessageCbInvoke(
			response_cb,
			response_usr,
			TyBufferAccess,
			buf.handle,
			0,
			0,
			0,
		)
		return
	}

	MessageCbInvoke(
		response_cb,
		response_usr,
		TyBufferAccess,
		buf.handle,
		VoidStarToPtrT(unsafe.Pointer(&(bytes)[0])),
		UintPtrT(len(bytes)),
		0,
	)
}

func CallBufferReserve(
	id UintPtrT,
	add UintPtrT,
	response_cb MessageCb,
	response_usr unsafe.Pointer,
) {
	buf := BufferFromPtr(id)
	buf.mu.Lock()
	defer buf.mu.Unlock()

	if buf.closed {
		panic("BufferClosed")
	}

	buf.buf.Grow(int(add))

	MessageCbInvoke(
		response_cb,
		response_usr,
		TyBufferReserve,
		0,
		0,
		0,
		0,
	)
}

func CallBufferExtend(
	id UintPtrT,
	data UintPtrT,
	data_len UintPtrT,
	response_cb MessageCb,
	response_usr unsafe.Pointer,
) {
	buf := BufferFromPtr(id)
	buf.mu.Lock()
	defer buf.mu.Unlock()

	if buf.closed {
		panic("BufferClosed")
	}

	raw := unsafe.Slice(PtrToCharStar(data), data_len)

	// docs say err is always nil, so no point in checking it
	buf.buf.Write(raw)

	MessageCbInvoke(
		response_cb,
		response_usr,
		TyBufferExtend,
		0,
		0,
		0,
		0,
	)
}

func CallBufferRead(
	id UintPtrT,
	cnt UintPtrT,
	response_cb MessageCb,
	response_usr unsafe.Pointer,
) {
	buf := BufferFromPtr(id)
	buf.mu.Lock()
	defer buf.mu.Unlock()

	if buf.closed {
		panic("BufferClosed")
	}

	bytes := buf.buf.Next(int(cnt))

	if bytes == nil || len(bytes) == 0 {
		MessageCbInvoke(
			response_cb,
			response_usr,
			TyBufferRead,
			0,
			0,
			0,
			0,
		)
		return
	}

	MessageCbInvoke(
		response_cb,
		response_usr,
		TyBufferRead,
		VoidStarToPtrT(unsafe.Pointer(&(bytes)[0])),
		UintPtrT(len(bytes)),
		0,
		0,
	)
}