/* */
/* Embedded resource forks accessor (body). */
/* */
-/* Copyright 2004, 2005, 2006 by */
+/* Copyright 2004, 2005, 2006, 2007, 2008, 2009 by */
/* Masatake YAMATO and Redhat K.K. */
/* */
/* FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are */
}
+ 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 **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;
+ 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;
+ FT_RFork_Ref *ref;
error = FT_Stream_Seek( stream, map_offset );
if ( error )
return error;
- if ( FT_NEW_ARRAY( offsets_internal, *count ) )
+ if ( FT_NEW_ARRAY( ref, *count ) )
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_USHORT( ref[j].res_id ) )
+ goto Exit;
+ if ( FT_STREAM_SKIP( 2 ) ) /* resource name */
+ goto Exit;
if ( FT_READ_LONG( temp ) )
- {
- FT_FREE( offsets_internal );
- return error;
- }
-
- offsets_internal[j] = rdata_pos + ( temp & 0xFFFFFFL );
+ goto Exit;
+ if ( FT_STREAM_SKIP( 4 ) ) /* mbz */
+ goto Exit;
- (void)FT_STREAM_SKIP( 4 ); /* mbz */
+ ref[j].offset = temp & 0xFFFFFFL;
}
+ ft_qsort( ref, *count, sizeof ( FT_RFork_Ref ),
+ ( int(*)(const void*, const void*) )
+ ft_raccess_sort_ref_by_id );
+
+ 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;
- return FT_Err_Ok;
+ Exit:
+ FT_FREE( ref );
+ return error;
}
}
typedef FT_Error
(*raccess_guess_func)( FT_Library library,
FT_Stream stream,
- char * base_file_name,
+ 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 *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 *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 *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 *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 *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 *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 *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 *base_file_name,
char **result_file_name,
FT_Long *result_offset );
static FT_Error
raccess_guess_apple_generic( FT_Library library,
FT_Stream stream,
- char * base_file_name,
+ char *base_file_name,
FT_Int32 magic,
FT_Long *result_offset );
raccess_guess_apple_double,
raccess_guess_apple_single,
raccess_guess_darwin_ufs_export,
+ raccess_guess_darwin_newvfs,
raccess_guess_darwin_hfsplus,
raccess_guess_vfat,
raccess_guess_linux_cap,
for ( i = 0; i < FT_RACCESS_N_RULES; i++ )
{
new_names[i] = NULL;
- errors[i] = FT_Stream_Seek( stream, 0 );
+ if ( NULL != stream )
+ errors[i] = FT_Stream_Seek( stream, 0 );
+ else
+ errors[i] = FT_Err_Ok;
+
if ( errors[i] )
continue ;
static FT_Error
raccess_guess_apple_double( FT_Library library,
FT_Stream stream,
- char * base_file_name,
+ char *base_file_name,
char **result_file_name,
FT_Long *result_offset )
{
- FT_Int32 magic = ( 0x00 << 24 | 0x05 << 16 | 0x16 << 8 | 0x07 );
+ FT_Int32 magic = ( 0x00 << 24 ) |
+ ( 0x05 << 16 ) |
+ ( 0x16 << 8 ) |
+ 0x07;
*result_file_name = NULL;
+ if ( NULL == stream )
+ return FT_Err_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 *base_file_name,
char **result_file_name,
FT_Long *result_offset )
{
- FT_Int32 magic = (0x00 << 24 | 0x05 << 16 | 0x16 << 8 | 0x00);
+ FT_Int32 magic = ( 0x00 << 24 ) |
+ ( 0x05 << 16 ) |
+ ( 0x16 << 8 ) |
+ 0x00;
*result_file_name = NULL;
+ if ( NULL == stream )
+ return FT_Err_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 *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 *base_file_name,
char **result_file_name,
FT_Long *result_offset )
{
memory = library->memory;
- if ( base_file_len > FT_INT_MAX )
+ if ( base_file_len + 6 > FT_INT_MAX )
return FT_Err_Array_Too_Large;
if ( FT_ALLOC( newpath, base_file_len + 6 ) )
}
+ 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;
+ FT_Memory memory;
+ FT_Long base_file_len = ft_strlen( base_file_name );
+
+ FT_UNUSED( stream );
+
+
+ memory = library->memory;
+
+ if ( base_file_len + 18 > FT_INT_MAX )
+ return FT_Err_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 *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 *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 *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 *base_file_name,
char **result_file_name,
FT_Long *result_offset )
{
static FT_Error
raccess_guess_apple_generic( FT_Library library,
FT_Stream stream,
- char * base_file_name,
+ char *base_file_name,
FT_Int32 magic,
FT_Long *result_offset )
{
return FT_Err_Ok;
}
else
- FT_Stream_Skip( stream, 4 + 4 ); /* offset + length */
+ {
+ error = FT_Stream_Skip( stream, 4 + 4 ); /* offset + length */
+ if ( error )
+ return error;
}
+ }
return FT_Err_Unknown_File_Format;
}
static FT_Error
raccess_guess_linux_double_from_file_name( FT_Library library,
- char * file_name,
+ char *file_name,
FT_Long *result_offset )
{
FT_Open_Args args2;
const char *insertion )
{
char* new_name;
- char* tmp;
+ const char* tmp;
const char* slash;
- unsigned new_length;
+ size_t new_length;
FT_Error error = FT_Err_Ok;
FT_UNUSED( error );
FT_BASE_DEF( void )
FT_Raccess_Guess( FT_Library library,
FT_Stream stream,
- char* base_name,
+ char *base_name,
char **new_names,
FT_Long *offsets,
FT_Error *errors )