LTP GCOV extension - code coverage report
Current view: directory - and-httpd/src - mime_types.c
Test: And-httpd coverage
Date: 2006-09-11 Instrumented lines: 202
Code covered: 81.7 % Executed lines: 165

       1                 : 
       2                 : #include "mime_types.h"
       3                 : 
       4                 : #define EX_UTILS_NO_FUNCS 1
       5                 : #include "ex_utils.h"
       6                 : 
       7                 : #include "mk.h"
       8                 : 
       9                 : #if COMPILE_DEBUG
      10                 : # define MIME_TYPES__INIT_SECT_SZ 2
      11                 : # define MIME_TYPES__INIT_TYPE_SZ 2
      12                 : #else
      13                 : # define MIME_TYPES__INIT_SECT_SZ 128
      14                 : # define MIME_TYPES__INIT_TYPE_SZ  64
      15                 : #endif
      16                 : 
      17                 : static Vstr_sect_node *mime_types__srch(Mime_types_data *mime,
      18                 :                                         const Vstr_base *fname,
      19                 :                                         size_t pos, size_t len)
      20            3884 : {
      21            3884 :   unsigned int num = 0;
      22                 :   
      23            1942 :   ASSERT(fname && len && mime->ents->num);
      24                 : 
      25            3884 :   num = mime->ents->num - 1; /* FIXME: off by one for addition */
      26          142648 :   while (num)
      27                 :   {
      28          134980 :     size_t epos  = VSTR_SECTS_NUM(mime->ents, num)->pos;
      29          134980 :     size_t elen  = VSTR_SECTS_NUM(mime->ents, num)->len;
      30          134980 :     unsigned int ext_num = num;
      31                 :     
      32          134980 :     --num;
      33          134980 :     --num;
      34                 : 
      35          134980 :     if (vstr_cmp_eq(fname, pos, len, mime->ent_data, epos, elen))
      36             100 :       return (VSTR_SECTS_NUM(mime->ents, ext_num));
      37                 :   }
      38                 : 
      39            3784 :   return (NULL);
      40                 : }
      41                 : 
      42                 : static void mime_type__type_add(Mime_types_data *mime, unsigned char type)
      43            3884 : {
      44            1942 :   MALLOC_CHECK_SZ_MEM(mime->types, mime->type_sz);
      45                 :   
      46            1942 :   ASSERT(mime->type_num <= mime->type_sz);
      47                 : 
      48            3884 :   if (mime->type_num >= mime->type_sz)
      49                 :   {
      50             203 :     unsigned char *tmp = NULL;
      51             203 :     unsigned int sz    = mime->type_sz  * 2;
      52                 : 
      53             203 :     if (!MV(mime->types, tmp, sz))
      54                 :     {
      55               0 :       mime->ents->malloc_bad = TRUE;
      56               0 :       return;
      57                 :     }
      58                 :     
      59             203 :     mime->type_sz = sz;
      60                 :   }
      61                 :   
      62            3884 :   mime->types[mime->type_num++] = type;
      63                 :   
      64            1942 :   ASSERT(mime->type_num <= mime->type_sz);
      65                 : }
      66                 : 
      67                 : int mime_types_load_simple(Mime_types *pmime, const char *fname)
      68             140 : {
      69             140 :   Mime_types_data *mime = pmime->ref->ptr;
      70             140 :   size_t orig_ent_data_len   = mime->ent_data->len;
      71             140 :   unsigned int orig_ents_num = mime->ents->num;
      72             140 :   Vstr_base *data = NULL;
      73             140 :   Vstr_sects *lines = NULL;
      74             140 :   unsigned int num = 0;
      75             140 :   Vstr_sects *sects = NULL;
      76             140 :   size_t data_pos = 0;
      77             140 :   size_t data_len = 0;
      78             140 :   int saved_errno = ENOMEM;
      79                 : 
      80              70 :   ASSERT(pmime && pmime->ref && (pmime->ref->ref == 1));
      81                 :   
      82             140 :   if (!fname || !*fname)
      83              28 :     return (TRUE);
      84                 :   
      85             112 :   if (!(data = vstr_make_base(NULL)))
      86               0 :     goto fail_data;
      87                 : 
      88             112 :   if (!(lines = vstr_sects_make(128)))
      89               0 :     goto fail_sects_lines;
      90                 : 
      91             112 :   if (!(sects = vstr_sects_make(4)))
      92               0 :     goto fail_sects_tmp;
      93                 : 
      94             112 :   if (!vstr_sc_read_len_file(data, data_pos, fname, 0, 0, NULL))
      95               0 :     goto fail_read_file;
      96                 : 
      97             112 :   data_len = data->len - data_pos++;
      98             112 :   vstr_split_cstr_buf(data, data_pos, data_len, "\n", lines, 0, 0);
      99             112 :   if (lines->malloc_bad)
     100               0 :     goto fail_split_file;
     101                 : 
     102            2932 :   while (++num <= lines->num)
     103                 :   {
     104            2764 :     size_t pos = VSTR_SECTS_NUM(lines, num)->pos;
     105            2764 :     size_t len = VSTR_SECTS_NUM(lines, num)->len;
     106            2764 :     Vstr_sect_node *sct = NULL;
     107                 : 
     108            2764 :     if (vstr_export_chr(data, pos) == '#')
     109             526 :       continue;
     110                 : 
     111            2238 :     sects->num = 0;
     112            2238 :     vstr_split_cstr_chrs(data, pos, len, " \t", sects, 0, 0);
     113            2238 :     if (sects->malloc_bad)
     114               0 :       goto fail_split_line;
     115                 :     
     116            7241 :     while (sects->num > 1)
     117                 :     {
     118            3884 :       Vstr_sect_node *sext = VSTR_SECTS_NUM(sects, sects->num);
     119            3884 :       size_t spos = 0;
     120            3884 :       size_t slen = 0;
     121            3884 :       Vstr_sect_node *old_sext = NULL;
     122            3884 :       unsigned char type = MIME_TYPES_TYPE_END;
     123                 :       
     124            3884 :       if (!sct)
     125                 :       {
     126            1982 :         sct = VSTR_SECTS_NUM(sects, 1);
     127            1982 :         spos = mime->ent_data->len + 1;
     128            1982 :         vstr_add_vstr(mime->ent_data, mime->ent_data->len,
     129                 :                       data, sct->pos, sct->len, VSTR_TYPE_ADD_DEF);
     130            1982 :         sct->pos = spos;
     131                 :       }
     132            3884 :       vstr_sects_add(mime->ents, sct->pos, sct->len);
     133                 : 
     134            3884 :       if (vstr_export_chr(data, sext->pos) != '.')
     135                 :       {
     136            3044 :         if (!vstr_srch_chr_fwd(data, sext->pos + 1, sext->len - 1, '.'))
     137            2792 :           type = MIME_TYPES_TYPE_EXT1;
     138                 : 
     139            3044 :         vstr_add_cstr_buf(mime->ent_data, mime->ent_data->len, ".");
     140            3044 :         spos = mime->ent_data->len;
     141            3044 :         slen = sext->len + 1;
     142                 :       }
     143                 :       else 
     144                 :       { /* chop the . off and use everything else */
     145             840 :         sext->len--; sext->pos++;
     146             840 :         spos = mime->ent_data->len + 1;
     147             840 :         slen = sext->len;
     148                 :       }
     149                 :       
     150            3884 :       vstr_add_vstr(mime->ent_data, mime->ent_data->len,
     151                 :                     data, sext->pos, sext->len, VSTR_TYPE_ADD_DEF);
     152                 : 
     153                 :       /* replace old versions ... so we can match forwards */
     154            3884 :       if ((old_sext = mime_types__srch(mime, mime->ent_data, spos, slen)))
     155             100 :         old_sext->len = 0;
     156                 : 
     157            3884 :       vstr_sects_add(mime->ents, spos, slen);
     158            3884 :       mime_type__type_add(mime, type);
     159            3884 :       sects->num--;
     160                 :     }
     161                 :   }
     162                 : 
     163             112 :   if (mime->ent_data->conf->malloc_bad || mime->ents->malloc_bad)
     164                 :     goto fail_end_malloc_check;
     165                 : 
     166             112 :   vstr_sects_free(sects);
     167             112 :   vstr_sects_free(lines);
     168             112 :   vstr_free_base(data);
     169                 : 
     170             112 :   return (TRUE);
     171                 :   
     172               0 :  fail_end_malloc_check:
     173               0 :   vstr_sc_reduce(mime->ent_data, 1, mime->ent_data->len,
     174                 :                  mime->ent_data->len - orig_ent_data_len);
     175               0 :   mime->ents->num = orig_ents_num;
     176               0 :  fail_split_line:
     177               0 :  fail_split_file:
     178               0 :   errno = ENOMEM;
     179               0 :  fail_read_file:
     180               0 :   saved_errno = errno;
     181               0 :   vstr_sects_free(lines);
     182               0 :  fail_sects_tmp:
     183               0 :   vstr_sects_free(sects);
     184               0 :  fail_sects_lines:
     185               0 :   vstr_free_base(data);
     186               0 :  fail_data:
     187               0 :   errno = saved_errno;
     188               0 :   return (FALSE);
     189                 : }
     190                 : 
     191                 : static void mime_types__filedata_free(Vstr_ref *ref)
     192             144 : {
     193                 :   
     194             144 :   Mime_types_data *mime = ref->ptr;
     195                 :   
     196             144 :   vstr_free_base(mime->ent_data); mime->ent_data = NULL;
     197             144 :   vstr_sects_free(mime->ents);    mime->ents     = NULL;
     198             144 :   F(mime->types);                 mime->types    = NULL;
     199                 :   
     200             144 :   (*mime->pref_func)(ref);
     201             144 : }
     202                 : 
     203                 : int mime_types_init(Mime_types *pmime,
     204                 :                     const Vstr_base *def_vs1, size_t def_pos, size_t def_len)
     205             138 : {
     206             138 :   Mime_types_data *mime = NULL;
     207                 :   
     208              69 :   ASSERT(pmime);
     209              69 :   ASSERT(def_vs1);
     210                 : 
     211             138 :   if (!(pmime->ref = vstr_ref_make_malloc(sizeof(Mime_types_data))))
     212               0 :     goto ref_malloc_fail;
     213             138 :   mime = pmime->ref->ptr;
     214                 : 
     215             138 :   if (!(mime->ent_data = vstr_make_base(NULL)))
     216               0 :     goto ent_data_malloc_fail;
     217                 :   
     218             138 :   if (!(mime->ents = vstr_sects_make(MIME_TYPES__INIT_SECT_SZ)))
     219               0 :     goto ents_malloc_fail;
     220                 : 
     221             138 :   if (!(mime->types = MK(MIME_TYPES__INIT_TYPE_SZ)))
     222               0 :     goto types_malloc_fail;
     223                 : 
     224             138 :   mime->type_sz  = MIME_TYPES__INIT_TYPE_SZ;
     225             138 :   mime->type_num = 0;
     226                 :   
     227                 :   /* make reference do the right thing... */
     228             138 :   mime->pref_func  = pmime->ref->func;
     229             138 :   pmime->ref->func = mime_types__filedata_free;
     230                 :   
     231             138 :   pmime->def_type_vs1 = def_vs1;
     232             138 :   pmime->def_type_pos = def_pos;
     233             138 :   pmime->def_type_len = def_len;
     234                 :   
     235             138 :   return (TRUE);
     236                 : 
     237               0 :  types_malloc_fail:
     238               0 :   vstr_sects_free(mime->ents);
     239               0 :  ents_malloc_fail:
     240               0 :   vstr_free_base(mime->ent_data);
     241               0 :  ent_data_malloc_fail:
     242               0 :   vstr_ref_del(pmime->ref);
     243               0 :  ref_malloc_fail:
     244               0 :   return (FALSE);
     245                 : }
     246                 : 
     247                 : int mime_types_match(const Mime_types *pmime,
     248                 :                      const Vstr_base *fname, size_t pos, size_t len,
     249                 :                      const Vstr_base **ret_vs1, size_t *ret_pos,size_t *ret_len)
     250           26305 : {
     251           26305 :   const Mime_types_data *mime = NULL;
     252           26305 :   unsigned int num = 0;
     253           26305 :   size_t pos_ext1 = 0;
     254           26305 :   size_t len_ext1 = 0;
     255           26305 :   size_t tmp = 0;
     256                 :   
     257           13160 :   ASSERT(pmime && pmime->ref && (pmime->ref->ref >= 1));
     258           13160 :   ASSERT(ret_vs1 && ret_pos && ret_len);
     259                 :   
     260           26305 :   mime = pmime->ref->ptr;
     261                 :   
     262           13160 :   MALLOC_CHECK_SZ_MEM(mime->types, mime->type_sz);
     263                 : 
     264                 :   /* find extension */
     265           26305 :   tmp = vstr_srch_chr_rev(fname, pos, len, '.');
     266           26305 :   if ((pos_ext1 = tmp))
     267           25208 :     len_ext1 = len - (pos_ext1 - pos);
     268                 :   
     269          786587 :   while (num++ < mime->ents->num)
     270                 :   {
     271          769489 :     size_t ctpos = VSTR_SECTS_NUM(mime->ents, num)->pos;
     272          769489 :     size_t ctlen = VSTR_SECTS_NUM(mime->ents, num)->len;
     273          769489 :     size_t epos  = 0;
     274          769489 :     size_t elen  = 0;
     275          769489 :     unsigned char type = mime->types[num / 2];
     276                 :     
     277          385352 :     ASSERT(mime->type_num <= mime->type_sz);
     278          385352 :     ASSERT(mime->type_num >  (num / 2));
     279          385352 :     ASSERT(num < mime->ents->num);
     280          769489 :     ++num;
     281          769489 :     epos  = VSTR_SECTS_NUM(mime->ents, num)->pos;
     282          769489 :     elen  = VSTR_SECTS_NUM(mime->ents, num)->len;
     283                 : 
     284          769489 :     if (!elen || (elen > len))
     285           15176 :       continue;
     286                 : 
     287          739167 :     switch (type)
     288                 :     {
     289                 :       case MIME_TYPES_TYPE_EXT1:
     290          616341 :         if (vstr_cmp_eq(fname, pos_ext1, len_ext1, mime->ent_data, epos, elen))
     291                 :         {
     292           21872 :           *ret_vs1 = mime->ent_data;
     293           21872 :           *ret_pos = ctpos;
     294           21872 :           *ret_len = ctlen;
     295           21872 :           return (TRUE);
     296                 :         }
     297          297632 :         ASSERT(!vstr_cmp_eod_eq(fname, pos, len, mime->ent_data, epos, elen));
     298          296837 :         break;
     299                 :         
     300                 :       case MIME_TYPES_TYPE_EXT2:
     301                 :       case MIME_TYPES_TYPE_EXT3:
     302                 :       case MIME_TYPES_TYPE_END:
     303          122826 :         if (vstr_cmp_eod_eq(fname, pos, len, mime->ent_data, epos, elen))
     304                 :         {
     305             480 :           *ret_vs1 = mime->ent_data;
     306             480 :           *ret_pos = ctpos;
     307             480 :           *ret_len = ctlen;
     308             480 :           return (TRUE);
     309                 :         }
     310                 : 
     311               0 :         ASSERT_NO_SWITCH_DEF();
     312                 :     }
     313                 :   }
     314                 : 
     315            3953 :   *ret_vs1 = pmime->def_type_vs1;
     316            3953 :   *ret_pos = pmime->def_type_pos;
     317            3953 :   *ret_len = pmime->def_type_len;
     318            3953 :   return (FALSE);
     319                 : }
     320                 : 
     321                 : void mime_types_exit(Mime_types *pmime)
     322             144 : {
     323              72 :   ASSERT(pmime && pmime->ref);
     324             144 :   vstr_ref_del(pmime->ref);       pmime->ref = NULL;
     325             144 : }
     326                 : 
     327                 : void mime_types_combine_filedata(Mime_types *pdst, Mime_types *psrc)
     328              68 : {
     329              68 :   Vstr_ref *tmp = NULL;
     330                 :   
     331              34 :   ASSERT(psrc && psrc->ref && (psrc->ref->ref >= 1));
     332              34 :   ASSERT(pdst && pdst->ref && (pdst->ref->ref == 1));
     333                 : 
     334              68 :   tmp = pdst->ref;
     335              68 :   pdst->ref = vstr_ref_add(psrc->ref);
     336              68 :   vstr_ref_del(tmp);
     337              68 : }

Generated by: LTP GCOV extension version 1.4