LTP GCOV extension - code coverage report
Current view: directory - src/base - pdf-stm-f-ahex.c
Test: libgnupdf.info
Date: 2010-07-31 Instrumented lines: 113
Code covered: 85.0 % Executed lines: 96

       1                 : /* -*- mode: C -*-
       2                 :  *
       3                 :  *       File:         pdf-stm-f-ahex.c
       4                 :  *       Date:         Fri Jul 13 17:08:41 2007
       5                 :  *
       6                 :  *       GNU PDF Library - ASCII Hex decoder filter
       7                 :  *
       8                 :  */
       9                 : 
      10                 : /* Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc. */
      11                 : 
      12                 : /* This program is free software: you can redistribute it and/or modify
      13                 :  * it under the terms of the GNU General Public License as published by
      14                 :  * the Free Software Foundation, either version 3 of the License, or
      15                 :  * (at your option) any later version.
      16                 :  *
      17                 :  * This program is distributed in the hope that it will be useful,
      18                 :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      19                 :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      20                 :  * GNU General Public License for more details.
      21                 :  *
      22                 :  * You should have received a copy of the GNU General Public License
      23                 :  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
      24                 :  */
      25                 : 
      26                 : #include <config.h>
      27                 : 
      28                 : #include <pdf-stm-f-ahex.h>
      29                 : 
      30                 : static pdf_u32_t pdf_stm_f_ahex_white_p (pdf_u32_t hex);
      31                 : static pdf_u32_t pdf_stm_f_ahex_hex_p (pdf_u32_t hex);
      32                 : static pdf_u32_t pdf_stm_f_ahex_hex2int (pdf_u32_t hex);
      33                 : static pdf_char_t pdf_stm_f_ahex_int2hex (pdf_u32_t n);
      34                 : 
      35                 : pdf_status_t
      36                 : pdf_stm_f_ahexenc_init (pdf_hash_t params,
      37                 :                         void **state)
      38               2 : {
      39                 :   pdf_stm_f_ahexenc_t filter_state;
      40                 : 
      41                 :   /* This filter uses no parameters */
      42                 :   /* Allocate the internal state structure */
      43               2 :   filter_state = pdf_alloc (sizeof (struct pdf_stm_f_ahexenc_s));
      44               2 :   if (filter_state == NULL)
      45                 :     {
      46               0 :       return PDF_ERROR;
      47                 :     }
      48                 :   
      49                 :   /* Initialize fields */
      50               2 :   filter_state->last_nibble = -1;
      51               2 :   filter_state->written_bytes = 0;
      52                 : 
      53               2 :   *state = (void *) filter_state;
      54                 : 
      55               2 :   return PDF_OK;
      56                 : }
      57                 : 
      58                 : #define PDF_STM_F_AHEX_LINE_WIDTH 60
      59                 : 
      60                 : pdf_status_t
      61                 : pdf_stm_f_ahexenc_apply (pdf_hash_t params,
      62                 :                          void *state,
      63                 :                          pdf_buffer_t in,
      64                 :                          pdf_buffer_t out,
      65                 :                          pdf_bool_t finish_p)
      66               6 : {
      67                 :   pdf_stm_f_ahexenc_t filter_state;
      68                 :   pdf_char_t first_nibble;
      69                 :   pdf_char_t second_nibble;
      70                 :   pdf_char_t in_char;
      71                 :   pdf_status_t ret;
      72                 : 
      73               6 :   if (finish_p)
      74                 :     {
      75                 :       /* Assume that there is room in the output buffer to hold the
      76                 :          EOD marker */
      77               2 :       out->data[out->wp++] = '>';
      78               2 :       return PDF_EEOF;
      79                 :     }
      80                 : 
      81               4 :   filter_state = (pdf_stm_f_ahexenc_t) state;
      82                 :   
      83               4 :   ret = PDF_OK;
      84              57 :   while (!pdf_buffer_full_p (out))
      85                 :     {
      86              53 :       if ((filter_state->written_bytes != 0) &&
      87                 :           (filter_state->written_bytes % PDF_STM_F_AHEX_LINE_WIDTH) == 0)
      88                 :         {
      89                 :           /* Write down a newline character */
      90               1 :           out->data[out->wp] = '\n';
      91               1 :           out->wp++;
      92               1 :           filter_state->written_bytes = 0;
      93               1 :           continue;
      94                 :         }
      95                 : 
      96                 :       /* Write down any pending nibble, if needed, without consuming
      97                 :          any input byte */
      98              52 :       if (filter_state->last_nibble != -1) 
      99                 :         {
     100               0 :           out->data[out->wp] = filter_state->last_nibble;
     101               0 :           out->wp++;
     102               0 :           filter_state->written_bytes++;
     103               0 :           filter_state->last_nibble = -1;
     104               0 :           continue;
     105                 :         }
     106                 : 
     107                 :       /* Try to consume an input byte */
     108              52 :       if (!pdf_buffer_eob_p (in))
     109                 :         {
     110                 :           /* For each byte in the input we should generate two bytes in the
     111                 :              output. */
     112              48 :           in_char = in->data[in->rp];
     113                 :           
     114                 :           /* Determine the hex digits to write for this input character */
     115              48 :           if (filter_state->last_nibble != -1)
     116                 :             {
     117               0 :               first_nibble = (pdf_char_t) filter_state->last_nibble;
     118               0 :               second_nibble = pdf_stm_f_ahex_int2hex (in_char >> 4);
     119                 :             }
     120                 :           else
     121                 :             {
     122              96 :               first_nibble = pdf_stm_f_ahex_int2hex (in_char >> 4);
     123              96 :               second_nibble = pdf_stm_f_ahex_int2hex (in_char);
     124                 :             }
     125              48 :           in->rp++;
     126                 : 
     127                 :           /* Write the hex digits into the output buffer, if
     128                 :              possible */
     129                 :           
     130                 :           /* First nibble */
     131              48 :           out->data[out->wp] = first_nibble;
     132              48 :           out->wp++;
     133              48 :           filter_state->written_bytes++;
     134                 :           
     135                 :           /* Maybe write the second nibble */
     136              48 :           if (pdf_buffer_full_p (out))
     137                 :             {
     138               0 :               filter_state->last_nibble = second_nibble;
     139                 :             }
     140                 :           else
     141                 :             {
     142              48 :               out->data[out->wp] = second_nibble;
     143              48 :               out->wp++;
     144              48 :               filter_state->written_bytes++;
     145                 :             }
     146                 :         }
     147                 :       else
     148                 :         {
     149                 :           /* We need more input */
     150               4 :           break;
     151                 :         }
     152                 :     }
     153                 : 
     154               4 :   if (pdf_buffer_full_p (out))
     155                 :     {
     156               0 :       ret = PDF_ENOUTPUT;
     157                 :     }
     158                 :   else
     159                 :     {
     160               4 :       ret = PDF_ENINPUT;
     161                 :     }
     162                 : 
     163               4 :   return ret;
     164                 : }
     165                 : 
     166                 : pdf_status_t
     167                 : pdf_stm_f_ahexenc_dealloc_state (void *state)
     168               2 : {
     169                 :   pdf_stm_f_ahexenc_t ahexenc_state;
     170                 : 
     171               2 :   ahexenc_state = (pdf_stm_f_ahexenc_t) state;
     172               2 :   pdf_dealloc (ahexenc_state);
     173                 : 
     174               2 :   return PDF_OK;
     175                 : }
     176                 : 
     177                 : pdf_status_t
     178                 : pdf_stm_f_ahexdec_init (pdf_hash_t params,
     179                 :                         void **state)
     180               3 : {
     181                 :   pdf_stm_f_ahexdec_t ahexdec_state;
     182                 :   pdf_status_t ret;
     183                 : 
     184                 :   /* This filter uses no parameters */
     185                 :   /* Allocate the internal state structure */
     186               3 :   ahexdec_state = pdf_alloc (sizeof(struct pdf_stm_f_ahexdec_s));
     187               3 :   if (ahexdec_state != NULL)
     188                 :     {
     189               3 :       ahexdec_state->last_nibble = -1;
     190               3 :       ahexdec_state->written_bytes = 0;
     191                 : 
     192               3 :       *state = ahexdec_state;
     193               3 :       ret = PDF_OK;
     194                 :     }
     195                 :   else
     196                 :     {
     197               0 :       ret = PDF_ERROR;
     198                 :     }
     199                 : 
     200               3 :   return ret;
     201                 : }
     202                 : 
     203                 : pdf_status_t
     204                 : pdf_stm_f_ahexdec_apply (pdf_hash_t params,
     205                 :                          void *state,
     206                 :                          pdf_buffer_t in,
     207                 :                          pdf_buffer_t out,
     208                 :                          pdf_bool_t finish_p)
     209               6 : {
     210                 :   pdf_status_t ret;
     211                 :   pdf_stm_f_ahexdec_t filter_state;
     212                 :   pdf_u32_t first_nibble;
     213                 :   pdf_u32_t second_nibble;
     214                 : 
     215               6 :   ret = PDF_OK;
     216               6 :   first_nibble = -1;
     217               6 :   second_nibble = -1;
     218               6 :   filter_state = (pdf_stm_f_ahexdec_t) state;
     219                 : 
     220              33 :   while (!pdf_buffer_full_p (out))
     221                 :     {
     222              27 :       if (pdf_buffer_eob_p (in))
     223                 :         {
     224                 :           /* Need more input */
     225               3 :           break;
     226                 :         }
     227                 :       else
     228                 :         {
     229                 :           /* Skip white characters */
     230              48 :           if (pdf_stm_f_ahex_white_p ((pdf_u32_t) in->data[in->rp]))
     231                 :             {
     232               4 :               in->rp++;
     233               4 :               continue;
     234                 :             }
     235                 : 
     236                 :           /* Detect the end of the hex data */
     237              20 :           if (in->data[in->rp] == '>')
     238                 :             {
     239               3 :               if (filter_state->last_nibble == -1)
     240                 :                 {
     241                 :                   /* We are done :'D */
     242               2 :                   in->rp++;
     243               2 :                   ret = PDF_EEOF;
     244               2 :                   break;
     245                 :                 }
     246                 :               else
     247                 :                 {
     248                 :                   /* Found an even number of hex digits. We assume that
     249                 :                      the second nibble is 0, so generate a byte of data
     250                 :                      and finish */
     251               2 :                   out->data[out->wp] =
     252                 :                     pdf_stm_f_ahex_hex2int (filter_state->last_nibble) << 4;
     253               1 :                   out->wp++;
     254               1 :                   filter_state->last_nibble = -1;
     255               1 :                   ret = PDF_EEOF;
     256               1 :                   break;
     257                 :                 }
     258                 :             }
     259                 :           
     260                 :           /* Detect an invalid character */
     261              34 :           if (!pdf_stm_f_ahex_hex_p ((pdf_u32_t) in->data[in->rp]))
     262                 :             {
     263               0 :               ret = PDF_ERROR;
     264               0 :               break;
     265                 :             }
     266                 :           
     267                 :           /* Process this character. This is the first or the second part
     268                 :              of a mibble. */
     269              17 :           if (filter_state->last_nibble == -1)
     270                 :             {
     271                 :               /* Get the first nibble */
     272               9 :               first_nibble = (pdf_u32_t) in->data[in->rp];
     273               9 :               in->rp++;
     274                 : 
     275               9 :               filter_state->last_nibble = first_nibble;
     276                 :             }
     277                 :           else
     278                 :             {
     279                 :               /* Get the second nibble */
     280               8 :               second_nibble = (pdf_u32_t) in->data[in->rp];
     281               8 :               in->rp++;
     282                 : 
     283                 :               /* Generate one byte of data */
     284               8 :               first_nibble = filter_state->last_nibble;
     285              24 :               out->data[out->wp] = (pdf_stm_f_ahex_hex2int (first_nibble) << 4)
     286                 :                 + pdf_stm_f_ahex_hex2int (second_nibble);
     287               8 :               out->wp++;
     288                 : 
     289               8 :               filter_state->last_nibble = -1;
     290                 :             }
     291                 :         }
     292                 :     }
     293                 :   
     294               6 :   if (ret == PDF_OK)
     295                 :     {
     296               3 :       if (pdf_buffer_eob_p (in))
     297                 :         {
     298               3 :           ret = PDF_ENINPUT;
     299                 :         }
     300                 :       else
     301                 :         {
     302               0 :           ret = PDF_ENOUTPUT;
     303                 :         }
     304                 :     }
     305                 : 
     306               6 :   return ret;
     307                 : }
     308                 : 
     309                 : pdf_status_t
     310                 : pdf_stm_f_ahexdec_dealloc_state (void *state)
     311               3 : {
     312                 :   pdf_stm_f_ahexenc_t ahexenc_state;
     313                 : 
     314               3 :   ahexenc_state = (pdf_stm_f_ahexenc_t) state;
     315               3 :   pdf_dealloc (ahexenc_state);
     316                 : 
     317               3 :   return PDF_OK;
     318                 : }
     319                 : 
     320                 : /* Private functions */
     321                 : 
     322                 : static pdf_u32_t
     323                 : pdf_stm_f_ahex_white_p (pdf_u32_t hex)
     324                 : {
     325              24 :   return ((hex == '\0')    /* Null */
     326                 :           || (hex == '\t') /* Tab */
     327                 :           || (hex == '\n') /* Line feed */
     328                 :           || (hex == '\f') /* Form feed */
     329                 :           || (hex == '\r') /* Carriage return */
     330                 :           || (hex == 32)); /* Space character */
     331                 : }
     332                 : 
     333                 : static pdf_u32_t
     334                 : pdf_stm_f_ahex_hex_p (pdf_u32_t hex)
     335                 : {
     336              17 :   return (((hex >= 'a') && (hex <= 'f')) ||
     337                 :           ((hex >= 'A') && (hex <= 'F')) ||
     338                 :           ((hex >= '0') && (hex <= '9')));
     339                 : }
     340                 : 
     341                 : static const pdf_char_t to_hex[16] = "0123456789ABCDEF";
     342                 : 
     343                 : static pdf_char_t
     344                 : pdf_stm_f_ahex_int2hex (pdf_u32_t hex)
     345                 : {
     346              96 :   return to_hex[hex & 0x0f];
     347                 : }
     348                 : 
     349                 : static pdf_u32_t
     350                 : pdf_stm_f_ahex_hex2int (pdf_u32_t hex)
     351                 : {
     352              17 :   if ((hex >= 'a') && (hex <= 'f'))
     353                 :     {
     354               0 :       return (hex - 'a') + 0xA;
     355                 :     }
     356              17 :   if ((hex >= 'A') && (hex <= 'F'))
     357                 :     {
     358               0 :       return (hex - 'A') + 0xA;
     359                 :     }
     360              17 :   if ((hex >= '0') && (hex <= '9'))
     361                 :     {
     362              17 :       return (hex - '0');
     363                 :     }
     364                 : 
     365               0 :   return -1;
     366                 : }
     367                 : 
     368                 : /* End of pdf_stm_f_ahex.c */

Generated by: LTP GCOV extension version 1.6