1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/ 2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* ftstream.c */ 4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* I/O stream support (body). */ 6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Copyright 2000-2002, 2004-2006, 2008-2011, 2013 by */ 8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* This file is part of the FreeType project, and may only be used, */ 11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* modified, and distributed under the terms of the FreeType project */ 12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* this file you indicate that you have read the license and */ 14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* understand and accept it fully. */ 15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/ 17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 19e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include <ft2build.h> 20e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include FT_INTERNAL_STREAM_H 21e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include FT_INTERNAL_DEBUG_H 22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* messages during execution. */ 29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef FT_COMPONENT 31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_COMPONENT trace_stream 32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( void ) 35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_OpenMemory( FT_Stream stream, 36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FT_Byte* base, 37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong size ) 38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->base = (FT_Byte*) base; 40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->size = size; 41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->pos = 0; 42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->cursor = 0; 43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->read = 0; 44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->close = 0; 45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( void ) 49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_Close( FT_Stream stream ) 50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( stream && stream->close ) 52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->close( stream ); 53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_Error ) 57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_Seek( FT_Stream stream, 58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong pos ) 59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_Err_Ok; 61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( stream->read ) 64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( stream->read( stream, pos, 0, 0 ) ) 66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "FT_Stream_Seek:" 68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " invalid i/o; pos = 0x%lx, size = 0x%lx\n", 69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pos, stream->size )); 70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_Stream_Operation ); 72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* note that seeking to the first position after the file is valid */ 75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( pos > stream->size ) 76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "FT_Stream_Seek:" 78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " invalid i/o; pos = 0x%lx, size = 0x%lx\n", 79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pos, stream->size )); 80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_Stream_Operation ); 82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error ) 85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->pos = pos; 86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_Error ) 92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_Skip( FT_Stream stream, 93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long distance ) 94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( distance < 0 ) 96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Stream_Operation ); 97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Stream_Seek( stream, (FT_ULong)( stream->pos + distance ) ); 99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_Long ) 103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_Pos( FT_Stream stream ) 104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return stream->pos; 106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_Error ) 110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_Read( FT_Stream stream, 111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* buffer, 112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong count ) 113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Stream_ReadAt( stream, stream->pos, buffer, count ); 115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_Error ) 119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_ReadAt( FT_Stream stream, 120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong pos, 121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* buffer, 122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong count ) 123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_Err_Ok; 125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong read_bytes; 126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( pos >= stream->size ) 129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "FT_Stream_ReadAt:" 131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " invalid i/o; pos = 0x%lx, size = 0x%lx\n", 132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pos, stream->size )); 133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Stream_Operation ); 135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( stream->read ) 138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov read_bytes = stream->read( stream, pos, buffer, count ); 139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov read_bytes = stream->size - pos; 142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( read_bytes > count ) 143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov read_bytes = count; 144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MEM_COPY( buffer, stream->base + pos, read_bytes ); 146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->pos = pos + read_bytes; 149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( read_bytes < count ) 151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "FT_Stream_ReadAt:" 153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " invalid read; expected %lu bytes, got %lu\n", 154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov count, read_bytes )); 155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_Stream_Operation ); 157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_ULong ) 164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_TryRead( FT_Stream stream, 165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* buffer, 166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong count ) 167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong read_bytes = 0; 169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( stream->pos >= stream->size ) 172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( stream->read ) 175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov read_bytes = stream->read( stream, stream->pos, buffer, count ); 176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov read_bytes = stream->size - stream->pos; 179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( read_bytes > count ) 180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov read_bytes = count; 181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MEM_COPY( buffer, stream->base + stream->pos, read_bytes ); 183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->pos += read_bytes; 186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return read_bytes; 189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_Error ) 193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_ExtractFrame( FT_Stream stream, 194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong count, 195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte** pbytes ) 196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Stream_EnterFrame( stream, count ); 201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error ) 202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *pbytes = (FT_Byte*)stream->cursor; 204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* equivalent to FT_Stream_ExitFrame(), with no memory block release */ 206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->cursor = 0; 207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->limit = 0; 208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( void ) 215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_ReleaseFrame( FT_Stream stream, 216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte** pbytes ) 217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( stream && stream->read ) 219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = stream->memory; 221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_DEBUG_MEMORY 223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_free( memory, *pbytes ); 224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *pbytes = NULL; 225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else 226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( *pbytes ); 227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *pbytes = 0; 230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_Error ) 234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_EnterFrame( FT_Stream stream, 235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong count ) 236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_Err_Ok; 238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong read_bytes; 239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check for nested frame access */ 242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ASSERT( stream && stream->cursor == 0 ); 243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( stream->read ) 245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* allocate the frame in memory */ 247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = stream->memory; 248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* simple sanity check */ 251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( count > stream->size ) 252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "FT_Stream_EnterFrame:" 254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " frame size (%lu) larger than stream size (%lu)\n", 255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov count, stream->size )); 256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_Stream_Operation ); 258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_DEBUG_MEMORY 262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* assume _ft_debug_file and _ft_debug_lineno are already set */ 263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->base = (unsigned char*)ft_mem_qalloc( memory, count, &error ); 264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else 267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_QALLOC( stream->base, count ) ) 268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* read it */ 271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov read_bytes = stream->read( stream, stream->pos, 272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->base, count ); 273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( read_bytes < count ) 274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "FT_Stream_EnterFrame:" 276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " invalid read; expected %lu bytes, got %lu\n", 277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov count, read_bytes )); 278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( stream->base ); 280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_Stream_Operation ); 281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->cursor = stream->base; 283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->limit = stream->cursor + count; 284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->pos += read_bytes; 285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check current and new position */ 289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( stream->pos >= stream->size || 290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->size - stream->pos < count ) 291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "FT_Stream_EnterFrame:" 293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " invalid i/o; pos = 0x%lx, count = %lu, size = 0x%lx\n", 294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->pos, count, stream->size )); 295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_Stream_Operation ); 297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* set cursor */ 301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->cursor = stream->base + stream->pos; 302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->limit = stream->cursor + count; 303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->pos += count; 304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( void ) 312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_ExitFrame( FT_Stream stream ) 313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* IMPORTANT: The assertion stream->cursor != 0 was removed, given */ 315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* that it is possible to access a frame of length 0 in */ 316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* some weird fonts (usually, when accessing an array of */ 317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* 0 records, like in some strange kern tables). */ 318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* In this case, the loader code handles the 0-length table */ 320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* gracefully; however, stream.cursor is really set to 0 by the */ 321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* FT_Stream_EnterFrame() call, and this is not an error. */ 322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ASSERT( stream ); 324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( stream->read ) 326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = stream->memory; 328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_DEBUG_MEMORY 330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_free( memory, stream->base ); 331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->base = NULL; 332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else 333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( stream->base ); 334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->cursor = 0; 337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->limit = 0; 338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_Char ) 342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_GetChar( FT_Stream stream ) 343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Char result; 345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ASSERT( stream && stream->cursor ); 348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = 0; 350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( stream->cursor < stream->limit ) 351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = *stream->cursor++; 352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_UShort ) 358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_GetUShort( FT_Stream stream ) 359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p; 361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Short result; 362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ASSERT( stream && stream->cursor ); 365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = 0; 367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = stream->cursor; 368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p + 1 < stream->limit ) 369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = FT_NEXT_USHORT( p ); 370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->cursor = p; 371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_UShort ) 377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_GetUShortLE( FT_Stream stream ) 378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p; 380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Short result; 381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ASSERT( stream && stream->cursor ); 384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = 0; 386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = stream->cursor; 387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p + 1 < stream->limit ) 388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = FT_NEXT_USHORT_LE( p ); 389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->cursor = p; 390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_ULong ) 396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_GetUOffset( FT_Stream stream ) 397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p; 399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long result; 400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ASSERT( stream && stream->cursor ); 403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = 0; 405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = stream->cursor; 406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p + 2 < stream->limit ) 407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = FT_NEXT_UOFF3( p ); 408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->cursor = p; 409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_ULong ) 414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_GetULong( FT_Stream stream ) 415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p; 417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long result; 418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ASSERT( stream && stream->cursor ); 421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = 0; 423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = stream->cursor; 424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p + 3 < stream->limit ) 425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = FT_NEXT_ULONG( p ); 426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->cursor = p; 427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_ULong ) 432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_GetULongLE( FT_Stream stream ) 433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p; 435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long result; 436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ASSERT( stream && stream->cursor ); 439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = 0; 441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = stream->cursor; 442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p + 3 < stream->limit ) 443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = FT_NEXT_ULONG_LE( p ); 444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->cursor = p; 445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_Char ) 450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_ReadChar( FT_Stream stream, 451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error* error ) 452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte result = 0; 454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ASSERT( stream ); 457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *error = FT_Err_Ok; 459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( stream->read ) 461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( stream->read( stream, stream->pos, &result, 1L ) != 1L ) 463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( stream->pos < stream->size ) 468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = stream->base[stream->pos]; 469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->pos++; 473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Fail: 477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *error = FT_THROW( Invalid_Stream_Operation ); 478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "FT_Stream_ReadChar:" 479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " invalid i/o; pos = 0x%lx, size = 0x%lx\n", 480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->pos, stream->size )); 481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_UShort ) 487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_ReadUShort( FT_Stream stream, 488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error* error ) 489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte reads[2]; 491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = 0; 492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Short result = 0; 493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ASSERT( stream ); 496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *error = FT_Err_Ok; 498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( stream->pos + 1 < stream->size ) 500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( stream->read ) 502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( stream->read( stream, stream->pos, reads, 2L ) != 2L ) 504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = reads; 507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = stream->base + stream->pos; 511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p ) 514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = FT_NEXT_USHORT( p ); 515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->pos += 2; 520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Fail: 524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *error = FT_THROW( Invalid_Stream_Operation ); 525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "FT_Stream_ReadUShort:" 526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " invalid i/o; pos = 0x%lx, size = 0x%lx\n", 527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->pos, stream->size )); 528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_UShort ) 534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_ReadUShortLE( FT_Stream stream, 535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error* error ) 536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte reads[2]; 538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = 0; 539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Short result = 0; 540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ASSERT( stream ); 543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *error = FT_Err_Ok; 545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( stream->pos + 1 < stream->size ) 547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( stream->read ) 549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( stream->read( stream, stream->pos, reads, 2L ) != 2L ) 551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = reads; 554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = stream->base + stream->pos; 558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p ) 561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = FT_NEXT_USHORT_LE( p ); 562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->pos += 2; 567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Fail: 571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *error = FT_THROW( Invalid_Stream_Operation ); 572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "FT_Stream_ReadUShortLE:" 573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " invalid i/o; pos = 0x%lx, size = 0x%lx\n", 574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->pos, stream->size )); 575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_ULong ) 581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_ReadUOffset( FT_Stream stream, 582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error* error ) 583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte reads[3]; 585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = 0; 586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long result = 0; 587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ASSERT( stream ); 590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *error = FT_Err_Ok; 592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( stream->pos + 2 < stream->size ) 594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( stream->read ) 596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (stream->read( stream, stream->pos, reads, 3L ) != 3L ) 598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = reads; 601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = stream->base + stream->pos; 605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p ) 608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = FT_NEXT_UOFF3( p ); 609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->pos += 3; 614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Fail: 618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *error = FT_THROW( Invalid_Stream_Operation ); 619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "FT_Stream_ReadUOffset:" 620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " invalid i/o; pos = 0x%lx, size = 0x%lx\n", 621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->pos, stream->size )); 622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_ULong ) 628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_ReadULong( FT_Stream stream, 629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error* error ) 630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte reads[4]; 632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = 0; 633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long result = 0; 634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ASSERT( stream ); 637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *error = FT_Err_Ok; 639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( stream->pos + 3 < stream->size ) 641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( stream->read ) 643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( stream->read( stream, stream->pos, reads, 4L ) != 4L ) 645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = reads; 648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = stream->base + stream->pos; 652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p ) 655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = FT_NEXT_ULONG( p ); 656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->pos += 4; 661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Fail: 665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *error = FT_THROW( Invalid_Stream_Operation ); 666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "FT_Stream_ReadULong:" 667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " invalid i/o; pos = 0x%lx, size = 0x%lx\n", 668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->pos, stream->size )); 669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_ULong ) 675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_ReadULongLE( FT_Stream stream, 676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error* error ) 677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte reads[4]; 679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = 0; 680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long result = 0; 681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ASSERT( stream ); 684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *error = FT_Err_Ok; 686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( stream->pos + 3 < stream->size ) 688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( stream->read ) 690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( stream->read( stream, stream->pos, reads, 4L ) != 4L ) 692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = reads; 695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = stream->base + stream->pos; 699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p ) 702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = FT_NEXT_ULONG_LE( p ); 703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->pos += 4; 708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Fail: 712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *error = FT_THROW( Invalid_Stream_Operation ); 713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "FT_Stream_ReadULongLE:" 714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " invalid i/o; pos = 0x%lx, size = 0x%lx\n", 715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->pos, stream->size )); 716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_Error ) 722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_ReadFields( FT_Stream stream, 723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FT_Frame_Field* fields, 724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void* structure ) 725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bool frame_accessed = 0; 728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* cursor; 729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 731e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ( !fields ) 732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Argument ); 733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 734e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ( !stream ) 735e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return FT_THROW( Invalid_Stream_Handle ); 736e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cursor = stream->cursor; 738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Err_Ok; 740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov do 741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong value; 743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int sign_shift; 744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p; 745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch ( fields->value ) 748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case ft_frame_start: /* access a new frame */ 750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Stream_EnterFrame( stream, fields->offset ); 751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov frame_accessed = 1; 755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cursor = stream->cursor; 756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fields++; 757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; /* loop! */ 758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case ft_frame_bytes: /* read a byte sequence */ 760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case ft_frame_skip: /* skip some bytes */ 761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt len = fields->size; 763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cursor + len > stream->limit ) 766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_Stream_Operation ); 768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( fields->value == ft_frame_bytes ) 772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = (FT_Byte*)structure + fields->offset; 774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MEM_COPY( p, cursor, len ); 775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cursor += len; 777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fields++; 778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case ft_frame_byte: 782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case ft_frame_schar: /* read a single byte */ 783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov value = FT_NEXT_BYTE( cursor ); 784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sign_shift = 24; 785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case ft_frame_short_be: 788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case ft_frame_ushort_be: /* read a 2-byte big-endian short */ 789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov value = FT_NEXT_USHORT( cursor) ; 790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sign_shift = 16; 791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case ft_frame_short_le: 794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case ft_frame_ushort_le: /* read a 2-byte little-endian short */ 795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov value = FT_NEXT_USHORT_LE( cursor ); 796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sign_shift = 16; 797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case ft_frame_long_be: 800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case ft_frame_ulong_be: /* read a 4-byte big-endian long */ 801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov value = FT_NEXT_ULONG( cursor ); 802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sign_shift = 0; 803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case ft_frame_long_le: 806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case ft_frame_ulong_le: /* read a 4-byte little-endian long */ 807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov value = FT_NEXT_ULONG_LE( cursor ); 808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sign_shift = 0; 809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case ft_frame_off3_be: 812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case ft_frame_uoff3_be: /* read a 3-byte big-endian long */ 813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov value = FT_NEXT_UOFF3( cursor ); 814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sign_shift = 8; 815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case ft_frame_off3_le: 818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case ft_frame_uoff3_le: /* read a 3-byte little-endian long */ 819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov value = FT_NEXT_UOFF3_LE( cursor ); 820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sign_shift = 8; 821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: 824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* otherwise, exit the loop */ 825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stream->cursor = cursor; 826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* now, compute the signed value is necessary */ 830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( fields->value & FT_FRAME_OP_SIGNED ) 831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov value = (FT_ULong)( (FT_Int32)( value << sign_shift ) >> sign_shift ); 832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* finally, store the value in the object */ 834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = (FT_Byte*)structure + fields->offset; 836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch ( fields->size ) 837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case ( 8 / FT_CHAR_BIT ): 839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *(FT_Byte*)p = (FT_Byte)value; 840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case ( 16 / FT_CHAR_BIT ): 843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *(FT_UShort*)p = (FT_UShort)value; 844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case ( 32 / FT_CHAR_BIT ): 847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *(FT_UInt32*)p = (FT_UInt32)value; 848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: /* for 64-bit systems */ 851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *(FT_ULong*)p = (FT_ULong)value; 852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* go to next field */ 855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fields++; 856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( 1 ); 858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* close the frame if it was opened by this read */ 861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( frame_accessed ) 862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_ExitFrame( stream ); 863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* END */ 869