grub2: bring back build of aros-side grub2 tools
[AROS.git] / rom / dos / fread.c
bloba9b457d49735753a066be96ef62ae3953bef5606
1 /*
2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: english
7 */
8 #include <aros/debug.h>
10 #include "dos_intern.h"
12 #define FETCHERR (-2)
14 /*****************************************************************************
16 NAME */
17 #include <proto/dos.h>
19 AROS_LH4(LONG, FRead,
21 /* SYNOPSIS */
22 AROS_LHA(BPTR , fh, D1),
23 AROS_LHA(APTR , block, D2),
24 AROS_LHA(ULONG, blocklen, D3),
25 AROS_LHA(ULONG, number, D4),
27 /* LOCATION */
28 struct DosLibrary *, DOSBase, 54, Dos)
30 /* FUNCTION
31 Read a number of blocks from a file.
32 The read is buffered.
34 INPUTS
35 fh - Read from this file
36 block - The data is put here
37 blocklen - This is the size of a single block
38 number - The number of blocks
40 RESULT
41 The number of blocks read from the file or 0 on EOF.
42 This function may return fewer than the requested number of blocks.
43 IoErr() gives additional information in case of an error.
45 NOTES
47 EXAMPLE
49 BUGS
51 SEE ALSO
52 Open(), FWrite(), FPutc(), Close()
54 INTERNALS
56 *****************************************************************************/
58 AROS_LIBFUNC_INIT
60 UBYTE *ptr;
61 LONG res = 0;
62 ULONG fetchsize = number * blocklen;
63 ULONG readsize;
65 ptr = block;
67 SetIoErr(0);
69 if((fetchsize == 0) || (fh == BNULL))
70 return 0;
72 while(fetchsize > 0)
74 res = vbuf_fetch(fh, ptr, fetchsize, DOSBase);
75 if (res < 0)
76 break;
77 ptr += res;
78 fetchsize -= res;
81 if(res == FETCHERR)
83 return EOF;
86 readsize = (ULONG)(ptr - (UBYTE *)block);
88 return (LONG)(readsize / blocklen);
90 AROS_LIBFUNC_EXIT
91 } /* FRead */
93 static LONG handle_write_mode(BPTR file, struct DosLibrary * DOSBase)
95 struct FileHandle *fh = (struct FileHandle *)BADDR(file);
97 /* If the file is in write mode... */
98 if(fh->fh_Flags & FHF_WRITE)
100 /* write the buffer (in many pieces if the first one isn't enough). */
101 LONG pos = 0;
103 while(pos != fh->fh_Pos)
105 LONG size = Write(file, BADDR(fh->fh_Buf) + pos, fh->fh_Pos - pos);
107 /* An error happened? Return it. */
108 if(size < 0)
110 return FETCHERR;
113 pos += size;
116 /* Reinit filehandle. */
117 fh->fh_Flags &= ~FHF_WRITE;
118 fh->fh_Pos = fh->fh_End = 0;
121 return 0;
124 /* Fetches up to remaining buffer content from file buffer
125 * Return values:
126 * (-2) on error
127 * (EOF) on EOF
128 * (>0) on successful fetch
130 LONG vbuf_fetch(BPTR file, UBYTE * buffer, ULONG fetchsize, struct DosLibrary *DOSBase)
132 /* Get pointer to filehandle */
133 struct FileHandle *fh = (struct FileHandle *)BADDR(file);
135 LONG size;
136 LONG bufsize;
138 if (fh == NULL)
140 return FETCHERR;
143 if (handle_write_mode(file, DOSBase) == FETCHERR)
145 return FETCHERR;
148 /* No normal characters left. */
149 if(fh->fh_Pos >= fh->fh_End)
151 /* Check for a pushed back EOF. */
152 if(fh->fh_Pos > fh->fh_End)
154 D(bug("FGetC: Weird pos: fh_Pos (%d) > fh_End (%d)\n", fh->fh_Pos, fh->fh_End));
155 /* Return EOF. */
156 return EOF;
159 /* Is there a buffer? */
160 if(fh->fh_Buf == BNULL)
162 if (NULL == vbuf_alloc(fh, NULL, IOBUFSIZE))
164 D(bug("FGetC: Can't allocate buffer\n"));
165 return FETCHERR;
169 /* Fill the buffer. */
170 if (fh->fh_Buf != fh->fh_OrigBuf) {
171 D(bug("FGetC: Can't trust fh_BufSize. Using 208 as the buffer size.\n"));
172 bufsize = 208;
173 } else {
174 bufsize = fh->fh_BufSize;
176 size = Read(file, BADDR(fh->fh_Buf), bufsize);
178 /* Prepare filehandle for data. */
179 if(size <= 0)
180 size = 0;
182 fh->fh_Pos = 0;
183 fh->fh_End = size;
185 /* No data read? Return EOF. */
186 if(size == 0)
188 D(bug("FGetC: Tried to Read() to a %d byte buffer, got 0)\n", bufsize));
189 return EOF;
193 /* If fh_End == 0, simulate an EOF */
194 if (fh->fh_End == 0) {
195 D(bug("FGetC: Got an EOF via fh_End == 0\n"));
196 return EOF;
199 /* All OK. Get requested data. */
200 size = fh->fh_End - fh->fh_Pos;
201 if (size > fetchsize) size = fetchsize;
202 if (size == 1) /* Don't do function call for 1 byte reads */
203 *buffer = ((UBYTE *)BADDR(fh->fh_Buf))[fh->fh_Pos];
204 else
205 CopyMem(((UBYTE *)BADDR(fh->fh_Buf)) + fh->fh_Pos, buffer, size);
207 fh->fh_Pos += size;
209 return size;