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