Detabbed
[AROS.git] / rom / dos / fgetc.c
blobb6ca1b1586af4dc6d58d2676b013e877e06fa8b1
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: english
7 */
9 #include <aros/debug.h>
10 #include <exec/memory.h>
11 #include <proto/exec.h>
13 #include <dos/stdio.h>
14 #include <dos/dosextens.h>
16 #include "dos_intern.h"
19 /*****************************************************************************
21 NAME */
22 #include <proto/dos.h>
24 AROS_LH1(LONG, FGetC,
26 /* SYNOPSIS */
27 AROS_LHA(BPTR, file, D1),
29 /* LOCATION */
30 struct DosLibrary *, DOSBase, 51, Dos)
32 /* FUNCTION
33 Get a character from a buffered file. Buffered I/O is more efficient
34 for small amounts of data but less for big chunks. You have to
35 use Flush() between buffered and non-buffered I/O or you'll
36 clutter your I/O stream.
38 INPUTS
39 file - filehandle
41 RESULT
42 The character read or EOF if the file ended or an error happened.
43 IoErr() gives additional information in that case.
45 NOTES
47 EXAMPLE
49 BUGS
51 SEE ALSO
52 IoErr(), Flush()
54 INTERNALS
56 *****************************************************************************/
58 AROS_LIBFUNC_INIT
60 /* Get pointer to filehandle */
61 struct FileHandle *fh = (struct FileHandle *)BADDR(file);
63 LONG size;
64 LONG bufsize;
66 if (fh == NULL)
68 return EOF;
71 /* If the file is in write mode... */
72 if(fh->fh_Flags & FHF_WRITE)
74 /* write the buffer (in many pieces if the first one isn't enough). */
75 LONG pos = 0;
77 while(pos != fh->fh_Pos)
79 size = Write(file, BADDR(fh->fh_Buf) + pos, fh->fh_Pos - pos);
81 /* An error happened? Return it. */
82 if(size < 0)
84 return EOF;
87 pos += size;
90 /* Reinit filehandle. */
91 fh->fh_Flags &= ~FHF_WRITE;
92 fh->fh_Pos = fh->fh_End = 0;
95 /* No normal characters left. */
96 if(fh->fh_Pos >= fh->fh_End)
98 /* Check for a pushed back EOF. */
99 if(fh->fh_Pos > fh->fh_End)
101 D(bug("FGetC: Weird pos: fh_Pos (%d) > fh_End (%d)\n", fh->fh_Pos, fh->fh_End));
102 /* Return EOF. */
103 return EOF;
106 /* Is there a buffer? */
107 if(fh->fh_Buf == BNULL)
109 if (NULL == vbuf_alloc(fh, NULL, IOBUFSIZE))
111 D(bug("FGetC: Can't allocate buffer\n"));
112 return(EOF);
116 /* Fill the buffer. */
117 if (fh->fh_Buf != fh->fh_OrigBuf) {
118 D(bug("FGetC: Can't trust fh_BufSize. Using 208 as the buffer size.\n"));
119 bufsize = 208;
120 } else {
121 bufsize = fh->fh_BufSize;
123 size = Read(file, BADDR(fh->fh_Buf), bufsize);
125 /* Prepare filehandle for data. */
126 if(size <= 0)
127 size = 0;
129 fh->fh_Pos = 0;
130 fh->fh_End = size;
132 /* No data read? Return EOF. */
133 if(size == 0)
135 D(bug("FGetC: Tried to Read() to a %d byte buffer, got 0)\n", bufsize));
136 return EOF;
140 /* If fh_End == 0, simulate an EOF */
141 if (fh->fh_End == 0) {
142 D(bug("FGetC: Got an EOF via fh_End == 0\n"));
143 return EOF;
146 /* All OK. Get data. */
147 return ((UBYTE *)BADDR(fh->fh_Buf))[fh->fh_Pos++];
149 AROS_LIBFUNC_EXIT
150 } /* FGetC */