text: /***************************************************************************/
  /*                                                                         */
  /*  ftsystem.c                                                             */
  /*                                                                         */
  /*    VMS-specific FreeType low-level system interface (body).             */
  /*                                                                         */
  /*  Copyright (C) 1996-2020 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.                                        */
  /*                                                                         */
  /***************************************************************************/
  
  
  #include <ft2build.h>
  /* we use our special ftconfig.h file, not the standard one */
  #include <ftconfig.h>
  #include FT_INTERNAL_DEBUG_H
  #include FT_SYSTEM_H
  #include FT_ERRORS_H
  #include FT_TYPES_H
  #include FT_INTERNAL_OBJECTS_H
  
  /* memory-mapping includes and definitions */
  #ifdef HAVE_UNISTD_H
  #include <unistd.h>
  #endif
  
  #include <sys/mman.h>
  
  #ifndef MAP_FILE
  #define MAP_FILE  0x00
  #endif
  
  #ifdef MUNMAP_USES_VOIDP
  #define MUNMAP_ARG_CAST  void *
  #else
  #define MUNMAP_ARG_CAST  char *
  #endif
  
  #ifdef NEED_MUNMAP_DECL
  
  #ifdef __cplusplus
  extern "C"
  #else
  extern
  #endif
  int
  munmap( char*  addr,
          int    len );
  
  #define MUNMAP_ARG_CAST  char *
  
  #endif /* NEED_DECLARATION_MUNMAP */
  
  #include <sys/types.h>
  #include <sys/stat.h>
  
  #ifdef HAVE_FCNTL_H
  #include <fcntl.h>
  #endif
  
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  
  
  /*************************************************************************/
  /*                                                                       */
  /*                       MEMORY MANAGEMENT INTERFACE                     */
  /*                                                                       */
  /*************************************************************************/
  
  
  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    ft_alloc                                                           */
  /*                                                                       */
  /* <Description>                                                         */
  /*    The memory allocation function.                                    */
  /*                                                                       */
  /* <Input>                                                               */
  /*    memory :: A pointer to the memory object.                          */
  /*                                                                       */
  /*    size   :: The requested size in bytes.                             */
  /*                                                                       */
  /* <Return>                                                              */
  /*    The address of newly allocated block.                              */
  /*                                                                       */
  FT_CALLBACK_DEF (void*)
  ft_alloc( FT_Memory
  memory,
  long size
  )
  {
  FT_UNUSED( memory );
  
  return
  malloc( size );
  }
  
  
  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    ft_realloc                                                         */
  /*                                                                       */
  /* <Description>                                                         */
  /*    The memory reallocation function.                                  */
  /*                                                                       */
  /* <Input>                                                               */
  /*    memory   :: A pointer to the memory object.                        */
  /*                                                                       */
  /*    cur_size :: The current size of the allocated memory block.        */
  /*                                                                       */
  /*    new_size :: The newly requested size in bytes.                     */
  /*                                                                       */
  /*    block    :: The current address of the block in memory.            */
  /*                                                                       */
  /* <Return>                                                              */
  /*    The address of the reallocated memory block.                       */
  /*                                                                       */
  FT_CALLBACK_DEF (void*)
  ft_realloc( FT_Memory
  memory,
  long cur_size,
  long new_size,
  void* block
  )
  {
  FT_UNUSED( memory );
  FT_UNUSED( cur_size );
  
  return
  realloc( block, new_size
  );
  }
  
  
  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    ft_free                                                            */
  /*                                                                       */
  /* <Description>                                                         */
  /*    The memory release function.                                       */
  /*                                                                       */
  /* <Input>                                                               */
  /*    memory :: A pointer to the memory object.                          */
  /*                                                                       */
  /*    block  :: The address of block in memory to be freed.              */
  /*                                                                       */
  FT_CALLBACK_DEF (void)
  ft_free( FT_Memory
  memory,
  void* block
  )
  {
  FT_UNUSED( memory );
  
  free( block );
  }
  
  
  /*************************************************************************/
  /*                                                                       */
  /*                     RESOURCE MANAGEMENT INTERFACE                     */
  /*                                                                       */
  /*************************************************************************/
  
  
  /*************************************************************************/
  /*                                                                       */
  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
  /* messages during execution.                                            */
  /*                                                                       */
  #undef  FT_COMPONENT
  #define FT_COMPONENT  io
  
  /* We use the macro STREAM_FILE for convenience to extract the       */
  /* system-specific stream handle from a given FreeType stream object */
  #define STREAM_FILE(stream)  ( (FILE*)stream->descriptor.pointer )
  
  
  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    ft_close_stream                                                    */
  /*                                                                       */
  /* <Description>                                                         */
  /*    The function to close a stream.                                    */
  /*                                                                       */
  /* <Input>                                                               */
  /*    stream :: A pointer to the stream object.                          */
  /*                                                                       */
  FT_CALLBACK_DEF (void)
  ft_close_stream( FT_Stream
  stream )
  {
  munmap((MUNMAP_ARG_CAST)stream->descriptor.pointer, stream->size );
  
  stream->descriptor.
  pointer = NULL;
  stream->
  size = 0;
  stream->
  base = 0;
  }
  
  /* documentation is in ftobjs.h */
  
  FT_BASE_DEF( FT_Error )
  FT_Stream_Open( FT_Stream
  stream,
  const char* filepathname
  )
  {
  int file;
  struct stat stat_buf;
  
  if ( !stream )
  return
  FT_THROW( Invalid_Stream_Handle );
  
  /* open the file */
  file = open (filepathname, O_RDONLY);
  if ( file < 0 )
  {
  FT_ERROR(( "FT_Stream_Open:" ));
  FT_ERROR(( " could not open `%s'\n", filepathname ));
  return
  FT_THROW( Cannot_Open_Resource );
  }
  
  if (
  fstat( file,
  &stat_buf ) < 0 )
  {
  FT_ERROR(( "FT_Stream_Open:" ));
  FT_ERROR(( " could not `fstat' file `%s'\n", filepathname ));
  goto
  Fail_Map;
  }
  
  stream->
  size = stat_buf.st_size;
  if ( !stream->size )
  {
  FT_ERROR(( "FT_Stream_Open:" ));
  FT_ERROR(( " opened `%s' but zero-sized\n", filepathname ));
  goto
  Fail_Map;
  }
  
  stream->
  pos = 0;
  stream->
  base = (unsigned char*) mmap (NULL,
                                stream->size,
                                PROT_READ,
                                MAP_FILE | MAP_PRIVATE,
                                file,
                                0);
  
  if ((long)stream->base == -1 )
  {
  FT_ERROR(( "FT_Stream_Open:" ));
  FT_ERROR(( " could not `mmap' file `%s'\n", filepathname ));
  goto
  Fail_Map;
  }
  
  close( file );
  
  stream->descriptor.
  pointer = stream->base;
  stream->pathname.
  pointer = (char*) filepathname;
  
  stream->
  close = ft_close_stream;
  stream->
  read = 0;
  
  FT_TRACE1(( "FT_Stream_Open:" ));
  FT_TRACE1(( " opened `%s' (%d bytes) successfully\n",
  filepathname, stream->size ));
  
  return
  FT_Err_Ok;
  
  Fail_Map:
  close( file );
  
  stream->
  base = NULL;
  stream->
  size = 0;
  stream->
  pos = 0;
  
  return
  FT_THROW( Cannot_Open_Stream );
  }
  
  #ifdef FT_DEBUG_MEMORY
  
  extern FT_Int
  ft_mem_debug_init( FT_Memory  memory );
  
  extern void
  ft_mem_debug_done( FT_Memory  memory );
  
  #endif
  
  /* documentation is in ftobjs.h */
  
  FT_BASE_DEF( FT_Memory )
  
  FT_New_Memory (void) {
    FT_Memory memory;
  
    memory = (FT_Memory)
    malloc (sizeof (*memory));
    if (memory) {
      memory->user = 0;
      memory->alloc = ft_alloc;
      memory->realloc = ft_realloc;
      memory->free = ft_free;
  #ifdef FT_DEBUG_MEMORY
      ft_mem_debug_init( memory );
  #endif
    }
  
    return memory;
  }
  
  /* documentation is in ftobjs.h */
  
  FT_BASE_DEF (void)
  FT_Done_Memory( FT_Memory
  memory )
  {
  #ifdef FT_DEBUG_MEMORY
  ft_mem_debug_done( memory );
  #endif
  memory->
  free( memory, memory
  );
  }
  
  
  /* END */
  