PageRenderTime 67ms CodeModel.GetById 18ms app.highlight 42ms RepoModel.GetById 2ms app.codeStats 0ms

/modules/freetype2/builds/unix/ftsystem.c

http://github.com/zpao/v8monkey
C | 419 lines | 208 code | 83 blank | 128 comment | 20 complexity | fb2559e19c18eece4429142e77024fde MD5 | raw file
  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 */