Revert "ci: skip "lib/test-fork-safe-execvpe.sh" on Alpine Linux"
[libnbd.git] / golang / aio_buffer.go
blobc39ed0fff07831bba10cc7c09f8cfffd4ef10235
1 /* libnbd golang AIO buffer.
2 * Copyright Red Hat
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 package libnbd
22 #cgo pkg-config: libnbd
23 #cgo CFLAGS: -D_GNU_SOURCE=1
25 #include <stdio.h>
26 #include <stdlib.h>
28 #include "libnbd.h"
29 #include "wrappers.h"
32 import "C"
34 import "unsafe"
36 /* Asynchronous I/O buffer. */
37 type AioBuffer struct {
38 P unsafe.Pointer
39 Size uint
42 // MakeAioBuffer makes a new buffer backed by an uninitialized C allocated
43 // array.
44 func MakeAioBuffer(size uint) AioBuffer {
45 return AioBuffer{C.malloc(C.ulong(size)), size}
48 // MakeAioBuffer makes a new buffer backed by a C allocated array. The
49 // underlying buffer is set to zero.
50 func MakeAioBufferZero(size uint) AioBuffer {
51 return AioBuffer{C.calloc(C.ulong(1), C.ulong(size)), size}
54 // FromBytes makes a new buffer backed by a C allocated array, initialized by
55 // copying the given Go slice.
56 func FromBytes(buf []byte) AioBuffer {
57 ret := MakeAioBuffer(uint(len(buf)))
58 copy(ret.Slice(), buf)
59 return ret
62 // Free deallocates the underlying C allocated array. Using the buffer after
63 // Free() will panic.
64 func (b *AioBuffer) Free() {
65 if b.P != nil {
66 C.free(b.P)
67 b.P = nil
71 // Bytes copies the underlying C array to Go allocated memory and return a
72 // slice. Modifying the returned slice does not modify the underlying buffer
73 // backing array.
74 func (b *AioBuffer) Bytes() []byte {
75 if b.P == nil {
76 panic("Using AioBuffer after Free()")
78 return C.GoBytes(b.P, C.int(b.Size))
81 // Slice creates a slice backed by the underlying C array. The slice can be
82 // used to access or modify the contents of the underlying array. The slice
83 // must not be used after caling Free().
84 func (b *AioBuffer) Slice() []byte {
85 if b.P == nil {
86 panic("Using AioBuffer after Free()")
88 // See https://github.com/golang/go/wiki/cgo#turning-c-arrays-into-go-slices
89 // TODO: Use unsafe.Slice() when we require Go 1.17.
90 return (*[1 << 30]byte)(b.P)[:b.Size:b.Size]
93 // Get returns a pointer to a byte in the underlying C array. The pointer can
94 // be used to modify the underlying array. The pointer must not be used after
95 // calling Free().
96 func (b *AioBuffer) Get(i uint) *byte {
97 if b.P == nil {
98 panic("Using AioBuffer after Free()")
100 return (*byte)(unsafe.Pointer(uintptr(b.P) + uintptr(i)))