forked from hillu/go-yara
-
Notifications
You must be signed in to change notification settings - Fork 0
/
stream.go
69 lines (63 loc) · 1.58 KB
/
stream.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
60
61
62
63
64
65
66
67
68
69
// Copyright © 2015-2020 Hilko Bengen <[email protected]>
// All rights reserved.
//
// Use of this source code is governed by the license that can be
// found in the LICENSE file.
package yara
import (
"io"
"reflect"
"unsafe"
)
// #include <string.h>
import "C"
//export streamRead
func streamRead(ptr unsafe.Pointer, size, nmemb C.size_t, userData unsafe.Pointer) C.size_t {
if size == 0 || nmemb == 0 {
return nmemb
}
reader := (*cgoHandle)(userData).Value().(io.Reader)
buf := make([]byte, 0)
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
hdr.Data = uintptr(ptr)
hdr.Len = int(size * nmemb)
hdr.Cap = hdr.Len
s := int(size)
for i := 0; i < int(nmemb); i++ {
if sz, err := io.ReadFull(reader, buf[i*s:(i+1)*s]); sz < int(size) && err != nil {
return C.size_t(i)
}
}
return nmemb
}
// writeFull does its best to write all of buf to w. See io.ReadFull.
func writeFull(w io.Writer, buf []byte) (n int, err error) {
var i int
for n < len(buf) {
i, err = w.Write(buf[n:])
n += i
if err != nil {
break
}
}
return
}
//export streamWrite
func streamWrite(ptr unsafe.Pointer, size, nmemb C.size_t, userData unsafe.Pointer) C.size_t {
if size == 0 || nmemb == 0 {
return nmemb
}
writer := (*cgoHandle)(userData).Value().(io.Writer)
buf := make([]byte, 0)
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
hdr.Data = uintptr(ptr)
hdr.Len = int(size * nmemb)
hdr.Cap = hdr.Len
s := int(size)
for i := 0; i < int(nmemb); i++ {
if sz, err := writeFull(writer, buf[i*s:(i+1)*s]); sz < int(size) && err != nil {
return C.size_t(i)
}
}
return nmemb
}