xref: /inferno-os/libfreetype/ftsysio.c (revision 46439007cf417cbd9ac8049bb4122c890097a0fa)
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
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
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
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
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
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 )
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 )
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