]> git.wh0rd.org - fontconfig.git/blobdiff - src/fccache.c
fc-cache: convert
[fontconfig.git] / src / fccache.c
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