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

📄 os2file.c

📁 字体缩放显示
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************* * *  os2file.c (OS2 version)                                      2.1 * *    File I/O Component (body). * *  Copyright 1996-2001 by Michal Necasek, *  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. * *  NOTES: * *   This implementation relies on the OS/2 file API. It was provided *   by the PM FreeType DLL author, Michal Necasek. * ******************************************************************/#include "ttconfig.h"#include <os2.h>   /* !Mike! */#include <stdio.h>#include <string.h>#ifdef HAVE_UNISTD_H#include <unistd.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 *//* For now, we don't define additional error messages in the core library  *//* to report open-on demand errors.  Define these errors as standard ones. */#define TT_Err_Could_Not_ReOpen_File  TT_Err_Could_Not_Open_File#define TT_Err_Could_Not_ReSeek_File  TT_Err_Could_Not_Open_File  /* This definition is mandatory for each file component! */  FT_EXPORT_FUNC( const TFileFrame ) TT_Null_FileFrame = { NULL, 0, 0 };/* It has proven useful to do some bounds checks during development phase. *//* They should probably be undefined for speed reasons in a later release. */#if 0#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  /* Because a stream can be flushed, i.e., its file handle can be     */  /* closed to save system resources, we must keep the stream's file   */  /* pathname to be able to re-open it on demand when it is flushed.   */  struct  _TStream_Rec  {    Bool     opened;                     /* is the stream handle opened ? */    String*  name;                       /* the file's pathname           */    Long     position;                   /* current pos. within the file  */    HFILE    file;                       /* file handle         !Mike!    */    Long     base;                       /* stream base in file           */    Long     size;                       /* stream size in file           */  };  typedef struct _TStream_Rec  TStream_Rec;  typedef TStream_Rec*         PStream_Rec;  /* We support embedded TrueType files by allowing them to be         */  /* inside any file, at any location, hence the 'base' argument.      */  /* Note, however, that the current implementation does not allow you */  /* to specify a 'base' index when opening a file.                    */  /* (will come later)                                                 */  /* I still don't know if this will turn out useful...   - DavidT     */#define STREAM2REC( x )  ( (TStream_Rec*)HANDLE_Val( x ) )  static  TT_Error  Stream_Activate  ( PStream_Rec  stream );  static  TT_Error  Stream_Deactivate( PStream_Rec  stream );#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  ****/  /****                                                           ****/  /*******************************************************************/  /*******************************************************************/  /*******************************************************************/  /* In non-reentrant builds, we allocate a single block where we'll */  /* place all the frames smaller than FRAME_CACHE_SIZE, rather than */  /* allocating a new block on each access.  Bigger frames will be   */  /* malloced normally in the heap.                                  */  /*                                                                 */  /* See TT_Access_Frame() and TT_Forget_Frame() for details.        */#define FRAME_CACHE_SIZE  2048  /* 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 */    Byte*        frame_cache; /* frame cache     */    PStream_Rec  stream;      /* current stream  */    TFileFrame   frame;       /* current frame   */  };  typedef struct _TFile_Component  TFile_Component;  static TFile_Component  files;#define CUR_Stream  files.stream#define CUR_Frame   files.frame#define STREAM_VARS  /* void */#define STREAM_VAR   /* void *//* 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.                   *//******************************************************************* * *  Function    :  TTFile_Init * *  Description :  Initializes the File component. * ******************************************************************/ FT_INTERNAL_FUNC( TT_Error ) TTFile_Init( PEngine_Instance  engine ) {   TT_Error  error;   MUTEX_Create( files.lock );   files.stream = NULL;   ZERO_Frame( files.frame );   if ( ALLOC( files.frame_cache, FRAME_CACHE_SIZE ) )     return error;   return TT_Err_Ok; }/******************************************************************* * *  Function    :  TTFile_Done * *  Description :  Finalizes the File component. * ******************************************************************/ FT_INTERNAL_FUNC( TT_Error ) TTFile_Done( PEngine_Instance  engine ) {   FREE( files.frame_cache );   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. * ******************************************************************/  FT_EXPORT_FUNC( TT_Error )  TT_Use_Stream( TT_Stream   org_stream,                 TT_Stream*  stream )  {     MUTEX_Lock( files.lock );                /* lock file mutex    */     *stream = org_stream;                    /* copy the stream    */     files.stream = STREAM2REC( org_stream ); /* set current stream */     Stream_Activate( files.stream );     return TT_Err_Ok;  }/******************************************************************* * *  Function    : TT_Done_Stream * *  Description : Releases a given stream. * *  Input  :  stream  target stream * *  Output :  Error code. * ******************************************************************/ FT_EXPORT_FUNC( TT_Error ) TT_Done_Stream( TT_Stream*  stream ) {    HANDLE_Set( *stream, NULL );    MUTEX_Release( files.lock );    return TT_Err_Ok; }/******************************************************************* * *  Function    :  TT_Access_Frame * *  Description :  Notifies the component that we're going to read *                 'size' bytes from the current file position. *                 This function should load/cache/map these bytes *                 so that they will be addressed by the GET_xxx() *                 functions easily. * *  Input  :  size   number of bytes to access. * *  Output :  SUCCESS on success.  FAILURE on error. * *  Notes:    The function fails if the byte range is not within the *            the file, or if there is not enough memory to cache *            the bytes properly (which usually means that `size' is *            too big in both cases). * ******************************************************************/  FT_EXPORT_FUNC( TT_Error )  TT_Access_Frame( STREAM_ARGS FRAME_ARGS Long  size )  {    TT_Error  error;    if ( CUR_Frame.address != NULL )      return TT_Err_Nested_Frame_Access;    if ( size <= FRAME_CACHE_SIZE )    {      /* use the cache */      CUR_Frame.address = files.frame_cache;      CUR_Frame.size    = FRAME_CACHE_SIZE;    }    else    {      if ( ALLOC( CUR_Frame.address, size ) )        return error;      CUR_Frame.size    = size;    }    error = TT_Read_File( STREAM_VARS (void*)CUR_Frame.address, size );    if ( error )    {      if ( size > FRAME_CACHE_SIZE )        FREE( CUR_Frame.address );      CUR_Frame.address = NULL;      CUR_Frame.size    = 0;    }    CUR_Frame.cursor = CUR_Frame.address;    return error;  }/******************************************************************* * *  Function    :  TT_Check_And_Access_Frame * *  Description :  Notifies the component that we're going to read *                 `size' bytes from the current file position. *                 This function should load/cache/map these bytes *                 so that they will be addressed by the GET_xxx() *                 functions easily. * *  Input  :  size   number of bytes to access. * *  Output :  SUCCESS on success.  FAILURE on error. * *  Notes:    The function truncates `size' if the byte range is not *            within the file. * *            It will fail if there is not enough memory to cache *            the bytes properly (which usually means that `size' is *            too big). * *            It will fail if you make two consecutive calls *            to TT_Access_Frame(), without a TT_Forget_Frame() between *            them. * *            The only difference with TT_Access_Frame() is that we *            check that the frame is within the current file.  We *            otherwise truncate it. * ******************************************************************/  FT_EXPORT_FUNC( TT_Error )  TT_Check_And_Access_Frame( STREAM_ARGS FRAME_ARGS Long  size )  {    TT_Error  error;    Long      readBytes, requested;    if ( CUR_Frame.address != NULL )      return TT_Err_Nested_Frame_Access;    if ( size <= FRAME_CACHE_SIZE )    {      /* use the cache */      CUR_Frame.address = files.frame_cache;      CUR_Frame.size    = FRAME_CACHE_SIZE;    }    else    {      if ( ALLOC( CUR_Frame.address, size ) )        return error;      CUR_Frame.size    = size;    }    requested = size;    readBytes = CUR_Stream->size - TT_File_Pos( STREAM_VAR );    if ( size > readBytes )      size = readBytes;    error = TT_Read_File( STREAM_VARS (void*)CUR_Frame.address, size );    if ( error )    {      if ( requested > FRAME_CACHE_SIZE )        FREE( CUR_Frame.address );      CUR_Frame.address = NULL;      CUR_Frame.size    = 0;    }    CUR_Frame.cursor = CUR_Frame.address;    return error;  }/******************************************************************* * *  Function    :  TT_Forget_Frame * *  Description :  Releases a cached frame after reading. * *  Input  :  None * *  Output :  SUCCESS on success.  FAILURE on error. * ******************************************************************/  FT_EXPORT_FUNC( TT_Error )  TT_Forget_Frame( FRAME_ARG )  {    if ( CUR_Frame.address == NULL )      return TT_Err_Nested_Frame_Access;    if ( CUR_Frame.size > FRAME_CACHE_SIZE )      FREE( CUR_Frame.address );    ZERO_Frame( CUR_Frame );    return TT_Err_Ok;  }#else /* TT_CONFIG_OPTION_THREAD_SAFE */  /*******************************************************************/  /*******************************************************************/  /*******************************************************************/

⌨️ 快捷键说明

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