aboutsummaryrefslogtreecommitdiffstats
path: root/src/gfile/gfile.h
blob: 65088c03896c163d9af58cfd548ff3202b45db84 (plain)
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
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
/*
 * This file is subject to the terms of the GFX License. If a copy of
 * the license was not distributed with this file, you can obtain one at:
 *
 *              http://ugfx.org/license.html
 */

/**
 * @file    src/gfile/gfile.h
 * @brief   GFILE - File IO Routines header file.
 *
 * @addtogroup GFILE
 *
 * @brief	Module which contains operating system independent file I/O.
 *
 * @{
 */

#ifndef _GFILE_H
#define _GFILE_H

#include "../../gfx.h"

#if GFX_USE_GFILE || defined(__DOXYGEN__)

/*===========================================================================*/
/* Type definitions                                                          */
/*===========================================================================*/

/**
 * @brief	A file pointer
 */

typedef struct GFILE GFILE;
typedef struct gfileList gfileList;

extern GFILE *gfileStdIn;
extern GFILE *gfileStdErr;
extern GFILE *gfileStdOut;

/*===========================================================================*/
/* External declarations.                                                    */
/*===========================================================================*/

/**
 * @brief					Check if file exists
 * 
 * @param[in] fname			The file name
 * 
 * @return					gTrue if file exists, gFalse otherwise
 * 
 * @api
 */
gBool		gfileExists(const char *fname);

/**
 * @brief					Delete file
 * 
 * @param[in] fname			The file name
 * 
 * @return					gTrue on success, gFalse otherwise
 * 
 * @api
 */
gBool		gfileDelete(const char *fname);

/**
 * @brief					Get the size of a file
 * @note					Please use @p gfileGetSize() if the file is opened
 * 
 * @param[in] fname			The file name
 * 
 * @return					File size on success, -1 on error
 * 
 * @api
 */
long int	gfileGetFilesize(const char *fname);

/**
 * @brief					Rename file
 *
 * @param[in] oldname		The current file name
 * @param[in] newname		The new name of the file
 *
 * @return					gTrue on success, gFalse otherwise
 *
 * @api
 */
gBool		gfileRename(const char *oldname, const char *newname);

/**
 * @brief					Open file
 * @details					A file must be opened before it can be accessed
 * @details					The resulting GFILE will be used for all functions that access the file.
 *
 * @param[in] fname			The file name
 * @param[in] mode			The mode.
 *
 * @return					Valid GFILE on success, 0 otherwise
 *
 * @note					The modes follow the c library fopen() standard.
 * 							The valid modes are:
 * 							<ul><li>r   - Open for read, the file must exist</li>
 * 								<li>w   - Open for write, the file is truncated if it exists</li>
 * 								<li>wx  - Open for write, the file must not exist</li>
 * 								<li>a   - Open for append, the file is truncated if it exists</li>
 * 								<li>ax  - Open for append, the file must not exists</li>
 * 							</ul>
 * 							The following flags can also be added to the above modes:<br/>
 * 							<ul><li>+   - Open for both read and write</li>
 * 								<li>b   - Open as a binary file rather than a text file</li>
 * 							</ul>
 * @note					Not all file-systems support all modes. For example, write
 * 							is not available with the ROM file-system. Similarly few platforms
 * 							distinguish between binary and text files.
 * @note					Even though binary vs. text is relevant only for a small number of platforms
 * 							the "b" flag should always be specified for binary files such as images.
 * 							This ensures portability to other platforms. The extra flag will be ignored
 * 							on platforms where it is not relevant.
 *
 * @api
 */	
GFILE *		gfileOpen(const char *fname, const char *mode);

/**
 * @brief					Close file
 * @details					Closes a file after is has been opened using @p gfileOpen()
 *
 * @param[in] f				The file
 *
 * @api
 */
void		gfileClose(GFILE *f);

/**
 * @brief					Read from file
 * @details					Reads a given amount of bytes from the file
 * @details					The read/write cursor will not be reset when calling this function
 *
 * @param[in] f				The file
 * @param[out] buf			The buffer in which to save the content that has been read from the file
 * @param[in] len			Amount of bytes to read
 *
 * @return					Amount of bytes read
 *
 * @api
 */
