add SDL2_ttf support
[platform/upstream/SDL.git] / extension / SDL2_ttf-2.0.14 / external / freetype-2.4.12 / builds / unix / ftsystem.c
1 /***************************************************************************/
2 /*                                                                         */
3 /*  ftsystem.c                                                             */
4 /*                                                                         */
5 /*    Unix-specific FreeType low-level system interface (body).            */
6 /*                                                                         */
7 /*  Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007, 2008 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 #include <ft2build.h>
20   /* we use our special ftconfig.h file, not the standard one */
21 #include <ftconfig.h>
22 #include FT_INTERNAL_DEBUG_H
23 #include FT_SYSTEM_H
24 #include FT_ERRORS_H
25 #include FT_TYPES_H
26 #include FT_INTERNAL_STREAM_H
27
28   /* memory-mapping includes and definitions */
29 #ifdef HAVE_UNISTD_H
30 #include <unistd.h>
31 #endif
32
33 #include <sys/mman.h>
34 #ifndef MAP_FILE
35 #define MAP_FILE  0x00
36 #endif
37
38 #ifdef MUNMAP_USES_VOIDP
39 #define MUNMAP_ARG_CAST  void *
40 #else
41 #define MUNMAP_ARG_CAST  char *
42 #endif
43
44 #ifdef NEED_MUNMAP_DECL
45
46 #ifdef __cplusplus
47   extern "C"
48 #else
49   extern
50 #endif
51   int
52   munmap( char*  addr,
53           int    len );
54
55 #define MUNMAP_ARG_CAST  char *
56
57 #endif /* NEED_DECLARATION_MUNMAP */
58
59
60 #include <sys/types.h>
61 #include <sys/stat.h>
62
63 #ifdef HAVE_FCNTL_H
64 #include <fcntl.h>
65 #endif
66
67 #include <stdio.h>
68 #include <stdlib.h>
69 #include <string.h>
70 #include <errno.h>
71
72
73   /*************************************************************************/
74   /*                                                                       */
75   /*                       MEMORY MANAGEMENT INTERFACE                     */
76   /*                                                                       */
77   /*************************************************************************/
78
79
80   /*************************************************************************/
81   /*                                                                       */
82   /* <Function>                                                            */
83   /*    ft_alloc                                                           */
84   /*                                                                       */
85   /* <Description>                                                         */
86   /*    The memory allocation function.                                    */
87   /*                                                                       */
88   /* <Input>                                                               */
89   /*    memory :: A pointer to the memory object.                          */
90   /*                                                                       */
91   /*    size   :: The requested size in bytes.                             */
92   /*                                                                       */
93   /* <Return>                                                              */
94   /*    The address of newly allocated block.                              */
95   /*                                                                       */
96   FT_CALLBACK_DEF( void* )
97   ft_alloc( FT_Memory  memory,
98             long       size )
99   {
100     FT_UNUSED( memory );
101
102     return malloc( size );
103   }
104
105
106   /*************************************************************************/
107   /*                                                                       */
108   /* <Function>                                                            */
109   /*    ft_realloc                                                         */
110   /*                                                                       */
111   /* <Description>                                                         */
112   /*    The memory reallocation function.                                  */
113   /*                                                                       */
114   /* <Input>                                                               */
115   /*    memory   :: A pointer to the memory object.                        */
116   /*                                                                       */
117   /*    cur_size :: The current size of the allocated memory block.        */
118   /*                                                                       */
119   /*    new_size :: The newly requested size in bytes.                     */
120   /*                                                                       */
121   /*    block    :: The current address of the block in memory.            */
122   /*                                                                       */
123   /* <Return>                                                              */
124   /*    The address of the reallocated memory block.                       */
125   /*                                                                       */
126   FT_CALLBACK_DEF( void* )
127   ft_realloc( FT_Memory  memory,
128               long       cur_size,
129               long       new_size,
130               void*      block )
131   {
132     FT_UNUSED( memory );
133     FT_UNUSED( cur_size );
134
135     return realloc( block, new_size );
136   }
137
138
139   /*************************************************************************/
140   /*                                                                       */
141   /* <Function>                                                            */
142   /*    ft_free                                                            */
143   /*                                                                       */
144   /* <Description>                                                         */
145   /*    The memory release function.                                       */
146   /*                                                                       */
147   /* <Input>                                                               */
148   /*    memory :: A pointer to the memory object.                          */
149   /*                                                                       */
150   /*    block  :: The address of block in memory to be freed.              */
151   /*                                                                       */
152   FT_CALLBACK_DEF( void )
153   ft_free( FT_Memory  memory,
154            void*      block )
155   {
156     FT_UNUSED( memory );
157
158     free( block );
159   }
160
161
162   /*************************************************************************/
163   /*                                                                       */
164   /*                     RESOURCE MANAGEMENT INTERFACE                     */
165   /*                                                                       */
166   /*************************************************************************/
167
168
169   /*************************************************************************/
170   /*                                                                       */
171   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
172   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
173   /* messages during execution.                                            */
174   /*                                                                       */
175 #undef  FT_COMPONENT
176 #define FT_COMPONENT  trace_io
177
178   /* We use the macro STREAM_FILE for convenience to extract the       */
179   /* system-specific stream handle from a given FreeType stream object */
180 #define STREAM_FILE( stream )  ( (FILE*)stream->descriptor.pointer )
181
182
183   /*************************************************************************/
184   /*                                                                       */
185   /* <Function>                                                            */
186   /*    ft_close_stream_by_munmap                                          */
187   /*                                                                       */
188   /* <Description>                                                         */
189   /*    The function to close a stream which is opened by mmap.            */
190   /*                                                                       */
191   /* <Input>                                                               */
192   /*    stream :: A pointer to the stream object.                          */
193   /*                                                                       */
194   FT_CALLBACK_DEF( void )
195   ft_close_stream_by_munmap( FT_Stream  stream )
196   {
197     munmap( (MUNMAP_ARG_CAST)stream->descriptor.pointer, stream->size );
198
199     stream->descriptor.pointer = NULL;
200     stream->size               = 0;
201     stream->base               = 0;
202   }
203
204
205   /*************************************************************************/
206   /*                                                                       */
207   /* <Function>                                                            */
208   /*    ft_close_stream_by_free                                            */
209   /*                                                                       */
210   /* <Description>                                                         */
211   /*    The function to close a stream which is created by ft_alloc.       */
212   /*                                                                       */
213   /* <Input>                                                               */
214   /*    stream :: A pointer to the stream object.                          */
215   /*                                                                       */
216   FT_CALLBACK_DEF( void )
217   ft_close_stream_by_free( FT_Stream  stream )
218   {
219     ft_free( NULL, stream->descriptor.pointer );
220
221     stream->descriptor.pointer = NULL;
222     stream->size               = 0;
223     stream->base               = 0;
224   }
225
226
227   /* documentation is in ftobjs.h */
228
229   FT_BASE_DEF( FT_Error )
230   FT_Stream_Open( FT_Stream    stream,
231                   const char*  filepathname )
232   {
233     int          file;
234     struct stat  stat_buf;
235
236
237     if ( !stream )
238       return FT_Err_Invalid_Stream_Handle;
239
240     /* open the file */
241     file = open( filepathname, O_RDONLY );
242     if ( file < 0 )
243     {
244       FT_ERROR(( "FT_Stream_Open:" ));
245       FT_ERROR(( " could not open `%s'\n", filepathname ));
246       return FT_Err_Cannot_Open_Resource;
247     }
248
249     /* Here we ensure that a "fork" will _not_ duplicate   */
250     /* our opened input streams on Unix.  This is critical */
251     /* since it avoids some (possible) access control      */
252     /* issues and cleans up the kernel file table a bit.   */
253     /*                                                     */
254 #ifdef F_SETFD
255 #ifdef FD_CLOEXEC
256     (void)fcntl( file, F_SETFD, FD_CLOEXEC );
257 #else
258     (void)fcntl( file, F_SETFD, 1 );
259 #endif /* FD_CLOEXEC */
260 #endif /* F_SETFD */
261
262     if ( fstat( file, &stat_buf ) < 0 )
263     {
264       FT_ERROR(( "FT_Stream_Open:" ));
265       FT_ERROR(( " could not `fstat' file `%s'\n", filepathname ));
266       goto Fail_Map;
267     }
268
269     /* XXX: TODO -- real 64bit platform support                        */
270     /*                                                                 */
271     /* `stream->size' is typedef'd to unsigned long (in                */
272     /* freetype/ftsystem.h); `stat_buf.st_size', however, is usually   */
273     /* typedef'd to off_t (in sys/stat.h).                             */
274     /* On some platforms, the former is 32bit and the latter is 64bit. */
275     /* To avoid overflow caused by fonts in huge files larger than     */
276     /* 2GB, do a test.  Temporary fix proposed by Sean McBride.        */
277     /*                                                                 */
278     if ( stat_buf.st_size > LONG_MAX )
279     {
280       FT_ERROR(( "FT_Stream_Open: file is too big\n" ));
281       goto Fail_Map;
282     }
283     else if ( stat_buf.st_size == 0 )
284     {
285       FT_ERROR(( "FT_Stream_Open: zero-length file\n" ));
286       goto Fail_Map;
287     }
288
289     /* This cast potentially truncates a 64bit to 32bit! */
290     stream->size = (unsigned long)stat_buf.st_size;
291     stream->pos  = 0;
292     stream->base = (unsigned char *)mmap( NULL,
293                                           stream->size,
294                                           PROT_READ,
295                                           MAP_FILE | MAP_PRIVATE,
296                                           file,
297                                           0 );
298
299     /* on some RTOS, mmap might return 0 */
300     if ( (long)stream->base != -1 && stream->base != NULL )
301       stream->close = ft_close_stream_by_munmap;
302     else
303     {
304       ssize_t  total_read_count;
305
306
307       FT_ERROR(( "FT_Stream_Open:" ));
308       FT_ERROR(( " could not `mmap' file `%s'\n", filepathname ));
309
310       stream->base = (unsigned char*)ft_alloc( NULL, stream->size );
311
312       if ( !stream->base )
313       {
314         FT_ERROR(( "FT_Stream_Open:" ));
315         FT_ERROR(( " could not `alloc' memory\n" ));
316         goto Fail_Map;
317       }
318
319       total_read_count = 0;
320       do {
321         ssize_t  read_count;
322
323
324         read_count = read( file,
325                            stream->base + total_read_count,
326                            stream->size - total_read_count );
327
328         if ( read_count <= 0 )
329         {
330           if ( read_count == -1 && errno == EINTR )
331             continue;
332
333           FT_ERROR(( "FT_Stream_Open:" ));
334           FT_ERROR(( " error while `read'ing file `%s'\n", filepathname ));
335           goto Fail_Read;
336         }
337
338         total_read_count += read_count;
339
340       } while ( (unsigned long)total_read_count != stream->size );
341
342       stream->close = ft_close_stream_by_free;
343     }
344
345     close( file );
346
347     stream->descriptor.pointer = stream->base;
348     stream->pathname.pointer   = (char*)filepathname;
349
350     stream->read = 0;
351
352     FT_TRACE1(( "FT_Stream_Open:" ));
353     FT_TRACE1(( " opened `%s' (%d bytes) successfully\n",
354                 filepathname, stream->size ));
355
356     return FT_Err_Ok;
357
358   Fail_Read:
359     ft_free( NULL, stream->base );
360
361   Fail_Map:
362     close( file );
363
364     stream->base = NULL;
365     stream->size = 0;
366     stream->pos  = 0;
367
368     return FT_Err_Cannot_Open_Stream;
369   }
370
371
372 #ifdef FT_DEBUG_MEMORY
373
374   extern FT_Int
375   ft_mem_debug_init( FT_Memory  memory );
376
377   extern void
378   ft_mem_debug_done( FT_Memory  memory );
379
380 #endif
381
382
383   /* documentation is in ftobjs.h */
384
385   FT_BASE_DEF( FT_Memory )
386   FT_New_Memory( void )
387   {
388     FT_Memory  memory;
389
390
391     memory = (FT_Memory)malloc( sizeof ( *memory ) );
392     if ( memory )
393     {
394       memory->user    = 0;
395       memory->alloc   = ft_alloc;
396       memory->realloc = ft_realloc;
397       memory->free    = ft_free;
398 #ifdef FT_DEBUG_MEMORY
399       ft_mem_debug_init( memory );
400 #endif
401     }
402
403     return memory;
404   }
405
406
407   /* documentation is in ftobjs.h */
408
409   FT_BASE_DEF( void )
410   FT_Done_Memory( FT_Memory  memory )
411   {
412 #ifdef FT_DEBUG_MEMORY
413     ft_mem_debug_done( memory );
414 #endif
415     memory->free( memory, memory );
416   }
417
418
419 /* END */