1 /***************************************************************************/
2 /* */
3 /* ftstream.c */
4 /* */
5 /* I/O stream support (body). */
6 /* */
7 /* Copyright 2000-2018 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 #include FT_INTERNAL_STREAM_H
21 #include FT_INTERNAL_DEBUG_H
22
23
24 /*************************************************************************/
25 /* */
26 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
27 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
28 /* messages during execution. */
29 /* */
30 #undef FT_COMPONENT
31 #define FT_COMPONENT trace_stream
32
33
34 FT_BASE_DEF( void )
35 FT_Stream_OpenMemory( FT_Stream stream,
36 const FT_Byte* base,
37 FT_ULong size )
38 {
39 stream->base = (FT_Byte*) base;
40 stream->size = size;
41 stream->pos = 0;
42 stream->cursor = NULL;
43 stream->read = NULL;
44 stream->close = NULL;
45 }
46
47
48 FT_BASE_DEF( void )
49 FT_Stream_Close( FT_Stream stream )
50 {
51 if ( stream && stream->close )
202 {
203 *pbytes = (FT_Byte*)stream->cursor;
204
205 /* equivalent to FT_Stream_ExitFrame(), with no memory block release */
206 stream->cursor = NULL;
207 stream->limit = NULL;
208 }
209
210 return error;
211 }
212
213
214 FT_BASE_DEF( void )
215 FT_Stream_ReleaseFrame( FT_Stream stream,
216 FT_Byte** pbytes )
217 {
218 if ( stream && stream->read )
219 {
220 FT_Memory memory = stream->memory;
221
222 #ifdef FT_DEBUG_MEMORY
223 ft_mem_free( memory, *pbytes );
224 *pbytes = NULL;
225 #else
226 FT_FREE( *pbytes );
227 #endif
228 }
229 *pbytes = NULL;
230 }
231
232
233 FT_BASE_DEF( FT_Error )
234 FT_Stream_EnterFrame( FT_Stream stream,
235 FT_ULong count )
236 {
237 FT_Error error = FT_Err_Ok;
238 FT_ULong read_bytes;
239
240
241 /* check for nested frame access */
242 FT_ASSERT( stream && stream->cursor == 0 );
243
244 if ( stream->read )
245 {
246 /* allocate the frame in memory */
247 FT_Memory memory = stream->memory;
248
249
250 /* simple sanity check */
251 if ( count > stream->size )
252 {
253 FT_ERROR(( "FT_Stream_EnterFrame:"
254 " frame size (%lu) larger than stream size (%lu)\n",
255 count, stream->size ));
256
257 error = FT_THROW( Invalid_Stream_Operation );
258 goto Exit;
259 }
260
264 (FT_Long)count,
265 &error );
266 if ( error )
267 goto Exit;
268 #else
269 if ( FT_QALLOC( stream->base, count ) )
270 goto Exit;
271 #endif
272 /* read it */
273 read_bytes = stream->read( stream, stream->pos,
274 stream->base, count );
275 if ( read_bytes < count )
276 {
277 FT_ERROR(( "FT_Stream_EnterFrame:"
278 " invalid read; expected %lu bytes, got %lu\n",
279 count, read_bytes ));
280
281 FT_FREE( stream->base );
282 error = FT_THROW( Invalid_Stream_Operation );
283 }
284 stream->cursor = stream->base;
285 stream->limit = stream->cursor + count;
286 stream->pos += read_bytes;
287 }
288 else
289 {
290 /* check current and new position */
291 if ( stream->pos >= stream->size ||
292 stream->size - stream->pos < count )
293 {
294 FT_ERROR(( "FT_Stream_EnterFrame:"
295 " invalid i/o; pos = 0x%lx, count = %lu, size = 0x%lx\n",
296 stream->pos, count, stream->size ));
297
298 error = FT_THROW( Invalid_Stream_Operation );
299 goto Exit;
300 }
301
302 /* set cursor */
303 stream->cursor = stream->base + stream->pos;
304 stream->limit = stream->cursor + count;
305 stream->pos += count;
306 }
307
308 Exit:
309 return error;
310 }
311
312
313 FT_BASE_DEF( void )
314 FT_Stream_ExitFrame( FT_Stream stream )
315 {
316 /* IMPORTANT: The assertion stream->cursor != 0 was removed, given */
317 /* that it is possible to access a frame of length 0 in */
318 /* some weird fonts (usually, when accessing an array of */
319 /* 0 records, like in some strange kern tables). */
320 /* */
321 /* In this case, the loader code handles the 0-length table */
322 /* gracefully; however, stream.cursor is really set to 0 by the */
323 /* FT_Stream_EnterFrame() call, and this is not an error. */
324 /* */
325 FT_ASSERT( stream );
326
327 if ( stream->read )
328 {
329 FT_Memory memory = stream->memory;
330
331 #ifdef FT_DEBUG_MEMORY
332 ft_mem_free( memory, stream->base );
333 stream->base = NULL;
334 #else
335 FT_FREE( stream->base );
336 #endif
337 }
338 stream->cursor = NULL;
339 stream->limit = NULL;
340 }
341
342
343 FT_BASE_DEF( FT_Char )
344 FT_Stream_GetChar( FT_Stream stream )
345 {
346 FT_Char result;
347
348
349 FT_ASSERT( stream && stream->cursor );
350
351 result = 0;
352 if ( stream->cursor < stream->limit )
353 result = (FT_Char)*stream->cursor++;
354
355 return result;
356 }
357
|
1 /****************************************************************************
2 *
3 * ftstream.c
4 *
5 * I/O stream support (body).
6 *
7 * Copyright (C) 2000-2019 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 #include FT_INTERNAL_STREAM_H
21 #include FT_INTERNAL_DEBUG_H
22
23
24 /**************************************************************************
25 *
26 * The macro FT_COMPONENT is used in trace mode. It is an implicit
27 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
28 * messages during execution.
29 */
30 #undef FT_COMPONENT
31 #define FT_COMPONENT stream
32
33
34 FT_BASE_DEF( void )
35 FT_Stream_OpenMemory( FT_Stream stream,
36 const FT_Byte* base,
37 FT_ULong size )
38 {
39 stream->base = (FT_Byte*) base;
40 stream->size = size;
41 stream->pos = 0;
42 stream->cursor = NULL;
43 stream->read = NULL;
44 stream->close = NULL;
45 }
46
47
48 FT_BASE_DEF( void )
49 FT_Stream_Close( FT_Stream stream )
50 {
51 if ( stream && stream->close )
202 {
203 *pbytes = (FT_Byte*)stream->cursor;
204
205 /* equivalent to FT_Stream_ExitFrame(), with no memory block release */
206 stream->cursor = NULL;
207 stream->limit = NULL;
208 }
209
210 return error;
211 }
212
213
214 FT_BASE_DEF( void )
215 FT_Stream_ReleaseFrame( FT_Stream stream,
216 FT_Byte** pbytes )
217 {
218 if ( stream && stream->read )
219 {
220 FT_Memory memory = stream->memory;
221
222
223 #ifdef FT_DEBUG_MEMORY
224 ft_mem_free( memory, *pbytes );
225 #else
226 FT_FREE( *pbytes );
227 #endif
228 }
229
230 *pbytes = NULL;
231 }
232
233
234 FT_BASE_DEF( FT_Error )
235 FT_Stream_EnterFrame( FT_Stream stream,
236 FT_ULong count )
237 {
238 FT_Error error = FT_Err_Ok;
239 FT_ULong read_bytes;
240
241
242 FT_TRACE7(( "FT_Stream_EnterFrame: %ld bytes\n", count ));
243
244 /* check for nested frame access */
245 FT_ASSERT( stream && stream->cursor == 0 );
246
247 if ( stream->read )
248 {
249 /* allocate the frame in memory */
250 FT_Memory memory = stream->memory;
251
252
253 /* simple sanity check */
254 if ( count > stream->size )
255 {
256 FT_ERROR(( "FT_Stream_EnterFrame:"
257 " frame size (%lu) larger than stream size (%lu)\n",
258 count, stream->size ));
259
260 error = FT_THROW( Invalid_Stream_Operation );
261 goto Exit;
262 }
263
267 (FT_Long)count,
268 &error );
269 if ( error )
270 goto Exit;
271 #else
272 if ( FT_QALLOC( stream->base, count ) )
273 goto Exit;
274 #endif
275 /* read it */
276 read_bytes = stream->read( stream, stream->pos,
277 stream->base, count );
278 if ( read_bytes < count )
279 {
280 FT_ERROR(( "FT_Stream_EnterFrame:"
281 " invalid read; expected %lu bytes, got %lu\n",
282 count, read_bytes ));
283
284 FT_FREE( stream->base );
285 error = FT_THROW( Invalid_Stream_Operation );
286 }
287
288 stream->cursor = stream->base;
289 stream->limit = stream->cursor + count;
290 stream->pos += read_bytes;
291 }
292 else
293 {
294 /* check current and new position */
295 if ( stream->pos >= stream->size ||
296 stream->size - stream->pos < count )
297 {
298 FT_ERROR(( "FT_Stream_EnterFrame:"
299 " invalid i/o; pos = 0x%lx, count = %lu, size = 0x%lx\n",
300 stream->pos, count, stream->size ));
301
302 error = FT_THROW( Invalid_Stream_Operation );
303 goto Exit;
304 }
305
306 /* set cursor */
307 stream->cursor = stream->base + stream->pos;
308 stream->limit = stream->cursor + count;
309 stream->pos += count;
310 }
311
312 Exit:
313 return error;
314 }
315
316
317 FT_BASE_DEF( void )
318 FT_Stream_ExitFrame( FT_Stream stream )
319 {
320 /* IMPORTANT: The assertion stream->cursor != 0 was removed, given */
321 /* that it is possible to access a frame of length 0 in */
322 /* some weird fonts (usually, when accessing an array of */
323 /* 0 records, like in some strange kern tables). */
324 /* */
325 /* In this case, the loader code handles the 0-length table */
326 /* gracefully; however, stream.cursor is really set to 0 by the */
327 /* FT_Stream_EnterFrame() call, and this is not an error. */
328
329 FT_TRACE7(( "FT_Stream_ExitFrame\n" ));
330
331 FT_ASSERT( stream );
332
333 if ( stream->read )
334 {
335 FT_Memory memory = stream->memory;
336
337
338 #ifdef FT_DEBUG_MEMORY
339 ft_mem_free( memory, stream->base );
340 stream->base = NULL;
341 #else
342 FT_FREE( stream->base );
343 #endif
344 }
345
346 stream->cursor = NULL;
347 stream->limit = NULL;
348 }
349
350
351 FT_BASE_DEF( FT_Char )
352 FT_Stream_GetChar( FT_Stream stream )
353 {
354 FT_Char result;
355
356
357 FT_ASSERT( stream && stream->cursor );
358
359 result = 0;
360 if ( stream->cursor < stream->limit )
361 result = (FT_Char)*stream->cursor++;
362
363 return result;
364 }
365
|