diff options
author | Jeff Muizelaar <jeff@infidigm.net> | 2006-09-06 23:28:53 +0000 |
---|---|---|
committer | Jeff Muizelaar <jeff@infidigm.net> | 2006-09-06 23:28:53 +0000 |
commit | f6d8d8e8a9b57f8c6ebec9a2f9e82fea8a52403e (patch) | |
tree | c1d76cba71b38c5c5b7865e07d8dbbfe8d3d8557 /read-cache.c | |
parent | 1e0195ed5c1d9562af9138ad782fc8ee68443390 (diff) |
Add support for a reference cache file that contains SHA1 hashes of the
reference images. Having the cache avoids the performance hit of reading and
decompressing the reference pngs.
Diffstat (limited to 'read-cache.c')
-rw-r--r-- | read-cache.c | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/read-cache.c b/read-cache.c new file mode 100644 index 0000000..17ac58f --- /dev/null +++ b/read-cache.c @@ -0,0 +1,90 @@ +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <string.h> +#include <libgen.h> +#include <openssl/sha.h> +#include "read-cache.h" + +unsigned char *cache; +unsigned char *cache_end; +unsigned char *current_cache_entry; +void cache_init(const char *path) +{ + FILE *f = cache_open(path, "r"); + if (!f) { + printf("no cache\n"); + return; + } + struct stat buf; + fstat(fileno(f), &buf); + cache = malloc(buf.st_size); + fread(cache, 1, buf.st_size, f); + fclose(f); + + /* set the current entry to the begining of the cache */ + current_cache_entry = cache; + cache_end = cache + buf.st_size; +} + +FILE *cache_open(const char *path, const char *mode) +{ + FILE *cache; + char *cache_path; + char *path_copy = strdup(path); + char *dir = dirname(path_copy); + asprintf(&cache_path, "%s/cache", dir); + cache = fopen(cache_path, mode); + free(cache_path); + free(path_copy); + return cache; +} + +#define MIN(a, b) (a) < (b) ? (a) : (b) + +static void print_hash(const unsigned char *hash) +{ + int i; + for (i=0; i<SHA_DIGEST_LENGTH; i++) { + printf("%02x", hash[i]); + } + printf("\n"); +} + +int cache_compare(const char *path, const unsigned char *buffer, unsigned int length) +{ + char *path_copy = strdup(path); + char *name = basename(path_copy); + int match = 0; + //printf("compare: %s\n", path); + int name_length = strlen(name); + while (current_cache_entry < cache_end) { + int cache_length = strlen(current_cache_entry); + int min_length = MIN(cache_length, name_length); + int result = memcmp(name, current_cache_entry, min_length); + if (result == 0) { + unsigned char *cache_hash = current_cache_entry + cache_length + 1; + unsigned char hash[SHA_DIGEST_LENGTH]; + //printf("found entry\n"); + SHA1(buffer, length, hash); + print_hash(cache_hash); + print_hash(hash); + current_cache_entry = cache_hash + SHA_DIGEST_LENGTH; + match = memcmp(hash, cache_hash, SHA_DIGEST_LENGTH) == 0 ? 1 : 0; + //printf("match %d\n", match); + break; + } else if (result < 0) { + //printf("moving to next entry: %s vs. %s did not match\n", name, current_cache_entry); + current_cache_entry += cache_length + 1 + SHA_DIGEST_LENGTH; + break; + } else { + //printf("trying next entry: %s vs. %s did not match\n", name, current_cache_entry); + current_cache_entry += cache_length + 1 + SHA_DIGEST_LENGTH; + } + } + free(path_copy); + + return match; +} |