forked from szferi/gomdb
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathval.go
59 lines (50 loc) · 1.2 KB
/
val.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package mdb
/*
#include <memory.h>
#include <stdlib.h>
#include <lmdb.h>
*/
import "C"
import (
"reflect"
"unsafe"
)
// MDB_val
type Val C.MDB_val
// Create a Val that points to p's data. the Val's data must not be freed
// manually and C references must not survive the garbage collection of p (and
// the returned Val).
func Wrap(p []byte) *Val {
l := C.size_t(len(p))
ptr := C.malloc(C.sizeof_MDB_val + l)
C.memset(ptr, 0, C.sizeof_MDB_val+l)
val := (*C.MDB_val)(ptr)
val.mv_size = l
if l != 0 {
bitesPtr := unsafe.Pointer(uintptr(ptr) + uintptr(C.sizeof_MDB_val))
C.memcpy(bitesPtr, unsafe.Pointer(&p[0]), l)
val.mv_data = bitesPtr
}
return (*Val)(val)
}
func (v *Val) Free() {
if v != nil {
C.free(unsafe.Pointer(v))
}
}
// If val is nil, a empty slice is retured.
func (v *Val) Bytes() []byte {
return C.GoBytes(v.mv_data, C.int(v.mv_size))
}
func (v *Val) BytesNoCopy() []byte {
hdr := reflect.SliceHeader{
Data: uintptr(unsafe.Pointer(v.mv_data)),
Len: int(v.mv_size),
Cap: int(v.mv_size),
}
return *(*[]byte)(unsafe.Pointer(&hdr))
}
// If val is nil, an empty string is returned.
func (v *Val) String() string {
return C.GoStringN((*C.char)(v.mv_data), C.int(v.mv_size))
}