2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
8 #include <aros/debug.h>
10 #include "dos_intern.h"
14 /*****************************************************************************
17 #include <proto/dos.h>
22 AROS_LHA(BPTR
, fh
, D1
),
23 AROS_LHA(APTR
, block
, D2
),
24 AROS_LHA(ULONG
, blocklen
, D3
),
25 AROS_LHA(ULONG
, number
, D4
),
28 struct DosLibrary
*, DOSBase
, 54, Dos
)
31 Read a number of blocks from a file.
34 fh - Read from this file
35 block - The data is put here
36 blocklen - This is the size of a single block
37 number - The number of blocks
40 The number of blocks read from the file or 0 on EOF.
41 This function may return fewer than the requested number of blocks.
42 IoErr() gives additional information in case of an error.
51 Open(), FWrite(), FPutc(), Close()
55 *****************************************************************************/
61 ULONG fetchsize
= number
* blocklen
;
68 if((fetchsize
== 0) || (fh
== BNULL
))
73 res
= vbuf_fetch(fh
, ptr
, fetchsize
, DOSBase
);
85 readsize
= (ULONG
)(ptr
- (UBYTE
*)block
);
88 return (LONG
)(readsize
/ blocklen
);
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). */
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. */
116 /* Reinit filehandle. */
117 fh
->fh_Flags
&= ~FHF_WRITE
;
118 fh
->fh_Pos
= fh
->fh_End
= 0;
124 /* Fetches up to remaining buffer content from file buffer
128 * (>0) on sucesfull 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
);
143 if (handle_write_mode(file
, DOSBase
) == 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
));
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"));
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"));
174 bufsize
= fh
->fh_BufSize
;
176 size
= Read(file
, BADDR(fh
->fh_Buf
), bufsize
);
178 /* Prepare filehandle for data. */
185 /* No data read? Return EOF. */
188 D(bug("FGetC: Tried to Read() to a %d byte buffer, got 0)\n", bufsize
));
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"));
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
];
205 CopyMem(((UBYTE
*)BADDR(fh
->fh_Buf
)) + fh
->fh_Pos
, buffer
, size
);