emb.c

00001 /*
00002  * Copyright (c) 2005-2012 by KoanLogic s.r.l. <http://www.koanlogic.com>
00003  * All rights reserved.
00004  *
00005  * This file is part of KLone, and as such it is subject to the license stated
00006  * in the LICENSE file which you have received as part of this distribution.
00007  *
00008  * $Id: emb.c,v 1.23 2010/06/02 07:46:57 tho Exp $
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 /* these are klone-site autogen functions */
00018 void register_pages(void);
00019 void unregister_pages(void);
00020 
00021 static u_hmap_t *embmap = NULL;     /* hashmap of embedded resources */
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         /* no free function needed for static values */
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         /* call autogen external function (cannot be called more then once!) */
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     /* dbg_err_ifm (res == NULL, "%s not found", filename); */
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     /* See how many elements are registered. */
00154     dbg_err_if ((nelems = u_hmap_count(embmap)) <= 0);
00155 
00156     /* Create the array of strings needed to hold the list. */
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     /* Walk through the embfs to collect res names. */
00164     u_hmap_foreach_arg(embmap, listadd, list);
00165 
00166     /* Copy out result. */
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)     /* EOF */
00210             break;
00211         else if (c < 0) /* read error */
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 /* Here 'val' is an embres_t object and 'arg' the res names' list. */
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     /* Skip over already filled slots. */
00239     for (i = 0; list[i] != NULL; i++)
00240         ;
00241 
00242     /* Attach the resource filename. */
00243     dbg_err_sif ((list[i] = u_strdup(res->filename)) == NULL);
00244 
00245     return 0;
00246 err:
00247     return ~0;
00248 }
00249 

←Products
Copyright © 2005-2012 - KoanLogic S.r.l. - All rights reserved