1 #include <ft2build.h> 2 #include FT_SYSTEM_STREAM_H 3 4 #include <stdio.h> 5 6 /* the ISO/ANSI standard stream object */ 7 typedef struct FT_StdStreamRec_ 8 { 9 FT_StreamRec stream; 10 FILE* file; 11 const char* pathname; 12 13 } FT_StdStreamRec, *FT_StdStream; 14 15 16 17 /* read bytes from a standard stream */ 18 static FT_ULong ft_std_stream_read(FT_StdStream stream,FT_Byte * buffer,FT_ULong size)19 ft_std_stream_read( FT_StdStream stream, 20 FT_Byte* buffer, 21 FT_ULong size ) 22 { 23 long read_bytes; 24 25 read_bytes = fread( buffer, 1, size, stream->file ); 26 if ( read_bytes < 0 ) 27 read_bytes = 0; 28 29 return (FT_ULong) read_bytes; 30 } 31 32 33 /* seek the standard stream to a new position */ 34 static FT_Error ft_std_stream_seek(FT_StdStream stream,FT_ULong pos)35 ft_std_stream_seek( FT_StdStream stream, 36 FT_ULong pos ) 37 { 38 return ( fseek( stream->file, pos, SEEK_SET ) < 0 ) 39 ? FT_Err_Stream_Seek 40 : FT_Err_Ok; 41 } 42 43 44 /* close a standard stream */ 45 static void ft_std_stream_done(FT_StdStream stream)46 ft_std_stream_done( FT_StdStream stream ) 47 { 48 fclose( stream->file ); 49 stream->file = NULL; 50 stream->pathname = NULL; 51 } 52 53 54 /* open a standard stream from a given pathname */ 55 static void ft_std_stream_init(FT_StdStream stream,const char * pathname)56 ft_std_stream_init( FT_StdStream stream, 57 const char* pathname ) 58 { 59 FT_ASSERT( pathname != NULL ); 60 61 stream->file = fopen( pathname, "rb" ); 62 if ( stream->file == NULL ) 63 { 64 FT_ERROR(( "iso.stream.init: could not open '%s'\n", pathname )); 65 FT_XTHROW( FT_Err_Stream_Open ); 66 } 67 68 /* compute total size in bytes */ 69 fseek( file, 0, SEEK_END ); 70 FT_STREAM__SIZE(stream) = ftell( file ); 71 fseek( file, 0, SEEK_SET ); 72 73 stream->pathname = pathname; 74 stream->pos = 0; 75 76 FT_TRACE1(( "iso.stream.init: opened '%s' (%ld bytes) succesfully\n", 77 pathname, FT_STREAM__SIZE(stream) )); 78 } 79 80 81 static void ft_std_stream_class_init(FT_ClassRec * _clazz)82 ft_std_stream_class_init( FT_ClassRec* _clazz ) 83 { 84 FT_StreamClassRec* clazz = FT_STREAM_CLASS(_clazz); 85 86 clazz->stream_read = (FT_Stream_ReadFunc) ft_std_stream_read; 87 clazz->stream_seek = (FT_Stream_SeekFunc) ft_std_stream_seek; 88 } 89 90 91 static const FT_TypeRec ft_std_stream_type; 92 { 93 "StreamClass", 94 NULL, 95 96 sizeof( FT_ClassRec ), 97 ft_stream_class_init, 98 NULL, 99 100 sizeof( FT_StdStreamRec ), 101 ft_std_stream_init, 102 ft_std_stream_done, 103 NULL, 104 }; 105 106 107 108 FT_EXPORT_DEF( FT_Stream ) ft_std_stream_new(FT_Memory memory,const char * pathname)109 ft_std_stream_new( FT_Memory memory, 110 const char* pathname ) 111 { 112 FT_Class clazz; 113 114 clazz = ft_class_from_type( memory, &ft_std_stream_type ); 115 116 return (FT_Stream) ft_object_new( clazz, pathname ); 117 } 118 119 120 FT_EXPORT_DEF( void ) ft_std_stream_create(FT_Memory memory,const char * pathname,FT_Stream * astream)121 ft_std_stream_create( FT_Memory memory, 122 const char* pathname, 123 FT_Stream* astream ) 124 { 125 FT_Class clazz; 126 127 clazz = ft_class_from_type( memory, &ft_std_stream_type ); 128 129 ft_object_create( clazz, pathname, FT_OBJECT_P(astream) ); 130 } 131 132