123a0898aSmrg/*
223a0898aSmrg
323a0898aSmrgCopyright 1991, 1998  The Open Group
423a0898aSmrg
523a0898aSmrgPermission to use, copy, modify, distribute, and sell this software and its
623a0898aSmrgdocumentation for any purpose is hereby granted without fee, provided that
723a0898aSmrgthe above copyright notice appear in all copies and that both that
823a0898aSmrgcopyright notice and this permission notice appear in supporting
923a0898aSmrgdocumentation.
1023a0898aSmrg
1123a0898aSmrgThe above copyright notice and this permission notice shall be included
1223a0898aSmrgin all copies or substantial portions of the Software.
1323a0898aSmrg
1423a0898aSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1523a0898aSmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1623a0898aSmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
1723a0898aSmrgIN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
1823a0898aSmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
1923a0898aSmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2023a0898aSmrgOTHER DEALINGS IN THE SOFTWARE.
2123a0898aSmrg
2223a0898aSmrgExcept as contained in this notice, the name of The Open Group shall
2323a0898aSmrgnot be used in advertising or otherwise to promote the sale, use or
2423a0898aSmrgother dealings in this Software without prior written authorization
2523a0898aSmrgfrom The Open Group.
2623a0898aSmrg
2723a0898aSmrg*/
2823a0898aSmrg
2923a0898aSmrg/*
3023a0898aSmrg * Author:  Keith Packard, MIT X Consortium
3123a0898aSmrg */
3223a0898aSmrg
3323a0898aSmrg
3423a0898aSmrg#ifdef HAVE_CONFIG_H
3523a0898aSmrg#include <config.h>
3623a0898aSmrg#endif
3723a0898aSmrg#include <X11/Xos.h>
3823a0898aSmrg#include <X11/fonts/fontmisc.h>
3923a0898aSmrg#include <X11/fonts/bufio.h>
4023a0898aSmrg#include <errno.h>
4123a0898aSmrg
4223a0898aSmrgBufFilePtr
4323a0898aSmrgBufFileCreate (char *private,
4423a0898aSmrg	       int (*input)(BufFilePtr),
4523a0898aSmrg	       int (*output)(int, BufFilePtr),
4623a0898aSmrg	       int (*skip)(BufFilePtr, int),
4723a0898aSmrg	       int (*close)(BufFilePtr, int))
4823a0898aSmrg{
4923a0898aSmrg    BufFilePtr	f;
5023a0898aSmrg
517f7f5e4eSmrg    f = malloc (sizeof *f);
5223a0898aSmrg    if (!f)
5323a0898aSmrg	return 0;
5423a0898aSmrg    f->private = private;
5523a0898aSmrg    f->bufp = f->buffer;
5623a0898aSmrg    f->left = 0;
5723a0898aSmrg    f->input = input;
5823a0898aSmrg    f->output = output;
5923a0898aSmrg    f->skip = skip;
6023a0898aSmrg    f->eof  = 0;
6123a0898aSmrg    f->close = close;
6223a0898aSmrg    return f;
6323a0898aSmrg}
6423a0898aSmrg
6523a0898aSmrg#define FileDes(f)  ((int)(long) (f)->private)
6623a0898aSmrg
6723a0898aSmrgstatic int
6823a0898aSmrgBufFileRawFill (BufFilePtr f)
6923a0898aSmrg{
7023a0898aSmrg    int	left;
7123a0898aSmrg
7223a0898aSmrg    left = read (FileDes(f), (char *)f->buffer, BUFFILESIZE);
7323a0898aSmrg    if (left <= 0) {
7423a0898aSmrg	f->left = 0;
7523a0898aSmrg	return BUFFILEEOF;
7623a0898aSmrg    }
7723a0898aSmrg    f->left = left - 1;
7823a0898aSmrg    f->bufp = f->buffer + 1;
7923a0898aSmrg    return f->buffer[0];
8023a0898aSmrg}
8123a0898aSmrg
8223a0898aSmrgstatic int
8323a0898aSmrgBufFileRawSkip (BufFilePtr f, int count)
8423a0898aSmrg{
8523a0898aSmrg    int	    curoff;
8623a0898aSmrg    int	    fileoff;
8723a0898aSmrg    int	    todo;
8823a0898aSmrg
8923a0898aSmrg    curoff = f->bufp - f->buffer;
9023a0898aSmrg    fileoff = curoff + f->left;
9123a0898aSmrg    if (curoff + count <= fileoff) {
9223a0898aSmrg	f->bufp += count;
9323a0898aSmrg	f->left -= count;
9423a0898aSmrg    } else {
9523a0898aSmrg	todo = count - (fileoff - curoff);
9623a0898aSmrg	if (lseek (FileDes(f), todo, 1) == -1) {
9723a0898aSmrg	    if (errno != ESPIPE)
9823a0898aSmrg		return BUFFILEEOF;
9923a0898aSmrg	    while (todo) {
10023a0898aSmrg		curoff = BUFFILESIZE;
10123a0898aSmrg		if (curoff > todo)
10223a0898aSmrg		    curoff = todo;
10323a0898aSmrg		fileoff = read (FileDes(f), (char *)f->buffer, curoff);
10423a0898aSmrg		if (fileoff <= 0)
10523a0898aSmrg		    return BUFFILEEOF;
10623a0898aSmrg		todo -= fileoff;
10723a0898aSmrg	    }
10823a0898aSmrg	}
10923a0898aSmrg	f->left = 0;
11023a0898aSmrg    }
11123a0898aSmrg    return count;
11223a0898aSmrg}
11323a0898aSmrg
11423a0898aSmrgstatic int
11523a0898aSmrgBufFileRawClose (BufFilePtr f, int doClose)
11623a0898aSmrg{
11723a0898aSmrg    if (doClose)
11823a0898aSmrg	close (FileDes (f));
11923a0898aSmrg    return 1;
12023a0898aSmrg}
12123a0898aSmrg
12223a0898aSmrgBufFilePtr
12323a0898aSmrgBufFileOpenRead (int fd)
12423a0898aSmrg{
1257f7f5e4eSmrg#if defined (WIN32)
12623a0898aSmrg    /* hv: I'd bet WIN32 has the same effect here */
12723a0898aSmrg    setmode(fd,O_BINARY);
12823a0898aSmrg#endif
12923a0898aSmrg    return BufFileCreate ((char *)(long) fd, BufFileRawFill, 0, BufFileRawSkip, BufFileRawClose);
13023a0898aSmrg}
13123a0898aSmrg
13223a0898aSmrgstatic int
13323a0898aSmrgBufFileRawFlush (int c, BufFilePtr f)
13423a0898aSmrg{
13523a0898aSmrg    int	cnt;
13623a0898aSmrg
13723a0898aSmrg    if (c != BUFFILEEOF)
13823a0898aSmrg	*f->bufp++ = c;
13923a0898aSmrg    cnt = f->bufp - f->buffer;
14023a0898aSmrg    f->bufp = f->buffer;
14123a0898aSmrg    f->left = BUFFILESIZE;
14223a0898aSmrg    if (write (FileDes(f), (char *)f->buffer, cnt) != cnt)
14323a0898aSmrg	return BUFFILEEOF;
14423a0898aSmrg    return c;
14523a0898aSmrg}
14623a0898aSmrg
14723a0898aSmrgstatic int
14823a0898aSmrgBufFileFlush (BufFilePtr f, int doClose)
14923a0898aSmrg{
15023a0898aSmrg    if (f->bufp != f->buffer)
15123a0898aSmrg	return (*f->output) (BUFFILEEOF, f);
15223a0898aSmrg    return 0;
15323a0898aSmrg}
15423a0898aSmrg
15523a0898aSmrgBufFilePtr
15623a0898aSmrgBufFileOpenWrite (int fd)
15723a0898aSmrg{
15823a0898aSmrg    BufFilePtr	f;
15923a0898aSmrg
1607f7f5e4eSmrg#if defined(WIN32)
16123a0898aSmrg    /* hv: I'd bet WIN32 has the same effect here */
16223a0898aSmrg    setmode(fd,O_BINARY);
16323a0898aSmrg#endif
16423a0898aSmrg    f = BufFileCreate ((char *)(long) fd, 0, BufFileRawFlush, 0, BufFileFlush);
16561b3db43Smrg    if (f != NULL) {
16661b3db43Smrg	f->bufp = f->buffer;
16761b3db43Smrg	f->left = BUFFILESIZE;
16861b3db43Smrg    }
16923a0898aSmrg    return f;
17023a0898aSmrg}
17123a0898aSmrg
17223a0898aSmrgint
17323a0898aSmrgBufFileRead (BufFilePtr f, char *b, int n)
17423a0898aSmrg{
17523a0898aSmrg    int	    c, cnt;
17623a0898aSmrg    cnt = n;
17723a0898aSmrg    while (cnt--) {
17823a0898aSmrg	c = BufFileGet (f);
17923a0898aSmrg	if (c == BUFFILEEOF)
18023a0898aSmrg	    break;
18123a0898aSmrg	*b++ = c;
18223a0898aSmrg    }
18323a0898aSmrg    return n - cnt - 1;
18423a0898aSmrg}
18523a0898aSmrg
18623a0898aSmrgint
18723a0898aSmrgBufFileWrite (BufFilePtr f, char *b, int n)
18823a0898aSmrg{
18923a0898aSmrg    int	    cnt;
19023a0898aSmrg    cnt = n;
19123a0898aSmrg    while (cnt--) {
19223a0898aSmrg	if (BufFilePut (*b++, f) == BUFFILEEOF)
19323a0898aSmrg	    return BUFFILEEOF;
19423a0898aSmrg    }
19523a0898aSmrg    return n;
19623a0898aSmrg}
19723a0898aSmrg
19823a0898aSmrgint
19923a0898aSmrgBufFileClose (BufFilePtr f, int doClose)
20023a0898aSmrg{
20123a0898aSmrg    int ret;
20223a0898aSmrg    ret = (*f->close) (f, doClose);
2037f7f5e4eSmrg    free (f);
20423a0898aSmrg    return ret;
20523a0898aSmrg}
206