/*
 * stdio.h - User level <stdio> library definition.
 * 
 * Author     Alain Greiner (2016,2017,2018,2019)
 *
 * Copyright (c) UPMC Sorbonne Universites
 *
 * This file is part of ALMOS-MKH.
 *
 * ALMOS-MKH is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2.0 of the License.
 *
 * ALMOS-MKH is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#ifndef _STDIO_H_
#define _STDIO_H_

/*********************************************************************************************
 * This file defines the user level, TXT related <stdio> library.
 * These functions call the read() and write() functions defined in the <unistd> library
 * to access the TXT terminal.
 ********************************************************************************************/

#define  MAX_OPEN_FILE_PER_PROCESS  256
#define  VALID_OPEN_FILE            0x12345678
#define  EOF                        -1
#define  NULL                       (void *)0

/*********************************************************************************************
 * This defines the user level FILE structure.
 ********************************************************************************************/

typedef struct stream_s
{
    int fd;          // index in both kernel fd_array[], and user open_file_array[]
    int key;         // entry valid in open_file_array[] when (key == VALID_OPEN_FILE)
}
FILE;

/*********************************************************************************************
 * This function causes the file/directory named <old> to be renamed as <new>.
 * If <new> exists, it is previously removed.
 *********************************************************************************************
 * @ returns 0 if success / returns -1 if failure.
 ********************************************************************************************/
int rename( const char * old,
            const char * new );

/*********************************************************************************************
 * This function writes a formated string to the standard "stdout" stream.
 *********************************************************************************************
 * @ returns number of characters written if success / returns -1 if failure.
 ********************************************************************************************/
int printf( const char * format, ... );

/*********************************************************************************************
 * This function writes one single character to the standard "stdout" stream.
 *********************************************************************************************
 * @ returns written character code if success / returns 0 (EOF) if failure.
 ********************************************************************************************/
int putchar( int c );

/*********************************************************************************************
 * This function returns one single character from the standard "stdin" stream.
 *********************************************************************************************
 * @ returns read character code if success / returns 0 (EOF) if failure.
 ********************************************************************************************/
int getchar( void );

/*********************************************************************************************
 * This function copies a formated string to a fixed size buffer. 
 * it includes the NUL terminating character. 
 * it cheks that the formated string fit in the buffer length.
 *********************************************************************************************
 * @ string    : pointer on target buffer.
 * @ length    : max bumber of characters in target buffer.
 * @ format    : formated string.
 * @ returns number of characters written if success / returns -1 if failure.
 ********************************************************************************************/
int snprintf( char         * string,
              unsigned int   length,
              const char   * format, ... );

/*********************************************************************************************
 * This function opens the file identified by the <pathname> argument and associates
 * the stream pointed by <FILE> with it.
 * The <mode> argument is a string that can have the following values:
 * - "r"   Open text file for reading. 
 *         The stream is positioned at the beginning of the file.
 * - "r+"  Open for reading and writing. 
 *         The stream is positioned at the beginning of the file.
 * - "w"   Truncate the file to zero length or create text file for writing.
 *         The stream is positioned at the beginning of the file.
 * - "w+"  Open for reading and writing.
 *         The file is created if it does not exist, otherwise it is truncated.
 *         The stream is positioned at the beginning of the file.
 * - "a"   Open for writing.  The file is created if it does not exist.
 *         The stream is positioned at the end of the file.  
 *         Subsequent writes to the file will always end up at the current end of file,
 *         irrespective of any intervening fseek() or similar.
 * - "a+"  Open for reading and writing.  
 *         The file is created if it does not exist.  
 *         The stream is positioned at the end of the file.
 *         Subsequent writes to the file will always end up at the current end of file,
 *         irrespective of any intervening fseek() or similar.
 *********************************************************************************************
 * @ pathname  : file pathname.
 * @ mode      : must be NULL <=> only "w+" mode is supported. 
 * @ returns a stream pointer if success / returns NULL if file not found.
 ********************************************************************************************/
FILE * fopen( const char * pathname,
              const char * mode );

/*********************************************************************************************
 * This function dissociates the stream from its underlying file and close this file.
 * If the stream was being used for output, any buffered data is written first.
 *********************************************************************************************
 * @ stream    : pointer on a stream.
 * @ returns 0 if success / returns EOF if failure.
 ********************************************************************************************/
int fclose( FILE * stream );

/*********************************************************************************************
 * This function copies a formated string to an output stream identified by the <stream>
 * argument. It can be a  regular file or a character oriented output device.
 *********************************************************************************************
 * @ stream    : pointer on a stream.
 * @ format    : formated string.
 * @ returns number of characters written if success / returns -1 if failure.
 ********************************************************************************************/
int fprintf( FILE       * stream,
             const char * format, ... );

/*********************************************************************************************
 * This function moves <nitems> oblects, each <size> bytes long, from an input stream
 * identified by <stream>, to the user buffer identified by the <buffer> argument.
 * It can be a regular file or a character oriented input device.
 *********************************************************************************************
 * @ buffer    : pointer on user buffer.
 * @ size      : item size in bytes.
 * @ nitems    : number of items.
 * @ stream    : pointer on a stream.
 * @ returns actual number of items read if success / returns 0 if failure.
 ********************************************************************************************/
unsigned int fread( void         * buffer,
                    unsigned int   size,
                    unsigned int   nitems,
                    FILE         * stream );  

/*********************************************************************************************
 * This function moves <nitems> oblects, each <size> bytes long, from an user buffer
 * identified by the <buffer> argument, to an output stream identified by <stream>.
 * It can be a  regular file or a character oriented input device.
 *********************************************************************************************
 * @ buffer    : pointer on user buffer.
 * @ size      : item size in bytes.
 * @ nitems    : number of items.
 * @ stream    : pointer on a stream.
 * @ returns actual number of written items if success / returns 0 if failure.
 ********************************************************************************************/
unsigned int fwrite( void         * buffer,
                     unsigned int   size,
                     unsigned int   nitems,
                     FILE         * stream );  

/*********************************************************************************************
 * This function moves <nitems> oblects, each <size> bytes long, from an input stream
 * identified by <stream>, to the user buffer identified by the <buffer> argument.
 * It can be a regular file or a character oriented input device.
 *********************************************************************************************
 * @ stream    : pointer on a stream.
 * @ offset    : used to compute new offset value.
 * @ whence    : operation type (SEEK_SET / SEEK_CUR / SEEK_END)
 * @ return 0 if success / returns -1 if failure.
 ********************************************************************************************/
unsigned int fseek( FILE        * stream,
                    unsigned int  offset,
                    int           whence );


#endif  // _STDIO_H_
