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.
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
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.
52 Open(), FWrite(), FPutc(), Close()
56 *****************************************************************************/
62 ULONG fetchsize
= number
* blocklen
;
69 if((fetchsize
== 0) || (fh
== BNULL
))
74 res
= vbuf_fetch(fh
, ptr
, fetchsize
, DOSBase
);
86 readsize
= (ULONG
)(ptr
- (UBYTE
*)block
);
89 return (LONG
)(readsize
/ blocklen
);
94 static LONG
handle_write_mode(BPTR file
, struct DosLibrary
* DOSBase
)
96 struct FileHandle
*fh
= (struct FileHandle
*)BADDR(file
);
98 /* If the file is in write mode... */
99 if(fh
->fh_Flags
& FHF_WRITE
)
101 /* write the buffer (in many pieces if the first one isn't enough). */
104 while(pos
!= fh
->fh_Pos
)
106 LONG size
= Write(file
, BADDR(fh
->fh_Buf
) + pos
, fh
->fh_Pos
- pos
);
108 /* An error happened? Return it. */
117 /* Reinit filehandle. */
118 fh
->fh_Flags
&= ~FHF_WRITE
;
119 fh
->fh_Pos
= fh
->fh_End
= 0;
125 /* Fetches up to remaining buffer content from file buffer
129 * (>0) on sucesfull fetch
131 LONG
vbuf_fetch(BPTR file
, UBYTE
* buffer
, ULONG fetchsize
, struct DosLibrary
*DOSBase
)
133 /* Get pointer to filehandle */
134 struct FileHandle
*fh
= (struct FileHandle
*)BADDR(file
);
144 if (handle_write_mode(file
, DOSBase
) == FETCHERR
)
149 /* No normal characters left. */
150 if(fh
->fh_Pos
>= fh
->fh_End
)
152 /* Check for a pushed back EOF. */
153 if(fh
->fh_Pos
> fh
->fh_End
)
155 D(bug("FGetC: Weird pos: fh_Pos (%d) > fh_End (%d)\n", fh
->fh_Pos
, fh
->fh_End
));
160 /* Is there a buffer? */
161 if(fh
->fh_Buf
== BNULL
)
163 if (NULL
== vbuf_alloc(fh
, NULL
, IOBUFSIZE
))
165 D(bug("FGetC: Can't allocate buffer\n"));
170 /* Fill the buffer. */
171 if (fh
->fh_Buf
!= fh
->fh_OrigBuf
) {
172 D(bug("FGetC: Can't trust fh_BufSize. Using 208 as the buffer size.\n"));
175 bufsize
= fh
->fh_BufSize
;
177 size
= Read(file
, BADDR(fh
->fh_Buf
), bufsize
);
179 /* Prepare filehandle for data. */
186 /* No data read? Return EOF. */
189 D(bug("FGetC: Tried to Read() to a %d byte buffer, got 0)\n", bufsize
));
194 /* If fh_End == 0, simulate an EOF */
195 if (fh
->fh_End
== 0) {
196 D(bug("FGetC: Got an EOF via fh_End == 0\n"));
200 /* All OK. Get requested data. */
201 size
= fh
->fh_End
- fh
->fh_Pos
;
202 if (size
> fetchsize
) size
= fetchsize
;
203 if (size
== 1) /* Don't do function call for 1 byte reads */
204 *buffer
= ((UBYTE
*)BADDR(fh
->fh_Buf
))[fh
->fh_Pos
];
206 CopyMem(((UBYTE
*)BADDR(fh
->fh_Buf
)) + fh
->fh_Pos
, buffer
, size
);