-
-
Notifications
You must be signed in to change notification settings - Fork 219
/
rwops.go
365 lines (312 loc) · 9.72 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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
package sdl
/*
#include "sdl_wrapper.h"
static Sint64 RWsize(SDL_RWops *ctx)
{
return ctx->size(ctx);
}
static Sint64 RWseek(SDL_RWops *ctx, Sint64 offset, int whence)
{
return ctx->seek(ctx, offset, whence);
}
static size_t RWread(SDL_RWops *ctx, void *ptr, size_t size, size_t maxnum)
{
return ctx->read(ctx, ptr, size, maxnum);
}
static size_t RWwrite(SDL_RWops *ctx, void *ptr, size_t size, size_t num)
{
return ctx->write(ctx, ptr, size, num);
}
static int RWclose(SDL_RWops *ctx)
{
return ctx->close(ctx);
}
#if !(SDL_VERSION_ATLEAST(2,0,6))
#if defined(WARN_OUTDATED)
#pragma message("SDL_LoadFile_RW is not supported before SDL 2.0.6")
#endif
static void * SDL_LoadFile_RW(SDL_RWops * src, size_t *datasize, int freesrc)
{
return 0;
}
#endif
*/
import "C"
import (
"reflect"
"unsafe"
)
// RWops types
// (https://wiki.libsdl.org/SDL_RWops#stream_type)
type RWStreamType int
const (
RWOPS_UNKNOWN RWStreamType = C.SDL_RWOPS_UNKNOWN // unknown stream type
RWOPS_WINFILE RWStreamType = C.SDL_RWOPS_WINFILE // win32 file
RWOPS_STDFILE RWStreamType = C.SDL_RWOPS_STDFILE // stdio file
RWOPS_JNIFILE RWStreamType = C.SDL_RWOPS_JNIFILE // android asset
RWOPS_MEMORY RWStreamType = C.SDL_RWOPS_MEMORY // memory stream
RWOPS_MEMORY_RO RWStreamType = C.SDL_RWOPS_MEMORY_RO // read-only memory stream
)
// RWops seek from
// (https://wiki.libsdl.org/SDL_RWops#seek_function)
type RWSeek int
const (
RW_SEEK_SET RWSeek = C.RW_SEEK_SET // seek from the beginning of data
RW_SEEK_CUR RWSeek = C.RW_SEEK_CUR // seek relative to current read point
RW_SEEK_END RWSeek = C.RW_SEEK_END // seek relative to the end of data
)
// RWops provides an abstract interface to stream I/O. Applications can generally ignore the specifics of this structure's internals and treat them as opaque pointers. The details are important to lower-level code that might need to implement one of these, however.
// (https://wiki.libsdl.org/SDL_RWops)
type RWops C.SDL_RWops
func (rwops *RWops) cptr() *C.SDL_RWops {
return (*C.SDL_RWops)(rwops)
}
// RWFromFile creates a new RWops structure for reading from and/or writing to a named file.
// (https://wiki.libsdl.org/SDL_RWFromFile)
func RWFromFile(file, mode string) *RWops {
_file := C.CString(file)
_mode := C.CString(mode)
defer C.free(unsafe.Pointer(_file))
defer C.free(unsafe.Pointer(_mode))
return (*RWops)(unsafe.Pointer(C.SDL_RWFromFile(_file, _mode)))
}
// RWFromMem prepares a read-write memory buffer for use with RWops.
// (https://wiki.libsdl.org/SDL_RWFromMem)
func RWFromMem(mem []byte) (*RWops, error) {
if mem == nil {
return nil, ErrInvalidParameters
}
header := (*reflect.SliceHeader)(unsafe.Pointer(&mem))
_mem := unsafe.Pointer(header.Data)
rwops := (*RWops)(unsafe.Pointer(C.SDL_RWFromMem(_mem, C.int(len(mem)))))
if rwops == nil {
return nil, GetError()
}
return rwops, nil
}
// AllocRW allocates an empty, unpopulated RWops structure.
// (https://wiki.libsdl.org/SDL_AllocRW)
func AllocRW() *RWops {
return (*RWops)(unsafe.Pointer(C.SDL_AllocRW()))
}
// Free frees the RWops structure allocated by AllocRW().
// (https://wiki.libsdl.org/SDL_FreeRW)
func (rwops *RWops) Free() error {
if rwops == nil {
return ErrInvalidParameters
}
C.SDL_FreeRW(rwops.cptr())
return nil
}
// Size returns the size of the data stream in the RWops.
// (https://wiki.libsdl.org/SDL_RWsize)
func (rwops *RWops) Size() (int64, error) {
n := int64(C.RWsize(rwops.cptr()))
if n < 0 {
return n, GetError()
}
return n, nil
}
// Seek seeks within the RWops data stream.
// (https://wiki.libsdl.org/SDL_RWseek)
func (rwops *RWops) Seek(offset int64, whence RWSeek) (int64, error) {
if rwops == nil {
return -1, ErrInvalidParameters
}
ret := int64(C.RWseek(rwops.cptr(), C.Sint64(offset), C.int(whence)))
if ret < 0 {
return ret, GetError()
}
return ret, nil
}
// Read reads from a data source.
// (https://wiki.libsdl.org/SDL_RWread)
func (rwops *RWops) Read(buf []byte) (n int, err error) {
return rwops.Read2(buf, 1, uint(len(buf)))
}
// Read2 reads from a data source (native).
// (https://wiki.libsdl.org/SDL_RWread)
func (rwops *RWops) Read2(buf []byte, size, maxnum uint) (n int, err error) {
if rwops == nil || buf == nil {
return 0, ErrInvalidParameters
}
header := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
_data := unsafe.Pointer(header.Data)
n = int(C.RWread(rwops.cptr(), _data, C.size_t(size), C.size_t(maxnum)))
if n == 0 {
err = GetError()
}
return
}
// Tell returns the current read/write offset in the RWops data stream.
// (https://wiki.libsdl.org/SDL_RWtell)
func (rwops *RWops) Tell() (int64, error) {
if rwops == nil {
return 0, ErrInvalidParameters
}
ret := int64(C.RWseek(rwops.cptr(), 0, C.int(RW_SEEK_CUR)))
if ret < 0 {
return ret, GetError()
}
return ret, nil
}
// Write writes to the RWops data stream.
// (https://wiki.libsdl.org/SDL_RWwrite)
func (rwops *RWops) Write(buf []byte) (n int, err error) {
return rwops.Write2(buf, 1, uint(len(buf)))
}
// Write2 writes to the RWops data stream (native).
// (https://wiki.libsdl.org/SDL_RWwrite)
func (rwops *RWops) Write2(buf []byte, size, num uint) (n int, err error) {
if rwops == nil || buf == nil {
return 0, ErrInvalidParameters
}
header := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
_data := unsafe.Pointer(header.Data)
n = int(C.RWwrite(rwops.cptr(), _data, C.size_t(size), C.size_t(num)))
if n < int(num) {
err = GetError()
}
return
}
// Close closes and frees the allocated RWops structure.
// (https://wiki.libsdl.org/SDL_RWclose)
func (rwops *RWops) Close() error {
if rwops != nil && C.RWclose(rwops.cptr()) != 0 {
return GetError()
}
return nil
}
// ReadU8 reads a byte from the RWops.
// (https://wiki.libsdl.org/SDL_ReadU8)
func (rwops *RWops) ReadU8() uint8 {
if rwops == nil {
return 0
}
return uint8(C.SDL_ReadU8(rwops.cptr()))
}
// ReadLE16 reads 16 bits of little-endian data from the RWops and returns in native format.
// (https://wiki.libsdl.org/SDL_ReadLE16)
func (rwops *RWops) ReadLE16() uint16 {
if rwops == nil {
return 0
}
return uint16(C.SDL_ReadLE16(rwops.cptr()))
}
// ReadBE16 read 16 bits of big-endian data from the RWops and returns in native format.
// (https://wiki.libsdl.org/SDL_ReadBE16)
func (rwops *RWops) ReadBE16() uint16 {
if rwops == nil {
return 0
}
return uint16(C.SDL_ReadBE16(rwops.cptr()))
}
// ReadLE32 reads 32 bits of little-endian data from the RWops and returns in native format.
// (https://wiki.libsdl.org/SDL_ReadLE32)
func (rwops *RWops) ReadLE32() uint32 {
if rwops == nil {
return 0
}
return uint32(C.SDL_ReadLE32(rwops.cptr()))
}
// ReadBE32 reads 32 bits of big-endian data from the RWops and returns in native format.
// (https://wiki.libsdl.org/SDL_ReadBE32)
func (rwops *RWops) ReadBE32() uint32 {
if rwops == nil {
return 0
}
return uint32(C.SDL_ReadBE32(rwops.cptr()))
}
// ReadLE64 reads 64 bits of little-endian data from the RWops and returns in native format.
// (https://wiki.libsdl.org/SDL_ReadLE64)
func (rwops *RWops) ReadLE64() uint64 {
if rwops == nil {
return 0
}
return uint64(C.SDL_ReadLE64(rwops.cptr()))
}
// ReadBE64 reads 64 bits of big-endian data from the RWops and returns in native format.
// (https://wiki.libsdl.org/SDL_ReadBE64)
func (rwops *RWops) ReadBE64() uint64 {
if rwops == nil {
return 0
}
return uint64(C.SDL_ReadBE64(rwops.cptr()))
}
// LoadFile_RW loads all the data from an SDL data stream.
// (https://wiki.libsdl.org/SDL_LoadFile_RW)
func (src *RWops) LoadFileRW(freesrc bool) (data []byte, size int) {
var _size C.size_t
var _freesrc C.int = 0
if freesrc {
_freesrc = 1
}
_data := C.SDL_LoadFile_RW(src.cptr(), &_size, _freesrc)
sliceHeader := (*reflect.SliceHeader)(unsafe.Pointer(&data))
sliceHeader.Cap = int(_size)
sliceHeader.Len = int(_size)
sliceHeader.Data = uintptr(_data)
size = int(_size)
return
}
// LoadFile loads an entire file
// (https://wiki.libsdl.org/SDL_LoadFile)
func LoadFile(file string) (data []byte, size int) {
return RWFromFile(file, "rb").LoadFileRW(true)
}
// WriteU8 writes a byte to the RWops.
// (https://wiki.libsdl.org/SDL_WriteU8)
func (rwops *RWops) WriteU8(value uint8) uint {
if rwops == nil {
return 0
}
return uint(C.SDL_WriteU8(rwops.cptr(), C.Uint8(value)))
}
// WriteLE16 writes 16 bits in native format to the RWops as little-endian data.
// (https://wiki.libsdl.org/SDL_WriteLE16)
func (rwops *RWops) WriteLE16(value uint16) uint {
if rwops == nil {
return 0
}
return uint(C.SDL_WriteLE16(rwops.cptr(), C.Uint16(value)))
}
// WriteBE16 writes 16 bits in native format to the RWops as big-endian data.
// (https://wiki.libsdl.org/SDL_WriteBE16)
func (rwops *RWops) WriteBE16(value uint16) uint {
if rwops == nil {
return 0
}
return uint(C.SDL_WriteBE16(rwops.cptr(), C.Uint16(value)))
}
// WriteLE32 writes 32 bits in native format to the RWops as little-endian data.
// (https://wiki.libsdl.org/SDL_WriteLE32)
func (rwops *RWops) WriteLE32(value uint32) uint {
if rwops == nil {
return 0
}
return uint(C.SDL_WriteLE32(rwops.cptr(), C.Uint32(value)))
}
// WriteBE32 writes 32 bits in native format to the RWops as big-endian data.
// (https://wiki.libsdl.org/SDL_WriteBE32)
func (rwops *RWops) WriteBE32(value uint32) uint {
if rwops == nil {
return 0
}
return uint(C.SDL_WriteBE32(rwops.cptr(), C.Uint32(value)))
}
// WriteLE64 writes 64 bits in native format to the RWops as little-endian data.
// (https://wiki.libsdl.org/SDL_WriteLE64)
func (rwops *RWops) WriteLE64(value uint64) uint {
if rwops == nil {
return 0
}
return uint(C.SDL_WriteLE64(rwops.cptr(), C.Uint64(value)))
}
// WriteBE64 writes 64 bits in native format to the RWops as big-endian data.
// (https://wiki.libsdl.org/SDL_WriteBE64)
func (rwops *RWops) WriteBE64(value uint64) uint {
if rwops == nil {
return 0
}
return uint(C.SDL_WriteBE64(rwops.cptr(), C.Uint64(value)))
}