bump version
[AROS.git] / rom / dos / fwrite.c
blobc7770444bc32a912735e1604c025839b9129fdc5
1 /*
2 Copyright © 1995-2013, The AROS Development Team. All rights reserved.
3 $Id$
5 Lang: english
6 */
7 #include "dos_intern.h"
9 #include <aros/debug.h>
12 /*****************************************************************************
14 NAME */
15 #include <proto/dos.h>
17 AROS_LH4(LONG, FWrite,
18 /* FWrite -- Writes a number of blocks to an output (buffered) */
20 /* SYNOPSIS */
21 AROS_LHA(BPTR , fh, D1),
22 AROS_LHA(CONST_APTR , block, D2),
23 AROS_LHA(ULONG, blocklen, D3),
24 AROS_LHA(ULONG, numblocks, D4),
26 /* LOCATION */
27 struct DosLibrary *, DOSBase, 55, Dos)
29 /* FUNCTION
30 Buffered write of a number of blocks to a stream.
31 May write fewer blocks than requested.
33 INPUTS
34 fh - Write to this file
35 block - The data begins here
36 blocklen - number of bytes per block. Must be > 0.
37 numblocks - number of blocks to write. Must be > 0.
39 RESULT
40 The number of blocks written to the file or EOF on error. IoErr()
41 gives additional information in case of an error.
43 NOTES
44 Some releases of AmigaOS may not clear IoErr(), while AROS
45 does. For full backwards compatibility, you may want to call
46 SetIoErr(0L) before FWrite() if you need to be able to check
47 the error code.
49 EXAMPLE
51 BUGS
53 SEE ALSO
54 Open(), FRead(), FPutc(), Close()
56 *****************************************************************************/
58 AROS_LIBFUNC_INIT
60 ASSERT_VALID_PTR(BADDR(fh));
61 ASSERT_VALID_PTR(block);
62 ASSERT(blocklen > 0);
63 ASSERT(numblocks > 0);
65 ULONG written;
66 const UBYTE *ptr;
68 ptr = block;
70 SetIoErr(0);
72 for(written = 0; written < numblocks; written++)
74 if (FWriteChars(fh, ptr, blocklen, DOSBase) != blocklen)
76 return(EOF);
78 else
80 ptr += blocklen;
84 return written;
86 AROS_LIBFUNC_EXIT
87 } /* FWrite */
90 LONG
91 FWriteChars(BPTR file, CONST UBYTE* buffer, ULONG length, struct DosLibrary *DOSBase)
93 ASSERT_VALID_PTR(BADDR(file));
94 ASSERT_VALID_PTR(buffer);
96 /* Get pointer to filehandle. */
97 struct FileHandle *fh = (struct FileHandle *)BADDR(file);
99 if (fh == NULL)
100 return EOF;
102 /* Check if file is in write mode */
103 if (!(fh->fh_Flags & FHF_WRITE))
105 if (fh->fh_Pos < fh->fh_End)
107 /* Read mode. Try to seek back to the current position. */
108 if (Seek(file, fh->fh_Pos - fh->fh_End, OFFSET_CURRENT) < 0)
110 fh->fh_Pos = fh->fh_End = 0;
112 return EOF;
116 /* Is there a buffer? */
117 if (fh->fh_Buf == BNULL)
119 if (vbuf_alloc(fh, NULL, IOBUFSIZE) == NULL)
121 return(EOF);
125 /* Prepare buffer */
126 fh->fh_Flags |= FHF_WRITE;
128 fh->fh_Pos = 0;
129 fh->fh_End = fh->fh_BufSize;
132 LONG
133 written = -1;
135 if (fh->fh_Flags & FHF_NOBUF)
137 LONG
138 goOn = TRUE;
140 if (fh->fh_Pos != 0)
142 goOn = Flush(file);
145 if (goOn)
147 written = Write(file, buffer, length);
150 else
152 for (written = 0; written < length; ++written)
154 /* Check if there is still some space in the buffer */
155 if (fh->fh_Pos >= fh->fh_End)
157 if (!Flush(file))
159 written = -1;
160 break;
164 /* Write data */
165 ((UBYTE *)BADDR(fh->fh_Buf))[fh->fh_Pos++] = buffer[written];
167 if (fh->fh_Flags & FHF_LINEBUF
168 && (buffer[written] == '\n' || buffer[written] == '\r'
169 || buffer[written] == '\0'))
171 if (!Flush(file))
173 written = -1;
174 break;
180 return(written);