| Index: third_party/freetype2/src/src/base/ftrfork.c
|
| diff --git a/third_party/freetype2/src/src/base/ftrfork.c b/third_party/freetype2/src/src/base/ftrfork.c
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..c30c76678e64fe7b89accb0070266bebb4d4a988
|
| --- /dev/null
|
| +++ b/third_party/freetype2/src/src/base/ftrfork.c
|
| @@ -0,0 +1,880 @@
|
| +/***************************************************************************/
|
| +/* */
|
| +/* ftrfork.c */
|
| +/* */
|
| +/* Embedded resource forks accessor (body). */
|
| +/* */
|
| +/* Copyright 2004-2015 by */
|
| +/* Masatake YAMATO and Redhat K.K. */
|
| +/* */
|
| +/* FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are */
|
| +/* derived from ftobjs.c. */
|
| +/* */
|
| +/* This file is part of the FreeType project, and may only be used, */
|
| +/* modified, and distributed under the terms of the FreeType project */
|
| +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
|
| +/* this file you indicate that you have read the license and */
|
| +/* understand and accept it fully. */
|
| +/* */
|
| +/***************************************************************************/
|
| +
|
| +/***************************************************************************/
|
| +/* Development of the code in this file is support of */
|
| +/* Information-technology Promotion Agency, Japan. */
|
| +/***************************************************************************/
|
| +
|
| +
|
| +#include <ft2build.h>
|
| +#include FT_INTERNAL_DEBUG_H
|
| +#include FT_INTERNAL_STREAM_H
|
| +#include FT_INTERNAL_RFORK_H
|
| +#include "basepic.h"
|
| +#include "ftbase.h"
|
| +
|
| +#undef FT_COMPONENT
|
| +#define FT_COMPONENT trace_raccess
|
| +
|
| +
|
| + /*************************************************************************/
|
| + /*************************************************************************/
|
| + /*************************************************************************/
|
| + /**** ****/
|
| + /**** ****/
|
| + /**** Resource fork directory access ****/
|
| + /**** ****/
|
| + /**** ****/
|
| + /*************************************************************************/
|
| + /*************************************************************************/
|
| + /*************************************************************************/
|
| +
|
| + FT_BASE_DEF( FT_Error )
|
| + FT_Raccess_Get_HeaderInfo( FT_Library library,
|
| + FT_Stream stream,
|
| + FT_Long rfork_offset,
|
| + FT_Long *map_offset,
|
| + FT_Long *rdata_pos )
|
| + {
|
| + FT_Error error;
|
| + unsigned char head[16], head2[16];
|
| + FT_Long map_pos, rdata_len;
|
| + int allzeros, allmatch, i;
|
| + FT_Long type_list;
|
| +
|
| + FT_UNUSED( library );
|
| +
|
| +
|
| + error = FT_Stream_Seek( stream, (FT_ULong)rfork_offset );
|
| + if ( error )
|
| + return error;
|
| +
|
| + error = FT_Stream_Read( stream, (FT_Byte *)head, 16 );
|
| + if ( error )
|
| + return error;
|
| +
|
| + /* ensure positive values */
|
| + if ( head[0] >= 0x80 || head[4] >= 0x80 || head[8] >= 0x80 )
|
| + return FT_THROW( Unknown_File_Format );
|
| +
|
| + *rdata_pos = ( head[ 0] << 24 ) |
|
| + ( head[ 1] << 16 ) |
|
| + ( head[ 2] << 8 ) |
|
| + head[ 3];
|
| + map_pos = ( head[ 4] << 24 ) |
|
| + ( head[ 5] << 16 ) |
|
| + ( head[ 6] << 8 ) |
|
| + head[ 7];
|
| + rdata_len = ( head[ 8] << 24 ) |
|
| + ( head[ 9] << 16 ) |
|
| + ( head[10] << 8 ) |
|
| + head[11];
|
| +
|
| + /* map_len = head[12] .. head[15] */
|
| +
|
| + if ( *rdata_pos != map_pos - rdata_len || map_pos == 0 )
|
| + return FT_THROW( Unknown_File_Format );
|
| +
|
| + if ( FT_LONG_MAX - rfork_offset < *rdata_pos ||
|
| + FT_LONG_MAX - rfork_offset < map_pos )
|
| + return FT_THROW( Unknown_File_Format );
|
| +
|
| + *rdata_pos += rfork_offset;
|
| + map_pos += rfork_offset;
|
| +
|
| + error = FT_Stream_Seek( stream, (FT_ULong)map_pos );
|
| + if ( error )
|
| + return error;
|
| +
|
| + head2[15] = (FT_Byte)( head[15] + 1 ); /* make it be different */
|
| +
|
| + error = FT_Stream_Read( stream, (FT_Byte*)head2, 16 );
|
| + if ( error )
|
| + return error;
|
| +
|
| + allzeros = 1;
|
| + allmatch = 1;
|
| + for ( i = 0; i < 16; ++i )
|
| + {
|
| + if ( head2[i] != 0 )
|
| + allzeros = 0;
|
| + if ( head2[i] != head[i] )
|
| + allmatch = 0;
|
| + }
|
| + if ( !allzeros && !allmatch )
|
| + return FT_THROW( Unknown_File_Format );
|
| +
|
| + /* If we have reached this point then it is probably a mac resource */
|
| + /* file. Now, does it contain any interesting resources? */
|
| + /* Skip handle to next resource map, the file resource number, and */
|
| + /* attributes. */
|
| + (void)FT_STREAM_SKIP( 4 /* skip handle to next resource map */
|
| + + 2 /* skip file resource number */
|
| + + 2 ); /* skip attributes */
|
| +
|
| + if ( FT_READ_USHORT( type_list ) )
|
| + return error;
|
| + if ( type_list == -1 )
|
| + return FT_THROW( Unknown_File_Format );
|
| +
|
| + error = FT_Stream_Seek( stream, (FT_ULong)( map_pos + type_list ) );
|
| + if ( error )
|
| + return error;
|
| +
|
| + *map_offset = map_pos + type_list;
|
| + return FT_Err_Ok;
|
| + }
|
| +
|
| +
|
| + static int
|
| + ft_raccess_sort_ref_by_id( FT_RFork_Ref* a,
|
| + FT_RFork_Ref* b )
|
| + {
|
| + if ( a->res_id < b->res_id )
|
| + return -1;
|
| + else if ( a->res_id > b->res_id )
|
| + return 1;
|
| + else
|
| + return 0;
|
| + }
|
| +
|
| +
|
| + FT_BASE_DEF( FT_Error )
|
| + FT_Raccess_Get_DataOffsets( FT_Library library,
|
| + FT_Stream stream,
|
| + FT_Long map_offset,
|
| + FT_Long rdata_pos,
|
| + FT_Long tag,
|
| + FT_Bool sort_by_res_id,
|
| + FT_Long **offsets,
|
| + FT_Long *count )
|
| + {
|
| + FT_Error error;
|
| + int i, j, cnt, subcnt;
|
| + FT_Long tag_internal, rpos;
|
| + FT_Memory memory = library->memory;
|
| + FT_Long temp;
|
| + FT_Long *offsets_internal = NULL;
|
| + FT_RFork_Ref *ref = NULL;
|
| +
|
| +
|
| + FT_TRACE3(( "\n" ));
|
| + error = FT_Stream_Seek( stream, (FT_ULong)map_offset );
|
| + if ( error )
|
| + return error;
|
| +
|
| + if ( FT_READ_USHORT( cnt ) )
|
| + return error;
|
| + cnt++;
|
| +
|
| + for ( i = 0; i < cnt; ++i )
|
| + {
|
| + if ( FT_READ_LONG( tag_internal ) ||
|
| + FT_READ_USHORT( subcnt ) ||
|
| + FT_READ_USHORT( rpos ) )
|
| + return error;
|
| +
|
| + FT_TRACE2(( "Resource tags: %c%c%c%c\n",
|
| + (char)( 0xFF & ( tag_internal >> 24 ) ),
|
| + (char)( 0xFF & ( tag_internal >> 16 ) ),
|
| + (char)( 0xFF & ( tag_internal >> 8 ) ),
|
| + (char)( 0xFF & ( tag_internal >> 0 ) ) ));
|
| + FT_TRACE3(( " : subcount=%d, suboffset=0x%04x\n",
|
| + subcnt, rpos ));
|
| +
|
| + if ( tag_internal == tag )
|
| + {
|
| + *count = subcnt + 1;
|
| + rpos += map_offset;
|
| +
|
| + error = FT_Stream_Seek( stream, (FT_ULong)rpos );
|
| + if ( error )
|
| + return error;
|
| +
|
| + if ( FT_NEW_ARRAY( ref, *count ) )
|
| + return error;
|
| +
|
| + for ( j = 0; j < *count; ++j )
|
| + {
|
| + if ( FT_READ_USHORT( ref[j].res_id ) )
|
| + goto Exit;
|
| + if ( FT_STREAM_SKIP( 2 ) ) /* resource name */
|
| + goto Exit;
|
| + if ( FT_READ_LONG( temp ) )
|
| + goto Exit;
|
| + if ( FT_STREAM_SKIP( 4 ) ) /* mbz */
|
| + goto Exit;
|
| +
|
| + ref[j].offset = temp & 0xFFFFFFL;
|
| + FT_TRACE3(( " [%d]:"
|
| + " resource_id=0x%04x, offset=0x%08x\n",
|
| + j, ref[j].res_id, ref[j].offset ));
|
| + }
|
| +
|
| + if (sort_by_res_id)
|
| + {
|
| + ft_qsort( ref, (size_t)*count, sizeof ( FT_RFork_Ref ),
|
| + ( int(*)(const void*, const void*) )
|
| + ft_raccess_sort_ref_by_id );
|
| +
|
| + FT_TRACE3(( " -- sort resources by their ids --\n" ));
|
| + for ( j = 0; j < *count; ++ j ) {
|
| + FT_TRACE3(( " [%d]:"
|
| + " resource_id=0x%04x, offset=0x%08x\n",
|
| + j, ref[j].res_id, ref[j].offset ));
|
| + }
|
| + }
|
| +
|
| + if ( FT_NEW_ARRAY( offsets_internal, *count ) )
|
| + goto Exit;
|
| +
|
| + /* XXX: duplicated reference ID,
|
| + * gap between reference IDs are acceptable?
|
| + * further investigation on Apple implementation is needed.
|
| + */
|
| + for ( j = 0; j < *count; ++j )
|
| + offsets_internal[j] = rdata_pos + ref[j].offset;
|
| +
|
| + *offsets = offsets_internal;
|
| + error = FT_Err_Ok;
|
| +
|
| + Exit:
|
| + FT_FREE( ref );
|
| + return error;
|
| + }
|
| + }
|
| +
|
| + return FT_THROW( Cannot_Open_Resource );
|
| + }
|
| +
|
| +
|
| +#ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK
|
| +
|
| + /*************************************************************************/
|
| + /*************************************************************************/
|
| + /*************************************************************************/
|
| + /**** ****/
|
| + /**** ****/
|
| + /**** Guessing functions ****/
|
| + /**** ****/
|
| + /**** When you add a new guessing function, ****/
|
| + /**** update FT_RACCESS_N_RULES in ftrfork.h. ****/
|
| + /**** ****/
|
| + /*************************************************************************/
|
| + /*************************************************************************/
|
| + /*************************************************************************/
|
| +
|
| + static FT_Error
|
| + raccess_guess_apple_double( FT_Library library,
|
| + FT_Stream stream,
|
| + char *base_file_name,
|
| + char **result_file_name,
|
| + FT_Long *result_offset );
|
| +
|
| + static FT_Error
|
| + raccess_guess_apple_single( FT_Library library,
|
| + FT_Stream stream,
|
| + char *base_file_name,
|
| + char **result_file_name,
|
| + FT_Long *result_offset );
|
| +
|
| + static FT_Error
|
| + raccess_guess_darwin_ufs_export( FT_Library library,
|
| + FT_Stream stream,
|
| + char *base_file_name,
|
| + char **result_file_name,
|
| + FT_Long *result_offset );
|
| +
|
| + static FT_Error
|
| + raccess_guess_darwin_newvfs( FT_Library library,
|
| + FT_Stream stream,
|
| + char *base_file_name,
|
| + char **result_file_name,
|
| + FT_Long *result_offset );
|
| +
|
| + static FT_Error
|
| + raccess_guess_darwin_hfsplus( FT_Library library,
|
| + FT_Stream stream,
|
| + char *base_file_name,
|
| + char **result_file_name,
|
| + FT_Long *result_offset );
|
| +
|
| + static FT_Error
|
| + raccess_guess_vfat( FT_Library library,
|
| + FT_Stream stream,
|
| + char *base_file_name,
|
| + char **result_file_name,
|
| + FT_Long *result_offset );
|
| +
|
| + static FT_Error
|
| + raccess_guess_linux_cap( FT_Library library,
|
| + FT_Stream stream,
|
| + char *base_file_name,
|
| + char **result_file_name,
|
| + FT_Long *result_offset );
|
| +
|
| + static FT_Error
|
| + raccess_guess_linux_double( FT_Library library,
|
| + FT_Stream stream,
|
| + char *base_file_name,
|
| + char **result_file_name,
|
| + FT_Long *result_offset );
|
| +
|
| + static FT_Error
|
| + raccess_guess_linux_netatalk( FT_Library library,
|
| + FT_Stream stream,
|
| + char *base_file_name,
|
| + char **result_file_name,
|
| + FT_Long *result_offset );
|
| +
|
| +
|
| + CONST_FT_RFORK_RULE_ARRAY_BEGIN(ft_raccess_guess_table,
|
| + ft_raccess_guess_rec)
|
| + CONST_FT_RFORK_RULE_ARRAY_ENTRY(apple_double, apple_double)
|
| + CONST_FT_RFORK_RULE_ARRAY_ENTRY(apple_single, apple_single)
|
| + CONST_FT_RFORK_RULE_ARRAY_ENTRY(darwin_ufs_export, darwin_ufs_export)
|
| + CONST_FT_RFORK_RULE_ARRAY_ENTRY(darwin_newvfs, darwin_newvfs)
|
| + CONST_FT_RFORK_RULE_ARRAY_ENTRY(darwin_hfsplus, darwin_hfsplus)
|
| + CONST_FT_RFORK_RULE_ARRAY_ENTRY(vfat, vfat)
|
| + CONST_FT_RFORK_RULE_ARRAY_ENTRY(linux_cap, linux_cap)
|
| + CONST_FT_RFORK_RULE_ARRAY_ENTRY(linux_double, linux_double)
|
| + CONST_FT_RFORK_RULE_ARRAY_ENTRY(linux_netatalk, linux_netatalk)
|
| + CONST_FT_RFORK_RULE_ARRAY_END
|
| +
|
| +
|
| + /*************************************************************************/
|
| + /**** ****/
|
| + /**** Helper functions ****/
|
| + /**** ****/
|
| + /*************************************************************************/
|
| +
|
| + static FT_Error
|
| + raccess_guess_apple_generic( FT_Library library,
|
| + FT_Stream stream,
|
| + char *base_file_name,
|
| + FT_Int32 magic,
|
| + FT_Long *result_offset );
|
| +
|
| + static FT_Error
|
| + raccess_guess_linux_double_from_file_name( FT_Library library,
|
| + char * file_name,
|
| + FT_Long *result_offset );
|
| +
|
| + static char *
|
| + raccess_make_file_name( FT_Memory memory,
|
| + const char *original_name,
|
| + const char *insertion );
|
| +
|
| + FT_BASE_DEF( void )
|
| + FT_Raccess_Guess( FT_Library library,
|
| + FT_Stream stream,
|
| + char* base_name,
|
| + char **new_names,
|
| + FT_Long *offsets,
|
| + FT_Error *errors )
|
| + {
|
| + FT_Int i;
|
| +
|
| +
|
| + for ( i = 0; i < FT_RACCESS_N_RULES; i++ )
|
| + {
|
| + new_names[i] = NULL;
|
| + if ( NULL != stream )
|
| + errors[i] = FT_Stream_Seek( stream, 0 );
|
| + else
|
| + errors[i] = FT_Err_Ok;
|
| +
|
| + if ( errors[i] )
|
| + continue ;
|
| +
|
| + errors[i] = (FT_RACCESS_GUESS_TABLE_GET[i].func)( library,
|
| + stream, base_name,
|
| + &(new_names[i]),
|
| + &(offsets[i]) );
|
| + }
|
| +
|
| + return;
|
| + }
|
| +
|
| +
|
| +#ifndef FT_MACINTOSH
|
| + static FT_RFork_Rule
|
| + raccess_get_rule_type_from_rule_index( FT_Library library,
|
| + FT_UInt rule_index )
|
| + {
|
| + FT_UNUSED( library );
|
| +
|
| + if ( rule_index >= FT_RACCESS_N_RULES )
|
| + return FT_RFork_Rule_invalid;
|
| +
|
| + return FT_RACCESS_GUESS_TABLE_GET[rule_index].type;
|
| + }
|
| +
|
| +
|
| + /*
|
| + * For this function, refer ftbase.h.
|
| + */
|
| + FT_LOCAL_DEF( FT_Bool )
|
| + ft_raccess_rule_by_darwin_vfs( FT_Library library,
|
| + FT_UInt rule_index )
|
| + {
|
| + switch( raccess_get_rule_type_from_rule_index( library, rule_index ) )
|
| + {
|
| + case FT_RFork_Rule_darwin_newvfs:
|
| + case FT_RFork_Rule_darwin_hfsplus:
|
| + return TRUE;
|
| +
|
| + default:
|
| + return FALSE;
|
| + }
|
| + }
|
| +#endif
|
| +
|
| +
|
| + static FT_Error
|
| + raccess_guess_apple_double( FT_Library library,
|
| + FT_Stream stream,
|
| + char *base_file_name,
|
| + char **result_file_name,
|
| + FT_Long *result_offset )
|
| + {
|
| + FT_Int32 magic = ( 0x00 << 24 ) |
|
| + ( 0x05 << 16 ) |
|
| + ( 0x16 << 8 ) |
|
| + 0x07;
|
| +
|
| +
|
| + *result_file_name = NULL;
|
| + if ( NULL == stream )
|
| + return FT_THROW( Cannot_Open_Stream );
|
| +
|
| + return raccess_guess_apple_generic( library, stream, base_file_name,
|
| + magic, result_offset );
|
| + }
|
| +
|
| +
|
| + static FT_Error
|
| + raccess_guess_apple_single( FT_Library library,
|
| + FT_Stream stream,
|
| + char *base_file_name,
|
| + char **result_file_name,
|
| + FT_Long *result_offset )
|
| + {
|
| + FT_Int32 magic = ( 0x00 << 24 ) |
|
| + ( 0x05 << 16 ) |
|
| + ( 0x16 << 8 ) |
|
| + 0x00;
|
| +
|
| +
|
| + *result_file_name = NULL;
|
| + if ( NULL == stream )
|
| + return FT_THROW( Cannot_Open_Stream );
|
| +
|
| + return raccess_guess_apple_generic( library, stream, base_file_name,
|
| + magic, result_offset );
|
| + }
|
| +
|
| +
|
| + static FT_Error
|
| + raccess_guess_darwin_ufs_export( FT_Library library,
|
| + FT_Stream stream,
|
| + char *base_file_name,
|
| + char **result_file_name,
|
| + FT_Long *result_offset )
|
| + {
|
| + char* newpath;
|
| + FT_Error error;
|
| + FT_Memory memory;
|
| +
|
| + FT_UNUSED( stream );
|
| +
|
| +
|
| + memory = library->memory;
|
| + newpath = raccess_make_file_name( memory, base_file_name, "._" );
|
| + if ( !newpath )
|
| + return FT_THROW( Out_Of_Memory );
|
| +
|
| + error = raccess_guess_linux_double_from_file_name( library, newpath,
|
| + result_offset );
|
| + if ( !error )
|
| + *result_file_name = newpath;
|
| + else
|
| + FT_FREE( newpath );
|
| +
|
| + return error;
|
| + }
|
| +
|
| +
|
| + static FT_Error
|
| + raccess_guess_darwin_hfsplus( FT_Library library,
|
| + FT_Stream stream,
|
| + char *base_file_name,
|
| + char **result_file_name,
|
| + FT_Long *result_offset )
|
| + {
|
| + /*
|
| + Only meaningful on systems with hfs+ drivers (or Macs).
|
| + */
|
| + FT_Error error;
|
| + char* newpath = NULL;
|
| + FT_Memory memory;
|
| + FT_Long base_file_len = (FT_Long)ft_strlen( base_file_name );
|
| +
|
| + FT_UNUSED( stream );
|
| +
|
| +
|
| + memory = library->memory;
|
| +
|
| + if ( base_file_len + 6 > FT_INT_MAX )
|
| + return FT_THROW( Array_Too_Large );
|
| +
|
| + if ( FT_ALLOC( newpath, base_file_len + 6 ) )
|
| + return error;
|
| +
|
| + FT_MEM_COPY( newpath, base_file_name, base_file_len );
|
| + FT_MEM_COPY( newpath + base_file_len, "/rsrc", 6 );
|
| +
|
| + *result_file_name = newpath;
|
| + *result_offset = 0;
|
| +
|
| + return FT_Err_Ok;
|
| + }
|
| +
|
| +
|
| + static FT_Error
|
| + raccess_guess_darwin_newvfs( FT_Library library,
|
| + FT_Stream stream,
|
| + char *base_file_name,
|
| + char **result_file_name,
|
| + FT_Long *result_offset )
|
| + {
|
| + /*
|
| + Only meaningful on systems with Mac OS X (> 10.1).
|
| + */
|
| + FT_Error error;
|
| + char* newpath = NULL;
|
| + FT_Memory memory;
|
| + FT_Long base_file_len = (FT_Long)ft_strlen( base_file_name );
|
| +
|
| + FT_UNUSED( stream );
|
| +
|
| +
|
| + memory = library->memory;
|
| +
|
| + if ( base_file_len + 18 > FT_INT_MAX )
|
| + return FT_THROW( Array_Too_Large );
|
| +
|
| + if ( FT_ALLOC( newpath, base_file_len + 18 ) )
|
| + return error;
|
| +
|
| + FT_MEM_COPY( newpath, base_file_name, base_file_len );
|
| + FT_MEM_COPY( newpath + base_file_len, "/..namedfork/rsrc", 18 );
|
| +
|
| + *result_file_name = newpath;
|
| + *result_offset = 0;
|
| +
|
| + return FT_Err_Ok;
|
| + }
|
| +
|
| +
|
| + static FT_Error
|
| + raccess_guess_vfat( FT_Library library,
|
| + FT_Stream stream,
|
| + char *base_file_name,
|
| + char **result_file_name,
|
| + FT_Long *result_offset )
|
| + {
|
| + char* newpath;
|
| + FT_Memory memory;
|
| +
|
| + FT_UNUSED( stream );
|
| +
|
| +
|
| + memory = library->memory;
|
| +
|
| + newpath = raccess_make_file_name( memory, base_file_name,
|
| + "resource.frk/" );
|
| + if ( !newpath )
|
| + return FT_THROW( Out_Of_Memory );
|
| +
|
| + *result_file_name = newpath;
|
| + *result_offset = 0;
|
| +
|
| + return FT_Err_Ok;
|
| + }
|
| +
|
| +
|
| + static FT_Error
|
| + raccess_guess_linux_cap( FT_Library library,
|
| + FT_Stream stream,
|
| + char *base_file_name,
|
| + char **result_file_name,
|
| + FT_Long *result_offset )
|
| + {
|
| + char* newpath;
|
| + FT_Memory memory;
|
| +
|
| + FT_UNUSED( stream );
|
| +
|
| +
|
| + memory = library->memory;
|
| +
|
| + newpath = raccess_make_file_name( memory, base_file_name, ".resource/" );
|
| + if ( !newpath )
|
| + return FT_THROW( Out_Of_Memory );
|
| +
|
| + *result_file_name = newpath;
|
| + *result_offset = 0;
|
| +
|
| + return FT_Err_Ok;
|
| + }
|
| +
|
| +
|
| + static FT_Error
|
| + raccess_guess_linux_double( FT_Library library,
|
| + FT_Stream stream,
|
| + char *base_file_name,
|
| + char **result_file_name,
|
| + FT_Long *result_offset )
|
| + {
|
| + char* newpath;
|
| + FT_Error error;
|
| + FT_Memory memory;
|
| +
|
| + FT_UNUSED( stream );
|
| +
|
| +
|
| + memory = library->memory;
|
| +
|
| + newpath = raccess_make_file_name( memory, base_file_name, "%" );
|
| + if ( !newpath )
|
| + return FT_THROW( Out_Of_Memory );
|
| +
|
| + error = raccess_guess_linux_double_from_file_name( library, newpath,
|
| + result_offset );
|
| + if ( !error )
|
| + *result_file_name = newpath;
|
| + else
|
| + FT_FREE( newpath );
|
| +
|
| + return error;
|
| + }
|
| +
|
| +
|
| + static FT_Error
|
| + raccess_guess_linux_netatalk( FT_Library library,
|
| + FT_Stream stream,
|
| + char *base_file_name,
|
| + char **result_file_name,
|
| + FT_Long *result_offset )
|
| + {
|
| + char* newpath;
|
| + FT_Error error;
|
| + FT_Memory memory;
|
| +
|
| + FT_UNUSED( stream );
|
| +
|
| +
|
| + memory = library->memory;
|
| +
|
| + newpath = raccess_make_file_name( memory, base_file_name,
|
| + ".AppleDouble/" );
|
| + if ( !newpath )
|
| + return FT_THROW( Out_Of_Memory );
|
| +
|
| + error = raccess_guess_linux_double_from_file_name( library, newpath,
|
| + result_offset );
|
| + if ( !error )
|
| + *result_file_name = newpath;
|
| + else
|
| + FT_FREE( newpath );
|
| +
|
| + return error;
|
| + }
|
| +
|
| +
|
| + static FT_Error
|
| + raccess_guess_apple_generic( FT_Library library,
|
| + FT_Stream stream,
|
| + char *base_file_name,
|
| + FT_Int32 magic,
|
| + FT_Long *result_offset )
|
| + {
|
| + FT_Int32 magic_from_stream;
|
| + FT_Error error;
|
| + FT_Int32 version_number = 0;
|
| + FT_UShort n_of_entries;
|
| +
|
| + int i;
|
| + FT_Int32 entry_id, entry_offset, entry_length = 0;
|
| +
|
| + const FT_Int32 resource_fork_entry_id = 0x2;
|
| +
|
| + FT_UNUSED( library );
|
| + FT_UNUSED( base_file_name );
|
| + FT_UNUSED( version_number );
|
| + FT_UNUSED( entry_length );
|
| +
|
| +
|
| + if ( FT_READ_LONG( magic_from_stream ) )
|
| + return error;
|
| + if ( magic_from_stream != magic )
|
| + return FT_THROW( Unknown_File_Format );
|
| +
|
| + if ( FT_READ_LONG( version_number ) )
|
| + return error;
|
| +
|
| + /* filler */
|
| + error = FT_Stream_Skip( stream, 16 );
|
| + if ( error )
|
| + return error;
|
| +
|
| + if ( FT_READ_USHORT( n_of_entries ) )
|
| + return error;
|
| + if ( n_of_entries == 0 )
|
| + return FT_THROW( Unknown_File_Format );
|
| +
|
| + for ( i = 0; i < n_of_entries; i++ )
|
| + {
|
| + if ( FT_READ_LONG( entry_id ) )
|
| + return error;
|
| + if ( entry_id == resource_fork_entry_id )
|
| + {
|
| + if ( FT_READ_LONG( entry_offset ) ||
|
| + FT_READ_LONG( entry_length ) )
|
| + continue;
|
| + *result_offset = entry_offset;
|
| +
|
| + return FT_Err_Ok;
|
| + }
|
| + else
|
| + {
|
| + error = FT_Stream_Skip( stream, 4 + 4 ); /* offset + length */
|
| + if ( error )
|
| + return error;
|
| + }
|
| + }
|
| +
|
| + return FT_THROW( Unknown_File_Format );
|
| + }
|
| +
|
| +
|
| + static FT_Error
|
| + raccess_guess_linux_double_from_file_name( FT_Library library,
|
| + char *file_name,
|
| + FT_Long *result_offset )
|
| + {
|
| + FT_Open_Args args2;
|
| + FT_Stream stream2;
|
| + char * nouse = NULL;
|
| + FT_Error error;
|
| +
|
| +
|
| + args2.flags = FT_OPEN_PATHNAME;
|
| + args2.pathname = file_name;
|
| + error = FT_Stream_New( library, &args2, &stream2 );
|
| + if ( error )
|
| + return error;
|
| +
|
| + error = raccess_guess_apple_double( library, stream2, file_name,
|
| + &nouse, result_offset );
|
| +
|
| + FT_Stream_Free( stream2, 0 );
|
| +
|
| + return error;
|
| + }
|
| +
|
| +
|
| + static char*
|
| + raccess_make_file_name( FT_Memory memory,
|
| + const char *original_name,
|
| + const char *insertion )
|
| + {
|
| + char* new_name = NULL;
|
| + const char* tmp;
|
| + const char* slash;
|
| + size_t new_length;
|
| + FT_Error error = FT_Err_Ok;
|
| +
|
| + FT_UNUSED( error );
|
| +
|
| +
|
| + new_length = ft_strlen( original_name ) + ft_strlen( insertion );
|
| + if ( FT_ALLOC( new_name, new_length + 1 ) )
|
| + return NULL;
|
| +
|
| + tmp = ft_strrchr( original_name, '/' );
|
| + if ( tmp )
|
| + {
|
| + ft_strncpy( new_name,
|
| + original_name,
|
| + (size_t)( tmp - original_name + 1 ) );
|
| + new_name[tmp - original_name + 1] = '\0';
|
| + slash = tmp + 1;
|
| + }
|
| + else
|
| + {
|
| + slash = original_name;
|
| + new_name[0] = '\0';
|
| + }
|
| +
|
| + ft_strcat( new_name, insertion );
|
| + ft_strcat( new_name, slash );
|
| +
|
| + return new_name;
|
| + }
|
| +
|
| +
|
| +#else /* !FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */
|
| +
|
| +
|
| + /*************************************************************************/
|
| + /* Dummy function; just sets errors */
|
| + /*************************************************************************/
|
| +
|
| + FT_BASE_DEF( void )
|
| + FT_Raccess_Guess( FT_Library library,
|
| + FT_Stream stream,
|
| + char *base_name,
|
| + char **new_names,
|
| + FT_Long *offsets,
|
| + FT_Error *errors )
|
| + {
|
| + FT_Int i;
|
| +
|
| + FT_UNUSED( library );
|
| + FT_UNUSED( stream );
|
| + FT_UNUSED( base_name );
|
| +
|
| +
|
| + for ( i = 0; i < FT_RACCESS_N_RULES; i++ )
|
| + {
|
| + new_names[i] = NULL;
|
| + offsets[i] = 0;
|
| + errors[i] = FT_ERR( Unimplemented_Feature );
|
| + }
|
| + }
|
| +
|
| +
|
| +#endif /* !FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */
|
| +
|
| +
|
| +/* END */
|
|
|