Index: trunk/src_3rd/load_cache/Makefile =================================================================== --- trunk/src_3rd/load_cache/Makefile (nonexistent) +++ trunk/src_3rd/load_cache/Makefile (revision 756) @@ -0,0 +1,4 @@ +CFLAGS = -I.. -Wall -std=c89 -pedantic + +load_cache.o: load_cache.c load_cache.h + $(CC) $(CFLAGS) -c -o load_cache.o load_cache.c \ No newline at end of file Index: trunk/src_3rd/load_cache/load_cache.c =================================================================== --- trunk/src_3rd/load_cache/load_cache.c (nonexistent) +++ trunk/src_3rd/load_cache/load_cache.c (revision 756) @@ -0,0 +1,113 @@ +#include +#include +#include +#include "load_cache.h" + +char *ldch_strdup(const char *s) +{ + int l = strlen(s); + char *o = malloc(l+1); + return memcpy(o, s, l+1); +} + +void ldch_init(ldch_ctx_t *ctx) +{ + memset(ctx, 0, sizeof(ldch_ctx_t)); + htsp_init(&ctx->low_parsers, strhash, strkeyeq); + htsp_init(&ctx->high_parsers, strhash, strkeyeq); + htsp_init(&ctx->files, strhash, strkeyeq); + ctx->next_low_uid = 1; +} + +ldch_low_parser_t *ldch_reg_low_parser(ldch_ctx_t *ctx, const char *name) +{ + ldch_low_parser_t *p; + + p = htsp_get(&ctx->low_parsers, name); + if (p != NULL) + return NULL; + + p = calloc(sizeof(ldch_low_parser_t), 1); + p->name = ldch_strdup(name); + p->uid = ctx->next_low_uid++; + htsp_set(&ctx->low_parsers, p->name, p); + return p; +} + +ldch_high_parser_t *ldch_reg_high_parser(ldch_ctx_t *ctx, const char *name) +{ + ldch_high_parser_t *p; + + p = htsp_get(&ctx->high_parsers, name); + if (p != NULL) + return NULL; + + p = calloc(sizeof(ldch_high_parser_t), 1); + p->name = ldch_strdup(name); + htsp_set(&ctx->high_parsers, p->name, p); + return p; +} + +ldch_low_parser_t *ldch_lookup_low_parser(ldch_ctx_t *ctx, const char *name) +{ + return htsp_get(&ctx->low_parsers, name); +} + +ldch_high_parser_t *ldch_lookup_high_parser(ldch_ctx_t *ctx, const char *name) +{ + return htsp_get(&ctx->high_parsers, name); +} + + +ldch_data_t *ldch_load_(ldch_ctx_t *ctx, const char *filename, ldch_low_parser_t *low, ldch_high_parser_t *high, void *low_call_ctx, void *high_call_ctx) +{ + ldch_file_t *file = htsp_get(&ctx->files, filename); + void **d; + ldch_data_t *data; + + /* get low level */ + if (file == NULL) { + file = low->parse(low, low_call_ctx, filename); + if (file == NULL) + return NULL; + + } + else { + if (low->uid != file->low_parser) + return NULL; /* can't parse the same file twice, with different low level */ + } + + /* get high level parsing donw */ + d = vtp0_get(&file->data, low->uid, 1); + if (d == NULL) + return NULL; /* allocation error */ + + if (*d == NULL) { + data = high->parse(high, high_call_ctx, file, filename); + if (data == NULL) + return NULL; + *d = data; + } + else + data = *d; + + data->refco++; + return data; +} + + +ldch_data_t *ldch_load(ldch_ctx_t *ctx, const char *filename, const char *lows, const char *highs, void *low_call_ctx, void *high_call_ctx) +{ + ldch_low_parser_t *low; + ldch_high_parser_t *high; + + low = ldch_lookup_low_parser(ctx, lows); + if (low == NULL) + return NULL; + + high = ldch_lookup_high_parser(ctx, highs); + if (high == NULL) + return NULL; + + return ldch_load_(ctx, filename, low, high, low_call_ctx, high_call_ctx); +} Index: trunk/src_3rd/load_cache/load_cache.h =================================================================== --- trunk/src_3rd/load_cache/load_cache.h (nonexistent) +++ trunk/src_3rd/load_cache/load_cache.h (revision 756) @@ -0,0 +1,60 @@ +#include +#include + +typedef struct ldch_ctx_s ldch_ctx_t; +typedef struct ldch_data_s ldch_data_t; +typedef struct ldch_file_s ldch_file_t; +typedef struct ldch_low_parser_s ldch_low_parser_t; +typedef struct ldch_high_parser_s ldch_high_parser_t; +typedef int ldch_uid_t; + +struct ldch_low_parser_s { + char *name; + ldch_uid_t uid; + ldch_file_t *(*parse)(ldch_low_parser_t *parser, void *call_ctx, const char *fn); + void *used_data; +}; + +struct ldch_high_parser_s { + char *name; + ldch_data_t *(*parse)(ldch_high_parser_t *parser, void *call_ctx, ldch_file_t *file, const char *fn); + void *used_data; +}; + +struct ldch_data_s { + ldch_file_t *parent; + int refco; + int payload_size; + char payload[1]; /* real size: payload_size (caches parsed data) */ +}; + +struct ldch_file_s { + ldch_ctx_t *parent; + char *name; /* file name */ + vtp0_t data; /* -> (ldch_data_t *), indexed by high_parser uid */ + void *user_data; + ldch_uid_t low_parser; + int low_payload_size; + char low_payload[1]; /* real size: low_payload_size (caches low level parsed data) */ +}; + +struct ldch_ctx_s { + htsp_t low_parsers; + htsp_t high_parsers; + htsp_t files; /* of ldch_file_t */ + void *user_data; + ldch_uid_t next_low_uid; +}; + + +void ldch_init(ldch_ctx_t *ctx); + +ldch_low_parser_t *ldch_reg_low_parser(ldch_ctx_t *ctx, const char *name); +ldch_high_parser_t *ldch_reg_high_parser(ldch_ctx_t *ctx, const char *name); + +ldch_low_parser_t *ldch_lookup_low_parser(ldch_ctx_t *ctx, const char *name); +ldch_high_parser_t *ldch_lookup_high_parser(ldch_ctx_t *ctx, const char *name); + +ldch_data_t *ldch_load_(ldch_ctx_t *ctx, const char *filename, ldch_low_parser_t *low, ldch_high_parser_t *high, void *low_call_ctx, void *high_call_ctx); +ldch_data_t *ldch_load(ldch_ctx_t *ctx, const char *filename, const char *low, const char *high, void *low_call_ctx, void *high_call_ctx); +