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