1 /***************************************************************************/ 2 /* */ 3 /* ftsystem.c */ 4 /* */ 5 /* VMS-specific FreeType low-level system interface (body). */ 6 /* */ 7 /* Copyright (C) 1996-2020 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 <freetype/internal/ftdebug.h> 23 #include <freetype/ftsystem.h> 24 #include <freetype/fterrors.h> 25 #include <freetype/fttypes.h> 26 #include <freetype/internal/ftobjs.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 71 72 /*************************************************************************/ 73 /* */ 74 /* MEMORY MANAGEMENT INTERFACE */ 75 /* */ 76 /*************************************************************************/ 77 78 79 /*************************************************************************/ 80 /* */ 81 /* <Function> */ 82 /* ft_alloc */ 83 /* */ 84 /* <Description> */ 85 /* The memory allocation function. */ 86 /* */ 87 /* <Input> */ 88 /* memory :: A pointer to the memory object. */ 89 /* */ 90 /* size :: The requested size in bytes. */ 91 /* */ 92 /* <Return> */ 93 /* The address of newly allocated block. */ 94 /* */ 95 FT_CALLBACK_DEF( void* ) ft_alloc(FT_Memory memory,long size)96 ft_alloc( FT_Memory memory, 97 long size ) 98 { 99 FT_UNUSED( memory ); 100 101 return malloc( size ); 102 } 103 104 105 /*************************************************************************/ 106 /* */ 107 /* <Function> */ 108 /* ft_realloc */ 109 /* */ 110 /* <Description> */ 111 /* The memory reallocation function. */ 112 /* */ 113 /* <Input> */ 114 /* memory :: A pointer to the memory object. */ 115 /* */ 116 /* cur_size :: The current size of the allocated memory block. */ 117 /* */ 118 /* new_size :: The newly requested size in bytes. */ 119 /* */ 120 /* block :: The current address of the block in memory. */ 121 /* */ 122 /* <Return> */ 123 /* The address of the reallocated memory block. */ 124 /* */ 125 FT_CALLBACK_DEF( void* ) ft_realloc(FT_Memory memory,long cur_size,long new_size,void * block)126 ft_realloc( FT_Memory memory, 127 long cur_size, 128 long new_size, 129 void* block ) 130 { 131 FT_UNUSED( memory ); 132 FT_UNUSED( cur_size ); 133 134 return realloc( block, new_size ); 135 } 136 137 138 /*************************************************************************/ 139 /* */ 140 /* <Function> */ 141 /* ft_free */ 142 /* */ 143 /* <Description> */ 144 /* The memory release function. */ 145 /* */ 146 /* <Input> */ 147 /* memory :: A pointer to the memory object. */ 148 /* */ 149 /* block :: The address of block in memory to be freed. */ 150 /* */ 151 FT_CALLBACK_DEF( void ) ft_free(FT_Memory memory,void * block)152 ft_free( FT_Memory memory, 153 void* block ) 154 { 155 FT_UNUSED( memory ); 156 157 free( block ); 158 } 159 160 161 /*************************************************************************/ 162 /* */ 163 /* RESOURCE MANAGEMENT INTERFACE */ 164 /* */ 165 /*************************************************************************/ 166 167 168 /*************************************************************************/ 169 /* */ 170 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 171 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 172 /* messages during execution. */ 173 /* */ 174 #undef FT_COMPONENT 175 #define FT_COMPONENT io 176 177 /* We use the macro STREAM_FILE for convenience to extract the */ 178 /* system-specific stream handle from a given FreeType stream object */ 179 #define STREAM_FILE( stream ) ( (FILE*)stream->descriptor.pointer ) 180 181 182 /*************************************************************************/ 183 /* */ 184 /* <Function> */ 185 /* ft_close_stream */ 186 /* */ 187 /* <Description> */ 188 /* The function to close a stream. */ 189 /* */ 190 /* <Input> */ 191 /* stream :: A pointer to the stream object. */ 192 /* */ 193 FT_CALLBACK_DEF( void ) ft_close_stream(FT_Stream stream)194 ft_close_stream( FT_Stream stream ) 195 { 196 munmap( (MUNMAP_ARG_CAST)stream->descriptor.pointer, stream->size ); 197 198 stream->descriptor.pointer = NULL; 199 stream->size = 0; 200 stream->base = 0; 201 } 202 203 204 /* documentation is in ftobjs.h */ 205 206 FT_BASE_DEF( FT_Error ) FT_Stream_Open(FT_Stream stream,const char * filepathname)207 FT_Stream_Open( FT_Stream stream, 208 const char* filepathname ) 209 { 210 int file; 211 struct stat stat_buf; 212 213 214 if ( !stream ) 215 return FT_THROW( Invalid_Stream_Handle ); 216 217 /* open the file */ 218 file = open( filepathname, O_RDONLY ); 219 if ( file < 0 ) 220 { 221 FT_ERROR(( "FT_Stream_Open:" )); 222 FT_ERROR(( " could not open `%s'\n", filepathname )); 223 return FT_THROW( Cannot_Open_Resource ); 224 } 225 226 if ( fstat( file, &stat_buf ) < 0 ) 227 { 228 FT_ERROR(( "FT_Stream_Open:" )); 229 FT_ERROR(( " could not `fstat' file `%s'\n", filepathname )); 230 goto Fail_Map; 231 } 232 233 stream->size = stat_buf.st_size; 234 if ( !stream->size ) 235 { 236 FT_ERROR(( "FT_Stream_Open:" )); 237 FT_ERROR(( " opened `%s' but zero-sized\n", filepathname )); 238 goto Fail_Map; 239 } 240 241 stream->pos = 0; 242 stream->base = (unsigned char *)mmap( NULL, 243 stream->size, 244 PROT_READ, 245 MAP_FILE | MAP_PRIVATE, 246 file, 247 0 ); 248 249 if ( (long)stream->base == -1 ) 250 { 251 FT_ERROR(( "FT_Stream_Open:" )); 252 FT_ERROR(( " could not `mmap' file `%s'\n", filepathname )); 253 goto Fail_Map; 254 } 255 256 close( file ); 257 258 stream->descriptor.pointer = stream->base; 259 stream->pathname.pointer = (char*)filepathname; 260 261 stream->close = ft_close_stream; 262 stream->read = 0; 263 264 FT_TRACE1(( "FT_Stream_Open:" )); 265 FT_TRACE1(( " opened `%s' (%d bytes) successfully\n", 266 filepathname, stream->size )); 267 268 return FT_Err_Ok; 269 270 Fail_Map: 271 close( file ); 272 273 stream->base = NULL; 274 stream->size = 0; 275 stream->pos = 0; 276 277 return FT_THROW( Cannot_Open_Stream ); 278 } 279 280 281 #ifdef FT_DEBUG_MEMORY 282 283 extern FT_Int 284 ft_mem_debug_init( FT_Memory memory ); 285 286 extern void 287 ft_mem_debug_done( FT_Memory memory ); 288 289 #endif 290 291 292 /* documentation is in ftobjs.h */ 293 294 FT_BASE_DEF( FT_Memory ) FT_New_Memory(void)295 FT_New_Memory( void ) 296 { 297 FT_Memory memory; 298 299 300 memory = (FT_Memory)malloc( sizeof ( *memory ) ); 301 if ( memory ) 302 { 303 memory->user = 0; 304 memory->alloc = ft_alloc; 305 memory->realloc = ft_realloc; 306 memory->free = ft_free; 307 #ifdef FT_DEBUG_MEMORY 308 ft_mem_debug_init( memory ); 309 #endif 310 } 311 312 return memory; 313 } 314 315 316 /* documentation is in ftobjs.h */ 317 318 FT_BASE_DEF( void ) FT_Done_Memory(FT_Memory memory)319 FT_Done_Memory( FT_Memory memory ) 320 { 321 #ifdef FT_DEBUG_MEMORY 322 ft_mem_debug_done( memory ); 323 #endif 324 memory->free( memory, memory ); 325 } 326 327 328 /* END */ 329