00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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
00027
00028
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
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
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
00242 FT_ASSERT( stream && stream->cursor == 0 );
00243
00244 if ( stream->read )
00245 {
00246
00247 FT_Memory memory = stream->memory;
00248
00249 #ifdef FT_DEBUG_MEMORY
00250
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
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
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
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
00303
00304
00305
00306
00307
00308
00309
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:
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;
00742
00743 case ft_frame_bytes:
00744 case ft_frame_skip:
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:
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:
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:
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:
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:
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:
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:
00803 value = FT_NEXT_UOFF3_LE(cursor);
00804 sign_shift = 8;
00805 break;
00806
00807 default:
00808
00809 stream->cursor = cursor;
00810 goto Exit;
00811 }
00812
00813
00814 if ( fields->value & FT_FRAME_OP_SIGNED )
00815 value = (FT_ULong)( (FT_Int32)( value << sign_shift ) >> sign_shift );
00816
00817
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:
00835 *(FT_ULong*)p = (FT_ULong)value;
00836 }
00837
00838
00839 fields++;
00840 }
00841 while ( 1 );
00842
00843 Exit:
00844
00845 if ( frame_accessed )
00846 FT_Stream_ExitFrame( stream );
00847
00848 return error;
00849 }
00850
00851
00852