size_t		gfileRead(GFILE *f, void *buf, size_t len);

/**
 * @brief					Write to file
 * @details					Write a given amount of bytes to the file
 * @details					The read/write cursor will not be reset when calling this function
 *
 * @param[in] f				The file
 * @param[in] buf			The buffer which contains the content that will be written to the file
 * @param[in] len			Amount of bytes to write
 *
 * @return					Amount of bytes written
 *
 * @api
 */
size_t		gfileWrite(GFILE *f, const void *buf, size_t len);

/**
 * @brief					Get the current position of the read/write cursor
 *
 * @param[in] f				The file
 *
 * @return					The current position in the file
 *
 * @api
 */
long int	gfileGetPos(GFILE *f);

/**
 * @brief					Set the position of the read/write cursor
 *
 * @param[in] f				The file
 * @param[in] pos			The position to which the cursor will be set
 *
 * @return					gTrue on success, gFalse otherwise
 *
 * @api
 */
gBool		gfileSetPos(GFILE *f, long int pos);

/**
 * @brief					Get the size of file
 * @note					Please use @p gfileGetFilesize() if the file is not opened
 *
 * @param[in] f				The file
 *
 * @return					The size of the file
 *
 * @api
 */
long int	gfileGetSize(GFILE *f);

/**
 * @brief					Check for EOF
 * @details					Checks if the cursor is at the end of the file
 *
 * @param[in] f				The file
 *
 * @return					gTrue if EOF, gFalse otherwise
 *
 * @api
 */
gBool		gfileEOF(GFILE *f);

/**
 * @brief					Mount a logical drive (aka partition)
 *
 * @details					Not supported by every file system
 * @details					Currently just one drive at one is supported.
 *
 * @param[in] fs			The file system (F for FatFS)
 * @param[in] drive			The logical drive prefix
 *
 * @return					gTrue on success, gFalse otherwise
 *
 * @api
 */
gBool gfileMount(char fs, const char *drive);

/**
 * @brief					Unmount a logical drive (aka partition)
 *
 * @details					Does have no effect if @p gfileMount() as been called before hand
 *
 * @param[in] fs			The file system (F for FatFS)
 * @param[in] drive			The logical drive prefix
 *
 * @return					gTrue on success, gFalse otherwise
 *
 * @api
 */
gBool gfileUnmount(char fs, const char *drive);

/**
 * @brief					Syncs the file object (flushes the buffer)
 *
 * @details					Not supported by every file system
 *
 * @param[in] f				The file
 *
 * @return					gTrue on success, gFalse otherwise
 *
 * @api
 */
gBool gfileSync(GFILE *f);

#if GFILE_NEED_FILELISTS || defined(__DOXYGEN__)
	/**
	 * @brief				Open a file list
	 *
	 * @param[in] fs		The file system (F for FatFS)
	 * @param[in] path		Path information to pass to the file system
	 * @param[in] dirs		Pass gTrue to get directories only, gFalse to get files only
	 *
	 * @return				A pointer to a file list on success, NULL otherwise
	 *
	 * @note				The path parameter is handled in a file-system specific way. It could be
	 * 						treated as a directory name, it may be treated as a file pattern, or it
	 * 						may be ignored. Passing NULL will always return the full list of files
	 * 						in at least the top level directory.
	 * @note				For file systems that do not support directories, passing gTrue for dirs
	 * 						will return an error.
	 * @note				You must call @p gfileCloseFileList() when you have finished with the
	 * 						file list in order to free resources.
	 *
	 * @api
	 */
	gfileList *gfileOpenFileList(char fs, const char *path, gBool dirs);

	/**
	 * @brief				Get the next file in a file list.
	 *
	 * @param[in] pfl		Pointer to a file list returned by @p gfileOpenFileList()
	 *
	 * @return				A pointer to a file (or directory) name. Returns NULL if there are no more.
	 *
	 * @note				The file name may contain the full directory path or may not depending
	 * 						on how the file system treats directories.
	 * @note				The returned buffer may be destroyed by the next call to any of
	 * 						@p gfileOpenFileList(), @p gfileReadFileList() or @p gfileCloseFileList().
	 * 						Do not use this pointer after one of those calls.
	 *
	 * @api
	 */
	const char *gfileReadFileList(gfileList *pfl);

	/**
	 * @brief				Close a file list.
	 *
	 * @param[in] pfl		Pointer to a file list returned by @p gfileOpenFileList()
	 *
	 * @api
	 */
	void gfileCloseFileList(gfileList *pfl);
