emb.c
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <klone/emb.h>
00012 #include <klone/io.h>
00013 #include <klone/codecs.h>
00014 #include <u/libu.h>
00015 #include <u/toolbox/hmap.h>
00016
00017
00018 void register_pages(void);
00019 void unregister_pages(void);
00020
00021 static u_hmap_t *embmap = NULL;
00022 static int init = 0;
00023
00024 static int listadd (const void *val, const void *arg);
00025
00026 int emb_init(void)
00027 {
00028 u_hmap_opts_t *hopts = NULL;
00029
00030 if(init++ == 0)
00031 {
00032 dbg_err_if (u_hmap_opts_new(&hopts));
00033
00034
00035 dbg_err_if (u_hmap_opts_set_val_freefunc(hopts, NULL));
00036
00037 dbg_err_if (u_hmap_easy_new(hopts, &embmap));
00038 hopts = NULL;
00039
00040
00041 u_dbg("registering embedded resources");
00042 register_pages();
00043 }
00044
00045 return 0;
00046
00047 err:
00048 if (hopts)
00049 u_hmap_opts_free(hopts);
00050
00051 return ~0;
00052 }
00053
00054 int emb_term(void)
00055 {
00056 dbg_err_if(init == 0);
00057
00058 unregister_pages();
00059
00060 U_FREEF(embmap, u_hmap_easy_free);
00061
00062 return 0;
00063 err:
00064 return ~0;
00065 }
00066
00067 int emb_register(embres_t *res)
00068 {
00069 dbg_err_if(init == 0 || res == NULL);
00070
00071 if(res->type == ET_FILE)
00072 u_dbg("registering %s (%s)", res->filename,
00073 ((embfile_t*)res)->comp ? "compressed" : "uncompressed");
00074 else
00075 u_dbg("registering %s", res->filename);
00076
00077 dbg_err_if (u_hmap_easy_put(embmap, res->filename, (const void *) res));
00078
00079 return 0;
00080 err:
00081 return ~0;
00082 }
00083
00084 int emb_unregister(embres_t *res)
00085 {
00086 dbg_err_if(init == 0 || res == NULL);
00087
00088 if (embmap)
00089 dbg_err_if (u_hmap_easy_del(embmap, res->filename));
00090
00091 return 0;
00092 err:
00093 return ~0;
00094 }
00095
00096 int emb_lookup(const char *filename, embres_t **pr)
00097 {
00098 embres_t *res;
00099
00100 dbg_err_if (init == 0);
00101 dbg_err_if (filename == NULL);
00102 dbg_err_if (filename[0] == '\0');
00103 dbg_err_if (pr == NULL);
00104
00105 res = u_hmap_easy_get(embmap, filename);
00106
00107 nop_err_if (res == NULL);
00108
00109 *pr = res;
00110
00111 return 0;
00112 err:
00113 return ~0;
00114 }
00115
00116 int emb_open(const char *file, io_t **pio)
00117 {
00118 embfile_t *e = NULL;
00119 codec_t *gzip = NULL;
00120 io_t *io;
00121
00122 dbg_return_if (pio == NULL, ~0);
00123 dbg_return_if (file == NULL, ~0);
00124
00125 dbg_err_if(emb_lookup(file, (embres_t**)&e) || e->res.type != ET_FILE);
00126
00127 dbg_err_if(io_mem_create((char*)e->data, e->size, 0, &io));
00128
00129 #ifdef HAVE_LIBZ
00130 if(e->comp)
00131 {
00132 dbg_err_if(codec_gzip_create(GZIP_UNCOMPRESS, &gzip));
00133 dbg_err_if(io_codec_add_tail(io, (codec_t*)gzip));
00134 gzip = NULL;
00135 }
00136 #endif
00137
00138 *pio = io;
00139
00140 return 0;
00141 err:
00142 if(gzip)
00143 codec_free(gzip);
00144 return ~0;
00145 }
00146
00147 int emb_list (char ***plist)
00148 {
00149 size_t i;
00150 ssize_t nelems;
00151 char **list = NULL;
00152
00153
00154 dbg_err_if ((nelems = u_hmap_count(embmap)) <= 0);
00155
00156
00157 list = u_malloc(((size_t) nelems + 1) * sizeof(char *));
00158 dbg_err_sif (list == NULL);
00159
00160 for (i = 0; i <= (size_t) nelems; i++)
00161 list[i] = NULL;
00162
00163
00164 u_hmap_foreach_arg(embmap, listadd, list);
00165
00166
00167 *plist = list;
00168
00169 return 0;
00170 err:
00171 if (list)
00172 emb_list_free(list);
00173 return ~0;
00174 }
00175
00176 void emb_list_free (char **list)
00177 {
00178 size_t i;
00179
00180 if (list == NULL)
00181 return;
00182
00183 for (i = 0; list[i] != NULL; i++)
00184 u_free(list[i]);
00185
00186 u_free(list);
00187
00188 return;
00189 }
00190
00191 int emb_to_ubuf(const char *res_name, u_buf_t **pubuf)
00192 {
00193 int c;
00194 char buf[1024];
00195 io_t *tmp = NULL;
00196 u_buf_t *ubuf = NULL;
00197
00198 dbg_err_if(res_name == NULL);
00199 dbg_err_if(pubuf == NULL);
00200
00201 dbg_err_if(emb_open(res_name, &tmp));
00202
00203 dbg_err_if(u_buf_create(&ubuf));
00204
00205 for (;;)
00206 {
00207 c = io_read(tmp, buf, sizeof(buf));
00208
00209 if (c == 0)
00210 break;
00211 else if (c < 0)
00212 goto err;
00213
00214 dbg_err_if (u_buf_append(ubuf, buf, c));
00215 }
00216
00217 io_free(tmp); tmp = NULL;
00218
00219 *pubuf = ubuf;
00220
00221 return 0;
00222 err:
00223 if (tmp)
00224 io_free(tmp);
00225 if (ubuf)
00226 u_buf_free(ubuf);
00227
00228 return ~0;
00229 }
00230
00231
00232 static int listadd (const void *val, const void *arg)
00233 {
00234 size_t i;
00235 const char **list = (const char **) arg;
00236 const embres_t *res = (const embres_t *) val;
00237
00238
00239 for (i = 0; list[i] != NULL; i++)
00240 ;
00241
00242
00243 dbg_err_sif ((list[i] = u_strdup(res->filename)) == NULL);
00244
00245 return 0;
00246 err:
00247 return ~0;
00248 }
00249