diff --git a/buffer.go b/buffer.go index 1ae04db..a17cbd4 100644 --- a/buffer.go +++ b/buffer.go @@ -8,10 +8,10 @@ import ( // Buffer owns byte memory that can be passed safely to C. // -// buffer := NewBuffer(16) -// defer buffer.Free() -// n := buffer.CopyFrom([]byte("payload")) -// _ = buffer.Bytes()[:n] +// buffer := NewBuffer(16) +// defer buffer.Free() +// n := buffer.CopyFrom([]byte("payload")) +// _ = buffer.Bytes()[:n] type Buffer struct { data []byte length int @@ -21,7 +21,10 @@ type Buffer struct { pinner runtime.Pinner } -// NewBuffer allocates memory and pins it so Ptr can be used across C boundaries. +// NewBuffer allocates memory and pins it so Ptr can be safely shared with C. +// +// buffer := NewBuffer(32) +// defer buffer.Free() func NewBuffer(size int) *Buffer { if size < 0 { panic("cgo.NewBuffer: size must be non-negative") @@ -43,6 +46,9 @@ func NewBuffer(size int) *Buffer { } // Free releases the pinned memory backing slice and marks the buffer as freed. +// +// buffer := NewBuffer(8) +// defer buffer.Free() func (b *Buffer) Free() { if b == nil { return @@ -62,6 +68,9 @@ func (b *Buffer) Free() { } // CopyFrom copies bytes from src into the buffer and returns bytes copied. +// +// buffer := NewBuffer(3) +// buffer.CopyFrom([]byte("abc")) func (b *Buffer) CopyFrom(src []byte) int { b.assertNotFreed() if len(src) == 0 || b.length == 0 { @@ -77,25 +86,38 @@ func (b *Buffer) CopyFrom(src []byte) int { return copied } -// Bytes returns a mutable byte slice backed by the buffer memory. +// Bytes returns the mutable byte slice backed by the buffer memory. +// +// buffer := NewBuffer(4) +// n := buffer.CopyFrom([]byte("go")) +// _ = buffer.Bytes()[:n] func (b *Buffer) Bytes() []byte { b.assertNotFreed() return b.data } // Ptr returns the raw pointer to the buffer. +// +// buffer := NewBuffer(4) +// call := buffer.Ptr() func (b *Buffer) Ptr() unsafe.Pointer { b.assertNotFreed() return b.pointer } -// Len returns the current buffer length. +// Len returns the allocated byte length of the buffer. +// +// buffer := NewBuffer(4) +// if buffer.Len() == 4 { ... } func (b *Buffer) Len() int { b.assertNotFreed() return b.length } // IsFreed reports whether Free has already been called. +// +// buffer := NewBuffer(4) +// if buffer.IsFreed() { ... } func (b *Buffer) IsFreed() bool { return b.freed.Load() } diff --git a/scope.go b/scope.go index a9ddb3c..6bea065 100644 --- a/scope.go +++ b/scope.go @@ -25,11 +25,16 @@ type Scope struct { } // NewScope creates a zero-value scope for grouped CGo allocations. +// +// scope := NewScope() +// defer scope.FreeAll() func NewScope() *Scope { return &Scope{} } -// Buffer allocates a new managed buffer. +// Buffer allocates a managed buffer and registers it for scope cleanup. +// +// buffer := scope.Buffer(64) func (s *Scope) Buffer(size int) *Buffer { s.lock.Lock() defer s.lock.Unlock() @@ -43,7 +48,9 @@ func (s *Scope) Buffer(size int) *Buffer { return buffer } -// CString allocates a managed C string. +// CString allocates a managed C string and registers it for scope cleanup. +// +// cString := scope.CString("hello") func (s *Scope) CString(value string) *C.char { s.lock.Lock() defer s.lock.Unlock() @@ -58,6 +65,9 @@ func (s *Scope) CString(value string) *C.char { } // FreeAll releases every allocation created under this scope. +// +// scope := NewScope() +// defer scope.FreeAll() func (s *Scope) FreeAll() { if s == nil { return @@ -86,6 +96,8 @@ func (s *Scope) FreeAll() { } // IsFreed reports whether FreeAll has been called. +// +// if scope.IsFreed() { return } func (s *Scope) IsFreed() bool { if s == nil { return true @@ -94,6 +106,9 @@ func (s *Scope) IsFreed() bool { } // Close releases every allocation in the scope and implements io.Closer. +// +// scope := NewScope() +// defer scope.Close() func (s *Scope) Close() error { s.FreeAll() return nil diff --git a/string_conversion.go b/string_conversion.go index f73b2ee..5a1c4bc 100644 --- a/string_conversion.go +++ b/string_conversion.go @@ -139,10 +139,12 @@ func cIntBitSize() int { return int(unsafe.Sizeof(C.int(0)) * 8) } -// Call invokes a C function pointer and maps a non-zero return into a Go error using errno mapping. +// Call invokes a C function pointer and maps a non-zero return into a Go error. // -// err := cgo.Call(unsafe.Pointer(C.some_function), cgo.SizeT(len(data))) -// err == nil indicates success. +// err := Call(unsafe.Pointer(C.some_function), buffer.Ptr(), SizeT(len(data))) +// if err != nil { +// return err +// } func Call(function unsafe.Pointer, args ...interface{}) error { if function == nil { panic("cgo.Call: function pointer is nil") @@ -795,9 +797,9 @@ func toSyscallArg(value interface{}) (uintptr, bool) { // GoString converts a null-terminated C string to a Go string. // -// cStr := C.CString("example") -// result := cgo.GoString(cStr) -// cgo.Free(unsafe.Pointer(cStr)) +// cString := CString("example") +// result := GoString(cString) +// Free(unsafe.Pointer(cString)) func GoString(cs *C.char) string { if cs == nil { return "" @@ -807,16 +809,16 @@ func GoString(cs *C.char) string { // CString converts a Go string to a C string. // -// cStr := cgo.CString("hello") -// defer cgo.Free(unsafe.Pointer(cStr)) +// cString := CString("hello") +// defer Free(unsafe.Pointer(cString)) func CString(value string) *C.char { return C.CString(value) } // Free releases memory previously returned by CString. // -// cStr := cgo.CString("hello") -// cgo.Free(unsafe.Pointer(cStr)) +// cString := CString("hello") +// Free(unsafe.Pointer(cString)) func Free(ptr unsafe.Pointer) { if ptr == nil { return @@ -826,17 +828,17 @@ func Free(ptr unsafe.Pointer) { // Errno converts a C error number to a Go error. // -// rc := cgo.Errno(-2) -func Errno(rc C.int) error { - if rc == 0 { +// resultCode := Errno(-2) +func Errno(resultCode C.int) error { + if resultCode == 0 { return nil } - return syscall.Errno(rc) + return syscall.Errno(resultCode) } // WithErrno runs a function that returns C.int and maps the result to Go error. // -// result, err := cgo.WithErrno(func() C.int { +// resultCode, err := WithErrno(func() C.int { // return C.my_function() // }) func WithErrno(fn func() C.int) (int, error) {