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