ftstream.c

Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  ftstream.c                                                             */
00004 /*                                                                         */
00005 /*    I/O stream support (body).                                           */
00006 /*                                                                         */
00007 /*  Copyright 2000-2001, 2002, 2004, 2005, 2006, 2008, 2009 by             */
00008 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
00009 /*                                                                         */
00010 /*  This file is part of the FreeType project, and may only be used,       */
00011 /*  modified, and distributed under the terms of the FreeType project      */
00012 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
00013 /*  this file you indicate that you have read the license and              */
00014 /*  understand and accept it fully.                                        */
00015 /*                                                                         */
00016 /***************************************************************************/
00017 
00018 
00019 #include <ft2build.h>
00020 #include FT_INTERNAL_STREAM_H
00021 #include FT_INTERNAL_DEBUG_H
00022 
00023 
00024   /*************************************************************************/
00025   /*                                                                       */
00026   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
00027   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
00028   /* messages during execution.                                            */
00029   /*                                                                       */
00030 #undef  FT_COMPONENT
00031 #define FT_COMPONENT  trace_stream
00032 
00033 
00034   FT_BASE_DEF( void )
00035   FT_Stream_OpenMemory( FT_Stream       stream,
00036                         const FT_Byte*  base,
00037                         FT_ULong        size )
00038   {
00039     stream->base   = (FT_Byte*) base;
00040     stream->size   = size;
00041     stream->pos    = 0;
00042     stream->cursor = 0;
00043     stream->read   = 0;
00044     stream->close  = 0;
00045   }
00046 
00047 
00048   FT_BASE_DEF( void )
00049   FT_Stream_Close( FT_Stream  stream )
00050   {
00051     if ( stream && stream->close )
00052       stream->close( stream );
00053   }
00054 
00055 
00056   FT_BASE_DEF( FT_Error )
00057   FT_Stream_Seek( FT_Stream  stream,
00058                   FT_ULong   pos )
00059   {
00060     FT_Error  error = FT_Err_Ok;
00061 
00062 
00063     if ( stream->read )
00064     {
00065       if ( stream->read( stream, pos, 0, 0 ) )
00066       {
00067         FT_ERROR(( "FT_Stream_Seek:"
00068                    " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
00069                    pos, stream->size ));
00070 
00071         error = FT_Err_Invalid_Stream_Operation;
00072       }
00073     }
00074     /* note that seeking to the first position after the file is valid */
00075     else if ( pos > stream->size )
00076     {
00077       FT_ERROR(( "FT_Stream_Seek:"
00078                  " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
00079                  pos, stream->size ));
00080 
00081       error = FT_Err_Invalid_Stream_Operation;
00082     }
00083 
00084     if ( !error )
00085       stream->pos = pos;
00086 
00087     return error;
00088   }
00089 
00090 
00091   FT_BASE_DEF( FT_Error )
00092   FT_Stream_Skip( FT_Stream  stream,
00093                   FT_Long    distance )
00094   {
00095     if ( distance < 0 )
00096       return FT_Err_Invalid_Stream_Operation;
00097 
00098     return FT_Stream_Seek( stream, (FT_ULong)( stream->pos + distance ) );
00099   }
00100 
00101 
00102   FT_BASE_DEF( FT_Long )
00103   FT_Stream_Pos( FT_Stream  stream )
00104   {
00105     return stream->pos;
00106   }
00107 
00108 
00109   FT_BASE_DEF( FT_Error )
00110   FT_Stream_Read( FT_Stream  stream,
00111                   FT_Byte*   buffer,
00112                   FT_ULong   count )
00113   {
00114     return FT_Stream_ReadAt( stream, stream->pos, buffer, count );
00115   }
00116 
00117 
00118   FT_BASE_DEF( FT_Error )
00119   FT_Stream_ReadAt( FT_Stream  stream,
00120                     FT_ULong   pos,
00121                     FT_Byte*   buffer,
00122                     FT_ULong   count )
00123   {
00124     FT_Error  error = FT_Err_Ok;
00125     FT_ULong  read_bytes;
00126 
00127 
00128     if ( pos >= stream->size )
00129     {
00130       FT_ERROR(( "FT_Stream_ReadAt:"
00131                  " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
00132                  pos, stream->size ));
00133 
00134       return FT_Err_Invalid_Stream_Operation;
00135     }
00136 
00137     if ( stream->read )
00138       read_bytes = stream->read( stream, pos, buffer, count );
00139     else
00140     {
00141       read_bytes = stream->size - pos;
00142       if ( read_bytes > count )
00143         read_bytes = count;
00144 
00145       FT_MEM_COPY( buffer, stream->base + pos, read_bytes );
00146     }
00147 
00148     stream->pos = pos + read_bytes;
00149 
00150     if ( read_bytes < count )
00151     {
00152       FT_ERROR(( "FT_Stream_ReadAt:"
00153                  " invalid read; expected %lu bytes, got %lu\n",
00154                  count, read_bytes ));
00155 
00156       error = FT_Err_Invalid_Stream_Operation;
00157     }
00158 
00159     return error;
00160   }
00161 
00162 
00163   FT_BASE_DEF( FT_ULong )
00164   FT_Stream_TryRead( FT_Stream  stream,
00165                      FT_Byte*   buffer,
00166                      FT_ULong   count )
00167   {
00168     FT_ULong  read_bytes = 0;
00169 
00170 
00171     if ( stream->pos >= stream->size )
00172       goto Exit;
00173 
00174     if ( stream->read )
00175       read_bytes = stream->read( stream, stream->pos, buffer, count );
00176     else
00177     {
00178       read_bytes = stream->size - stream->pos;
00179       if ( read_bytes > count )
00180         read_bytes = count;
00181 
00182       FT_MEM_COPY( buffer, stream->base + stream->pos, read_bytes );
00183     }
00184 
00185     stream->pos += read_bytes;
00186 
00187   Exit:
00188     return read_bytes;
00189   }
00190 
00191 
00192   FT_BASE_DEF( FT_Error )
00193   FT_Stream_ExtractFrame( FT_Stream  stream,
00194                           FT_ULong   count,
00195                           FT_Byte**  pbytes )
00196   {
00197     FT_Error  error;
00198 
00199 
00200     error = FT_Stream_EnterFrame( stream, count );
00201     if ( !error )
00202     {
00203       *pbytes = (FT_Byte*)stream->cursor;
00204 
00205       /* equivalent to FT_Stream_ExitFrame(), with no memory block release */
00206       stream->cursor = 0;
00207       stream->limit  = 0;
00208     }
00209 
00210     return error;
00211   }
00212 
00213 
00214   FT_BASE_DEF( void )
00215   FT_Stream_ReleaseFrame( FT_Stream  stream,
00216                           FT_Byte**  pbytes )
00217   {
00218     if ( stream && stream->read )
00219     {
00220       FT_Memory  memory = stream->memory;
00221 
00222 #ifdef FT_DEBUG_MEMORY
00223       ft_mem_free( memory, *pbytes );
00224       *pbytes = NULL;
00225 #else
00226       FT_FREE( *pbytes );
00227 #endif
00228     }
00229     *pbytes = 0;
00230   }
00231 
00232 
00233   FT_BASE_DEF( FT_Error )
00234   FT_Stream_EnterFrame( FT_Stream  stream,
00235                         FT_ULong   count )
00236   {
00237     FT_Error  error = FT_Err_Ok;
00238     FT_ULong  read_bytes;
00239 
00240 
00241     /* check for nested frame access */
00242     FT_ASSERT( stream && stream->cursor == 0 );
00243 
00244     if ( stream->read )
00245     {
00246       /* allocate the frame in memory */
00247       FT_Memory  memory = stream->memory;
00248 
00249 #ifdef FT_DEBUG_MEMORY
00250       /* assume _ft_debug_file and _ft_debug_lineno are already set */
00251       stream->base = (unsigned char*)ft_mem_qalloc( memory, count, &error );
00252       if ( error )
00253         goto Exit;
00254 #else
00255       if ( FT_QALLOC( stream->base, count ) )
00256         goto Exit;
00257 #endif
00258       /* read it */
00259       read_bytes = stream->read( stream, stream->pos,
00260                                  stream->base, count );
00261       if ( read_bytes < count )
00262       {
00263         FT_ERROR(( "FT_Stream_EnterFrame:"
00264                    " invalid read; expected %lu bytes, got %lu\n",
00265                    count, read_bytes ));
00266 
00267         FT_FREE( stream->base );
00268         error = FT_Err_Invalid_Stream_Operation;
00269       }
00270       stream->cursor = stream->base;
00271       stream->limit  = stream->cursor + count;
00272       stream->pos   += read_bytes;
00273     }
00274     else
00275     {
00276       /* check current and new position */
00277       if ( stream->pos >= stream->size        ||
00278            stream->pos + count > stream->size )
00279       {
00280         FT_ERROR(( "FT_Stream_EnterFrame:"
00281                    " invalid i/o; pos = 0x%lx, count = %lu, size = 0x%lx\n",
00282                    stream->pos, count, stream->size ));
00283 
00284         error = FT_Err_Invalid_Stream_Operation;
00285         goto Exit;
00286       }
00287 
00288       /* set cursor */
00289       stream->cursor = stream->base + stream->pos;
00290       stream->limit  = stream->cursor + count;
00291       stream->pos   += count;
00292     }
00293 
00294   Exit:
00295     return error;
00296   }
00297 
00298 
00299   FT_BASE_DEF( void )
00300   FT_Stream_ExitFrame( FT_Stream  stream )
00301   {
00302     /* IMPORTANT: The assertion stream->cursor != 0 was removed, given    */
00303     /*            that it is possible to access a frame of length 0 in    */
00304     /*            some weird fonts (usually, when accessing an array of   */
00305     /*            0 records, like in some strange kern tables).           */
00306     /*                                                                    */
00307     /*  In this case, the loader code handles the 0-length table          */
00308     /*  gracefully; however, stream.cursor is really set to 0 by the      */
00309     /*  FT_Stream_EnterFrame() call, and this is not an error.            */
00310     /*                                                                    */
00311     FT_ASSERT( stream );
00312 
00313     if ( stream->read )
00314     {
00315       FT_Memory  memory = stream->memory;
00316 
00317 #ifdef FT_DEBUG_MEMORY
00318       ft_mem_free( memory, stream->base );
00319       stream->base = NULL;
00320 #else
00321       FT_FREE( stream->base );
00322 #endif
00323     }
00324     stream->cursor = 0;
00325     stream->limit  = 0;
00326   }
00327 
00328 
00329   FT_BASE_DEF( FT_Char )
00330   FT_Stream_GetChar( FT_Stream  stream )
00331   {
00332     FT_Char  result;
00333 
00334 
00335     FT_ASSERT( stream && stream->cursor );
00336 
00337     result = 0;
00338     if ( stream->cursor < stream->limit )
00339       result = *stream->cursor++;
00340 
00341     return result;
00342   }
00343 
00344 
00345   FT_BASE_DEF( FT_Short )
00346   FT_Stream_GetShort( FT_Stream  stream )
00347   {
00348     FT_Byte*  p;
00349     FT_Short  result;
00350 
00351 
00352     FT_ASSERT( stream && stream->cursor );
00353 
00354     result         = 0;
00355     p              = stream->cursor;
00356     if ( p + 1 < stream->limit )
00357       result       = FT_NEXT_SHORT( p );
00358     stream->cursor = p;
00359 
00360     return result;
00361   }
00362 
00363 
00364   FT_BASE_DEF( FT_Short )
00365   FT_Stream_GetShortLE( FT_Stream  stream )
00366   {
00367     FT_Byte*  p;
00368     FT_Short  result;
00369 
00370 
00371     FT_ASSERT( stream && stream->cursor );
00372 
00373     result         = 0;
00374     p              = stream->cursor;
00375     if ( p + 1 < stream->limit )
00376       result       = FT_NEXT_SHORT_LE( p );
00377     stream->cursor = p;
00378 
00379     return result;
00380   }
00381 
00382 
00383   FT_BASE_DEF( FT_Long )
00384   FT_Stream_GetOffset( FT_Stream  stream )
00385   {
00386     FT_Byte*  p;
00387     FT_Long   result;
00388 
00389 
00390     FT_ASSERT( stream && stream->cursor );
00391 
00392     result         = 0;
00393     p              = stream->cursor;
00394     if ( p + 2 < stream->limit )
00395       result       = FT_NEXT_OFF3( p );
00396     stream->cursor = p;
00397     return result;
00398   }
00399 
00400 
00401   FT_BASE_DEF( FT_Long )
00402   FT_Stream_GetLong( FT_Stream  stream )
00403   {
00404     FT_Byte*  p;
00405     FT_Long   result;
00406 
00407 
00408     FT_ASSERT( stream && stream->cursor );
00409 
00410     result         = 0;
00411     p              = stream->cursor;
00412     if ( p + 3 < stream->limit )
00413       result       = FT_NEXT_LONG( p );
00414     stream->cursor = p;
00415     return result;
00416   }
00417 
00418 
00419   FT_BASE_DEF( FT_Long )
00420   FT_Stream_GetLongLE( FT_Stream  stream )
00421   {
00422     FT_Byte*  p;
00423     FT_Long   result;
00424 
00425 
00426     FT_ASSERT( stream && stream->cursor );
00427 
00428     result         = 0;
00429     p              = stream->cursor;
00430     if ( p + 3 < stream->limit )
00431       result       = FT_NEXT_LONG_LE( p );
00432     stream->cursor = p;
00433     return result;
00434   }
00435 
00436 
00437   FT_BASE_DEF( FT_Char )
00438   FT_Stream_ReadChar( FT_Stream  stream,
00439                       FT_Error*  error )
00440   {
00441     FT_Byte  result = 0;
00442 
00443 
00444     FT_ASSERT( stream );
00445 
00446     *error = FT_Err_Ok;
00447 
00448     if ( stream->read )
00449     {
00450       if ( stream->read( stream, stream->pos, &result, 1L ) != 1L )
00451         goto Fail;
00452     }
00453     else
00454     {
00455       if ( stream->pos < stream->size )
00456         result = stream->base[stream->pos];
00457       else
00458         goto Fail;
00459     }
00460     stream->pos++;
00461 
00462     return result;
00463 
00464   Fail:
00465     *error = FT_Err_Invalid_Stream_Operation;
00466     FT_ERROR(( "FT_Stream_ReadChar:"
00467                " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
00468                stream->pos, stream->size ));
00469 
00470     return 0;
00471   }
00472 
00473 
00474   FT_BASE_DEF( FT_Short )
00475   FT_Stream_ReadShort( FT_Stream  stream,
00476                        FT_Error*  error )
00477   {
00478     FT_Byte   reads[2];
00479     FT_Byte*  p = 0;
00480     FT_Short  result = 0;
00481 
00482 
00483     FT_ASSERT( stream );
00484 
00485     *error = FT_Err_Ok;
00486 
00487     if ( stream->pos + 1 < stream->size )
00488     {
00489       if ( stream->read )
00490       {
00491         if ( stream->read( stream, stream->pos, reads, 2L ) != 2L )
00492           goto Fail;
00493 
00494         p = reads;
00495       }
00496       else
00497       {
00498         p = stream->base + stream->pos;
00499       }
00500 
00501       if ( p )
00502         result = FT_NEXT_SHORT( p );
00503     }
00504     else
00505       goto Fail;
00506 
00507     stream->pos += 2;
00508 
00509     return result;
00510 
00511   Fail:
00512     *error = FT_Err_Invalid_Stream_Operation;
00513     FT_ERROR(( "FT_Stream_ReadShort:"
00514                " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
00515                stream->pos, stream->size ));
00516 
00517     return 0;
00518   }
00519 
00520 
00521   FT_BASE_DEF( FT_Short )
00522   FT_Stream_ReadShortLE( FT_Stream  stream,
00523                          FT_Error*  error )
00524   {
00525     FT_Byte   reads[2];
00526     FT_Byte*  p = 0;
00527     FT_Short  result = 0;
00528 
00529 
00530     FT_ASSERT( stream );
00531 
00532     *error = FT_Err_Ok;
00533 
00534     if ( stream->pos + 1 < stream->size )
00535     {
00536       if ( stream->read )
00537       {
00538         if ( stream->read( stream, stream->pos, reads, 2L ) != 2L )
00539           goto Fail;
00540 
00541         p = reads;
00542       }
00543       else
00544       {
00545         p = stream->base + stream->pos;
00546       }
00547 
00548       if ( p )
00549         result = FT_NEXT_SHORT_LE( p );
00550     }
00551     else
00552       goto Fail;
00553 
00554     stream->pos += 2;
00555 
00556     return result;
00557 
00558   Fail:
00559     *error = FT_Err_Invalid_Stream_Operation;
00560     FT_ERROR(( "FT_Stream_ReadShortLE:"
00561                " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
00562                stream->pos, stream->size ));
00563 
00564     return 0;
00565   }
00566 
00567 
00568   FT_BASE_DEF( FT_Long )
00569   FT_Stream_ReadOffset( FT_Stream  stream,
00570                         FT_Error*  error )
00571   {
00572     FT_Byte   reads[3];
00573     FT_Byte*  p = 0;
00574     FT_Long   result = 0;
00575 
00576 
00577     FT_ASSERT( stream );
00578 
00579     *error = FT_Err_Ok;
00580 
00581     if ( stream->pos + 2 < stream->size )
00582     {
00583       if ( stream->read )
00584       {
00585         if (stream->read( stream, stream->pos, reads, 3L ) != 3L )
00586           goto Fail;
00587 
00588         p = reads;
00589       }
00590       else
00591       {
00592         p = stream->base + stream->pos;
00593       }
00594 
00595       if ( p )
00596         result = FT_NEXT_OFF3( p );
00597     }
00598     else
00599       goto Fail;
00600 
00601     stream->pos += 3;
00602 
00603     return result;
00604 
00605   Fail:
00606     *error = FT_Err_Invalid_Stream_Operation;
00607     FT_ERROR(( "FT_Stream_ReadOffset:"
00608                " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
00609                stream->pos, stream->size ));
00610 
00611     return 0;
00612   }
00613 
00614 
00615   FT_BASE_DEF( FT_Long )
00616   FT_Stream_ReadLong( FT_Stream  stream,
00617                       FT_Error*  error )
00618   {
00619     FT_Byte   reads[4];
00620     FT_Byte*  p = 0;
00621     FT_Long   result = 0;
00622 
00623 
00624     FT_ASSERT( stream );
00625 
00626     *error = FT_Err_Ok;
00627 
00628     if ( stream->pos + 3 < stream->size )
00629     {
00630       if ( stream->read )
00631       {
00632         if ( stream->read( stream, stream->pos, reads, 4L ) != 4L )
00633           goto Fail;
00634 
00635         p = reads;
00636       }
00637       else
00638       {
00639         p = stream->base + stream->pos;
00640       }
00641 
00642       if ( p )
00643         result = FT_NEXT_LONG( p );
00644     }
00645     else
00646       goto Fail;
00647 
00648     stream->pos += 4;
00649 
00650     return result;
00651 
00652   Fail:
00653     *error = FT_Err_Invalid_Stream_Operation;
00654     FT_ERROR(( "FT_Stream_ReadLong:"
00655                " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
00656                stream->pos, stream->size ));
00657 
00658     return 0;
00659   }
00660 
00661 
00662   FT_BASE_DEF( FT_Long )
00663   FT_Stream_ReadLongLE( FT_Stream  stream,
00664                         FT_Error*  error )
00665   {
00666     FT_Byte   reads[4];
00667     FT_Byte*  p = 0;
00668     FT_Long   result = 0;
00669 
00670 
00671     FT_ASSERT( stream );
00672 
00673     *error = FT_Err_Ok;
00674 
00675     if ( stream->pos + 3 < stream->size )
00676     {
00677       if ( stream->read )
00678       {
00679         if ( stream->read( stream, stream->pos, reads, 4L ) != 4L )
00680           goto Fail;
00681 
00682         p = reads;
00683       }
00684       else
00685       {
00686         p = stream->base + stream->pos;
00687       }
00688 
00689       if ( p )
00690         result = FT_NEXT_LONG_LE( p );
00691     }
00692     else
00693       goto Fail;
00694 
00695     stream->pos += 4;
00696 
00697     return result;
00698 
00699   Fail:
00700     *error = FT_Err_Invalid_Stream_Operation;
00701     FT_ERROR(( "FT_Stream_ReadLongLE:"
00702                " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
00703                stream->pos, stream->size ));
00704 
00705     return 0;
00706   }
00707 
00708 
00709   FT_BASE_DEF( FT_Error )
00710   FT_Stream_ReadFields( FT_Stream              stream,
00711                         const FT_Frame_Field*  fields,
00712                         void*                  structure )
00713   {
00714     FT_Error  error;
00715     FT_Bool   frame_accessed = 0;
00716     FT_Byte*  cursor;
00717 
00718     if ( !fields || !stream )
00719       return FT_Err_Invalid_Argument;
00720 
00721     cursor = stream->cursor;
00722 
00723     error = FT_Err_Ok;
00724     do
00725     {
00726       FT_ULong  value;
00727       FT_Int    sign_shift;
00728       FT_Byte*  p;
00729 
00730 
00731       switch ( fields->value )
00732       {
00733       case ft_frame_start:  /* access a new frame */
00734         error = FT_Stream_EnterFrame( stream, fields->offset );
00735         if ( error )
00736           goto Exit;
00737 
00738         frame_accessed = 1;
00739         cursor         = stream->cursor;
00740         fields++;
00741         continue;  /* loop! */
00742 
00743       case ft_frame_bytes:  /* read a byte sequence */
00744       case ft_frame_skip:   /* skip some bytes      */
00745         {
00746           FT_UInt  len = fields->size;
00747 
00748 
00749           if ( cursor + len > stream->limit )
00750           {
00751             error = FT_Err_Invalid_Stream_Operation;
00752             goto Exit;
00753           }
00754 
00755           if ( fields->value == ft_frame_bytes )
00756           {
00757             p = (FT_Byte*)structure + fields->offset;
00758             FT_MEM_COPY( p, cursor, len );
00759           }
00760           cursor += len;
00761           fields++;
00762           continue;
00763         }
00764 
00765       case ft_frame_byte:
00766       case ft_frame_schar:  /* read a single byte */
00767         value = FT_NEXT_BYTE(cursor);
00768         sign_shift = 24;
00769         break;
00770 
00771       case ft_frame_short_be:
00772       case ft_frame_ushort_be:  /* read a 2-byte big-endian short */
00773         value = FT_NEXT_USHORT(cursor);
00774         sign_shift = 16;
00775         break;
00776 
00777       case ft_frame_short_le:
00778       case ft_frame_ushort_le:  /* read a 2-byte little-endian short */
00779         value = FT_NEXT_USHORT_LE(cursor);
00780         sign_shift = 16;
00781         break;
00782 
00783       case ft_frame_long_be:
00784       case ft_frame_ulong_be:  /* read a 4-byte big-endian long */
00785         value = FT_NEXT_ULONG(cursor);
00786         sign_shift = 0;
00787         break;
00788 
00789       case ft_frame_long_le:
00790       case ft_frame_ulong_le:  /* read a 4-byte little-endian long */
00791         value = FT_NEXT_ULONG_LE(cursor);
00792         sign_shift = 0;
00793         break;
00794 
00795       case ft_frame_off3_be:
00796       case ft_frame_uoff3_be:  /* read a 3-byte big-endian long */
00797         value = FT_NEXT_UOFF3(cursor);
00798         sign_shift = 8;
00799         break;
00800 
00801       case ft_frame_off3_le:
00802       case ft_frame_uoff3_le:  /* read a 3-byte little-endian long */
00803         value = FT_NEXT_UOFF3_LE(cursor);
00804         sign_shift = 8;
00805         break;
00806 
00807       default:
00808         /* otherwise, exit the loop */
00809         stream->cursor = cursor;
00810         goto Exit;
00811       }
00812 
00813       /* now, compute the signed value is necessary */
00814       if ( fields->value & FT_FRAME_OP_SIGNED )
00815         value = (FT_ULong)( (FT_Int32)( value << sign_shift ) >> sign_shift );
00816 
00817       /* finally, store the value in the object */
00818 
00819       p = (FT_Byte*)structure + fields->offset;
00820       switch ( fields->size )
00821       {
00822       case (8 / FT_CHAR_BIT):
00823         *(FT_Byte*)p = (FT_Byte)value;
00824         break;
00825 
00826       case (16 / FT_CHAR_BIT):
00827         *(FT_UShort*)p = (FT_UShort)value;
00828         break;
00829 
00830       case (32 / FT_CHAR_BIT):
00831         *(FT_UInt32*)p = (FT_UInt32)value;
00832         break;
00833 
00834       default:  /* for 64-bit systems */
00835         *(FT_ULong*)p = (FT_ULong)value;
00836       }
00837 
00838       /* go to next field */
00839       fields++;
00840     }
00841     while ( 1 );
00842 
00843   Exit:
00844     /* close the frame if it was opened by this read */
00845     if ( frame_accessed )
00846       FT_Stream_ExitFrame( stream );
00847 
00848     return error;
00849   }
00850 
00851 
00852 /* END */

Generated on Tue Jul 5 14:13:42 2011 for ROOT_528-00b_version by  doxygen 1.5.1