bufio.c revision 23a0898a
1/* $Xorg: bufio.c,v 1.4 2001/02/09 02:04:03 xorgcvs Exp $ */
2
3/*
4
5Copyright 1991, 1998  The Open Group
6
7Permission to use, copy, modify, distribute, and sell this software and its
8documentation for any purpose is hereby granted without fee, provided that
9the above copyright notice appear in all copies and that both that
10copyright notice and this permission notice appear in supporting
11documentation.
12
13The above copyright notice and this permission notice shall be included
14in all copies or substantial portions of the Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
20OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22OTHER DEALINGS IN THE SOFTWARE.
23
24Except as contained in this notice, the name of The Open Group shall
25not be used in advertising or otherwise to promote the sale, use or
26other dealings in this Software without prior written authorization
27from The Open Group.
28
29*/
30/* $XFree86: xc/lib/font/fontfile/bufio.c,v 3.9 2001/12/14 19:56:50 dawes Exp $ */
31
32/*
33 * Author:  Keith Packard, MIT X Consortium
34 */
35
36
37#ifdef HAVE_CONFIG_H
38#include <config.h>
39#endif
40#include <X11/Xos.h>
41#include <X11/fonts/fontmisc.h>
42#include <X11/fonts/bufio.h>
43#include <errno.h>
44
45BufFilePtr
46BufFileCreate (char *private,
47	       int (*input)(BufFilePtr),
48	       int (*output)(int, BufFilePtr),
49	       int (*skip)(BufFilePtr, int),
50	       int (*close)(BufFilePtr, int))
51{
52    BufFilePtr	f;
53
54    f = (BufFilePtr) xalloc (sizeof *f);
55    if (!f)
56	return 0;
57    f->private = private;
58    f->bufp = f->buffer;
59    f->left = 0;
60    f->input = input;
61    f->output = output;
62    f->skip = skip;
63    f->eof  = 0;
64    f->close = close;
65    return f;
66}
67
68#define FileDes(f)  ((int)(long) (f)->private)
69
70static int
71BufFileRawFill (BufFilePtr f)
72{
73    int	left;
74
75    left = read (FileDes(f), (char *)f->buffer, BUFFILESIZE);
76    if (left <= 0) {
77	f->left = 0;
78	return BUFFILEEOF;
79    }
80    f->left = left - 1;
81    f->bufp = f->buffer + 1;
82    return f->buffer[0];
83}
84
85static int
86BufFileRawSkip (BufFilePtr f, int count)
87{
88    int	    curoff;
89    int	    fileoff;
90    int	    todo;
91
92    curoff = f->bufp - f->buffer;
93    fileoff = curoff + f->left;
94    if (curoff + count <= fileoff) {
95	f->bufp += count;
96	f->left -= count;
97    } else {
98	todo = count - (fileoff - curoff);
99	if (lseek (FileDes(f), todo, 1) == -1) {
100	    if (errno != ESPIPE)
101		return BUFFILEEOF;
102	    while (todo) {
103		curoff = BUFFILESIZE;
104		if (curoff > todo)
105		    curoff = todo;
106		fileoff = read (FileDes(f), (char *)f->buffer, curoff);
107		if (fileoff <= 0)
108		    return BUFFILEEOF;
109		todo -= fileoff;
110	    }
111	}
112	f->left = 0;
113    }
114    return count;
115}
116
117static int
118BufFileRawClose (BufFilePtr f, int doClose)
119{
120    if (doClose)
121	close (FileDes (f));
122    return 1;
123}
124
125BufFilePtr
126BufFileOpenRead (int fd)
127{
128#if defined(__UNIXOS2__) || defined (WIN32)
129    /* hv: I'd bet WIN32 has the same effect here */
130    setmode(fd,O_BINARY);
131#endif
132    return BufFileCreate ((char *)(long) fd, BufFileRawFill, 0, BufFileRawSkip, BufFileRawClose);
133}
134
135static int
136BufFileRawFlush (int c, BufFilePtr f)
137{
138    int	cnt;
139
140    if (c != BUFFILEEOF)
141	*f->bufp++ = c;
142    cnt = f->bufp - f->buffer;
143    f->bufp = f->buffer;
144    f->left = BUFFILESIZE;
145    if (write (FileDes(f), (char *)f->buffer, cnt) != cnt)
146	return BUFFILEEOF;
147    return c;
148}
149
150static int
151BufFileFlush (BufFilePtr f, int doClose)
152{
153    if (f->bufp != f->buffer)
154	return (*f->output) (BUFFILEEOF, f);
155    return 0;
156}
157
158BufFilePtr
159BufFileOpenWrite (int fd)
160{
161    BufFilePtr	f;
162
163#if defined(__UNIXOS2__) || defined(WIN32)
164    /* hv: I'd bet WIN32 has the same effect here */
165    setmode(fd,O_BINARY);
166#endif
167    f = BufFileCreate ((char *)(long) fd, 0, BufFileRawFlush, 0, BufFileFlush);
168    f->bufp = f->buffer;
169    f->left = BUFFILESIZE;
170    return f;
171}
172
173int
174BufFileRead (BufFilePtr f, char *b, int n)
175{
176    int	    c, cnt;
177    cnt = n;
178    while (cnt--) {
179	c = BufFileGet (f);
180	if (c == BUFFILEEOF)
181	    break;
182	*b++ = c;
183    }
184    return n - cnt - 1;
185}
186
187int
188BufFileWrite (BufFilePtr f, char *b, int n)
189{
190    int	    cnt;
191    cnt = n;
192    while (cnt--) {
193	if (BufFilePut (*b++, f) == BUFFILEEOF)
194	    return BUFFILEEOF;
195    }
196    return n;
197}
198
199int
200BufFileClose (BufFilePtr f, int doClose)
201{
202    int ret;
203    ret = (*f->close) (f, doClose);
204    xfree (f);
205    return ret;
206}
207