#endif

#if (GFILE_NEED_CHIBIOSFS && GFX_USE_OS_CHIBIOS) || defined(__DOXYGEN__)
	/**
	 * @brief					Open file from a ChibiOS FileStream
	 *
	 * @param[in] FileStreamPtr	The BaseFileStream (ChibiOS V2) or FileStream (ChibiOS V3) to open as a GFILE
	 * @param[in] mode			The mode.
	 *
	 * @return					Valid GFILE on success, 0 otherwise
	 *
	 * @note					The modes are the same modes as in @p gfileOpen(). The
	 * 							open mode is NOT compared against the FileStream capabilities.
	 * @note					Supported operations are: read, write, getpos, setpos, eof and getsize
	 *
	 * @api
	 */
	GFILE *		gfileOpenChibiOSFileStream(void *FileStreamPtr, const char *mode);
	#define gfileOpenBaseFileStream(f,m)	gfileOpenChibiOSFileStream(f,m)
#endif

#if GFILE_NEED_MEMFS || defined(__DOXYGEN__)
	/**
	 * @brief					Open file from a memory pointer
	 *
	 * @param[in] memptr		The pointer to the memory
	 * @param[in] mode			The mode.
	 *
	 * @return					Valid GFILE on success, 0 otherwise
	 *
	 * @note					The modes are the same modes as in @p gfileOpen(). Note there is
	 * 							no concept of file-size. Be careful not to overwrite other memory or
	 * 							to read from inaccessible sections of memory.
	 * @note					Supported operations are: read, write, getpos, setpos
	 *
	 * @api
	 */
	GFILE *		gfileOpenMemory(void *memptr, const char *mode);
#endif

#if GFILE_NEED_STRINGS || defined(__DOXYGEN__)
	/**
	 * @brief					Open file from a null terminated C string
	 *
	 * @param[in] str			The pointer to the string or string buffer
	 * @param[in] mode			The mode
	 *
	 * @return					Valid GFILE on success, 0 otherwise
	 *
	 * @note					The modes are the same modes as in @p gfileOpen(). Note there is
	 * 							no concept of file-size. Be careful not to overwrite other memory or
	 * 							to read from inaccessible sections of memory.
	 * @note					Reading will return EOF when the NULL character is reached.
	 * @note					Writing will always place a NULL in the next character effectively terminating the
	 * 							string at the character just written.
	 * @note					Supported operations are: read, write, append, getpos, setpos
	 * @note					Be careful with setpos and getpos. They do not check for the end of the string.
	 * @note					Reading and Writing will read/write a maximum of one character at a time.
	 *
	 * @api
	 */
	GFILE *		gfileOpenString(char *str, const char *mode);
#endif

#if GFILE_NEED_PRINTG || defined(__DOXYGEN__)
	#include <stdarg.h>

	int vfnprintg(GFILE *f, int maxlen, const char *fmt, va_list arg);
	int fnprintg(GFILE *f, int maxlen, const char *fmt, ...);
	#define vfprintg(f,m,a)			vfnprintg(f,0,m,a)
	#define fprintg(f,m,...)		fnprintg(f,0,m,__VA_ARGS__)
	#define vprintg(m,a)			vfnprintg(gfileStdOut,0,m,a)
	#define printg(m,...)			fnprintg(gfileStdOut,0,m,__VA_ARGS__)

	#if GFILE_NEED_STRINGS
		int vsnprintg(char *buf, int maxlen, const char *fmt, va_list arg);
		int snprintg(char *buf, int maxlen, const char *fmt, ...);
		#define vsprintg(s,m,a)		vsnprintg(s,0,m,a)
		#define sprintg(s,m,...)	snprintg(s,0,m,__VA_ARGS__)
	#endif
