⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ttmmap.c

📁 神龙卡开发原代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************* * *  ttmmap.c                                                     2.0 * *    Memory-Mapped file component ( replaces ttfile.c ). * *  Copyright 1996-1999 by *  David Turner, Robert Wilhelm, and Werner Lemberg * *  This file is part of the FreeType project, and may only be used *  modified and distributed under the terms of the FreeType project *  license, LICENSE.TXT. By continuing to use, modify or distribute *  this file you indicate that you have read the license and *  understand and accept it fully. * *  Changes between 2.0 and 1.3 : * *  - adopted new design/separation introduced in ttfile.c 2.0 * ******************************************************************/#include "ttconfig.h"#include <stdio.h>#include <string.h>#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#include <sys/mman.h>#ifndef MAP_FILE#define MAP_FILE  0x00#endif/* * The prototype for munmap() is not provided on SunOS.  This needs to * have a check added later to see if the GNU C library is being used. * If so, then this prototype is not needed. */#if defined(__sun__) && !defined(SVR4) && !defined(__SVR4)  extern int  munmap( caddr_t  addr, int  len );#endif#include <sys/stat.h>#ifdef HAVE_FCNTL_H#include <fcntl.h>#endif#include "freetype.h"#include "tttypes.h"#include "ttdebug.h"#include "ttengine.h"#include "ttmutex.h"#include "ttmemory.h"#include "ttfile.h"     /* our prototypes */  /* This definition is mandatory for each file component! */  EXPORT_FUNC  const TFileFrame  TT_Null_FileFrame = { NULL, 0, 0 };    /* It has proven useful to do some bounds checks during   */  /* development phase.  Define DEBUG_FILE when compiling   */  /* this component to enable them.                         */#ifdef DEBUG_FILE#define CHECK_FRAME( frame, n )                          \  do {                                                   \    if ( frame.cursor + n > frame.address + frame.size ) \      Panic( "Frame boundary error!\n" );                \  } while ( 0 )#else#define CHECK_FRAME( frame, n ) \  do {                          \  } while( 0 )#endif  struct _TFileMap  {    String*  base;       /* base address of mapped file       */    Int      refcount;   /* reference count for mmaped region */    Long     size;       /* stream size in file               */    Long     offset;     /* offset in file                    */  };  typedef struct _TFileMap  TFileMap;#define MAP_Address( map )  (Byte*)( (map)->base + (map)->offset )  /* The stream record structure */  typedef struct _TStream_Rec  {    TFileMap*  map;     /* mapped file description */    Long       pos ;    /* cursor in mapped file   */  } TStream_Rec;  typedef TStream_Rec*  PStream_Rec;#define STREAM2REC( x )  ( (TStream_Rec*)HANDLE_Val( x ) )#ifndef TT_CONFIG_OPTION_THREAD_SAFE    /*******************************************************************/  /*******************************************************************/  /*******************************************************************/  /****                                                           ****/  /****  N O N   R E E N T R A N T   I M P L E M E N T A T I O N  ****/  /****                                                           ****/  /*******************************************************************/  /*******************************************************************/  /*******************************************************************/  /* The TFile_Component structure holds all the data that was */  /* previously declared static or global in this component.   */  /*                                                           */  /* It is accessible through the 'engine.file_component'      */  /* variable in re-entrant builds, or directly through the    */  /* static 'files' variable in other builds.                  */  struct _TFile_Component  {    TMutex       lock;        /* used by the thread-safe build only */    PStream_Rec  stream;      /* current stream  */    TFileFrame   frame;       /* current frame   */  };  typedef struct _TFile_Component  TFile_Component;/* The macro CUR_Stream denotes the current input stream              *//* Note that for the re-entrant version, the 'stream' name has been   *//* chosen according to the macro STREAM_ARGS.                         *//* The macro CUR_Frame denotes the current file frame               *//* Note that for the re-entrant version, the 'frame' name has been  *//* chosen according to the macro FRAME_ARGS.                        *//* The macro STREAM_VAR is used when calling public functions *//* that need an 'optional' stream argument.                   */#define CUR_Stream   files.stream            /* thread-safe macros */#define CUR_Frame    files.frame#define STREAM_VARS  /* void */#define STREAM_VAR   /* void */    /* the 'files' variable is only defined in non-reentrant builds */  static TFile_Component  files;/******************************************************************* * *  Function    :  TTFile_Init * *  Description :  Initializes the File component. * ******************************************************************/ LOCAL_FUNC TT_Error  TTFile_Init( PEngine_Instance  engine ) {   MUTEX_Create( files.lock );   files.stream = NULL;   ZERO_Frame( files.frame );   return TT_Err_Ok; }/******************************************************************* * *  Function    :  TTFile_Done * *  Description :  Finalizes the File component. * ******************************************************************/ LOCAL_FUNC TT_Error  TTFile_Done( PEngine_Instance  engine ) {   MUTEX_Destroy( files.lock );   return TT_Err_Ok; }/******************************************************************* * *  Function    : TT_Use_Stream * *  Description : Copies or duplicates a given stream. * *  Input  :  org_stream   original stream *            stream       target stream (copy or duplicate) * *  Output :  Error code * ******************************************************************/  EXPORT_FUNC  TT_Error  TT_Use_Stream( TT_Stream   org_stream,                           TT_Stream*  stream )  {    MUTEX_Lock( files.lock );    *stream = org_stream;    files.stream = STREAM2REC( org_stream );  /* set current stream */    return TT_Err_Ok;  }/******************************************************************* * *  Function    : TT_Done_Stream * *  Description : Releases a given stream. * *  Input  :  stream * *  Output :  Error code * ******************************************************************/ EXPORT_FUNC TT_Error  TT_Done_Stream( TT_Stream*  stream ) {   HANDLE_Set( *stream, NULL );   MUTEX_Release( files.lock );   return TT_Err_Ok; }#else /* TT_CONFIG_OPTION_THREAD_SAFE */  /*******************************************************************/  /*******************************************************************/  /*******************************************************************/  /********                                                   ********/  /********  R E E N T R A N T   I M P L E M E N T A T I O N  ********/  /********                                                   ********/  /*******************************************************************/  /*******************************************************************/  /*******************************************************************/#define CUR_Stream   STREAM2REC( stream )      /* re-entrant macros */#define CUR_Frame    (*frame)#define STREAM_VARS  stream,#define STREAM_VAR   stream/******************************************************************* * *  Function    :  TTFile_Init * *  Description :  Initializes the File component. * ******************************************************************/ LOCAL_FUNC TT_Error  TTFile_Init( PEngine_Instance  engine ) {   engine.file_component = NULL;   return TT_Err_Ok; }/******************************************************************* * *  Function    :  TTFile_Done * *  Description :  Finalizes the File component. * ******************************************************************/ LOCAL_FUNC TT_Error  TTFile_Done( PEngine_Instance  engine ) {   return TT_Err_Ok; }/******************************************************************* * *  Function    : TT_Use_Stream * *  Description : Copies or duplicates a given stream. * *  Input  :  org_stream   original stream *            stream       target stream (copy or duplicate) * *  Output :  Error code.  The output stream is set to NULL in *            case of Failure. * ******************************************************************/  EXPORT_FUNC  TT_Error  TT_Use_Stream( TT_Stream   input_stream,                           TT_Stream*  copy )  {    TT_Error     error;    PStream_Rec  stream_rec;    PStream_Rec  copy_rec;    stream_rec = STREAM2REC( input_stream );    if ( ALLOC( copy_rec, sizeof ( TStream_Rec ) ) )      goto Fail;    HANDLE_Set( *copy, copy_rec );    copy_rec->map->refcount++;    copy_rec->pos = 0;    return TT_Err_Ok;  Fail:    HANDLE_Set( *copy, NULL );    return error;  }/******************************************************************* * *  Function    : TT_Done_Stream * *  Description : Releases a given stream. * *  Input  :  stream * *  Output :  error code * ******************************************************************/ EXPORT_FUNC TT_Error  TT_Done_Stream( TT_Stream*  stream ) {   return TT_Close_Stream( stream ); }#endif /* TT_CONFIG_OPTION_THREAD_SAFE */  /*******************************************************************/  /*******************************************************************/  /*******************************************************************/  /***********                                             ***********/  /***********  C O M M O N   I M P L E M E N T A T I O N  ***********/  /***********                                             ***********/  /*******************************************************************/  /*******************************************************************/  /*******************************************************************//******************************************************************* * *  Function    :  AllocateMap * *  Description :  Allocates a new map from the table. * *  Output :  Pointer to new stream rec.  NULL in case of failure. * ******************************************************************/  static   TFileMap*  Allocate_Map( void )  {    TFileMap*  result;    if ( MEM_Alloc( result, sizeof ( TFileMap ) ) )      return NULL;    result->refcount = 1;    return result;  }/******************************************************************* * *  Function    :  ReleaseMap * *  Description :  Releases a used map to the table if reference i *                 counter reaches zero. * *  Input  :  map * *  Output :  None. * *  Note : Called by TT_Close_File() * ******************************************************************/  static   void  Release_Map ( TFileMap*  map )  {    map->refcount--;    if ( map->refcount <= 0 )    {      munmap ( (void*)map->base, map->size );      FREE( map );    }  }/******************************************************************* * *  Function    :  TT_Open_Stream * *  Description :  Opens the font file and saves the total file size. * *  Input  :  error          address of stream's error variable *                           (re-entrant build only). *            filepathname   pathname of the file to open *            stream         address of target TT_Stream structure * *  Output :  SUCCESS on success, FAILURE on error. *            The target stream is set to -1 in case of failure. * ******************************************************************/  LOCAL_FUNC  TT_Error  TT_Open_Stream( const String*  filepathname,                             TT_Stream*     stream )  {    TT_Error     error;    Int          file;    PStream_Rec  stream_rec;    TFileMap*    map;    struct stat  stat_buf;    if ( ALLOC( *stream, sizeof ( TStream_Rec ) ) )      return error;    map = Allocate_Map();    if ( !map )    {      error = TT_Err_Out_Of_Memory;      goto Memory_Fail;    }    stream_rec = STREAM2REC( *stream );    file = open( (String*)filepathname, O_RDONLY );    if ( file < 0 )      goto File_Fail;    if ( fstat( file, &stat_buf ) < 0 )      goto Map_Fail;    map->offset = 0;    map->size   = stat_buf.st_size + map->offset;    map->base   = mmap( NULL,                        map->size,                        PROT_READ,                        MAP_FILE | MAP_PRIVATE,                        file,                        0 );    if ( (long)map->base == -1 )      goto Map_Fail;    close( file );    stream_rec->map = map;    stream_rec->pos = 0;#ifndef TT_CONFIG_OPTION_THREAD_SAFE    CUR_Stream = stream_rec;#endif    return TT_Err_Ok;  Map_Fail:    close( file );  File_Fail:    error = TT_Err_Could_Not_Open_File;    FREE( map );  Memory_Fail:    FREE( *stream );    return error;  }/******************************************************************* * *  Function    : TT_Close_Stream * *  Description : Closes a stream. * *  Input  :  stream * *  Output :  SUCCESS (always) * ******************************************************************/  LOCAL_FUNC  TT_Error  TT_Close_Stream( TT_Stream*  stream )  {    PStream_Rec  rec = STREAM2REC( *stream );    Release_Map( rec->map );    FREE( rec );    HANDLE_Set( *stream, NULL );    return TT_Err_Ok;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -