Visualization Library 2.0.0-b5

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
ftsystem.c
Go to the documentation of this 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* )
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* )
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 )
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 )
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 )
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 
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 )
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 
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 
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 )
411  {
412 #ifdef FT_DEBUG_MEMORY
413  ft_mem_debug_done( memory );
414 #endif
415  memory->free( memory, memory );
416  }
417 
418 
419 /* END */
int FT_Error
Definition: fttypes.h:296
FT_New_Memory(void)
Definition: ftsystem.c:475
GLuint GLuint stream
int read(int fd, char *buf, int nbytes)
Definition: tif_acorn.c:331
#define NULL
Definition: ftobjs.h:61
signed int FT_Int
Definition: fttypes.h:216
#define FT_UNUSED(arg)
Definition: ftconfig.h:76
char * malloc()
return FT_Err_Ok
Definition: ftbbox.c:645
ft_close_stream_by_munmap(FT_Stream stream)
Definition: ftsystem.c:195
typedef void(APIENTRY *GLDEBUGPROCARB)(GLenum source
#define FT_TRACE1(varformat)
Definition: ftdebug.h:158
#define const
Definition: zconf.h:91
#define FT_ERROR(varformat)
Definition: ftdebug.h:181
#define FT_BASE_DEF(x)
Definition: ftconfig.h:258
FT_Stream_Open(FT_Stream stream, const char *filepathname)
Definition: ftsystem.c:381
GLenum const GLvoid * addr
GLenum GLsizei len
int close(int fd)
Definition: tif_acorn.c:320
typedef long(ZCALLBACK *tell_file_func) OF((voidpf opaque
int free()
#define FT_CALLBACK_DEF(x)
Definition: ftconfig.h:323
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
#define MUNMAP_ARG_CAST
Definition: ftsystem.c:41
#define MAP_FILE
Definition: ftsystem.c:35
ft_free(FT_Memory memory, void *block)
Definition: ftsystem.c:213
int open(const char *name, int flags, int mode)
Definition: tif_acorn.c:285
ft_close_stream_by_free(FT_Stream stream)
Definition: ftsystem.c:217
ft_alloc(FT_Memory memory, long size)
Definition: ftsystem.c:141
FT_Done_Memory(FT_Memory memory)
Definition: ftsystem.c:515
GLsizeiptr size
ft_realloc(FT_Memory memory, long cur_size, long new_size, void *block)
Definition: ftsystem.c:173