1 /*
2 * Utilities for efficient access to the TTFfile
3 *
4 * Copyright © 1997-1998 Herbert Duerr
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the Free Softaware
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 */
21
22 //#define DEBUG 1
23 #include "ttf.h"
24
25 #include <fcntl.h>
26 #include <sys/mman.h>
27 #include <sys/stat.h>
28 #include <unistd.h>
29
30 #include <cstddef>
31 #include <cstdlib>
32 #include <cstring>
33
34 void *
allocMem(int size)35 allocMem(int size)
36 {
37 return malloc(size);
38 }
39
40 void *
shrinkMem(void * ptr,int newsize)41 shrinkMem(void *ptr, int newsize)
42 {
43 return realloc(ptr, newsize);
44 }
45
46 void
deallocMem(void * ptr,int size XFSTT_ATTR_UNUSED)47 deallocMem(void *ptr, int size XFSTT_ATTR_UNUSED)
48 {
49 free(ptr);
50 }
51
52 #ifdef MEMDEBUG
53
54 #define MEMPTRS 8192
55
56 typedef struct {
57 void *ptr;
58 int len;
59 } memstruct;
60
61 static memstruct memdbg[MEMPTRS];
62 static int memidx = 0;
63 static int memcount = 0;
64 static int memused = 0;
65
66 void
cleanupMem()67 cleanupMem()
68 {
69 debug("Memory holes:\n");
70 for (int i = 0; i < memidx; ++i)
71 if (memdbg[i].ptr)
72 debug("MEM hole[%3d] = %p\n", i, memdbg[i].ptr);
73
74 if (memcount != 0)
75 debug("MEM hole: memcount = %d\n", memcount);
76 }
77
78 void *
operator new[](size_t size)79 operator new[](size_t size)
80 {
81 void *ptr = malloc(size);
82
83 memused += size;
84
85 debug("MEM new[](%5d) = %p", size, ptr);
86 debug(", memcount = %d, memidx = %d", ++memcount, memidx);
87
88 int i = memidx;
89
90 while (--i >= 0 && memdbg[i].ptr);
91 if (i <= 0)
92 i = memidx++;
93
94 debug(", idx = %d, used %d\n", i, memused);
95
96 memdbg[i].ptr = ptr;
97 memdbg[i].len = size;
98
99 return ptr;
100 }
101
102 void
operator delete[](void * ptr)103 operator delete[](void *ptr)
104 {
105 debug("MEM delete[](%p)", ptr);
106 debug(", memcount = %d, memidx = %d\n", --memcount, memidx);
107
108 int i = memidx;
109 while (--i >= 0 && memdbg[i].ptr != ptr);
110 if (i >= 0) {
111 memdbg[i].ptr = 0;
112 memused -= memdbg[i].len;
113 debug(", idx = %d, used %d\n", i, memused);
114 if (++i == memidx)
115 --memidx;
116 } else
117 debug("Cannot delete!\n");
118
119 free(ptr);
120 }
121
122 void *
operator new(size_t size)123 operator new(size_t size)
124 {
125 void *ptr = malloc(size);
126 memused += size;
127
128 debug("MEM new(%7d) = %p", size, ptr);
129 debug(", memcount = %d, memidx = %d", ++memcount, memidx);
130
131 int i = memidx;
132 while (--i >= 0 && memdbg[i].ptr);
133 if (i <= 0)
134 i = memidx++;
135
136 debug(", idx = %d, used %d\n", i, memused);
137
138 memdbg[i].ptr = ptr;
139 memdbg[i].len = size;
140
141 return ptr;
142 }
143
144 void
operator delete(void * ptr)145 operator delete(void *ptr)
146 {
147 debug("MEM delete(%p)", ptr);
148 debug(", memcount = %d, memidx = %d", --memcount, memidx);
149
150 int i = memidx;
151 while (--i >= 0 && memdbg[i].ptr != ptr);
152 if (i >= 0) {
153 memdbg[i].ptr = 0;
154 memused -= memdbg[i].len;
155 debug(", idx = %d, used %d\n", i, memused);
156 if (++i == memidx)
157 --memidx;
158 } else
159 debug("Cannot delete!\n");
160
161 free(ptr);
162 }
163
164 #endif /* MEMDEBUG */
165
RandomAccessFile(const char * fileName)166 RandomAccessFile::RandomAccessFile(const char *fileName)
167 {
168 int fd = open(fileName, O_RDONLY);
169 if (fd < 0) {
170 debug("Cannot open \"%s\"\n", fileName);
171 ptr = absbase = base = nullptr;
172 length = 0;
173 return;
174 }
175 struct stat st;
176 if (fstat(fd, &st) < 0) {
177 debug("Cannot stat \"%s\"\n", fileName);
178 ptr = absbase = base = nullptr;
179 length = 0;
180 close(fd);
181 return;
182 }
183 length = st.st_size;
184 base = (uint8_t *)mmap(nullptr, length, PROT_READ, MAP_SHARED, fd, 0L);
185 close(fd);
186 if (base == MAP_FAILED) {
187 debug("MMap failed '%s'\n", strerror(errno));
188 ptr = absbase = base = nullptr;
189 length = 0;
190 return;
191 }
192 ptr = absbase = base;
193 }
194
195 void
closeRAFile()196 RandomAccessFile::closeRAFile()
197 {
198 if (absbase && absbase == base && length > 0) {
199 munmap(base, length);
200 }
201 }
202
203 uint32_t
calcChecksum()204 RandomAccessFile::calcChecksum()
205 {
206 uint32_t checksum = 0;
207 uint8_t *saveptr = ptr;
208
209 for (int len = length >> 2; --len >= 0;)
210 checksum += readUInt();
211 if (length & 3)
212 checksum += readUInt() & (-1 << ((-length & 3) << 3));
213 ptr = saveptr;
214
215 debug("Checksum is %08X\n", calcChecksum());
216
217 return checksum;
218 }
219