mirror of
https://git.planet-casio.com/Vhex-Kernel-Core/fxlibc.git
synced 2024-12-28 04:23:38 +01:00
stdio: share the FILE implementation between all versions
This commit is contained in:
parent
f1512125d0
commit
294fda9731
8 changed files with 91 additions and 163 deletions
|
@ -11,7 +11,7 @@ extern "C" {
|
|||
** parse options, lay out strings, and generate output.
|
||||
*/
|
||||
|
||||
#include <bits/types/FILE.h>
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
|
|
|
@ -7,9 +7,97 @@ extern "C" {
|
|||
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/* Type of FILE handlers. */
|
||||
#include <bits/types/FILE.h>
|
||||
#define __FILE_BUF_READ 0
|
||||
#define __FILE_BUF_WRITE 1
|
||||
|
||||
/* The FILE structure is mostly a buffer around kernel-level I/O. Most of the
|
||||
work is maintaining that buffer to provide the basic fgetc()/fputc()
|
||||
functions, then everything else is built on top of the abstracted stream.
|
||||
|
||||
The buffer of a FILE can either be in reading or writing mode. When in
|
||||
reading mode, the buffer contains pre-fetched data from a previous read that
|
||||
hasn't yet been requested by the user. When in writing mode, the buffer
|
||||
contains data written by the user which hasn't yet been sent to the kernel.
|
||||
|
||||
The buffer has the following structure:
|
||||
|
||||
0 bufpos bufread bufsize
|
||||
+--------+---------+---------+
|
||||
|xxxxxxxx|rrrrrrrrr|uuuuuuuuu| (When reading)
|
||||
+--------+---------+---------+
|
||||
|wwwwwwww|uuuuuuuuuuuuuuuuuuu| (When writing)
|
||||
+--------+-------------------+
|
||||
|
||||
x: Data read from file descriptor and returned to user
|
||||
r: Data read from file descriptor not yet returned to user
|
||||
w: Data written by user not yet sent to file descriptor
|
||||
u: Undefined
|
||||
|
||||
In reading mode, the region [0..bufread) contains data obtained from the
|
||||
file. bufpos marks how much has been read, in the sense that [0..bufpos) has
|
||||
already been returned to the user while [bufpos..bufread) has not. The offset
|
||||
on the underlying file descriptor sits at bufread, so the position reported
|
||||
by ftell() is fdpos - bufread + bufpos. The rest of the buffer is undefined.
|
||||
|
||||
In writing mode, the region [0..bufpos) contains data received through API
|
||||
but not yet written to the file descriptor. ftell() reports fdpos + bufpos.
|
||||
The rest of the buffer is undefined.
|
||||
|
||||
The ungetc() function pushes back characters into the buffer; if the FILE is
|
||||
unbuffered, then it's made buffered temporarily to hold the characters and
|
||||
cleared at the next fflush() or read. The buffer is put in reading mode. For
|
||||
this reason, reading functions should test [fp->buf] to check whether there
|
||||
is a buffer instead of [fp->bufmode != _IONBF].
|
||||
|
||||
Many fields in the FILE structure are abstracted away by API calls in layers:
|
||||
|
||||
1. [fd], [fdpos] and [error] are updated by the primitive functions of
|
||||
fileutil.c which essentially wrap kernel I/O (plus clearerr() obviously).
|
||||
2. [buf], [bufsize], [bufmode] and [bufowned] are handled by setbuf(),
|
||||
setvbuf() and fclose().
|
||||
3. [bufpos], [bufread] and [bufdir] are set by primitive read/write functions
|
||||
like fgets() or fwrite(), and cleared by fflush().
|
||||
4. [readable], [writable], [append] and [text] are set by fopen() and
|
||||
freopen(), and used as read-only by the primitive functions of 3. */
|
||||
typedef struct {
|
||||
/* File descriptor */
|
||||
int fd;
|
||||
/* Current position in file, as tracked by the file descriptor (ie. not
|
||||
accounting for buffer operations) */
|
||||
size_t fdpos;
|
||||
|
||||
/* Pointer to buffer (NULL if _IONBF) */
|
||||
char *buf;
|
||||
/* Current position in buffer, water mark of read data in buffer, and
|
||||
buffer size; see header comment for details */
|
||||
size_t bufpos;
|
||||
size_t bufread;
|
||||
size_t bufsize;
|
||||
/* Number of ungetc()'d characters at the start of buffer data */
|
||||
int bufungetc;
|
||||
/* Buffering mode; one of _IOFBF, _IOLBF, or _IONBF */
|
||||
uint8_t bufmode :2;
|
||||
/* We own the buffer and it needs to be freed */
|
||||
uint8_t bufowned :1;
|
||||
/* __FILE_BUF_READ if the buffer is in reading mode
|
||||
__FILE_BUF_WRITE if it's in writing mode
|
||||
This mode can only be changed immediately after fflush(). */
|
||||
uint8_t bufdir :1;
|
||||
|
||||
/* Opening flags */
|
||||
uint8_t readable :1;
|
||||
uint8_t writable :1;
|
||||
uint8_t append :1;
|
||||
/* Non-zero if text mode, zero if binary mode */
|
||||
uint8_t text :1;
|
||||
/* EOF indicator */
|
||||
uint8_t eof :1;
|
||||
/* Error indicator */
|
||||
uint8_t error :1;
|
||||
} FILE;
|
||||
|
||||
/* Type of positions within files. We don't have wide-oriented streams. */
|
||||
typedef size_t fpos_t;
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
#ifndef __BITS_TYPES_FILE_H__
|
||||
# define __BITS_TYPES_FILE_H__
|
||||
|
||||
typedef struct {
|
||||
} FILE;
|
||||
|
||||
#endif /*__BITS_TYPES_FILE_H__*/
|
|
@ -1,7 +0,0 @@
|
|||
#ifndef __BITS_TYPES_FILE_H__
|
||||
# define __BITS_TYPES_FILE_H__
|
||||
|
||||
typedef struct {
|
||||
} FILE;
|
||||
|
||||
#endif /*__BITS_TYPES_FILE_H__*/
|
|
@ -1,99 +0,0 @@
|
|||
#ifndef __BITS_TYPES_FILE_H__
|
||||
# define __BITS_TYPES_FILE_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#define __FILE_BUF_READ 0
|
||||
#define __FILE_BUF_WRITE 1
|
||||
|
||||
/* The FILE structure is mostly a buffer around kernel-level I/O. Most of the
|
||||
work is maintaining that buffer to provide the basic fgetc()/fputc()
|
||||
functions, then everything else is built on top of the abstracted stream.
|
||||
|
||||
The buffer of a FILE can either be in reading or writing mode. When in
|
||||
reading mode, the buffer contains pre-fetched data from a previous read that
|
||||
hasn't yet been requested by the user. When in writing mode, the buffer
|
||||
contains data written by the user which hasn't yet been sent to the kernel.
|
||||
|
||||
The buffer has the following structure:
|
||||
|
||||
0 bufpos bufread bufsize
|
||||
+--------+---------+---------+
|
||||
|xxxxxxxx|rrrrrrrrr|uuuuuuuuu| (When reading)
|
||||
+--------+---------+---------+
|
||||
|wwwwwwww|uuuuuuuuuuuuuuuuuuu| (When writing)
|
||||
+--------+-------------------+
|
||||
|
||||
x: Data read from file descriptor and returned to user
|
||||
r: Data read from file descriptor not yet returned to user
|
||||
w: Data written by user not yet sent to file descriptor
|
||||
u: Undefined
|
||||
|
||||
In reading mode, the region [0..bufread) contains data obtained from the
|
||||
file. bufpos marks how much has been read, in the sense that [0..bufpos) has
|
||||
already been returned to the user while [bufpos..bufread) has not. The offset
|
||||
on the underlying file descriptor sits at bufread, so the position reported
|
||||
by ftell() is fdpos - bufread + bufpos. The rest of the buffer is undefined.
|
||||
|
||||
In writing mode, the region [0..bufpos) contains data received through API
|
||||
but not yet written to the file descriptor. ftell() reports fdpos + bufpos.
|
||||
The rest of the buffer is undefined.
|
||||
|
||||
The ungetc() function pushes back characters into the buffer; if the FILE is
|
||||
unbuffered, then it's made buffered temporarily to hold the characters and
|
||||
cleared at the next fflush() or read. The buffer is put in reading mode. For
|
||||
this reason, reading functions should test [fp->buf] to check whether there
|
||||
is a buffer instead of [fp->bufmode != _IONBF].
|
||||
|
||||
Many fields in the FILE structure are abstracted away by API calls in layers:
|
||||
|
||||
1. [fd], [fdpos] and [error] are updated by the primitive functions of
|
||||
fileutil.c which essentially wrap kernel I/O (plus clearerr() obviously).
|
||||
2. [buf], [bufsize], [bufmode] and [bufowned] are handled by setbuf(),
|
||||
setvbuf() and fclose().
|
||||
3. [bufpos], [bufread] and [bufdir] are set by primitive read/write functions
|
||||
like fgets() or fwrite(), and cleared by fflush().
|
||||
4. [readable], [writable], [append] and [text] are set by fopen() and
|
||||
freopen(), and used as read-only by the primitive functions of 3.
|
||||
|
||||
TODO: EOF indicator */
|
||||
typedef struct {
|
||||
/* File descriptor */
|
||||
int fd;
|
||||
/* Current position in file, as tracked by the file descriptor (ie. not
|
||||
accounting for buffer operations) */
|
||||
size_t fdpos;
|
||||
|
||||
/* Pointer to buffer (NULL if _IONBF) */
|
||||
char *buf;
|
||||
/* Current position in buffer, water mark of read data in buffer, and
|
||||
buffer size; see header comment for details */
|
||||
size_t bufpos;
|
||||
size_t bufread;
|
||||
size_t bufsize;
|
||||
/* Number of ungetc()'d characters at the start of buffer data */
|
||||
int bufungetc;
|
||||
/* Buffering mode; one of _IOFBF, _IOLBF, or _IONBF */
|
||||
uint8_t bufmode :2;
|
||||
/* We own the buffer and it needs to be freed */
|
||||
uint8_t bufowned :1;
|
||||
/* __FILE_BUF_READ if the buffer is in reading mode
|
||||
__FILE_BUF_WRITE if it's in writing mode
|
||||
This mode can only be changed immediately after fflush(). */
|
||||
uint8_t bufdir :1;
|
||||
|
||||
/* Opening flags */
|
||||
uint8_t readable :1;
|
||||
uint8_t writable :1;
|
||||
uint8_t append :1;
|
||||
/* Non-zero if text mode, zero if binary mode */
|
||||
uint8_t text :1;
|
||||
/* EOF indicator */
|
||||
uint8_t eof :1;
|
||||
/* Error indicator */
|
||||
uint8_t error :1;
|
||||
} FILE;
|
||||
|
||||
#endif /*__BITS_TYPES_FILE_H__*/
|
|
@ -1,13 +0,0 @@
|
|||
#ifndef __BITS_TYPES_FILE_H__
|
||||
# define __BITS_TYPES_FILE_H__
|
||||
|
||||
// opaque definition of the _IO_FILE
|
||||
struct _IO_FILE;
|
||||
|
||||
/*
|
||||
** The opaque type of streams.
|
||||
** This is the definition used elsewhere.
|
||||
*/
|
||||
typedef struct _IO_FILE FILE;
|
||||
|
||||
#endif /*__BITS_TYPES_FILE_H__*/
|
|
@ -1,8 +0,0 @@
|
|||
#ifndef __BITS_TYPES___FILE_H__
|
||||
# define ___BITS_TYPES___FILE_H__
|
||||
|
||||
// define opaque definition of the FILE type
|
||||
struct _IO_FILE;
|
||||
typedef struct _IO_FILE __FILE;
|
||||
|
||||
#endif /*__BITS_TYPES___FILE_H__*/
|
|
@ -1,26 +0,0 @@
|
|||
#ifndef __BITS_TYPES_STRUCT_FILE_H__
|
||||
# define __BITS_TYPES_STRUCT_FILE_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
//---
|
||||
// TODO: VFS abstraction ? or ABI-spesific abstraction ?
|
||||
//---
|
||||
|
||||
|
||||
// Define _IO_FILE
|
||||
// TODO: add open flags
|
||||
// TODO: add file descriptor ?
|
||||
// TODO: update me !
|
||||
struct _IO_FILE
|
||||
{
|
||||
off_t cursor;
|
||||
int permission;
|
||||
void *file_op;
|
||||
void *private;
|
||||
};
|
||||
|
||||
#endif /*__BITS_TYPES_STRUCT_FILE_H__*/
|
Loading…
Reference in a new issue