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