-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathrwops.go
139 lines (109 loc) · 2.5 KB
/
rwops.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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package sdl
import (
"bytes"
"io"
"reflect"
"unsafe"
)
// #include <SDL.h>
//
// #include "rwops.h"
import "C"
type RWops struct {
c *C.SDL_RWops
}
func (rw *RWops) Seek(offset int64, whence int) (int64, error) {
return int64(C.sdl2_seek(rw.c, C.long(offset), C.int(whence))), nil
}
func (rw *RWops) Tell() (int64, error) {
return int64(C.sdl2_tell(rw.c)), nil
}
func (rw *RWops) Read(data []byte) (int, error) {
n := C.sdl2_read(rw.c, unsafe.Pointer(&data[0]), 1, C.size_t(len(data)))
switch {
case n == 0:
return 0, io.EOF
case n < 0:
return 0, getError()
}
return int(n), nil
}
func (rw *RWops) Write(data []byte) (int, error) {
n := C.sdl2_write(rw.c, unsafe.Pointer(&data[0]), 1, C.size_t(len(data)))
switch {
case n == 0:
return 0, io.EOF
case n < 0:
return 0, getError()
}
return int(n), nil
}
func (rw *RWops) Close() error {
if C.sdl2_close(rw.c) != 0 {
return getError()
}
return nil
}
func RWFromFile(file string, mode string) (*RWops, error) {
cfile := C.CString(file)
defer C.free(unsafe.Pointer(cfile))
cmode := C.CString(mode)
defer C.free(unsafe.Pointer(cmode))
rw := C.SDL_RWFromFile(cfile, cmode)
if rw == nil {
return nil, getError()
}
return &RWops{rw}, nil
}
func RWFromMem(data []byte) (*RWops, error) {
rw := C.SDL_RWFromMem(unsafe.Pointer(&data[0]), C.int(len(data)))
if rw == nil {
return nil, getError()
}
return &RWops{rw}, nil
}
func RWFromConstMem(data []byte) (*RWops, error) {
rw := C.SDL_RWFromConstMem(unsafe.Pointer(&data[0]), C.int(len(data)))
if rw == nil {
return nil, getError()
}
return &RWops{rw}, nil
}
//export seekReadSeeker
func seekReadSeeker(ctx unsafe.Pointer, off int64, wh int) (int64, string) {
r := *(*io.ReadSeeker)(ctx)
n, err := r.Seek(off, wh)
if err != nil {
return -1, err.Error()
}
return n, ""
}
//export readReadSeeker
func readReadSeeker(ctx unsafe.Pointer, data unsafe.Pointer, size int, num int) (int, string) {
r := *(*io.ReadSeeker)(ctx)
buf := *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
Data: uintptr(data),
Len: size * num,
Cap: size * num,
}))
n, err := r.Read(buf)
if err != nil {
if err == io.EOF {
return 0, ""
}
return -1, err.Error()
}
return n, ""
}
func RWFromReadSeeker(r io.ReadSeeker) *RWops {
rw := C.RWFromReadSeeker(unsafe.Pointer(&r))
return &RWops{rw}
}
func RWFromReader(r io.Reader) (*RWops, error) {
var buf bytes.Buffer
_, err := io.Copy(&buf, r)
if err != nil {
return nil, err
}
return RWFromReadSeeker(bytes.NewReader(buf.Bytes())), nil
}