1 | /***************************************************************************/ |
2 | /* */ |
3 | /* ftsystem.c */ |
4 | /* */ |
5 | /* ANSI-specific FreeType low-level system interface (body). */ |
6 | /* */ |
7 | /* Copyright 1996-2018 by */ |
8 | /* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
9 | /* */ |
10 | /* This file is part of the FreeType project, and may only be used, */ |
11 | /* modified, and distributed under the terms of the FreeType project */ |
12 | /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
13 | /* this file you indicate that you have read the license and */ |
14 | /* understand and accept it fully. */ |
15 | /* */ |
16 | /***************************************************************************/ |
17 | |
18 | /*************************************************************************/ |
19 | /* */ |
20 | /* This file contains the default interface used by FreeType to access */ |
21 | /* low-level, i.e. memory management, i/o access as well as thread */ |
22 | /* synchronisation. It can be replaced by user-specific routines if */ |
23 | /* necessary. */ |
24 | /* */ |
25 | /*************************************************************************/ |
26 | |
27 | |
28 | #include <ft2build.h> |
29 | #include FT_CONFIG_CONFIG_H |
30 | #include FT_INTERNAL_DEBUG_H |
31 | #include FT_INTERNAL_STREAM_H |
32 | #include FT_SYSTEM_H |
33 | #include FT_ERRORS_H |
34 | #include FT_TYPES_H |
35 | |
36 | |
37 | /*************************************************************************/ |
38 | /* */ |
39 | /* MEMORY MANAGEMENT INTERFACE */ |
40 | /* */ |
41 | /*************************************************************************/ |
42 | |
43 | /*************************************************************************/ |
44 | /* */ |
45 | /* It is not necessary to do any error checking for the */ |
46 | /* allocation-related functions. This will be done by the higher level */ |
47 | /* routines like ft_mem_alloc() or ft_mem_realloc(). */ |
48 | /* */ |
49 | /*************************************************************************/ |
50 | |
51 | |
52 | /*************************************************************************/ |
53 | /* */ |
54 | /* <Function> */ |
55 | /* ft_alloc */ |
56 | /* */ |
57 | /* <Description> */ |
58 | /* The memory allocation function. */ |
59 | /* */ |
60 | /* <Input> */ |
61 | /* memory :: A pointer to the memory object. */ |
62 | /* */ |
63 | /* size :: The requested size in bytes. */ |
64 | /* */ |
65 | /* <Return> */ |
66 | /* The address of newly allocated block. */ |
67 | /* */ |
68 | FT_CALLBACK_DEF( void* ) |
69 | ft_alloc( FT_Memory memory, |
70 | long size ) |
71 | { |
72 | FT_UNUSED( memory ); |
73 | |
74 | return ft_smalloc( (size_t)size ); |
75 | } |
76 | |
77 | |
78 | /*************************************************************************/ |
79 | /* */ |
80 | /* <Function> */ |
81 | /* ft_realloc */ |
82 | /* */ |
83 | /* <Description> */ |
84 | /* The memory reallocation function. */ |
85 | /* */ |
86 | /* <Input> */ |
87 | /* memory :: A pointer to the memory object. */ |
88 | /* */ |
89 | /* cur_size :: The current size of the allocated memory block. */ |
90 | /* */ |
91 | /* new_size :: The newly requested size in bytes. */ |
92 | /* */ |
93 | /* block :: The current address of the block in memory. */ |
94 | /* */ |
95 | /* <Return> */ |
96 | /* The address of the reallocated memory block. */ |
97 | /* */ |
98 | FT_CALLBACK_DEF( void* ) |
99 | ft_realloc( FT_Memory memory, |
100 | long cur_size, |
101 | long new_size, |
102 | void* block ) |
103 | { |
104 | FT_UNUSED( memory ); |
105 | FT_UNUSED( cur_size ); |
106 | |
107 | return ft_srealloc( block, (size_t)new_size ); |
108 | } |
109 | |
110 | |
111 | /*************************************************************************/ |
112 | /* */ |
113 | /* <Function> */ |
114 | /* ft_free */ |
115 | /* */ |
116 | /* <Description> */ |
117 | /* The memory release function. */ |
118 | /* */ |
119 | /* <Input> */ |
120 | /* memory :: A pointer to the memory object. */ |
121 | /* */ |
122 | /* block :: The address of block in memory to be freed. */ |
123 | /* */ |
124 | FT_CALLBACK_DEF( void ) |
125 | ft_free( FT_Memory memory, |
126 | void* block ) |
127 | { |
128 | FT_UNUSED( memory ); |
129 | |
130 | ft_sfree( block ); |
131 | } |
132 | |
133 | |
134 | /*************************************************************************/ |
135 | /* */ |
136 | /* RESOURCE MANAGEMENT INTERFACE */ |
137 | /* */ |
138 | /*************************************************************************/ |
139 | |
140 | #ifndef FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT |
141 | |
142 | /*************************************************************************/ |
143 | /* */ |
144 | /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ |
145 | /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ |
146 | /* messages during execution. */ |
147 | /* */ |
148 | #undef FT_COMPONENT |
149 | #define FT_COMPONENT trace_io |
150 | |
151 | /* We use the macro STREAM_FILE for convenience to extract the */ |
152 | /* system-specific stream handle from a given FreeType stream object */ |
153 | #define STREAM_FILE( stream ) ( (FT_FILE*)stream->descriptor.pointer ) |
154 | |
155 | |
156 | /*************************************************************************/ |
157 | /* */ |
158 | /* <Function> */ |
159 | /* ft_ansi_stream_close */ |
160 | /* */ |
161 | /* <Description> */ |
162 | /* The function to close a stream. */ |
163 | /* */ |
164 | /* <Input> */ |
165 | /* stream :: A pointer to the stream object. */ |
166 | /* */ |
167 | FT_CALLBACK_DEF( void ) |
168 | ft_ansi_stream_close( FT_Stream stream ) |
169 | { |
170 | ft_fclose( STREAM_FILE( stream ) ); |
171 | |
172 | stream->descriptor.pointer = NULL; |
173 | stream->size = 0; |
174 | stream->base = NULL; |
175 | } |
176 | |
177 | |
178 | /*************************************************************************/ |
179 | /* */ |
180 | /* <Function> */ |
181 | /* ft_ansi_stream_io */ |
182 | /* */ |
183 | /* <Description> */ |
184 | /* The function to open a stream. */ |
185 | /* */ |
186 | /* <Input> */ |
187 | /* stream :: A pointer to the stream object. */ |
188 | /* */ |
189 | /* offset :: The position in the data stream to start reading. */ |
190 | /* */ |
191 | /* buffer :: The address of buffer to store the read data. */ |
192 | /* */ |
193 | /* count :: The number of bytes to read from the stream. */ |
194 | /* */ |
195 | /* <Return> */ |
196 | /* The number of bytes actually read. If `count' is zero (this is, */ |
197 | /* the function is used for seeking), a non-zero return value */ |
198 | /* indicates an error. */ |
199 | /* */ |
200 | FT_CALLBACK_DEF( unsigned long ) |
201 | ft_ansi_stream_io( FT_Stream stream, |
202 | unsigned long offset, |
203 | unsigned char* buffer, |
204 | unsigned long count ) |
205 | { |
206 | FT_FILE* file; |
207 | |
208 | |
209 | if ( !count && offset > stream->size ) |
210 | return 1; |
211 | |
212 | file = STREAM_FILE( stream ); |
213 | |
214 | if ( stream->pos != offset ) |
215 | ft_fseek( file, (long)offset, SEEK_SET ); |
216 | |
217 | return (unsigned long)ft_fread( buffer, 1, count, file ); |
218 | } |
219 | |
220 | |
221 | /* documentation is in ftstream.h */ |
222 | |
223 | FT_BASE_DEF( FT_Error ) |
224 | FT_Stream_Open( FT_Stream stream, |
225 | const char* filepathname ) |
226 | { |
227 | FT_FILE* file; |
228 | |
229 | |
230 | if ( !stream ) |
231 | return FT_THROW( Invalid_Stream_Handle ); |
232 | |
233 | stream->descriptor.pointer = NULL; |
234 | stream->pathname.pointer = (char*)filepathname; |
235 | stream->base = NULL; |
236 | stream->pos = 0; |
237 | stream->read = NULL; |
238 | stream->close = NULL; |
239 | |
240 | file = ft_fopen( filepathname, "rb" ); |
241 | if ( !file ) |
242 | { |
243 | FT_ERROR(( "FT_Stream_Open:" |
244 | " could not open `%s'\n" , filepathname )); |
245 | |
246 | return FT_THROW( Cannot_Open_Resource ); |
247 | } |
248 | |
249 | ft_fseek( file, 0, SEEK_END ); |
250 | stream->size = (unsigned long)ft_ftell( file ); |
251 | if ( !stream->size ) |
252 | { |
253 | FT_ERROR(( "FT_Stream_Open:" )); |
254 | FT_ERROR(( " opened `%s' but zero-sized\n" , filepathname )); |
255 | ft_fclose( file ); |
256 | return FT_THROW( Cannot_Open_Stream ); |
257 | } |
258 | ft_fseek( file, 0, SEEK_SET ); |
259 | |
260 | stream->descriptor.pointer = file; |
261 | stream->read = ft_ansi_stream_io; |
262 | stream->close = ft_ansi_stream_close; |
263 | |
264 | FT_TRACE1(( "FT_Stream_Open:" )); |
265 | FT_TRACE1(( " opened `%s' (%d bytes) successfully\n" , |
266 | filepathname, stream->size )); |
267 | |
268 | return FT_Err_Ok; |
269 | } |
270 | |
271 | #endif /* !FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT */ |
272 | |
273 | #ifdef FT_DEBUG_MEMORY |
274 | |
275 | extern FT_Int |
276 | ft_mem_debug_init( FT_Memory memory ); |
277 | |
278 | extern void |
279 | ft_mem_debug_done( FT_Memory memory ); |
280 | |
281 | #endif |
282 | |
283 | |
284 | /* documentation is in ftobjs.h */ |
285 | |
286 | FT_BASE_DEF( FT_Memory ) |
287 | FT_New_Memory( void ) |
288 | { |
289 | FT_Memory memory; |
290 | |
291 | |
292 | memory = (FT_Memory)ft_smalloc( sizeof ( *memory ) ); |
293 | if ( memory ) |
294 | { |
295 | memory->user = NULL; |
296 | memory->alloc = ft_alloc; |
297 | memory->realloc = ft_realloc; |
298 | memory->free = ft_free; |
299 | #ifdef FT_DEBUG_MEMORY |
300 | ft_mem_debug_init( memory ); |
301 | #endif |
302 | } |
303 | |
304 | return memory; |
305 | } |
306 | |
307 | |
308 | /* documentation is in ftobjs.h */ |
309 | |
310 | FT_BASE_DEF( void ) |
311 | FT_Done_Memory( FT_Memory memory ) |
312 | { |
313 | #ifdef FT_DEBUG_MEMORY |
314 | ft_mem_debug_done( memory ); |
315 | #endif |
316 | ft_sfree( memory ); |
317 | } |
318 | |
319 | |
320 | /* END */ |
321 | |