]> git.wh0rd.org - fontconfig.git/blobdiff - src/fccache.c
Add new API which unlinks directory caches and checks dir caches for
[fontconfig.git] / src / fccache.c
index efc1cf0342615324b7d70894cea67930494ee9b0..43e45af92cfbbcdb59595d49818c57274348bc7c 100644 (file)
@@ -2,6 +2,7 @@
  * $RCSId: xc/lib/fontconfig/src/fccache.c,v 1.12 2002/08/22 07:36:44 keithp Exp $
  *
  * Copyright © 2000 Keith Packard
+ * Copyright © 2005 Patrick Lam
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -37,7 +38,7 @@ static off_t
 FcCacheSkipToArch (int fd, const char * arch);
 
 static FcBool 
-FcCacheMoveDown (int fd, off_t start);
+FcCacheCopyOld (int fd, int fd_orig, off_t start);
 
 static void *
 FcDirCacheProduce (FcFontSet *set, FcCache * metadata);
@@ -59,8 +60,8 @@ FcCacheHaveBank (int bank);
 
 #define FC_DBG_CACHE_REF    1024
 
-static FcChar8 *
-FcCacheReadString (int fd, FcChar8 *dest, int len)
+static char *
+FcCacheReadString (int fd, char *dest, int len)
 {
     FcChar8    c;
     FcBool     escape;
@@ -68,7 +69,7 @@ FcCacheReadString (int fd, FcChar8 *dest, int len)
     int                i;
 
     if (len == 0)
-       return FcFalse;
+       return 0;
     
     size = len;
     i = 0;
@@ -100,7 +101,7 @@ FcCacheReadString (int fd, FcChar8 *dest, int len)
 }
 
 static FcBool
