Imported Upstream version 0.19.7
[platform/upstream/gettext.git] / gettext-tools / gnulib-lib / fd-ostream.c
1 /* DO NOT EDIT! GENERATED AUTOMATICALLY! */
2
3 #line 1 "fd-ostream.oo.c"
4 /* Output stream referring to a file descriptor.
5    Copyright (C) 2006-2007, 2015 Free Software Foundation, Inc.
6    Written by Bruno Haible <bruno@clisp.org>, 2006.
7
8    This program is free software: you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20
21 #include <config.h>
22
23 /* Specification.  */
24 #include "fd-ostream.h"
25
26 #include <assert.h>
27 #include <errno.h>
28 #include <stdlib.h>
29 #include <string.h>
30
31 #include "error.h"
32 #include "full-write.h"
33 #include "xalloc.h"
34 #include "gettext.h"
35
36 #define _(str) gettext (str)
37
38 #line 39 "fd-ostream.c"
39 #if !IS_CPLUSPLUS
40 #define fd_ostream_representation any_ostream_representation
41 #endif
42 #include "fd_ostream.priv.h"
43
44 const typeinfo_t fd_ostream_typeinfo = { "fd_ostream" };
45
46 static const typeinfo_t * const fd_ostream_superclasses[] =
47   { fd_ostream_SUPERCLASSES };
48
49 #define super ostream_vtable
50
51 #line 43 "fd-ostream.oo.c"
52
53 #define BUFSIZE 4096
54
55 /* Implementation of ostream_t methods.  */
56
57 static void
58 fd_ostream__write_mem (fd_ostream_t stream, const void *data, size_t len)
59 {
60   if (len > 0)
61     {
62       if (stream->buffer != NULL)
63         {
64           /* Buffered.  */
65           assert (stream->avail > 0);
66           #if 0 /* unoptimized */
67           do
68             {
69               size_t n = (len <= stream->avail ? len : stream->avail);
70               if (n > 0)
71                 {
72                   memcpy (stream->buffer + BUFSIZE - stream->avail, data, n);
73                   data = (char *) data + n;
74                   stream->avail -= n;
75                   len -= n;
76                 }
77               if (stream->avail == 0)
78                 {
79                   if (full_write (stream->fd, stream->buffer, BUFSIZE) < BUFSIZE)
80                     error (EXIT_FAILURE, errno, _("error writing to %s"),
81                            stream->filename);
82                   stream->avail = BUFSIZE;
83                 }
84             }
85           while (len > 0);
86           #else /* optimized */
87           if (len < stream->avail)
88             {
89               /* Move the data into the buffer.  */
90               memcpy (stream->buffer + BUFSIZE - stream->avail, data, len);
91               stream->avail -= len;
92             }
93           else
94             {
95               /* Split the data into:
96                    - a first chunk, which is added to the buffer and output,
97                    - a series of chunks of size BUFSIZE, which can be output
98                      directly, without going through the buffer, and
99                    - a last chunk, which is copied to the buffer.  */
100               size_t n = stream->avail;
101               memcpy (stream->buffer + BUFSIZE - stream->avail, data, n);
102               data = (char *) data + n;
103               len -= n;
104               if (full_write (stream->fd, stream->buffer, BUFSIZE) < BUFSIZE)
105                 error (EXIT_FAILURE, errno, _("error writing to %s"),
106                        stream->filename);
107
108               while (len >= BUFSIZE)
109                 {
110                   if (full_write (stream->fd, data, BUFSIZE) < BUFSIZE)
111                     error (EXIT_FAILURE, errno, _("error writing to %s"),
112                            stream->filename);
113                   data = (char *) data + BUFSIZE;
114                   len -= BUFSIZE;
115                 }
116
117               if (len > 0)
118                 memcpy (stream->buffer, data, len);
119               stream->avail = BUFSIZE - len;
120             }
121           #endif
122           assert (stream->avail > 0);
123         }
124       else
125         {
126           /* Unbuffered.  */
127           if (full_write (stream->fd, data, len) < len)
128             error (EXIT_FAILURE, errno, _("error writing to %s"),
129                    stream->filename);
130         }
131     }
132 }
133
134 static void
135 fd_ostream__flush (fd_ostream_t stream)
136 {
137   if (stream->buffer != NULL && stream->avail < BUFSIZE)
138     {
139       size_t filled = BUFSIZE - stream->avail;
140       if (full_write (stream->fd, stream->buffer, filled) < filled)
141         error (EXIT_FAILURE, errno, _("error writing to %s"), stream->filename);
142       stream->avail = BUFSIZE;
143     }
144 }
145
146 static void
147 fd_ostream__free (fd_ostream_t stream)
148 {
149   fd_ostream_flush (stream);
150   free (stream->filename);
151   free (stream);
152 }
153
154 /* Constructor.  */
155
156 fd_ostream_t
157 fd_ostream_create (int fd, const char *filename, bool buffered)
158 {
159   fd_ostream_t stream =
160     (struct fd_ostream_representation *)
161     xmalloc (sizeof (struct fd_ostream_representation)
162              + (buffered ? BUFSIZE : 0));
163
164   stream->base.vtable = &fd_ostream_vtable;
165   stream->fd = fd;
166   stream->filename = xstrdup (filename);
167   if (buffered)
168     {
169       stream->buffer =
170         (char *) (void *) stream + sizeof (struct fd_ostream_representation);
171       stream->avail = BUFSIZE;
172     }
173   else
174     stream->buffer = NULL;
175
176   return stream;
177 }
178
179 #line 180 "fd-ostream.c"
180
181 const struct fd_ostream_implementation fd_ostream_vtable =
182 {
183   fd_ostream_superclasses,
184   sizeof (fd_ostream_superclasses) / sizeof (fd_ostream_superclasses[0]),
185   sizeof (struct fd_ostream_representation),
186   fd_ostream__write_mem,
187   fd_ostream__flush,
188   fd_ostream__free,
189 };
190
191 #if !HAVE_INLINE
192
193 /* Define the functions that invoke the methods.  */
194
195 void
196 fd_ostream_write_mem (fd_ostream_t first_arg, const void *data, size_t len)
197 {
198   const struct fd_ostream_implementation *vtable =
199     ((struct fd_ostream_representation_header *) (struct fd_ostream_representation *) first_arg)->vtable;
200   vtable->write_mem (first_arg,data,len);
201 }
202
203 void
204 fd_ostream_flush (fd_ostream_t first_arg)
205 {
206   const struct fd_ostream_implementation *vtable =
207     ((struct fd_ostream_representation_header *) (struct fd_ostream_representation *) first_arg)->vtable;
208   vtable->flush (first_arg);
209 }
210
211 void
212 fd_ostream_free (fd_ostream_t first_arg)
213 {
214   const struct fd_ostream_implementation *vtable =
215     ((struct fd_ostream_representation_header *) (struct fd_ostream_representation *) first_arg)->vtable;
216   vtable->free (first_arg);
217 }
218
219 #endif