1 /+
2 +            Copyright 2022 – 2023 Aya Partridge
3 +          Copyright 2018 - 2022 Michael D. Parker
4 + Distributed under the Boost Software License, Version 1.0.
5 +     (See accompanying file LICENSE_1_0.txt or copy at
6 +           http://www.boost.org/LICENSE_1_0.txt)
7 +/
8 module sdl.rwops;
9 
10 import bindbc.sdl.config;
11 import bindbc.sdl.codegen;
12 
13 version(WebAssembly){
14 }else import core.stdc.stdio: FILE;
15 import sdl.stdinc: SDL_bool;
16 
17 enum: uint{
18 	SDL_RWOPS_UNKNOWN    = 0U,
19 	SDL_RWOPS_WINFILE    = 1U,
20 	SDL_RWOPS_STDFILE    = 2U,
21 	SDL_RWOPS_JNIFILE    = 3U,
22 	SDL_RWOPS_MEMORY     = 4U,
23 	SDL_RWOPS_MEMORY_RO  = 5U,
24 }
25 
26 struct SDL_RWops{
27 	extern(C) @nogc nothrow{
28 		long function(SDL_RWops*) size;
29 		long function(SDL_RWops*, long, int) seek;
30 		size_t function(SDL_RWops*, void*, size_t, size_t) read;
31 		size_t function(SDL_RWops*, const(void)*, size_t, size_t) write;
32 		int function(SDL_RWops*) close;
33 	}
34 	uint type;
35 	union Hidden_{
36 		version(Android){
37 			struct AndroidIO_{
38 				void* asset;
39 			}
40 			AndroidIO_ androidio;
41 		}else static if((){
42 			version(Windows)      return true;
43 			else version(WinGDK)  return true;
44 			else return false;
45 		}()){
46 			struct WindowsIO_{
47 				SDL_bool append;
48 				void* h;
49 				struct Buffer_{
50 					void* data;
51 					size_t size;
52 					size_t left;
53 				}
54 				Buffer_ buffer;
55 			}
56 			WindowsIO_ windowsio;
57 		}
58 		
59 		version(WebAssembly){
60 		}else{
61 			struct StdIO_{
62 				int autoclose;
63 				FILE* fp;
64 			}
65 			StdIO_ stdio;
66 		}
67 		
68 		struct Mem_{
69 			ubyte* base;
70 			ubyte* here;
71 			ubyte* stop;
72 		}
73 		Mem_ mem;
74 		
75 		struct Unknown_{
76 			void* data1;
77 			void* data2;
78 		}
79 		Unknown_ unknown;
80 	}
81 	Hidden_ hidden;
82 }
83 
84 enum{
85 	RW_SEEK_SET = 0,
86 	RW_SEEK_CUR = 1,
87 	RW_SEEK_END = 2,
88 }
89 
90 pragma(inline, true) @nogc nothrow{
91 	static if(sdlSupport < SDLSupport.v2_0_10){
92 		long SDL_RWsize(SDL_RWops* ctx){ return ctx.size(ctx); }
93 		long SDL_RWseek(SDL_RWops* ctx, long offset, int whence){ return ctx.seek(ctx, offset, whence); }
94 		long SDL_RWtell(SDL_RWops* ctx){ return ctx.seek(ctx, 0, RW_SEEK_CUR); }
95 		size_t SDL_RWread(SDL_RWops* ctx, void* ptr, size_t size, size_t n){ return ctx.read(ctx, ptr, size, n); }
96 		size_t SDL_RWwrite(SDL_RWops* ctx, const(void)* ptr, size_t size, size_t n){ return ctx.write(ctx, ptr, size, n); }
97 		int SDL_RWclose(SDL_RWops* ctx){ return ctx.close(ctx); }
98 	}
99 	static if(sdlSupport >= SDLSupport.v2_0_6){
100 		void* SDL_LoadFile(const(char)* filename, size_t datasize){
101 			return SDL_LoadFile_RW(SDL_RWFromFile(filename, "rb"), datasize, 1);
102 		}
103 	}
104 }
105 
106 mixin(joinFnBinds((){
107 	string[][] ret;
108 	ret ~= makeFnBinds([
109 		[q{SDL_RWops*}, q{SDL_RWFromFile}, q{const(char)* file, const(char)* mode}],
110 		[q{SDL_RWops*}, q{SDL_RWFromMem}, q{void* mem, int size}],
111 		[q{SDL_RWops*}, q{SDL_RWFromConstMem}, q{const(void)* mem, int size}],
112 		[q{SDL_RWops*}, q{SDL_AllocRW}, q{}],
113 		[q{void}, q{SDL_FreeRW}, q{SDL_RWops* context}],
114 		[q{ubyte}, q{SDL_ReadU8}, q{SDL_RWops* context}],
115 		[q{ushort}, q{SDL_ReadLE16}, q{SDL_RWops* context}],
116 		[q{ushort}, q{SDL_ReadBE16}, q{SDL_RWops* context}],
117 		[q{uint}, q{SDL_ReadLE32}, q{SDL_RWops* context}],
118 		[q{uint}, q{SDL_ReadBE32}, q{SDL_RWops* context}],
119 		[q{ulong}, q{SDL_ReadLE64}, q{SDL_RWops* context}],
120 		[q{ulong}, q{SDL_ReadBE64}, q{SDL_RWops* context}],
121 		[q{size_t}, q{SDL_WriteU8}, q{SDL_RWops* context, ubyte value}],
122 		[q{size_t}, q{SDL_WriteLE16}, q{SDL_RWops* context, ushort value}],
123 		[q{size_t}, q{SDL_WriteBE16}, q{SDL_RWops* context, ushort value}],
124 		[q{size_t}, q{SDL_WriteLE32}, q{SDL_RWops* context, uint value}],
125 		[q{size_t}, q{SDL_WriteBE32}, q{SDL_RWops* context, uint value}],
126 		[q{size_t}, q{SDL_WriteLE64}, q{SDL_RWops* context, ulong value}],
127 		[q{size_t}, q{SDL_WriteBE64}, q{SDL_RWops* context, ulong value}],
128 	]);
129 	version(WebAssembly){
130 	}else{
131 		ret ~= makeFnBinds([
132 			[q{SDL_RWops*}, q{SDL_RWFromFP}, q{FILE* ffp, SDL_bool autoclose}],
133 		]);
134 	}
135 	static if(sdlSupport >= SDLSupport.v2_0_6){
136 		ret ~= makeFnBinds([
137 			[q{void*}, q{SDL_LoadFile_RW}, q{SDL_RWops* context, size_t datasize, int freesrc}],
138 		]);
139 	}
140 	static if(sdlSupport >= SDLSupport.v2_0_10){
141 		ret ~= makeFnBinds([
142 			[q{long}, q{SDL_RWsize}, q{SDL_RWops* context}],
143 			[q{long}, q{SDL_RWseek}, q{SDL_RWops* context, long offset, int whence}],
144 			[q{long}, q{SDL_RWtell}, q{SDL_RWops* context}],
145 			[q{size_t}, q{SDL_RWread}, q{SDL_RWops* context, void* ptr, size_t size, size_t maxnum}],
146 			[q{size_t}, q{SDL_RWwrite}, q{SDL_RWops* context, const(void)* ptr, size_t size, size_t num}],
147 			[q{int}, q{SDL_RWclose}, q{SDL_RWops* context}],
148 		]);
149 	}
150 	return ret;
151 }()));