Skip to content

Commit 0ee14f9

Browse files
committed
sdl/rwops: Make basic RWops I/O methods more idiomatic and implement common Go interfaces
Signed-off-by: Lilis Iskandar <[email protected]>
1 parent af7a0fe commit 0ee14f9

File tree

1 file changed

+83
-31
lines changed

1 file changed

+83
-31
lines changed

sdl/rwops.go

+83-31
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ static int RWclose(SDL_RWops *ctx)
2828
}
2929
*/
3030
import "C"
31-
import "unsafe"
31+
import (
32+
"reflect"
33+
"unsafe"
34+
)
3235

3336
// RWops types
3437
const (
@@ -67,11 +70,19 @@ func RWFromFile(file, mode string) *RWops {
6770

6871
// RWFromMem prepares a read-write memory buffer for use with RWops.
6972
// (https://wiki.libsdl.org/SDL_RWFromMem)
70-
func RWFromMem(mem unsafe.Pointer, size int) *RWops {
73+
func RWFromMem(mem []byte) (*RWops, error) {
7174
if mem == nil {
72-
return nil
75+
return nil, ErrInvalidParameters
76+
}
77+
78+
header := (*reflect.SliceHeader)(unsafe.Pointer(&mem))
79+
_mem := unsafe.Pointer(header.Data)
80+
81+
rwops := (*RWops)(unsafe.Pointer(C.SDL_RWFromMem(_mem, C.int(len(mem)))))
82+
if rwops == nil {
83+
return nil, GetError()
7384
}
74-
return (*RWops)(unsafe.Pointer(C.SDL_RWFromMem(mem, C.int(size))))
85+
return rwops, nil
7586
}
7687

7788
// AllocRW allocates an empty, unpopulated RWops structure.
@@ -82,61 +93,102 @@ func AllocRW() *RWops {
8293

8394
// FreeRW frees the RWops structure allocated by AllocRW().
8495
// (https://wiki.libsdl.org/SDL_FreeRW)
85-
func (rwops *RWops) FreeRW() {
96+
func (rwops *RWops) Free() error {
8697
if rwops == nil {
87-
return
98+
return ErrInvalidParameters
8899
}
100+
89101
C.SDL_FreeRW(rwops.cptr())
102+
return nil
90103
}
91104

92-
// RWsize returns the size of the data stream in the RWops.
105+
// Size returns the size of the data stream in the RWops.
93106
// (https://wiki.libsdl.org/SDL_RWsize)
94-
func (rwops *RWops) RWsize() int64 {
95-
return int64(C.RWsize(rwops.cptr()))
107+
func (rwops *RWops) Size() (int64, error) {
108+
n := int64(C.RWsize(rwops.cptr()))
109+
if n < 0 {
110+
return n, GetError()
111+
}
112+
return n, nil
96113
}
97114

98-
// RWseek seek within the RWops data stream.
115+
// Seek seeks within the RWops data stream.
99116
// (https://wiki.libsdl.org/SDL_RWseek)
100-
func (rwops *RWops) RWseek(offset int64, whence int) int64 {
117+
func (rwops *RWops) Seek(offset int64, whence int) (int64, error) {
101118
if rwops == nil {
102-
return -1
119+
return -1, ErrInvalidParameters
103120
}
104-
return int64(C.RWseek(rwops.cptr(), C.Sint64(offset), C.int(whence)))
121+
122+
ret := int64(C.RWseek(rwops.cptr(), C.Sint64(offset), C.int(whence)))
123+
if ret < 0 {
124+
return ret, GetError()
125+
}
126+
return ret, nil
105127
}
106128

107-
// RWread read from a data source.
129+
// Read reads from a data source.
108130
// (https://wiki.libsdl.org/SDL_RWread)
109-
func (rwops *RWops) RWread(ptr unsafe.Pointer, size, maxnum uint) uint {
110-
if rwops == nil {
111-
return 0
131+
func (rwops *RWops) Read(buf []byte) (n int, err error) {
132+
return rwops.Read2(buf, 1, uint(len(buf)))
133+
}
134+
135+
// Read2 reads from a data source (native).
136+
// (https://wiki.libsdl.org/SDL_RWread)
137+
func (rwops *RWops) Read2(buf []byte, size, maxnum uint) (n int, err error) {
138+
if rwops == nil || buf == nil {
139+
return 0, ErrInvalidParameters
112140
}
113-
return uint(C.RWread(rwops.cptr(), ptr, C.size_t(size), C.size_t(maxnum)))
141+
142+
header := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
143+
_data := unsafe.Pointer(header.Data)
144+
145+
n = int(C.RWread(rwops.cptr(), _data, C.size_t(size), C.size_t(maxnum)))
146+
if n == 0 {
147+
err = GetError()
148+
}
149+
return
114150
}
115151

116-
// RWtell returns the current read/write offset in the RWops data stream.
152+
// Tell returns the current read/write offset in the RWops data stream.
117153
// (https://wiki.libsdl.org/SDL_RWtell)
118-
func (rwops *RWops) RWtell() int64 {
154+
func (rwops *RWops) Tell() (int64, error) {
119155
if rwops == nil {
120-
return 0
156+
return 0, ErrInvalidParameters
121157
}
122-
return int64(C.RWseek(rwops.cptr(), 0, RW_SEEK_CUR))
158+
159+
ret := int64(C.RWseek(rwops.cptr(), 0, RW_SEEK_CUR))
160+
if ret < 0 {
161+
return ret, GetError()
162+
}
163+
return ret, nil
123164
}
124165

125-
// RWwrite writes to the RWops data stream.
166+
// Write writes to the RWops data stream.
126167
// (https://wiki.libsdl.org/SDL_RWwrite)
127-
func (rwops *RWops) RWwrite(ptr unsafe.Pointer, size, num uint) uint {
128-
if rwops == nil {
129-
return 0
168+
func (rwops *RWops) Write(buf []byte) (n int, err error) {
169+
return rwops.Write2(buf, 1, uint(len(buf)))
170+
}
171+
172+
// Write2 writes to the RWops data stream (native).
173+
// (https://wiki.libsdl.org/SDL_RWwrite)
174+
func (rwops *RWops) Write2(buf []byte, size, num uint) (n int, err error) {
175+
if rwops == nil || buf == nil {
176+
return 0, ErrInvalidParameters
130177
}
131-
if ptr == nil {
132-
return 0
178+
179+
header := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
180+
_data := unsafe.Pointer(header.Data)
181+
182+
n = int(C.RWwrite(rwops.cptr(), _data, C.size_t(size), C.size_t(num)))
183+
if n < int(num) {
184+
err = GetError()
133185
}
134-
return uint(C.RWwrite(rwops.cptr(), ptr, C.size_t(size), C.size_t(size)))
186+
return
135187
}
136188

137-
// RWclose closes and frees the allocated RWops structure.
189+
// Close closes and frees the allocated RWops structure.
138190
// (https://wiki.libsdl.org/SDL_RWclose)
139-
func (rwops *RWops) RWclose() error {
191+
func (rwops *RWops) Close() error {
140192
if rwops != nil && C.RWclose(rwops.cptr()) != 0 {
141193
return GetError()
142194
}

0 commit comments

Comments
 (0)