Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / lib / DtHelp / bufio.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /*
24  * $XConsortium: bufio.c /main/5 1996/11/01 10:11:35 drk $
25  *
26  * Copyright 1991 Massachusetts Institute of Technology
27  *
28  * Permission to use, copy, modify, distribute, and sell this software and its
29  * documentation for any purpose is hereby granted without fee, provided that
30  * the above copyright notice appear in all copies and that both that
31  * copyright notice and this permission notice appear in supporting
32  * documentation, and that the name of M.I.T. not be used in advertising or
33  * publicity pertaining to distribution of the software without specific,
34  * written prior permission.  M.I.T. makes no representations about the
35  * suitability of this software for any purpose.  It is provided "as is"
36  * without express or implied warranty.
37  *
38  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
39  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
40  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
41  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
42  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
43  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
44  *
45  * Author:  Keith Packard, MIT X Consortium
46  */
47
48
49 /* #include    "fontmisc.h" */
50 #include    <errno.h>
51 #include    <stdio.h>
52 #include    <stdlib.h>
53 #include    <unistd.h>
54 #include    "bufioI.h"
55
56 #include <X11/Xos.h>
57 #ifdef X_NOT_STDC_ENV
58 extern int errno;
59 #endif
60
61 #ifndef MIN
62 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
63 #endif
64
65 #define FileDes(f)              ((int) (f)->hidden)
66 #define CompressFileDes(f)      (((CECompressInfoPtr) (f)->hidden)->fd)
67 #define CompressSize(f)         (((CECompressInfoPtr) (f)->hidden)->size)
68
69 static int
70 BufFileRawSkip (
71     BufFilePtr  f,
72     int         count )
73 {
74     int     curoff;
75     int     fileoff;
76     int     todo;
77
78     curoff = f->bufp - f->buffer;
79     fileoff = curoff + f->left;
80     if (curoff + count <= fileoff) {
81         f->bufp += count;
82         f->left -= count;
83     } else {
84         todo = count - (fileoff - curoff);
85         if (lseek (FileDes(f), todo, 1) == -1) {
86             if (errno != ESPIPE)
87                 return BUFFILEEOF;
88             while (todo) {
89                 curoff = BUFFILESIZE;
90                 if (curoff > todo)
91                     curoff = todo;
92                 fileoff = read (FileDes(f), f->buffer, curoff);
93                 if (fileoff <= 0)
94                     return BUFFILEEOF;
95                 todo -= fileoff;
96             }
97         }
98         f->left = 0;
99     }
100     return count;
101 }
102
103 static
104 BufFileRawFlush (
105     int         c,
106     BufFilePtr  f )
107 {
108     int cnt;
109
110     if (c != BUFFILEEOF)
111         *f->bufp++ = c;
112     cnt = f->bufp - f->buffer;
113     f->bufp = f->buffer;
114     f->left = BUFFILESIZE;
115     if (write (FileDes(f), f->buffer, cnt) != cnt)
116         return BUFFILEEOF;
117     return c;
118 }
119
120 BufFilePtr
121 _DtHelpCeBufFileOpenWr (int fd)
122 {
123     BufFilePtr  f;
124
125     f = _DtHelpCeBufFileCreate ((char *) fd, BufFileRawFlush, NULL, _DtHelpCeBufFileFlush);
126     f->bufp = f->buffer;
127     f->left = BUFFILESIZE;
128     return f;
129 }
130
131 #ifdef  obsolete_function
132 _DtHelpCeBufFileWrite (
133     BufFilePtr  f,
134     char        *b,
135     int         n )
136 {
137     int     cnt;
138     cnt = n;
139     while (cnt--) {
140         if (BufFilePut (*b++, f) == BUFFILEEOF)
141             return BUFFILEEOF;
142     }
143     return n;
144 }
145 #endif
146
147 int
148 _DtHelpCeBufFileFlush (BufFilePtr f, int doClose)
149 {
150     if (f->bufp != f->buffer)
151         (*f->io) (BUFFILEEOF, f);
152
153     if (doClose)
154         return (close (FileDes(f)));
155
156     return 0;
157 }
158
159 /*****************************************************************************
160  *                      Private Routines
161  *****************************************************************************/
162 /*****************************************************************************
163  *                      Routines working on a File descriptor
164  *****************************************************************************/
165 static int
166 FdRawRead (BufFilePtr f)
167 {
168     int left;
169
170     left = read (FileDes(f), f->buffer, BUFFILESIZE);
171     if (left <= 0) {
172         f->left = 0;
173         return BUFFILEEOF;
174     }
175     f->left = left - 1;
176     f->bufp = f->buffer + 1;
177     return f->buffer[0];
178 }
179
180 static  int
181 FdClose (
182     BufFilePtr  f,
183     int         doClose)
184 {
185     if (doClose)
186         close (FileDes (f));
187     return 1;
188 }
189
190 /*****************************************************************************
191  *                      Routines working on a Raw Compressed file
192  *****************************************************************************/
193 static int
194 CompressRawRead (BufFilePtr f)
195 {
196     int left;
197
198
199     left = read (CompressFileDes(f), f->buffer,
200                                         MIN(CompressSize(f),BUFFILESIZE));
201     if (left <= 0) {
202         f->left = 0;
203         CompressSize(f) = 0;
204         return BUFFILEEOF;
205     }
206     CompressSize(f) -= left;
207     f->left = left - 1;
208     f->bufp = f->buffer + 1;
209     return f->buffer[0];
210 }
211
212 static  int
213 CompressRawClose (
214     BufFilePtr  f,
215     int         doClose)
216 {
217     if (doClose)
218         close (CompressFileDes (f));
219     free(f->hidden);
220     return 1;
221 }
222
223 /*****************************************************************************
224  *                      Routines working on a Pipe
225  *****************************************************************************/
226 /*****************************************************************************
227  * Function:    int RdPipeStream (BufFilePtr f)
228  *
229  * Returns:
230  *
231  * Purpose:
232  *
233  *****************************************************************************/
234 static int
235 RdPipeStream (BufFilePtr f)
236 {
237     int    left;
238
239     left = fread(f->buffer, 1, BUFFILESIZE, FileStream(f));
240
241     if (left <= 0)
242       {
243         f->left = 0;
244         return BUFFILEEOF;
245       }
246
247     clearerr(FileStream(f));
248     f->left = left - 1;
249     f->bufp = f->buffer + 1;
250     return f->buffer[0];
251 }
252
253 /*********************************************************************
254  * Procedure: int ClosePipeStream (BufFilePtr f);
255  *
256  * Returns:
257  *
258  * Purpose:
259  *
260  ********************************************************************/
261 static int
262 ClosePipeStream (
263     BufFilePtr  f,
264     int         doClose)
265 {
266     if (doClose)
267         pclose(FileStream(f));
268
269     return 1;
270 }
271
272 /*****************************************************************************
273  *                      Semi-Public Routines
274  *****************************************************************************/
275 /*****************************************************************************
276  * Function:    BufFilePtr _DtHelpCeBufFileCreate (char *hidden,
277  *                                      int (*io)(), int (*skip)(),
278  *                                      int (*close)())
279  *
280  * Returns:     A pointer to malloc'ed memory or NULL.
281  *
282  * Purpose:     Create a buffered i/o mechanism.
283  *
284  *****************************************************************************/
285 BufFilePtr
286 _DtHelpCeBufFileCreate (
287     char    *hidden,
288     int     (*io)(),
289     int     (*skip)(),
290     int     (*close)() )
291 {
292     BufFilePtr  f;
293
294     f = (BufFilePtr) malloc (sizeof *f);
295     if (!f)
296         return 0;
297     f->hidden = hidden;
298     f->bufp = f->buffer;
299     f->left = 0;
300     f->io = io;
301     f->skip = skip;
302     f->close = close;
303     return f;
304 }
305
306 /*****************************************************************************
307  * Function:    BufFilePtr _DtHelpCeBufFileRdWithFd (int fd)
308  *
309  * Returns:     A pointer to malloc'ed memory or NULL.
310  *
311  * Purpose:     Create a buffered i/o mechanism using a file descriptor
312  *              as private data and attaching a raw read to the i/o
313  *              routine.
314  *
315  *****************************************************************************/
316 BufFilePtr
317 _DtHelpCeBufFileRdWithFd (int fd)
318 {
319     return _DtHelpCeBufFileCreate ((char *) fd, FdRawRead, BufFileRawSkip, FdClose);
320 }
321
322 /*****************************************************************************
323  * Function:    BufFilePtr _DtHelpCeBufFileRdRawZ (CECompressInfoPtr file)
324  *
325  * Returns:     A pointer to malloc'ed memory or NULL.
326  *
327  * Purpose:     Create a buffered i/o mechanism using a file descriptor
328  *              as private data and attaching a raw read of compressed
329  *              data to the i/o routine.
330  *
331  *****************************************************************************/
332 BufFilePtr
333 _DtHelpCeBufFileRdRawZ (CECompressInfoPtr file)
334 {
335     return _DtHelpCeBufFileCreate ((char *) file, CompressRawRead, NULL,
336                                                         CompressRawClose);
337 }
338
339 /*****************************************************************************
340  * Function:    void _DtHelpCeBufFileClose (BufFilePtr file, int doClose)
341  *
342  * Returns:     nothing
343  *
344  * Purpose:     Calls the close routine associated with the pointer.
345  *              Frees the BufFile information.
346  *
347  *****************************************************************************/
348 void
349 _DtHelpCeBufFileClose (
350     BufFilePtr  f,
351     int         doClose )
352 {
353     (void) (*f->close) (f, doClose);
354     free (f);
355 }
356
357 /*****************************************************************************
358  * Function:    void _DtHelpCeBufFileRd (BufFilePtr file, int doClose)
359  *
360  * Returns:     nothing
361  *
362  * Purpose:     Calls the close routine associated with the pointer.
363  *              Frees the BufFile information.
364  *
365  *****************************************************************************/
366 int
367 _DtHelpCeBufFileRd (
368     BufFilePtr  f,
369     char        *b,
370     int         n )
371 {
372     int     c, cnt;
373     cnt = n;
374     while (cnt--) {
375         c = BufFileGet (f);
376         if (c == BUFFILEEOF)
377             break;
378         *b++ = c;
379     }
380     return n - cnt - 1;
381 }
382
383 /*****************************************************************************
384  * Function:    BufFilePtr _DtHelpCeCreatePipeBufFile (FILE *stream)
385  *
386  * Returns:     A pointer to malloc'ed memory or NULL.
387  *
388  * Purpose:     Create a buffered i/o mechanism using a pipe descriptor
389  *              as private data and attaching a raw read to the i/o
390  *              routine.
391  *
392  *****************************************************************************/
393 BufFilePtr
394 _DtHelpCeCreatePipeBufFile (FILE *stream)
395 {
396     return _DtHelpCeBufFileCreate ((char *) stream,
397                                         RdPipeStream, NULL, ClosePipeStream);
398 }