X-Git-Url: https://git.wh0rd.org/?a=blobdiff_plain;f=src%2Ffccache.c;h=350b80521da9fe3ea34cfba7a125c7297b5a7932;hb=refs%2Fheads%2Fcache-conv;hp=e9f57f4ed736cf009dc2388b175457a1e73e4b49;hpb=d0471dd2faca37f7ee5997ad9db8278db0e99206;p=fontconfig.git diff --git a/src/fccache.c b/src/fccache.c index e9f57f4..350b805 100644 --- a/src/fccache.c +++ b/src/fccache.c @@ -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