#endif

#if GFILE_NEED_SCANG || defined(__DOXYGEN__)
	#include <stdarg.h>

	int vfscang(GFILE *f, const char *fmt, va_list arg);
	int fscang(GFILE *f, const char *fmt, ...);
	#define vscang(f,a)			vfscang(gfileStdIn,f,a)
	#define scang(f,...)		fscang(gfileStdIn,f,__VA_ARGS__)

	#if GFILE_NEED_STRINGS
		int vsscang(const char *buf, const char *fmt, va_list arg);
		int sscang(const char *buf, const char *fmt, ...);
	#endif
#endif

#if GFILE_NEED_STDIO && !defined(GFILE_NEED_STDIO_MUST_BE_OFF)
	// Needed routines and definitions
	size_t gstdioRead(void * ptr, size_t size, size_t count, GFILE *f);
	size_t gstdioWrite(const void * ptr, size_t size, size_t count, GFILE *f);
	int gstdioGetpos(GFILE *f, long int *pos);
	int gstdioSeek(GFILE *f, size_t offset, int origin);
	#define SEEK_SET	0
	#define SEEK_CUR	1
	#define SEEK_END	2

	// Stdio emulation
	#define stdin					gfileStdIn
	#define stdout					gfileStdOut
	#define stderr					gfileStdErr
	#define FOPEN_MAX				GFILE_MAX_GFILES
	#define TMP_MAX					GFILE_MAX_GFILES
	#define FILENAME_MAX			256						// Use a relatively small number for an embedded platform
	#define L_tmpnam				FILENAME_MAX
	#define P_tmpdir				"/tmp/"
	#define FILE					GFILE
	#define fopen(n,m)				gfileOpen(n,m)
	#define fclose(f)				gfileClose(f)
	#define fread(p,sz,cnt,f)		gstdioRead(p,sz,cnt,f)
	#define fwrite(p,sz,cnt,f)		gstdioWrite(p,sz,cnt,f)
	#define fseek(f,ofs,org)		gstdioSeek(f,ofs,org)
	#define remove(n)				(!gfileDelete(n))
	#define rename(o,n)				(!gfileRename(o,n))
	#define fflush(f)				(0)
	#define ftell(f)				gfileGetPos(f)
	#define fpos_t					long int
	#define fgetpos(f,pos)			gstdioGetpos(f,pos)
	#define fsetpos(f, pos)			(!gfileSetPos(f, *pos))
	#define rewind(f)				gfileSetPos(f, 0);
	#define feof(f)					gfileEOF(f)
	#define vfprintf(f,m,a)			vfnprintg(f,0,m,a)
	#define fprintf(f,m,...)		fnprintg(f,0,m,__VA_ARGS__)
	#define vprintf(m,a)			vfnprintg(gfileStdOut,0,m,a)
	#define printf(m,...)			fnprintg(gfileStdOut,0,m,__VA_ARGS__)
	#define vsnprintf(s,n,m,a)		vsnprintg(s,n,m,a)
	#define snprintf(s,n,m,...)		snprintg(s,n,m,__VA_ARGS__)
	#define vsprintf(s,m,a)			vsnprintg(s,0,m,a)
	#define sprintf(s,m,...)		snprintg(s,0,m,__VA_ARGS__)

	//TODO
	//void clearerr ( FILE * stream );
	//int ferror ( FILE * stream );
	//FILE * tmpfile ( void );		// Auto-deleting
	//char * tmpnam ( char * str );
	//char * mktemp (char *template);
	//FILE * freopen ( const char * filename, const char * mode, FILE * stream );
	//setbuf
	//setvbuf
	//fflush
	//fgetc
	//fgets
	//fputc
	//fputs
	//getc
	//getchar
	//puts
	//ungetc
	//void perror (const char * str);
#endif

#endif /* GFX_USE_GFILE */

#endif /* _GFILE_H */
/** @} */