ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

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, 2010 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 
00250       /* simple sanity check */
00251       if ( count > stream->size )
00252       {
00253         FT_ERROR(( "FT_Stream_EnterFrame:"
00254                    " frame size (%lu) larger than stream size (%lu)\n",
00255                    count, stream->size ));
00256 
00257         error = FT_Err_Invalid_Stream_Operation;
00258         goto Exit;
00259       }
00260 
00261 #ifdef FT_DEBUG_MEMORY
00262       /* assume _ft_debug_file and _ft_debug_lineno are already set */
00263       stream->base = (unsigned char*)ft_mem_qalloc( memory, count, &error );
00264       if ( error )
00265         goto Exit;
00266 #else
00267       if ( FT_QALLOC( stream->base, count ) )
00268         goto Exit;
00269 #endif
00270       /* read it */
00271       read_bytes = stream->read( stream, stream->pos,
00272                                  stream->base, count );
00273       if ( read_bytes < count )
00274       {
00275         FT_ERROR(( "FT_Stream_EnterFrame:"
00276                    " invalid read; expected %lu bytes, got %lu\n",
00277                    count, read_bytes ));
00278 
00279         FT_FREE( stream->base );
00280         error = FT_Err_Invalid_Stream_Operation;
00281       }
00282       stream->cursor = stream->base;
00283       stream->limit  = stream->cursor + count;
00284       stream->pos   += read_bytes;
00285     }
00286     else
00287     {
00288       /* check current and new position */
00289       if ( stream->pos >= stream->size        ||
00290            stream->size - stream->pos < count )
00291       {
00292         FT_ERROR(( "FT_Stream_EnterFrame:"
00293                    " invalid i/o; pos = 0x%lx, count = %lu, size = 0x%lx\n",
00294                    stream->pos, count, stream->size ));
00295 
00296         error = FT_Err_Invalid_Stream_Operation;
00297         goto Exit;
00298       }
00299 
00300       /* set cursor */
00301       stream->cursor = stream->base + stream->pos;
00302       stream->limit  = stream->cursor + count;
00303       stream->pos   += count;
00304     }
00305 
00306   Exit:
00307     return error;
00308   }
00309 
00310 
00311   FT_BASE_DEF( void )
00312   FT_Stream_ExitFrame( FT_Stream  stream )
00313   {
00314     /* IMPORTANT: The assertion stream->cursor != 0 was removed, given    */
00315     /*            that it is possible to access a frame of length 0 in    */
00316     /*            some weird fonts (usually, when accessing an array of   */
00317     /*            0 records, like in some strange kern tables).           */
00318     /*                                                                    */
00319     /*  In this case, the loader code handles the 0-length table          */
00320     /*  gracefully; however, stream.cursor is really set to 0 by the      */
00321     /*  FT_Stream_EnterFrame() call, and this is not an error.            */
00322     /*                                                                    */
00323     FT_ASSERT( stream );
00324 
00325     if ( stream->read )
00326     {
00327       FT_Memory  memory = stream->memory;
00328 
00329 #ifdef FT_DEBUG_MEMORY
00330       ft_mem_free( memory, stream->base );
00331       stream->base = NULL;
00332 #else
00333       FT_FREE( stream->base );
00334 #endif
00335     }
00336     stream->cursor = 0;
00337     stream->limit  = 0;
00338   }
00339 
00340 
00341   FT_BASE_DEF( FT_Char )
00342   FT_Stream_GetChar( FT_Stream  stream )
00343   {
00344     FT_Char  result;
00345 
00346 
00347     FT_ASSERT( stream && stream->cursor );
00348 
00349     result = 0;
00350     if ( stream->cursor < stream->limit )
00351       result = *stream->cursor++;
00352 
00353     return result;
00354   }
00355 
00356 
00357   FT_BASE_DEF( FT_Short )
00358   FT_Stream_GetShort( FT_Stream  stream )
00359   {
00360     FT_Byte*  p;
00361     FT_Short  result;
00362 
00363 
00364     FT_ASSERT( stream && stream->cursor );
00365 
00366     result         = 0;
00367     p              = stream->cursor;
00368     if ( p + 1 < stream->limit )
00369       result       = FT_NEXT_SHORT( p );
00370     stream->cursor = p;
00371 
00372     return result;
00373   }
00374 
00375 
00376   FT_BASE_DEF( FT_Short )
00377   FT_Stream_GetShortLE( FT_Stream  stream )
00378   {
00379     FT_Byte*  p;
00380     FT_Short  result;
00381 
00382 
00383     FT_ASSERT( stream && stream->cursor );
00384 
00385     result         = 0;
00386     p              = stream->cursor;
00387     if ( p + 1 < stream->limit )
00388       result       = FT_NEXT_SHORT_LE( p );
00389     stream->cursor = p;
00390 
00391     return result;
00392   }
00393 
00394 
00395   FT_BASE_DEF( FT_Long )
00396   FT_Stream_GetOffset( FT_Stream  stream )
00397   {
00398     FT_Byte*  p;
00399     FT_Long   result;
00400 
00401 
00402     FT_ASSERT( stream && stream->cursor );
00403 
00404     result         = 0;
00405     p              = stream->cursor;
00406     if ( p + 2 < stream->limit )
00407       result       = FT_NEXT_OFF3( p );
00408     stream->cursor = p;
00409     return result;
00410   }
00411 
00412 
00413   FT_BASE_DEF( FT_Long )
00414   FT_Stream_GetLong( FT_Stream  stream )
00415   {
00416     FT_Byte*  p;
00417     FT_Long   result;
00418 
00419 
00420     FT_ASSERT( stream && stream->cursor );
00421 
00422     result         = 0;
00423     p              = stream->cursor;
00424     if ( p + 3 < stream->limit )
00425       result       = FT_NEXT_LONG( p );
00426     stream->cursor = p;
00427     return result;
00428   }
00429 
00430 
00431   FT_BASE_DEF( FT_Long )
00432   FT_Stream_GetLongLE( FT_Stream  stream )
00433   {
00434     FT_Byte*  p;
00435     FT_Long   result;
00436 
00437 
00438     FT_ASSERT( stream && stream->cursor );
00439 
00440     result         = 0;
00441     p              = stream->cursor;
00442     if ( p + 3 < stream->limit )
00443       result       = FT_NEXT_LONG_LE( p );
00444     stream->cursor = p;
00445     return result;
00446   }
00447 
00448 
00449   FT_BASE_DEF( FT_Char )
00450   FT_Stream_ReadChar( FT_Stream  stream,
00451                       FT_Error*  error )
00452   {
00453     FT_Byte  result = 0;
00454 
00455 
00456     FT_ASSERT( stream );
00457 
00458     *error = FT_Err_Ok;
00459 
00460     if ( stream->read )
00461     {
00462       if ( stream->read( stream, stream->pos, &result, 1L ) != 1L )
00463         goto Fail;
00464     }
00465     else
00466     {
00467       if ( stream->pos < stream->size )
00468         result = stream->base[stream->pos];
00469       else
00470         goto Fail;
00471     }
00472     stream->pos++;
00473 
00474     return result;
00475 
00476   Fail:
00477     *error = FT_Err_Invalid_Stream_Operation;
00478     FT_ERROR(( "FT_Stream_ReadChar:"
00479                " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
00480                stream->pos, stream->size ));
00481 
00482     return 0;
00483   }
00484 
00485 
00486   FT_BASE_DEF( FT_Short )
00487   FT_Stream_ReadShort( FT_Stream  stream,
00488                        FT_Error*  error )
00489   {
00490     FT_Byte   reads[2];
00491     FT_Byte*  p = 0;
00492     FT_Short  result = 0;
00493 
00494 
00495     FT_ASSERT( stream );
00496 
00497     *error = FT_Err_Ok;
00498 
00499     if ( stream->pos + 1 < stream->size )
00500     {
00501       if ( stream->read )
00502       {
00503         if ( stream->read( stream, stream->pos, reads, 2L ) != 2L )
00504           goto Fail;
00505 
00506         p = reads;
00507       }
00508       else
00509       {
00510         p = stream->base + stream->pos;
00511       }
00512 
00513       if ( p )
00514         result = FT_NEXT_SHORT( p );
00515     }
00516     else
00517       goto Fail;
00518 
00519     stream->pos += 2;
00520 
00521     return result;
00522 
00523   Fail:
00524     *error = FT_Err_Invalid_Stream_Operation;
00525     FT_ERROR(( "FT_Stream_ReadShort:"
00526                " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
00527                stream->pos, stream->size ));
00528 
00529     return 0;
00530   }
00531 
00532 
00533   FT_BASE_DEF( FT_Short )
00534   FT_Stream_ReadShortLE( FT_Stream  stream,
00535                          FT_Error*  error )
00536   {
00537     FT_Byte   reads[2];
00538     FT_Byte*  p = 0;
00539     FT_Short  result = 0;
00540 
00541 
00542     FT_ASSERT( stream );
00543 
00544     *error = FT_Err_Ok;
00545 
00546     if ( stream->pos + 1 < stream->size )
00547     {
00548       if ( stream->read )
00549       {
00550         if ( stream->read( stream, stream->pos, reads, 2L ) != 2L )
00551           goto Fail;
00552 
00553         p = reads;
00554       }
00555       else
00556       {
00557         p = stream->base + stream->pos;
00558       }
00559 
00560       if ( p )
00561         result = FT_NEXT_SHORT_LE( p );
00562     }
00563     else
00564       goto Fail;
00565 
00566     stream->pos += 2;
00567 
00568     return result;
00569 
00570   Fail:
00571     *error = FT_Err_Invalid_Stream_Operation;
00572     FT_ERROR(( "FT_Stream_ReadShortLE:"
00573                " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
00574                stream->pos, stream->size ));
00575 
00576     return 0;
00577   }
00578 
00579 
00580   FT_BASE_DEF( FT_Long )
00581   FT_Stream_ReadOffset( FT_Stream  stream,
00582                         FT_Error*  error )
00583   {
00584     FT_Byte   reads[3];
00585     FT_Byte*  p = 0;
00586     FT_Long   result = 0;
00587 
00588 
00589     FT_ASSERT( stream );
00590 
00591     *error = FT_Err_Ok;
00592 
00593     if ( stream->pos + 2 < stream->size )
00594     {
00595       if ( stream->read )
00596       {
00597         if (stream->read( stream, stream->pos, reads, 3L ) != 3L )
00598           goto Fail;
00599 
00600         p = reads;
00601       }
00602       else
00603       {
00604         p = stream->base + stream->pos;
00605       }
00606 
00607       if ( p )
00608         result = FT_NEXT_OFF3( p );
00609     }
00610     else
00611       goto Fail;
00612 
00613     stream->pos += 3;
00614 
00615     return result;
00616 
00617   Fail:
00618     *error = FT_Err_Invalid_Stream_Operation;
00619     FT_ERROR(( "FT_Stream_ReadOffset:"
00620                " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
00621                stream->pos, stream->size ));
00622 
00623     return 0;
00624   }
00625 
00626 
00627   FT_BASE_DEF( FT_Long )
00628   FT_Stream_ReadLong( FT_Stream  stream,
00629                       FT_Error*  error )
00630   {
00631     FT_Byte   reads[4];
00632     FT_Byte*  p = 0;
00633     FT_Long   result = 0;
00634 
00635 
00636     FT_ASSERT( stream );
00637 
00638     *error = FT_Err_Ok;
00639 
00640     if ( stream->pos + 3 < stream->size )
00641     {
00642       if ( stream->read )
00643       {
00644         if ( stream->read( stream, stream->pos, reads, 4L ) != 4L )
00645           goto Fail;
00646 
00647         p = reads;
00648       }
00649       else
00650       {
00651         p = stream->base + stream->pos;
00652       }
00653 
00654       if ( p )
00655         result = FT_NEXT_LONG( p );
00656     }
00657     else
00658       goto Fail;
00659 
00660     stream->pos += 4;
00661 
00662     return result;
00663 
00664   Fail:
00665     *error = FT_Err_Invalid_Stream_Operation;
00666     FT_ERROR(( "FT_Stream_ReadLong:"
00667                " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
00668                stream->pos, stream->size ));
00669 
00670     return 0;
00671   }
00672 
00673 
00674   FT_BASE_DEF( FT_Long )
00675   FT_Stream_ReadLongLE( FT_Stream  stream,
00676                         FT_Error*  error )
00677   {
00678     FT_Byte   reads[4];
00679     FT_Byte*  p = 0;
00680     FT_Long   result = 0;
00681 
00682 
00683     FT_ASSERT( stream );
00684 
00685     *error = FT_Err_Ok;
00686 
00687     if ( stream->pos + 3 < stream->size )
00688     {
00689       if ( stream->read )
00690       {
00691         if ( stream->read( stream, stream->pos, reads, 4L ) != 4L )
00692           goto Fail;
00693 
00694         p = reads;
00695       }
00696       else
00697       {
00698         p = stream->base + stream->pos;
00699       }
00700 
00701       if ( p )
00702         result = FT_NEXT_LONG_LE( p );
00703     }
00704     else
00705       goto Fail;
00706 
00707     stream->pos += 4;
00708 
00709     return result;
00710 
00711   Fail:
00712     *error = FT_Err_Invalid_Stream_Operation;
00713     FT_ERROR(( "FT_Stream_ReadLongLE:"
00714                " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
00715                stream->pos, stream->size ));
00716 
00717     return 0;
00718   }
00719 
00720 
00721   FT_BASE_DEF( FT_Error )
00722   FT_Stream_ReadFields( FT_Stream              stream,
00723                         const FT_Frame_Field*  fields,
00724                         void*                  structure )
00725   {
00726     FT_Error  error;
00727     FT_Bool   frame_accessed = 0;
00728     FT_Byte*  cursor;
00729 
00730     if ( !fields || !stream )
00731       return FT_Err_Invalid_Argument;
00732 
00733     cursor = stream->cursor;
00734 
00735     error = FT_Err_Ok;
00736     do
00737     {
00738       FT_ULong  value;
00739       FT_Int    sign_shift;
00740       FT_Byte*  p;
00741 
00742 
00743       switch ( fields->value )
00744       {
00745       case ft_frame_start:  /* access a new frame */
00746         error = FT_Stream_EnterFrame( stream, fields->offset );
00747         if ( error )
00748           goto Exit;
00749 
00750         frame_accessed = 1;
00751         cursor         = stream->cursor;
00752         fields++;
00753         continue;  /* loop! */
00754 
00755       case ft_frame_bytes:  /* read a byte sequence */
00756       case ft_frame_skip:   /* skip some bytes      */
00757         {
00758           FT_UInt  len = fields->size;
00759 
00760 
00761           if ( cursor + len > stream->limit )
00762           {
00763             error = FT_Err_Invalid_Stream_Operation;
00764             goto Exit;
00765           }
00766 
00767           if ( fields->value == ft_frame_bytes )
00768           {
00769             p = (FT_Byte*)structure + fields->offset;
00770             FT_MEM_COPY( p, cursor, len );
00771           }
00772           cursor += len;
00773           fields++;
00774           continue;
00775         }
00776 
00777       case ft_frame_byte:
00778       case ft_frame_schar:  /* read a single byte */
00779         value = FT_NEXT_BYTE(cursor);
00780         sign_shift = 24;
00781         break;
00782 
00783       case ft_frame_short_be:
00784       case ft_frame_ushort_be:  /* read a 2-byte big-endian short */
00785         value = FT_NEXT_USHORT(cursor);
00786         sign_shift = 16;
00787         break;
00788 
00789       case ft_frame_short_le:
00790       case ft_frame_ushort_le:  /* read a 2-byte little-endian short */
00791         value = FT_NEXT_USHORT_LE(cursor);
00792         sign_shift = 16;
00793         break;
00794 
00795       case ft_frame_long_be:
00796       case ft_frame_ulong_be:  /* read a 4-byte big-endian long */
00797         value = FT_NEXT_ULONG(cursor);
00798         sign_shift = 0;
00799         break;
00800 
00801       case ft_frame_long_le:
00802       case ft_frame_ulong_le:  /* read a 4-byte little-endian long */
00803         value = FT_NEXT_ULONG_LE(cursor);
00804         sign_shift = 0;
00805         break;
00806 
00807       case ft_frame_off3_be:
00808       case ft_frame_uoff3_be:  /* read a 3-byte big-endian long */
00809         value = FT_NEXT_UOFF3(cursor);
00810         sign_shift = 8;
00811         break;
00812 
00813       case ft_frame_off3_le:
00814       case ft_frame_uoff3_le:  /* read a 3-byte little-endian long */
00815         value = FT_NEXT_UOFF3_LE(cursor);
00816         sign_shift = 8;
00817         break;
00818 
00819       default:
00820         /* otherwise, exit the loop */
00821         stream->cursor = cursor;
00822         goto Exit;
00823       }
00824 
00825       /* now, compute the signed value is necessary */
00826       if ( fields->value & FT_FRAME_OP_SIGNED )
00827         value = (FT_ULong)( (FT_Int32)( value << sign_shift ) >> sign_shift );
00828 
00829       /* finally, store the value in the object */
00830 
00831       p = (FT_Byte*)structure + fields->offset;
00832       switch ( fields->size )
00833       {
00834       case (8 / FT_CHAR_BIT):
00835         *(FT_Byte*)p = (FT_Byte)value;
00836         break;
00837 
00838       case (16 / FT_CHAR_BIT):
00839         *(FT_UShort*)p = (FT_UShort)value;
00840         break;
00841 
00842       case (32 / FT_CHAR_BIT):
00843         *(FT_UInt32*)p = (FT_UInt32)value;
00844         break;
00845 
00846       default:  /* for 64-bit systems */
00847         *(FT_ULong*)p = (FT_ULong)value;
00848       }
00849 
00850       /* go to next field */
00851       fields++;
00852     }
00853     while ( 1 );
00854 
00855   Exit:
00856     /* close the frame if it was opened by this read */
00857     if ( frame_accessed )
00858       FT_Stream_ExitFrame( stream );
00859 
00860     return error;
00861   }
00862 
00863 
00864 /* END */

Generated on Sat May 26 2012 04:32:38 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.