-FcCacheWriteString (int fd, const FcChar8 *chars)
+FcCacheWriteString (int fd, const char *chars)
 {
     if (write (fd, chars, strlen(chars)+1) != strlen(chars)+1)
        return FcFalse;
@@ -147,14 +148,20 @@ FcGlobalCacheDestroy (FcGlobalCache *cache)
 
 void
 FcGlobalCacheLoad (FcGlobalCache    *cache,
+                   FcStrSet        *staleDirs,
                   const FcChar8    *cache_file)
 {
-    FcChar8            name_buf[8192];
+    char               name_buf[8192];
     FcGlobalCacheDir   *d, *next;
     char               * current_arch_machine_name;
     char               candidate_arch_machine_name[MACHINE_SIGNATURE_SIZE + 9];
     off_t              current_arch_start;
 
+    struct stat        cache_stat, dir_stat;
+
+    if (stat ((char *) cache_file, &cache_stat) < 0)
+        return;
+
     cache->fd = open ((char *) cache_file, O_RDONLY);
     if (cache->fd == -1)
        return;
@@ -168,16 +175,30 @@ FcGlobalCacheLoad (FcGlobalCache    *cache,
         goto bail0;
 
     lseek (cache->fd, current_arch_start, SEEK_SET);
-    if (FcCacheReadString (cache->fd, candidate_arch_machine_name, 
-                          sizeof (candidate_arch_machine_name)) == 0)
+    FcCacheReadString (cache->fd, candidate_arch_machine_name, 
+                       sizeof (candidate_arch_machine_name));
+    if (strlen(candidate_arch_machine_name) == 0)
        goto bail0;
 
     while (1) 
     {
+       off_t targ;
+
        FcCacheReadString (cache->fd, name_buf, sizeof (name_buf));
        if (!strlen(name_buf))
            break;
 
+        if (stat ((char *) name_buf, &dir_stat) < 0 || 
+            dir_stat.st_mtime > cache_stat.st_mtime)
+        {
+            FcCache md;
+
+            FcStrSetAdd (staleDirs, FcStrCopy ((FcChar8 *)name_buf));
+            read (cache->fd, &md, sizeof (FcCache));
+            lseek (cache->fd, FcCacheNextOffset (lseek(cache->fd, 0, SEEK_CUR)) + md.count, SEEK_SET);
+            continue;
+        }
+
        d = malloc (sizeof (FcGlobalCacheDir));
        if (!d)
            goto bail1;
@@ -185,11 +206,14 @@ FcGlobalCacheLoad (FcGlobalCache    *cache,
        d->next = cache->dirs;
        cache->dirs = d;
 
-       d->name = FcStrCopy (name_buf);
+       d->name = (char *)FcStrCopy ((FcChar8 *)name_buf);
        d->ent = 0;
        d->offset = lseek (cache->fd, 0, SEEK_CUR);
-       read (cache->fd, &d->metadata, sizeof (FcCache));
-       lseek (cache->fd, d->metadata.count, SEEK_CUR);
+       if (read (cache->fd, &d->metadata, sizeof (FcCache)) != sizeof (FcCache))
+           goto bail1;
+       targ = FcCacheNextOffset (lseek(cache->fd, 0, SEEK_CUR)) + d->metadata.count;
+       if (lseek (cache->fd, targ, SEEK_SET) != targ)
+           goto bail1;
     }
     return;
 
@@ -201,37 +225,38 @@ FcGlobalCacheLoad (FcGlobalCache    *cache,
     }
     cache->dirs = 0;
  bail0:
-    free (current_arch_machine_name);
     close (cache->fd);
     cache->fd = -1;
     return;
 }
 
 FcBool
-FcGlobalCacheReadDir (FcFontSet *set, FcStrSet *dirs, FcGlobalCache * cache, const FcChar8 *dir, FcConfig *config)
+FcGlobalCacheReadDir (FcFontSet *set, FcStrSet *dirs, FcGlobalCache * cache, const char *dir, FcConfig *config)
 {
     FcGlobalCacheDir *d;
+    FcBool ret = FcFalse;
 
     if (cache->fd == -1)
        return FcFalse;
 
     for (d = cache->dirs; d; d = d->next)
     {
-       if (strcmp (d->name, dir) == 0)
+       if (strncmp (d->name, dir, strlen(dir)) == 0)
        {
            lseek (cache->fd, d->offset, SEEK_SET);
            if (!FcDirCacheConsume (cache->fd, set))
                return FcFalse;
-           return FcTrue;
+            if (strcmp (d->name, dir) == 0)
+               ret = FcTrue;
        }
     }
 
-    return FcFalse;
+    return ret;
 }
 
 FcBool
 FcGlobalCacheUpdate (FcGlobalCache  *cache,
-                    const FcChar8  *name,
+                    const char     *name,
                     FcFontSet      *set)
 {
     FcGlobalCacheDir * d;
@@ -256,7 +281,7 @@ FcGlobalCacheUpdate (FcGlobalCache  *cache,
 
     cache->updated = FcTrue;
 
-    d->name = FcStrCopy (name);
+    d->name = (char *)FcStrCopy ((FcChar8 *)name);
     d->ent = FcDirCacheProduce (set, &d->metadata);
     d->offset = 0;
     return FcTrue;
@@ -266,7 +291,7 @@ FcBool
 FcGlobalCacheSave (FcGlobalCache    *cache,
                   const FcChar8    *cache_file)
 {
-    int                        fd;
+    int                        fd, fd_orig;
     FcGlobalCacheDir   *dir;
     FcAtomic           *atomic;
     off_t              current_arch_start = 0, truncate_to;
@@ -283,7 +308,8 @@ FcGlobalCacheSave (FcGlobalCache    *cache,
     
     atomic = FcAtomicCreate (cache_file);
     if (!atomic)
-       goto bail0;
+       return FcFalse;
+
     if (!FcAtomicLock (atomic))
        goto bail1;
     fd = open ((char *) FcAtomicNewFile(atomic), O_RDWR | O_CREAT, 
@@ -291,19 +317,33 @@ FcGlobalCacheSave (FcGlobalCache    *cache,
     if (fd == -1)
        goto bail2;
 
+    fd_orig = open ((char *) FcAtomicOrigFile(atomic), O_RDONLY);
+
     current_arch_machine_name = FcCacheMachineSignature ();
-    current_arch_start = FcCacheSkipToArch(fd, current_arch_machine_name);
+    if (fd_orig == -1)
+        current_arch_start = 0;
+    else
+        current_arch_start = FcCacheSkipToArch (fd_orig, 
+                                                current_arch_machine_name);
+
     if (current_arch_start < 0)
-       current_arch_start = FcCacheNextOffset (lseek(fd, 0, SEEK_END));
+       current_arch_start = FcCacheNextOffset (lseek(fd_orig, 0, SEEK_END));
 
-    if (!FcCacheMoveDown(fd, current_arch_start))
-       goto bail2;
+    if (!FcCacheCopyOld(fd, fd_orig, current_arch_start))
+       goto bail3;
+
+    close (fd_orig);
+    fd_orig = -1;
 
     current_arch_start = lseek(fd, 0, SEEK_CUR);
     if (ftruncate (fd, current_arch_start) == -1)
-       goto bail2;
+       goto bail3;
+
+    header = malloc (10 + strlen (current_arch_machine_name));
+    if (!header)
+       goto bail3;
 
-    truncate_to = current_arch_start;
+    truncate_to = current_arch_start + strlen(current_arch_machine_name) + 11;
     for (dir = cache->dirs; dir; dir = dir->next)
     {
        truncate_to += strlen(dir->name) + 1;
@@ -312,13 +352,11 @@ FcGlobalCacheSave (FcGlobalCache    *cache,
        truncate_to += dir->metadata.count;
     }
     truncate_to -= current_arch_start;
-    header = malloc (10 + strlen (current_arch_machine_name));
-    if (!header)
-       goto bail1;
+
     sprintf (header, "%8x ", (int)truncate_to);
     strcat (header, current_arch_machine_name);
     if (!FcCacheWriteString (fd, header))
-       goto bail1;
+       goto bail4;
 
     for (dir = cache->dirs; dir; dir = dir->next)
     {
@@ -326,7 +364,7 @@ FcGlobalCacheSave (FcGlobalCache    *cache,
         {
             FcCacheWriteString (fd, dir->name);
             write (fd, &dir->metadata, sizeof(FcCache));
-            lseek (fd, FcCacheNextOffset (lseek(fd, 0, SEEK_END)), SEEK_SET);
+            lseek (fd, FcCacheNextOffset (lseek(fd, 0, SEEK_CUR)), SEEK_SET);
             write (fd, dir->ent, dir->metadata.count);
             free (dir->ent);
         }
@@ -334,10 +372,10 @@ FcGlobalCacheSave (FcGlobalCache    *cache,
     FcCacheWriteString (fd, "");
 
     if (close (fd) == -1)
-       goto bail3;
+       goto bail25;
     
     if (!FcAtomicReplaceOrig (atomic))
-       goto bail3;
+       goto bail25;
     
     FcAtomicUnlock (atomic);
     FcAtomicDestroy (atomic);
@@ -345,13 +383,19 @@ FcGlobalCacheSave (FcGlobalCache    *cache,
     cache->updated = FcFalse;
     return FcTrue;
 
-bail3:
+ bail4:
+    free (header);
+ bail3:
+    if (fd_orig != -1)
+        close (fd_orig);
+
+    close (fd);
+ bail25:
     FcAtomicDeleteNew (atomic);
-bail2:
+ bail2:
     FcAtomicUnlock (atomic);
-bail1:
+ bail1:
     FcAtomicDestroy (atomic);
-bail0:
     return FcFalse;
 }
 
@@ -383,13 +427,20 @@ FcCacheSkipToArch (int fd, const char * arch)
     {
        long bs;
 
-       lseek (fd, current_arch_start, SEEK_SET);
+       if (lseek (fd, current_arch_start, SEEK_SET) != current_arch_start)
+            return -1;
+
        if (FcCacheReadString (fd, candidate_arch_machine_name_count, 
                                sizeof (candidate_arch_machine_name_count)) == 0)
             return -1;
        if (!strlen(candidate_arch_machine_name_count))
            return -1;
        bs = strtol(candidate_arch_machine_name_count, &candidate_arch, 16);
+
+       // count = 0 should probably be distinguished from the !bs condition
+       if (!bs || bs < strlen (candidate_arch_machine_name_count))
+           return -1;
+
        candidate_arch++; /* skip leading space */
 
        if (strcmp (candidate_arch, arch)==0)
@@ -404,16 +455,34 @@ FcCacheSkipToArch (int fd, const char * arch)
  * down to cover it), and leaves the file pointer at the end of the
  * file. */
 static FcBool 
-FcCacheMoveDown (int fd, off_t start)
+FcCacheCopyOld (int fd, int fd_orig, off_t start)
 {
     char * buf = malloc (8192);
     char candidate_arch_machine_name[MACHINE_SIGNATURE_SIZE + 9];
     long bs;
     int c, bytes_skipped;
+    off_t loc;
 
     if (!buf)
        return FcFalse;
 
+    loc = 0;
+    lseek (fd, 0, SEEK_SET); lseek (fd_orig, 0, SEEK_SET);
+    do
+    {
+        int b = 8192;
+        if (loc + b > start)
+            b = start - loc;
+
+       if ((c = read (fd_orig, buf, b)) <= 0)
+           break;
+       if (write (fd, buf, c) < 0)
+           goto bail;
+
+        loc += c;
+    }
+    while (c > 0);
+
     lseek (fd, start, SEEK_SET);
     if (FcCacheReadString (fd, candidate_arch_machine_name, 
                           sizeof (candidate_arch_machine_name)) == 0)
@@ -448,6 +517,7 @@ FcCacheMoveDown (int fd, off_t start)
     return FcFalse;
 }
 
+/* Does not check that the cache has the appropriate arch section. */
 FcBool
 FcDirCacheValid (const FcChar8 *dir)
 {
@@ -464,6 +534,7 @@ FcDirCacheValid (const FcChar8 *dir)
         FcStrFree (cache_file);
         return FcFalse;
     }
+
     FcStrFree (cache_file);
     /*
      * If the directory has been modified more recently than
@@ -474,12 +545,47 @@ FcDirCacheValid (const FcChar8 *dir)
     return FcTrue;
 }
 
+/* Assumes that the cache file in 'dir' exists.
+ * Checks that the cache has the appropriate arch section. */
+FcBool
+FcDirCacheHasCurrentArch (const FcChar8 *dir)
+{
+    FcChar8     *cache_file = FcStrPlus (dir, (FcChar8 *) "/" FC_DIR_CACHE_FILE);
+    int        fd;
+    off_t      current_arch_start;
+    char       *current_arch_machine_name;
+
+    current_arch_machine_name = FcCacheMachineSignature();
+    fd = open ((char *)cache_file, O_RDONLY);
+    if (fd == -1)
+        return FcFalse;
+
+    current_arch_start = FcCacheSkipToArch(fd, current_arch_machine_name);
+    close (fd);
+
+    if (current_arch_start < 0)
+        return FcFalse;
+    
+    return FcTrue;
+}
+
+FcBool
+FcDirCacheUnlink (const FcChar8 *dir)
+{
+    FcChar8     *cache_file = FcStrPlus (dir, (FcChar8 *) "/" FC_DIR_CACHE_FILE);
+
+    if (!unlink ((char *)cache_file))
+        return FcFalse;
+
+    FcStrFree (cache_file);
+
+    return FcTrue;
+}
+
 static int
 FcCacheReadDirs (FcConfig * config, FcGlobalCache * cache, 
                 FcStrList *list, FcFontSet * set)
 {
-    DIR                        *d;
-    struct dirent      *e;
     int                        ret = 0;
     FcChar8            *dir;
     FcChar8            *file, *base;
@@ -488,8 +594,7 @@ FcCacheReadDirs (FcConfig * config, FcGlobalCache * cache,
     struct stat                statb;
 
     /*
-     * Now scan all of the directories into separate databases
-     * and write out the results
+     * Read in the results from 'list'.
      */
     while ((dir = FcStrListNext (list)))
     {
@@ -546,7 +651,7 @@ FcCacheReadDirs (FcConfig * config, FcGlobalCache * cache,
        if (!FcDirCacheValid (dir) || !FcDirCacheRead (set, subdirs, dir))
        {
            if (FcDebug () & FC_DBG_FONTSET)
-               printf ("scan dir %s\n", dir);
+               printf ("cache scan dir %s\n", dir);
 
            FcDirScanConfig (set, subdirs, cache, 
                             config->blanks, dir, FcFalse, config);
@@ -588,12 +693,12 @@ FcCacheRead (FcConfig *config, FcGlobalCache * cache)
 static FcBool
 FcDirCacheRead (FcFontSet * set, FcStrSet * dirs, const FcChar8 *dir)
 {
-    FcChar8         *cache_file = FcStrPlus (dir, (FcChar8 *) "/" FC_DIR_CACHE_FILE);
+    char *cache_file = (char *)FcStrPlus (dir, (FcChar8 *) "/" FC_DIR_CACHE_FILE);
     int fd;
     char * current_arch_machine_name;
     char candidate_arch_machine_name[9+MACHINE_SIGNATURE_SIZE];
     off_t current_arch_start = 0;
-    FcChar8        subdirName[FC_MAX_FILE_LEN + 1 + 12 + 1];
+    char subdirName[FC_MAX_FILE_LEN + 1 + 12 + 1];
 
     if (!cache_file)
         goto bail;
@@ -613,7 +718,7 @@ FcDirCacheRead (FcFontSet * set, FcStrSet * dirs, const FcChar8 *dir)
        goto bail1;
 
     while (strlen(FcCacheReadString (fd, subdirName, sizeof (subdirName))) > 0)
-        FcStrSetAdd (dirs, subdirName);
+        FcStrSetAdd (dirs, (FcChar8 *)subdirName);
 
     if (!FcDirCacheConsume (fd, set))
        goto bail1;
@@ -659,7 +764,7 @@ static void *
 FcDirCacheProduce (FcFontSet *set, FcCache *metadata)
 {
     void * current_dir_block, * final_dir_block;
-    static int rand_state = 0;
+    static unsigned int rand_state = 0;
     int bank;
 
     if (!rand_state) 
@@ -701,81 +806,111 @@ FcBool
 FcDirCacheWrite (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir)
 {
     FcChar8         *cache_file = FcStrPlus (dir, (FcChar8 *) "/" FC_DIR_CACHE_FILE);
-    int fd, i;
-    FcCache metadata;
-    off_t current_arch_start = 0, truncate_to;
-    char * current_arch_machine_name, * header;
-    void * current_dir_block;
+    int            fd, fd_orig, i, dirs_count;
+    FcAtomic       *atomic;
+    FcCache        metadata;
+    off_t          current_arch_start = 0, truncate_to;
+
+    char            *current_arch_machine_name, * header;
+    void           *current_dir_block;
 
     if (!cache_file)
         goto bail;
 
     current_dir_block = FcDirCacheProduce (set, &metadata);
 
-    if (!metadata.count)
-    {
-       unlink (cache_file);
-       free (cache_file);
-       return FcTrue;
-    }
-
-    if (!current_dir_block)
-       goto bail;
+    if (metadata.count && !current_dir_block)
+       goto bail0;
 
     if (FcDebug () & FC_DBG_CACHE)
         printf ("FcDirCacheWriteDir cache_file \"%s\"\n", cache_file);
 
-    fd = open(cache_file, O_RDWR | O_CREAT, 0666);
-    if (fd == -1)
+    atomic = FcAtomicCreate (cache_file);
+    if (!atomic)
         goto bail0;
 
+    if (!FcAtomicLock (atomic))
+        goto bail1;
+
+    fd_orig = open((char *)FcAtomicOrigFile (atomic), O_RDONLY, 0666);
+
+    fd = open((char *)FcAtomicNewFile (atomic), O_RDWR | O_CREAT, 0666);
+    if (fd == -1)
+        goto bail2;
+
     current_arch_machine_name = FcCacheMachineSignature ();
-    current_arch_start = FcCacheSkipToArch(fd, current_arch_machine_name);
+    current_arch_start = 0;
+
+    if (fd_orig != -1)
+        current_arch_start = 
+            FcCacheSkipToArch(fd_orig, current_arch_machine_name);
+
     if (current_arch_start < 0)
-       current_arch_start = FcCacheNextOffset (lseek(fd, 0, SEEK_END));
+       current_arch_start = FcCacheNextOffset (lseek(fd_orig, 0, SEEK_END));
 
-    if (!FcCacheMoveDown(fd, current_arch_start))
-       goto bail2;
+    if (fd_orig != -1 && !FcCacheCopyOld(fd, fd_orig, current_arch_start))
+       goto bail3;
+
+    if (fd_orig != -1)
+        close (fd_orig);
 
     current_arch_start = lseek(fd, 0, SEEK_CUR);
     if (ftruncate (fd, current_arch_start) == -1)
-       goto bail2;
+       goto bail3;
+
+    /* allocate space for subdir names in this block */
+    dirs_count = 0;
+    for (i = 0; i < dirs->size; i++)
+        dirs_count += strlen((char *)dirs->strs[i]) + 1;
+    dirs_count ++;
 
     /* now write the address of the next offset */
-    truncate_to = FcCacheNextOffset (FcCacheNextOffset (current_arch_start + sizeof (FcCache)) + metadata.count) - current_arch_start;
+    truncate_to = FcCacheNextOffset (FcCacheNextOffset (current_arch_start + sizeof (FcCache) + dirs_count) + metadata.count) - current_arch_start;
     header = malloc (10 + strlen (current_arch_machine_name));
     if (!header)
-       goto bail1;
+       goto bail3;
     sprintf (header, "%8x ", (int)truncate_to);
     strcat (header, current_arch_machine_name);
     if (!FcCacheWriteString (fd, header))
-       goto bail1;
+       goto bail4;
 
     for (i = 0; i < dirs->size; i++)
-        FcCacheWriteString (fd, dirs->strs[i]);
+        FcCacheWriteString (fd, (char *)dirs->strs[i]);
     FcCacheWriteString (fd, "");
 
     write (fd, &metadata, sizeof(FcCache));
-    lseek (fd, FcCacheNextOffset (lseek(fd, 0, SEEK_END)), SEEK_SET);
-    write (fd, current_dir_block, metadata.count);
-    free (current_dir_block);
+    if (metadata.count)
+    {
+       lseek (fd, FcCacheNextOffset (lseek(fd, 0, SEEK_END)), SEEK_SET);
+       write (fd, current_dir_block, metadata.count);
+       free (current_dir_block);
+    }
 
     /* this actually serves to pad out the cache file, if needed */
     if (ftruncate (fd, current_arch_start + truncate_to) == -1)
-       goto bail1;
+       goto bail4;
 
     close(fd);
+    if (!FcAtomicReplaceOrig(atomic))
+        goto bail4;
+    FcAtomicUnlock (atomic);
+    FcAtomicDestroy (atomic);
     return FcTrue;
 
- bail2:
+ bail4:
     free (header);
+ bail3:
+    close (fd);
+ bail2:
+    FcAtomicUnlock (atomic);
  bail1:
-    free (current_arch_machine_name);
+    FcAtomicDestroy (atomic);
  bail0:
-    free (current_dir_block);
- bail:
-    unlink (cache_file);
+    unlink ((char *)cache_file);
     free (cache_file);
+    if (current_dir_block)
+        free (current_dir_block);
+ bail:
     return FcFalse;
 }
 
@@ -790,25 +925,25 @@ FcCacheMachineSignature ()
             "%4x %4x %4x %4x %4x %4x %4x %4x %4x %4x %4x %4x "
             "%4x %4x %4x %4x %4x %4x %4x\n", 
             m[0], m[1], m[2], m[3],
-            sizeof (char),
-            sizeof (char *),
-            sizeof (int),
-            sizeof (FcPattern),
-            sizeof (FcPatternEltPtr),
-            sizeof (struct _FcPatternElt *),
-            sizeof (FcPatternElt),
-            sizeof (FcObjectPtr),
-            sizeof (FcValueListPtr),
-            sizeof (FcValue),
-            sizeof (FcValueBinding),
-            sizeof (struct _FcValueList *),
-            sizeof (FcCharSet),
-            sizeof (FcCharLeaf **),
-            sizeof (FcChar16 *),
-            sizeof (FcChar16),
-            sizeof (FcCharLeaf),
-            sizeof (FcChar32),
-            sizeof (FcCache));
+            (unsigned int)sizeof (char),
+            (unsigned int)sizeof (char *),
+            (unsigned int)sizeof (int),
+            (unsigned int)sizeof (FcPattern),
+            (unsigned int)sizeof (FcPatternEltPtr),
+            (unsigned int)sizeof (struct _FcPatternElt *),
+            (unsigned int)sizeof (FcPatternElt),
+            (unsigned int)sizeof (FcObjectPtr),
+            (unsigned int)sizeof (FcValueListPtr),
+            (unsigned int)sizeof (FcValue),
+            (unsigned int)sizeof (FcValueBinding),
+            (unsigned int)sizeof (struct _FcValueList *),
+            (unsigned int)sizeof (FcCharSet),
+            (unsigned int)sizeof (FcCharLeaf **),
+            (unsigned int)sizeof (FcChar16 *),
+            (unsigned int)sizeof (FcChar16),
+            (unsigned int)sizeof (FcCharLeaf),
+            (unsigned int)sizeof (FcChar32),
+            (unsigned int)sizeof (FcCache));
 
     return buf;
 }