1/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
2/* If you are missing that file, acquire a complete release at teeworlds.com. */
3
4#ifndef BASE_IO_H
5#define BASE_IO_H
6
7#include "types.h"
8
9#include <cstdint>
10
11/**
12 * File I/O related operations.
13 *
14 * @defgroup File-IO File I/O
15 */
16
17/**
18 * @ingroup File-IO
19 */
20enum
21{
22 /**
23 * Open file for reading.
24 *
25 * @see io_open
26 */
27 IOFLAG_READ = 1,
28 /**
29 * Open file for writing.
30 *
31 * @see io_open
32 */
33 IOFLAG_WRITE = 2,
34 /**
35 * Open file for appending at the end.
36 *
37 * @see io_open
38 */
39 IOFLAG_APPEND = 4,
40};
41
42/**
43 * @ingroup File-IO
44 */
45enum ESeekOrigin
46{
47 /**
48 * Start seeking from the beginning of the file.
49 *
50 * @see io_seek
51 */
52 IOSEEK_START = 0,
53 /**
54 * Start seeking from the current position.
55 *
56 * @see io_seek
57 */
58 IOSEEK_CUR = 1,
59 /**
60 * Start seeking from the end of the file.
61 *
62 * @see io_seek
63 */
64 IOSEEK_END = 2,
65};
66
67/**
68 * Opens a file.
69 *
70 * @ingroup File-IO
71 *
72 * @param filename File to open.
73 * @param flags A set of IOFLAG flags.
74 *
75 * @see IOFLAG_READ, IOFLAG_WRITE, IOFLAG_APPEND.
76 *
77 * @return A handle to the file on success, or `nullptr` on failure.
78 */
79IOHANDLE io_open(const char *filename, int flags);
80
81/**
82 * Reads data into a buffer from a file.
83 *
84 * @ingroup File-IO
85 *
86 * @param io Handle to the file to read data from.
87 * @param buffer Pointer to the buffer that will receive the data.
88 * @param size Number of bytes to read from the file.
89 *
90 * @return Number of bytes read.
91 */
92unsigned io_read(IOHANDLE io, void *buffer, unsigned size);
93
94/**
95 * Reads the rest of the file into a buffer.
96 *
97 * @ingroup File-IO
98 *
99 * @param io Handle to the file to read data from.
100 * @param result Receives the file's remaining contents.
101 * @param result_len Receives the file's remaining length.
102 *
103 * @return `true` on success, `false` on failure.
104 *
105 * @remark Does NOT guarantee that there are no internal null bytes.
106 * @remark The result must be freed after it has been used.
107 * @remark The function will fail if more than 1 GiB of memory would
108 * have to be allocated. Large files should not be loaded into memory.
109 */
110bool io_read_all(IOHANDLE io, void **result, unsigned *result_len);
111
112/**
113 * Reads the rest of the file into a null-terminated buffer with
114 * no internal null bytes.
115 *
116 * @ingroup File-IO
117 *
118 * @param io Handle to the file to read data from.
119 *
120 * @return The file's remaining contents, or `nullptr` on failure.
121 *
122 * @remark Guarantees that there are no internal null bytes.
123 * @remark Guarantees that result will contain null-termination.
124 * @remark The result must be freed after it has been used.
125 * @remark The function will fail if more than 1 GiB of memory would
126 * have to be allocated. Large files should not be loaded into memory.
127 */
128char *io_read_all_str(IOHANDLE io);
129
130/**
131 * Skips data in a file.
132 *
133 * @ingroup File-IO
134 *
135 * @param io Handle to the file.
136 * @param size Number of bytes to skip.
137 *
138 * @return `0` on success.
139 */
140int io_skip(IOHANDLE io, int64_t size);
141
142/**
143 * Seeks to a specified offset in the file.
144 *
145 * @ingroup File-IO
146 *
147 * @param io Handle to the file.
148 * @param offset Offset from position to search.
149 * @param origin Position to start searching from.
150 *
151 * @return `0` on success.
152 */
153int io_seek(IOHANDLE io, int64_t offset, ESeekOrigin origin);
154
155/**
156 * Gets the current position in the file.
157 *
158 * @ingroup File-IO
159 *
160 * @param io Handle to the file.
161 *
162 * @return The current position, or `-1` on failure.
163 */
164int64_t io_tell(IOHANDLE io);
165
166/**
167 * Gets the total length of the file. Resets cursor to the beginning.
168 *
169 * @ingroup File-IO
170 *
171 * @param io Handle to the file.
172 *
173 * @return The total size, or `-1` on failure.
174 */
175int64_t io_length(IOHANDLE io);
176
177/**
178 * Writes data from a buffer to a file.
179 *
180 * @ingroup File-IO
181 *
182 * @param io Handle to the file.
183 * @param buffer Pointer to the data that should be written.
184 * @param size Number of bytes to write.
185 *
186 * @return Number of bytes written.
187 */
188unsigned io_write(IOHANDLE io, const void *buffer, unsigned size);
189
190/**
191 * Writes a platform dependent newline to a file.
192 *
193 * @ingroup File-IO
194 *
195 * @param io Handle to the file.
196 *
197 * @return `true` on success, `false` on failure.
198 */
199bool io_write_newline(IOHANDLE io);
200
201/**
202 * Closes a file.
203 *
204 * @ingroup File-IO
205 *
206 * @param io Handle to the file.
207 *
208 * @return `0` on success.
209 */
210int io_close(IOHANDLE io);
211
212/**
213 * Empties all buffers and writes all pending data.
214 *
215 * @ingroup File-IO
216 *
217 * @param io Handle to the file.
218 *
219 * @return `0` on success.
220 */
221int io_flush(IOHANDLE io);
222
223/**
224 * Synchronize file changes to disk.
225 *
226 * @ingroup File-IO
227 *
228 * @param io Handle to the file.
229 *
230 * @return `0` on success.
231 */
232int io_sync(IOHANDLE io);
233
234/**
235 * Checks whether an error occurred during I/O with the file.
236 *
237 * @ingroup File-IO
238 *
239 * @param io Handle to the file.
240 *
241 * @return `0` on success, or non-`0` on error.
242 */
243int io_error(IOHANDLE io);
244
245/**
246 * Returns a handle for the standard input.
247 *
248 * @ingroup File-IO
249 *
250 * @return An @link IOHANDLE @endlink for the standard input.
251 *
252 * @remark The handle must not be closed.
253 */
254IOHANDLE io_stdin();
255
256/**
257 * Returns a handle for the standard output.
258 *
259 * @ingroup File-IO
260 *
261 * @return An @link IOHANDLE @endlink for the standard output.
262 *
263 * @remark The handle must not be closed.
264 */
265IOHANDLE io_stdout();
266
267/**
268 * Returns a handle for the standard error.
269 *
270 * @ingroup File-IO
271 *
272 * @return An @link IOHANDLE @endlink for the standard error.
273 *
274 * @remark The handle must not be closed.
275 */
276IOHANDLE io_stderr();
277
278/**
279 * Returns a handle for the current executable.
280 *
281 * @ingroup File-IO
282 *
283 * @return An @link IOHANDLE @endlink for the current executable.
284 */
285IOHANDLE io_current_exe();
286
287#endif
288