]> git.wh0rd.org - fontconfig.git/commitdiff
fc-cache: convert cache-conv
authorMike Frysinger <vapier@gentoo.org>
Tue, 8 Nov 2011 16:47:27 +0000 (11:47 -0500)
committerMike Frysinger <vapier@gentoo.org>
Tue, 8 Nov 2011 19:49:37 +0000 (14:49 -0500)
fc-cache/fc-cache.c
src/fccache.c

index 59a24bbb324e5c98dfc1e1de3a686125395ff055..9bac25d7f3e6db825d85ef7a7be111df3a6cfb72 100644 (file)
@@ -67,6 +67,7 @@
 #define _GNU_SOURCE
 #include <getopt.h>
 const struct option longopts[] = {
+    {"convert", 0, 0, 'c'},
     {"force", 0, 0, 'f'},
     {"really-force", 0, 0, 'r'},
     {"root", 1, 0, 'R'},
@@ -386,13 +387,18 @@ main (int argc, char **argv)
 #if HAVE_GETOPT_LONG || HAVE_GETOPT
     int                c;
 
+FcBool convert = FcFalse;
+
 #if HAVE_GETOPT_LONG
-    while ((c = getopt_long (argc, argv, "frR:sVvh", longopts, NULL)) != -1)
+    while ((c = getopt_long (argc, argv, "cfrR:sVvh", longopts, NULL)) != -1)
 #else
-    while ((c = getopt (argc, argv, "frR:sVvh")) != -1)
+    while ((c = getopt (argc, argv, "cfrR:sVvh")) != -1)
 #endif
     {
        switch (c) {
+       case 'c':
+           convert = FcTrue;
+           break;
        case 'r':
            really_force = FcTrue;
            /* fall through */
@@ -423,6 +429,20 @@ main (int argc, char **argv)
     i = 1;
 #endif
 
+    if (convert)
+    {
+       const FcChar8 *src_cache, *dst_cache, *src_type, *dst_type;
+
+       src_cache = (const FcChar8 *) argv[i++];
+       src_type = (const FcChar8 *) argv[i++];
+       dst_cache = (const FcChar8 *) argv[i++];
+       dst_type = (const FcChar8 *) argv[i++];
+
+       FcDirCacheConvert (src_cache, src_type, dst_cache, dst_type);
+
+       return 0;
+    }
+
     if (systemOnly)
        FcConfigEnableHome (FcFalse);
     config = FcInitLoadConfig ();
index e9f57f4ed736cf009dc2388b175457a1e73e4b49..350b80521da9fe3ea34cfba7a125c7297b5a7932 100644 (file)
@@ -1009,6 +1009,122 @@ FcDirCacheWrite (FcCache *cache, FcConfig *config)
     return FcFalse;
 }
 
+static void
+align_fd (int fd, off_t *pos, int align)
+{
+    int adj = *pos & (align - 1);
+    if (adj)
+    {
+       lseek (fd, adj, SEEK_CUR);
+       *pos += adj;
+    }
+}
+
+static uint64_t
+_conv_num (int src_fd, int dst_fd, off_t *src_pos, off_t *dst_pos,
+          FcBool src_be, FcBool dst_be, int src_psize, int dst_psize,
+          int src_read, int dst_write)
+{
+    unsigned char src[8], dst[8], *s, *d;
+    int i, src_step, dst_step;
+    uint64_t ret;
+
+    align_fd (src_fd, src_pos, src_read);
+    read (src_fd, src, src_read);
+    *src_pos += src_read;
+
+    if (src_be)
+       s = &src[src_read - 1], src_step = -1;
+    else
+       s = src, src_step = 1;
+    if (dst_be)
+       d = &dst[dst_write - 1], dst_step = -1;
+    else
+       d = dst, dst_step = 1;
+
+    ret = 0;
+    for (i = 0; i < src_read; ++i)
+    {
+       ret |= ((uint64_t) *s) << (8 * i);
+       *d = *s;
+       s += src_step;
+       d += dst_step;
+    }
+    for (; i < dst_write; ++i)
+    {
+       *d = 0;
+       d += dst_step;
+    }
+
+    align_fd (dst_fd, dst_pos, dst_write);
+    write (dst_fd, dst, dst_write);
+    *dst_pos += dst_write;
+
+    return ret;
+}
+#define conv_num(r, w) _conv_num (src_fd, dst_fd, &src_pos, &dst_pos, src_be, dst_be, src_psize, dst_psize, r, w)
+#define conv_ptr() conv_num (src_psize, dst_psize)
+#define conv_int() conv_num (4, 4)
+
+FcBool
+FcDirCacheConvert (const FcChar8 *src_cache, const FcChar8 *src_type,
+                  const FcChar8 *dst_cache, const FcChar8 *dst_type)
+{
+    /* See fcarch.h for the spec used here */
+    FcCache c;
+    FcBool src_be;
+    FcBool dst_be;
+    int src_psize;
+    int dst_psize;
+    int src_dalign;
+    int dst_dalign;
+    int src_fd;
+    int dst_fd;
+    off_t src_pos;
+    off_t dst_pos;
+    struct stat src_st;
+
+    src_be = !strncmp ((const char *) src_type, "be", 2);
+    dst_be = !strncmp ((const char *) dst_type, "be", 2);
+
+    src_psize = !strncmp ((const char *) src_type + 2, "32", 2) ? 4 : 8;
+    dst_psize = !strncmp ((const char *) dst_type + 2, "32", 2) ? 4 : 8;
+
+    if (src_psize == 4)
+       src_dalign = !strncmp ((const char *) src_type + 4, "d4", 2) ? 4 : 8;
+    else
+       src_dalign = src_psize;
+
+    if (dst_psize == 4)
+       dst_dalign = !strncmp ((const char *) dst_type + 4, "d4", 2) ? 4 : 8;
+    else
+       dst_dalign = dst_psize;
+
+    src_fd = open ((const char *) src_cache, O_RDONLY);
+    if (src_fd == -1)
+       return FcFalse;
+    dst_fd = open ((const char *) dst_cache, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
+    if (dst_fd == -1)
+    {
+       close (src_fd);
+       return FcFalse;
+    }
+    src_pos = dst_pos = 0;
+
+    /* Process FcCache at start of file */
+    c.magic = conv_int ();
+    c.version = conv_int ();
+    c.size = conv_ptr ();
+    c.dir = conv_ptr ();
+    c.dirs = conv_ptr ();
+    c.dirs_count = conv_int ();
+    c.set = conv_ptr ();
+    c.mtime = conv_int ();
+    align_fd (dst_fd, &dst_pos, dst_psize);
+
+    return FcFalse;
+}
+
 /*
  * Hokey little macro trick to permit the definitions of C functions
  * with the same name as CPP macros