Commit of the code which was suggested by Georg as a fix for:
[cake.git] / rom / dos / fwrite.c
blobd5dd36a1424033696bee91dafe413905a05ad9ee
1 /*
2 Copyright © 1995-2008, 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 Write a number of blocks to a file.
32 INPUTS
33 fh - Write to this file
34 block - The data begins here
35 blocklen - number of bytes per block. Must be > 0.
36 numblocks - number of blocks to write. Must be > 0.
38 RESULT
39 The number of blocks written to the file or EOF on error. IoErr()
40 gives additional information in case of an error.
42 SEE ALSO
43 Open(), FRead(), FPutc(), Close()
45 *****************************************************************************/
47 AROS_LIBFUNC_INIT
49 ASSERT_VALID_PTR(fh);
50 ASSERT_VALID_PTR(block);
51 ASSERT(blocklen > 0);
52 ASSERT(numblocks > 0);
54 ULONG len, written;
55 const UBYTE *ptr;
57 ptr = block;
58 len = 0;
60 SetIoErr(0);
62 for(written = 0; written < numblocks; written++)
64 if (FWriteChars(fh, ptr, blocklen, DOSBase) != blocklen)
66 return(EOF);
68 else
70 ptr += blocklen;
74 return written;
76 AROS_LIBFUNC_EXIT
77 } /* FWrite */
80 LONG
81 FWriteChars(BPTR file, CONST UBYTE* buffer, ULONG length, struct DosLibrary *DOSBase)
83 ASSERT_VALID_PTR(BADDR(file));
84 ASSERT_VALID_PTR(buffer);
86 /* Get pointer to filehandle. */
87 struct FileHandle *fh = (struct FileHandle *)BADDR(file);
89 /* Check if file is in write mode */
90 if (!(fh->fh_Flags & FHF_WRITE))
92 if (fh->fh_Pos < fh->fh_End)
94 /* Read mode. Try to seek back to the current position. */
95 if (Seek(file, fh->fh_Pos - fh->fh_End, OFFSET_CURRENT) < 0)
97 fh->fh_Pos = fh->fh_End = fh->fh_Buf;
99 return EOF;
103 /* Is there a buffer? */
104 if (fh->fh_Buf == NULL)
106 if (vbuf_alloc(fh, IOBUFSIZE, DOSBase) == NULL)
108 return(EOF);
112 /* Prepare buffer */
113 fh->fh_Flags |= FHF_WRITE;
115 fh->fh_Pos = fh->fh_Buf;
116 fh->fh_End = fh->fh_Buf + fh->fh_Size;
119 LONG
120 written = -1;
122 if (fh->fh_Flags & FHF_NOBUF)
124 LONG
125 goOn = TRUE;
127 if (fh->fh_Pos != fh->fh_Buf)
129 goOn = Flush(file);
132 if (goOn)
134 written = Write(file, buffer, length);
137 else
139 for (written = 0; written < length; ++written)
141 /* Check if there is still some space in the buffer */
142 if (fh->fh_Pos >= fh->fh_End)
144 if (!Flush(file))
146 written = -1;
147 break;
151 /* Write data */
152 *fh->fh_Pos++ = buffer[written];
154 if (fh->fh_Flags & FHF_LINEBUF
155 && (buffer[written] == '\n' || buffer[written] == '\r'
156 || buffer[written] == '\0'))
158 if (!Flush(file))
160 written = -1;
161 break;
167 return(written);