Commit c081a4a932503daa6d1d969e62611215d28c5445

suzuki toshiya 2010-10-13T17:05:42

[raccess] Grouping resource access rules based on Darwin VFS. MacOS X/Darwin kernel supports a few tricky methods to access a resource fork via ANSI C or POSIX interface. Current resource fork accessor tries all possible methods to support all kernels. But if a method could open a resource fork but no font is found, there is no need to try other methods older than tested method. To determine whether the rule index is for Darwin VFS, a local function ftrfork.c::raccess_rule_by_darwin_vfs() is introduced. To use this function in ftobjs.c etc but it should be inlined, it is exposed by ftbase.h. * src/base/ftrfork.c (FT_RFork_Rule): New enum type to identify the rules to access the resource fork. (raccess_guess_rec): New structure to bind the rule function and rule enum type. (FT_Raccess_Guess): The list of the rule functions is replaced by (raccess_guess_table): This. This is exposed to be used by other intra module functions. (raccess_rule_by_darwin_vfs): A function to return a boolean if the rule specified by the rule index is based on Darwin VFS.

diff --git a/ChangeLog b/ChangeLog
index c9422ca..d2ebebc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,29 @@
 2010-10-13  suzuki toshiya  <mpsuzuki@hiroshima-u.ac.jp>
 
+	[raccess] Grouping resource access rules based on Darwin VFS.
+
+	MacOS X/Darwin kernel supports a few tricky methods to access
+	a resource fork via ANSI C or POSIX interface.  Current resource
+	fork accessor tries all possible methods to support all kernels.
+	But if a method could open a resource fork but no font is found,
+	there is no need to try other methods older than tested method. 
+	To determine whether the rule index is for Darwin VFS, a local
+	function ftrfork.c::raccess_rule_by_darwin_vfs() is introduced.
+	To use this function in ftobjs.c etc but it should be inlined,
+	it is exposed by ftbase.h.
+
+	* src/base/ftrfork.c (FT_RFork_Rule): New enum type to identify
+	the rules to access the resource fork.
+	(raccess_guess_rec): New structure to bind the rule function and
+	rule enum type.
+	(FT_Raccess_Guess): The list of the rule functions is replaced by
+	(raccess_guess_table): This.  This is exposed to be used by other
+	intra module functions.
+	(raccess_rule_by_darwin_vfs): A function to return a boolean
+	if the rule specified by the rule index is based on Darwin VFS.
+
+2010-10-13  suzuki toshiya  <mpsuzuki@hiroshima-u.ac.jp>
+
 	Prevent to open a FT_Stream for zero-sized file on non-Unix.
 
 	builds/unix/ftsystem.c prevents to open an useless stream from
diff --git a/src/base/ftbase.h b/src/base/ftbase.h
index 1dc49f3..6375613 100644
--- a/src/base/ftbase.h
+++ b/src/base/ftbase.h
@@ -49,6 +49,17 @@ FT_BEGIN_HEADER
                          FT_Face     *aface );
 
 
+#ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK
+  /* Mac OS X/Darwin kernel often changes recommended method to access */
+  /* the resource fork and older methods makes the kernel issue the    */
+  /* warning of deprecated method.  To calm it down, the methods based */
+  /* on Darwin VFS should be grouped and skip the rest methods after   */
+  /* the case the resource is opened but found to lack a font in it.   */
+  FT_LOCAL( FT_Bool )
+  raccess_rule_by_darwin_vfs( FT_UInt  rule_index );
+#endif /* FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */
+
+
 FT_END_HEADER
 
 #endif /* __FTBASE_H__ */
diff --git a/src/base/ftrfork.c b/src/base/ftrfork.c
index f64d28b..6df2def 100644
--- a/src/base/ftrfork.c
+++ b/src/base/ftrfork.c
@@ -349,6 +349,42 @@
                           const char  *insertion );
 
 
+  typedef enum  FT_RFork_Rule_ {
+    FT_RFork_Rule_invalid = -2,
+    FT_RFork_Rule_uknown, /* -1 */
+    FT_RFork_Rule_apple_double,
+    FT_RFork_Rule_apple_single,
+    FT_RFork_Rule_darwin_ufs_export,
+    FT_RFork_Rule_darwin_newvfs,
+    FT_RFork_Rule_darwin_hfsplus,
+    FT_RFork_Rule_vfat,
+    FT_RFork_Rule_linux_cap,
+    FT_RFork_Rule_linux_double,
+    FT_RFork_Rule_linux_netatalk
+  } FT_RFork_Rule;
+
+  /* For fast translation between rule index and rule type,
+   * the macros FT_RFORK_xxx should be kept consistent with
+   * the raccess_guess_funcs table
+   */
+  typedef struct raccess_guess_rec_ {
+    raccess_guess_func  func;
+    FT_RFork_Rule       type;
+  } raccess_guess_rec;
+
+  static raccess_guess_rec  raccess_guess_table[FT_RACCESS_N_RULES] =
+  {
+    { raccess_guess_apple_double,	FT_RFork_Rule_apple_double, },
+    { raccess_guess_apple_single,	FT_RFork_Rule_apple_single, },
+    { raccess_guess_darwin_ufs_export,	FT_RFork_Rule_darwin_ufs_export, },
+    { raccess_guess_darwin_newvfs,	FT_RFork_Rule_darwin_newvfs, },
+    { raccess_guess_darwin_hfsplus,	FT_RFork_Rule_darwin_hfsplus, },
+    { raccess_guess_vfat,		FT_RFork_Rule_vfat, },
+    { raccess_guess_linux_cap,		FT_RFork_Rule_linux_cap, },
+    { raccess_guess_linux_double,	FT_RFork_Rule_linux_double, },
+    { raccess_guess_linux_netatalk,	FT_RFork_Rule_linux_netatalk, },
+  };
+
   FT_BASE_DEF( void )
   FT_Raccess_Guess( FT_Library  library,
                     FT_Stream   stream,
@@ -360,19 +396,6 @@
     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_newvfs,
-      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;
@@ -384,14 +407,41 @@
       if ( errors[i] )
         continue ;
 
-      errors[i] = (funcs[i])( library, stream, base_name,
-                              &(new_names[i]), &(offsets[i]) );
+      errors[i] = (raccess_guess_table[i].func)( library,
+                                                 stream, base_name,
+                                                 &(new_names[i]),
+                                                 &(offsets[i]) );
     }
 
     return;
   }
 
 
+  static FT_RFork_Rule
+  raccess_get_rule_type_from_rule_index( FT_UInt  rule_index )
+  {
+    if ( rule_index >= FT_RACCESS_N_RULES )
+      return FT_RFork_Rule_invalid;
+
+    return raccess_guess_table[rule_index].type;
+  }
+
+
+  FT_LOCAL_DEF( FT_Bool )
+  raccess_rule_by_darwin_vfs( FT_UInt  rule_index )
+  {
+    switch( raccess_get_rule_type_from_rule_index( rule_index ) )
+    {
+      case FT_RFork_Rule_darwin_newvfs:
+      case FT_RFork_Rule_darwin_hfsplus:
+        return TRUE;
+
+      default:
+        return FALSE;
+    }
+  }
+
+
   static FT_Error
   raccess_guess_apple_double( FT_Library  library,
                               FT_Stream   stream,