parent
b35d6d69e4
commit
67dcd4bcf4
14 changed files with 1183 additions and 222 deletions
@ -0,0 +1,184 @@ |
||||
/***************************************************************************/ |
||||
/* */ |
||||
/* ftrfork.h */ |
||||
/* */ |
||||
/* Embedded resource forks accessor (specification). */ |
||||
/* */ |
||||
/* Copyright 2004 by */ |
||||
/* Masatake YAMATO and Redhat K.K. */ |
||||
/* */ |
||||
/* 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. */ |
||||
/***************************************************************************/ |
||||
|
||||
|
||||
#ifndef __FTRFORK_H__ |
||||
#define __FTRFORK_H__ |
||||
|
||||
|
||||
#include <ft2build.h> |
||||
#include FT_INTERNAL_OBJECTS_H |
||||
|
||||
|
||||
FT_BEGIN_HEADER |
||||
|
||||
|
||||
/* Number of guessing rules supported in `FT_Raccess_Guess'. */ |
||||
/* Don't forget to increment the number if you add a new guessing rule. */ |
||||
#define FT_RACCESS_N_RULES 8 |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* <Function> */ |
||||
/* FT_Raccess_Guess */ |
||||
/* */ |
||||
/* <Description> */ |
||||
/* Guess a file name and offset where the actual resource fork is */ |
||||
/* stored. The macro FT_RACCESS_N_RULES holds the number of */ |
||||
/* guessing rules; the guessed result for the Nth rule is */ |
||||
/* represented as a triplet: a new file name (new_names[N]), a file */ |
||||
/* offset (offsets[N]), and an error code (errors[N]). */ |
||||
/* */ |
||||
/* <Input> */ |
||||
/* library :: */ |
||||
/* A FreeType library instance. */ |
||||
/* */ |
||||
/* stream :: */ |
||||
/* A file stream containing the resource fork. */ |
||||
/* */ |
||||
/* base_name :: */ |
||||
/* The (base) file name of the resource fork used for some */ |
||||
/* guessing rules. */ |
||||
/* */ |
||||
/* <Output> */ |
||||
/* new_names :: */ |
||||
/* An array of guessed file names in which the resource forks may */ |
||||
/* exist. If `new_names[N]' is NULL, the guessed file name is */ |
||||
/* equal to `base_name'. */ |
||||
/* */ |
||||
/* offsets :: */ |
||||
/* An array of guessed file offsets. `offsets[N]' holds the file */ |
||||
/* offset of the possible start of the resource fork in file */ |
||||
/* `new_names[N]'. */ |
||||
/* */ |
||||
/* errors :: */ |
||||
/* An array of FreeType error codes. `errors[N]' is the error */ |
||||
/* code of Nth guessing rule function. If `errors[N]' is not */ |
||||
/* FT_Err_Ok, `new_names[N]' and `offsets[N]' are meaningless. */ |
||||
/* */ |
||||
FT_BASE( void ) |
||||
FT_Raccess_Guess( FT_Library library, |
||||
FT_Stream stream, |
||||
char* base_name, |
||||
char** new_names, |
||||
FT_Long* offsets, |
||||
FT_Error* errors ); |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* <Function> */ |
||||
/* FT_Raccess_Get_HeaderInfo */ |
||||
/* */ |
||||
/* <Description> */ |
||||
/* Get the information from the header of resource fork. The */ |
||||
/* information includes the file offset where the resource map */ |
||||
/* starts, and the file offset where the resource data starts. */ |
||||
/* `FT_Raccess_Get_DataOffsets' requires these two data. */ |
||||
/* */ |
||||
/* <Input> */ |
||||
/* library :: */ |
||||
/* A FreeType library instance. */ |
||||
/* */ |
||||
/* stream :: */ |
||||
/* A file stream containing the resource fork. */ |
||||
/* */ |
||||
/* rfork_offset :: */ |
||||
/* The file offset where the resource fork starts. */ |
||||
/* */ |
||||
/* <Output> */ |
||||
/* map_offset :: */ |
||||
/* The file offset where the resource map starts. */ |
||||
/* */ |
||||
/* rdata_pos :: */ |
||||
/* The file offset where the resource data starts. */ |
||||
/* */ |
||||
/* <Return> */ |
||||
/* FreeType error code. FT_Err_Ok means success. */ |
||||
/* */ |
||||
FT_BASE( FT_Error ) |
||||
FT_Raccess_Get_HeaderInfo( FT_Library library, |
||||
FT_Stream stream, |
||||
FT_Long rfork_offset, |
||||
FT_Long *map_offset, |
||||
FT_Long *rdata_pos ); |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* <Function> */ |
||||
/* FT_Raccess_Get_DataOffsets */ |
||||
/* */ |
||||
/* <Description> */ |
||||
/* Get the data offsets for a tag in a resource fork. Offsets are */ |
||||
/* stored in an array because, in some cases, resources in a resource */ |
||||
/* fork have the same tag. */ |
||||
/* */ |
||||
/* <Input> */ |
||||
/* library :: */ |
||||
/* A FreeType library instance. */ |
||||
/* */ |
||||
/* stream :: */ |
||||
/* A file stream containing the resource fork. */ |
||||
/* */ |
||||
/* map_offset :: */ |
||||
/* The file offset where the resource map starts. */ |
||||
/* */ |
||||
/* rdata_pos :: */ |
||||
/* The file offset where the resource data starts. */ |
||||
/* */ |
||||
/* tag :: */ |
||||
/* The resource tag. */ |
||||
/* */ |
||||
/* <Output> */ |
||||
/* offsets :: */ |
||||
/* The stream offsets for the resource data specified by `tag'. */ |
||||
/* This array is allocated by the function, so you have to call */ |
||||
/* @FT_Free after use. */ |
||||
/* */ |
||||
/* count :: */ |
||||
/* The length of offsets array. */ |
||||
/* */ |
||||
/* <Return> */ |
||||
/* FreeType error code. FT_Err_Ok means success. */ |
||||
/* */ |
||||
/* <Note> */ |
||||
/* Normally you should use `FT_Raccess_Get_HeaderInfo' to get the */ |
||||
/* value for `map_offset' and `rdata_pos'. */ |
||||
/* */ |
||||
FT_BASE( FT_Error ) |
||||
FT_Raccess_Get_DataOffsets( FT_Library library, |
||||
FT_Stream stream, |
||||
FT_Long map_offset, |
||||
FT_Long rdata_pos, |
||||
FT_Long tag, |
||||
FT_Long **offsets, |
||||
FT_Long *count ); |
||||
|
||||
|
||||
FT_END_HEADER |
||||
|
||||
#endif /* __FTRFORK_H__ */ |
||||
|
||||
|
||||
/* END */ |
@ -0,0 +1,717 @@ |
||||
/***************************************************************************/ |
||||
/* */ |
||||
/* ftrfork.c */ |
||||
/* */ |
||||
/* Embedded resource forks accessor (body). */ |
||||
/* */ |
||||
/* Copyright 2004 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 |
||||
|
||||
|
||||
#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, rfork_offset ); |
||||
if ( error ) |
||||
return error; |
||||
|
||||
error = FT_Stream_Read( stream, (FT_Byte *)head, 16 ); |
||||
if ( error ) |
||||
return error; |
||||
|
||||
*rdata_pos = rfork_offset + ( ( head[0] << 24 ) | |
||||
( head[1] << 16 ) | |
||||
( head[2] << 8 ) | |
||||
head[3] ); |
||||
map_pos = rfork_offset + ( ( 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 + rdata_len != map_pos || map_pos == rfork_offset ) |
||||
return FT_Err_Unknown_File_Format; |
||||
|
||||
error = FT_Stream_Seek( stream, 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_Err_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_Err_Unknown_File_Format; |
||||
|
||||
error = FT_Stream_Seek( stream, map_pos + type_list ); |
||||
if ( error ) |
||||
return error; |
||||
|
||||
*map_offset = map_pos + type_list; |
||||
return FT_Err_Ok; |
||||
} |
||||
|
||||
|
||||
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_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; |
||||
|
||||
|
||||
error = FT_Stream_Seek( stream, 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 ) ) )); |
||||
|
||||
if ( tag_internal == tag ) |
||||
{ |
||||
*count = subcnt + 1; |
||||
rpos += map_offset; |
||||
|
||||
error = FT_Stream_Seek( stream, rpos ); |
||||
if ( error ) |
||||
return error; |
||||
|
||||
if ( FT_ALLOC( offsets_internal, *count * sizeof( FT_Long ) ) ) |
||||
return error; |
||||
|
||||
for ( j = 0; j < *count; ++j ) |
||||
{ |
||||
(void)FT_STREAM_SKIP( 2 ); /* resource id */ |
||||
(void)FT_STREAM_SKIP( 2 ); /* rsource name */ |
||||
|
||||
if ( FT_READ_LONG( temp ) ) |
||||
{ |
||||
FT_FREE( offsets_internal ); |
||||
return error; |
||||
} |
||||
|
||||
offsets_internal[j] = rdata_pos + ( temp & 0xFFFFFFL ); |
||||
|
||||
(void)FT_STREAM_SKIP( 4 ); /* mbz */ |
||||
} |
||||
|
||||
*offsets = offsets_internal; |
||||
|
||||
return FT_Err_Ok; |
||||
} |
||||
} |
||||
|
||||
return FT_Err_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. ****/ |
||||
/**** ****/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
|
||||
typedef FT_Error |
||||
(*raccess_guess_func)( FT_Library library, |
||||
FT_Stream stream, |
||||
char * base_file_name, |
||||
char **result_file_name, |
||||
FT_Long *result_offset ); |
||||
|
||||
|
||||
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_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 ); |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/**** ****/ |
||||
/**** 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_Long i; |
||||
|
||||
|
||||
raccess_guess_func funcs[FT_RACCESS_N_RULES] = |
||||
{ |
||||
raccess_guess_apple_double, |
||||
raccess_guess_apple_single, |
||||
raccess_guess_darwin_ufs_export, |
||||
raccess_guess_darwin_hfsplus, |
||||
raccess_guess_vfat, |
||||
raccess_guess_linux_cap, |
||||
raccess_guess_linux_double, |
||||
raccess_guess_linux_netatalk, |
||||
}; |
||||
|
||||
for ( i = 0; i < FT_RACCESS_N_RULES; i++ ) |
||||
{ |
||||
new_names[i] = NULL; |
||||
errors[i] = FT_Stream_Seek( stream, 0 ); |
||||
if ( errors[i] ) |
||||
continue ; |
||||
|
||||
errors[i] = (funcs[i])( library, stream, base_name, |
||||
&(new_names[i]), &(offsets[i]) ); |
||||
} |
||||
|
||||
return; |
||||
} |
||||
|
||||
|
||||
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; |
||||
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; |
||||
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_Err_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; |
||||
FT_Memory memory; |
||||
|
||||
FT_UNUSED( stream ); |
||||
|
||||
|
||||
memory = library->memory; |
||||
|
||||
if ( FT_ALLOC( newpath, |
||||
ft_strlen( base_file_name ) + ft_strlen( "/rsrc" ) + 1 ) ) |
||||
return error; |
||||
|
||||
ft_strcpy( newpath, base_file_name ); |
||||
ft_strcat( newpath, "/rsrc" ); |
||||
*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_Err_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_Err_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_Err_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_Err_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; |
||||
FT_UShort n_of_entries; |
||||
|
||||
int i; |
||||
FT_UInt32 entry_id, entry_offset, entry_length; |
||||
|
||||
const FT_UInt32 resource_fork_entry_id = 0x2; |
||||
|
||||
FT_UNUSED( library ); |
||||
FT_UNUSED( base_file_name ); |
||||
|
||||
|
||||
if ( FT_READ_LONG ( magic_from_stream ) ) |
||||
return error; |
||||
if ( magic_from_stream != magic ) |
||||
return FT_Err_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_Err_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 |
||||
FT_Stream_Skip( stream, 4 + 4 ); /* offset + length */ |
||||
} |
||||
|
||||
return FT_Err_Unknown_File_Format; |
||||
} |
||||
|
||||
|
||||
static FT_Error |
||||
raccess_guess_linux_double_from_file_name( FT_Library library, |
||||
char * file_name, |
||||
FT_Long *result_offset ) |
||||
{ |
||||
FT_Memory memory; |
||||
FT_Open_Args args2; |
||||
FT_Stream stream2; |
||||
char * nouse = NULL; |
||||
FT_Error error; |
||||
|
||||
|
||||
memory = library->memory; |
||||
|
||||
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_Close( stream2 ); |
||||
|
||||
return error; |
||||
} |
||||
|
||||
|
||||
static char* |
||||
raccess_make_file_name( FT_Memory memory, |
||||
const char *original_name, |
||||
const char *insertion ) |
||||
{ |
||||
char* new_name; |
||||
char* tmp; |
||||
const char* slash; |
||||
unsigned new_length; |
||||
FT_ULong 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, 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 ) |
||||
{ |
||||
int i; |
||||
|
||||
|
||||
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 */ |
Loading…
Reference in new issue