LTP GCOV extension - code coverage report
Current view: directory - src/base - pdf-token.c
Test: libgnupdf.info
Date: 2010-07-31 Instrumented lines: 121
Code covered: 66.1 % Executed lines: 80

       1                 : /* -*- mode: C -*-
       2                 :  *
       3                 :  *       File:         pdf-token.c
       4                 :  *       Date:         Sat Jul  7 03:04:30 2007
       5                 :  *
       6                 :  *       GNU PDF Library - PDF token objects
       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 <string.h>
      29                 : #include <assert.h>
      30                 : #include <math.h>
      31                 : 
      32                 : #include <pdf-token.h>
      33                 : #include <pdf-alloc.h>
      34                 : 
      35                 : /* Private functions */
      36                 : 
      37                 : static INLINE pdf_status_t
      38                 : pdf_token_new (enum pdf_token_type_e type, pdf_token_t *token)
      39            1988 : {
      40                 :   pdf_token_t new;
      41            1988 :   assert (token);
      42                 : 
      43            1988 :   new = (pdf_token_t) pdf_alloc (sizeof (struct pdf_token_s));
      44            1988 :   if (!new)
      45               0 :     return PDF_ENOMEM;
      46                 : 
      47            1988 :   new->type = type;
      48            1988 :   *token = new;
      49            1988 :   return PDF_OK;
      50                 : }
      51                 : 
      52                 : pdf_status_t
      53                 : pdf_token_destroy (pdf_token_t token)
      54            1988 : {
      55            1988 :   assert (token);
      56            1988 :   switch (token->type)
      57                 :     {
      58                 :     case PDF_TOKEN_STRING:   /* fall through */
      59                 :     case PDF_TOKEN_NAME:     /* fall through */
      60                 :     case PDF_TOKEN_KEYWORD:  /* fall through */
      61                 :     case PDF_TOKEN_COMMENT:
      62                 :       {
      63            1358 :         pdf_dealloc (token->value.buffer.data);
      64                 :         break;
      65                 :       }
      66                 :     default:
      67                 :       {
      68                 :         /* NOP */
      69                 :         break;
      70                 :       }
      71                 :     }
      72                 : 
      73            1988 :   pdf_dealloc (token);
      74            1988 :   return PDF_OK;
      75                 : }
      76                 : 
      77                 : static pdf_status_t
      78                 : pdf_token_buffer_new (enum pdf_token_type_e type,
      79                 :                       const pdf_char_t *value,
      80                 :                       pdf_size_t size,
      81                 :                       pdf_bool_t nullterm,
      82                 :                       pdf_token_t *token)
      83            1358 : {
      84            1358 :   pdf_token_t new_obj = NULL;
      85            1358 :   pdf_status_t rv = pdf_token_new (type, &new_obj);
      86            1358 :   if (rv != PDF_OK)
      87               0 :     goto fail;
      88                 : 
      89            1358 :   rv = PDF_ENOMEM;
      90            1358 :   new_obj->value.buffer.data = pdf_alloc (size + 1);
      91            1358 :   if (!new_obj->value.buffer.data)
      92               0 :     goto fail;
      93                 : 
      94            1358 :   new_obj->value.buffer.size = size;
      95            1358 :   memcpy (new_obj->value.buffer.data, value, size);
      96                 : 
      97                 :   /* If the value isn't null terminated, append a non-null character
      98                 :    * to catch bugs. */
      99            1358 :   new_obj->value.buffer.data[size] = nullterm ? 0 : 'X';
     100                 : 
     101            1358 :   *token = new_obj;
     102            1358 :   return PDF_OK;
     103                 : 
     104               0 : fail:
     105               0 :   if (new_obj)
     106               0 :     pdf_dealloc (new_obj);
     107               0 :   return rv;
     108                 : }
     109                 : 
     110                 : 
     111                 : /* General functions */
     112                 : 
     113                 : enum pdf_token_type_e
     114                 : pdf_token_get_type (const pdf_token_t token)
     115            1246 : {
     116            1246 :   assert (token);
     117            1246 :   return token->type;
     118                 : }
     119                 : 
     120                 : pdf_bool_t
     121                 : pdf_token_equal_p (const pdf_token_t token1, const pdf_token_t token2)
     122             364 : {
     123             364 :   assert (token1 && token2);
     124             364 :   if (token1->type != token2->type)
     125               0 :     return PDF_FALSE;
     126                 : 
     127             364 :   switch (token1->type)
     128                 :     {
     129                 :     case PDF_TOKEN_DICT_START:   /* fall through */
     130                 :     case PDF_TOKEN_DICT_END:     /* fall through */
     131                 :     case PDF_TOKEN_ARRAY_START:  /* fall through */
     132                 :     case PDF_TOKEN_ARRAY_END:    /* fall through */
     133                 :     case PDF_TOKEN_PROC_START:   /* fall through */
     134                 :     case PDF_TOKEN_PROC_END:
     135               6 :       return PDF_TRUE;
     136                 : 
     137                 :     case PDF_TOKEN_INTEGER:
     138               3 :       return token1->value.integer == token2->value.integer;
     139                 : 
     140                 :     case PDF_TOKEN_REAL:
     141               2 :       return token1->value.real == token2->value.real;
     142                 : 
     143                 :     case PDF_TOKEN_COMMENT:  /* fall through */
     144                 :     case PDF_TOKEN_STRING:   /* fall through */
     145                 :     case PDF_TOKEN_NAME:     /* fall through */
     146                 :     case PDF_TOKEN_KEYWORD:
     147                 :       {
     148             353 :         struct pdf_token_buffer_s *buf1 = &token1->value.buffer;
     149             353 :         struct pdf_token_buffer_s *buf2 = &token2->value.buffer;
     150             353 :         return (buf1->size == buf2->size
     151                 :                  && ( buf1->data == buf2->data
     152                 :                       || !memcmp (buf1->data, buf2->data, buf1->size) ));
     153                 :       }
     154                 : 
     155                 :     default:
     156               0 :       assert (0);  /* shouldn't happen */
     157                 :       return 0;
     158                 :     }
     159                 : }
     160                 : 
     161                 : pdf_status_t
     162                 : pdf_token_dup (const pdf_token_t token, pdf_token_t *new)
     163               0 : {
     164               0 :   assert (token);
     165               0 :   switch (token->type)
     166                 :     {
     167                 :     case PDF_TOKEN_DICT_START:   /* fall through */
     168                 :     case PDF_TOKEN_DICT_END:     /* fall through */
     169                 :     case PDF_TOKEN_ARRAY_START:  /* fall through */
     170                 :     case PDF_TOKEN_ARRAY_END:    /* fall through */
     171                 :     case PDF_TOKEN_PROC_START:   /* fall through */
     172                 :     case PDF_TOKEN_PROC_END:
     173               0 :       return pdf_token_valueless_new (token->type, new);
     174                 : 
     175                 :     case PDF_TOKEN_INTEGER:
     176               0 :       return pdf_token_integer_new (token->value.integer, new);
     177                 : 
     178                 :     case PDF_TOKEN_REAL:
     179               0 :       return pdf_token_real_new (token->value.real, new);
     180                 : 
     181                 :     case PDF_TOKEN_STRING:
     182               0 :       return pdf_token_string_new (token->value.buffer.data,
     183                 :                                    token->value.buffer.size,
     184                 :                                    new);
     185                 :     case PDF_TOKEN_NAME:
     186               0 :       return pdf_token_name_new (token->value.buffer.data,
     187                 :                                  token->value.buffer.size,
     188                 :                                  new);
     189                 :     case PDF_TOKEN_KEYWORD:
     190               0 :       return pdf_token_keyword_new (token->value.buffer.data,
     191                 :                                     token->value.buffer.size,
     192                 :                                     new);
     193                 :     case PDF_TOKEN_COMMENT:
     194               0 :       return pdf_token_comment_new (token->value.buffer.data,
     195                 :                                     token->value.buffer.size,
     196                 :                                     new);
     197                 :     default:
     198                 :       /* Should not be reached: make the compiler happy */
     199               0 :       return PDF_EBADDATA;
     200                 :     }
     201                 : }
     202                 : 
     203                 : pdf_status_t
     204                 : pdf_token_valueless_new (enum pdf_token_type_e type,
     205                 :                          pdf_token_t *token)
     206             439 : {
     207             439 :   switch (type)
     208                 :   {
     209                 :     case PDF_TOKEN_DICT_START:   /* fall through */
     210                 :     case PDF_TOKEN_DICT_END:     /* fall through */
     211                 :     case PDF_TOKEN_ARRAY_START:  /* fall through */
     212                 :     case PDF_TOKEN_ARRAY_END:    /* fall through */
     213                 :     case PDF_TOKEN_PROC_START:   /* fall through */
     214                 :     case PDF_TOKEN_PROC_END:
     215             439 :       return pdf_token_new (type, token);
     216                 :     default:
     217               0 :       return PDF_EBADDATA;
     218                 :   }
     219                 : }
     220                 : 
     221                 : 
     222                 : /** integers *****/
     223                 : 
     224                 : pdf_status_t
     225                 : pdf_token_integer_new (pdf_i32_t value, pdf_token_t *token)
     226             176 : {
     227             176 :   pdf_status_t rv = pdf_token_new (PDF_TOKEN_INTEGER, token);
     228             176 :   if (rv == PDF_OK)
     229             176 :     (*token)->value.integer = value;
     230                 : 
     231             176 :   return rv;
     232                 : }
     233                 : 
     234                 : pdf_i32_t
     235                 : pdf_token_get_integer_value (const pdf_token_t token)
     236             170 : {
     237             170 :   assert (token && token->type == PDF_TOKEN_INTEGER);
     238             170 :   return token->value.integer;
     239                 : }
     240                 : 
     241                 : 
     242                 : /** reals *****/
     243                 : 
     244                 : pdf_status_t
     245                 : pdf_token_real_new (pdf_real_t value, pdf_token_t *token)
     246              15 : {
     247                 :   pdf_status_t rv;
     248                 : 
     249              15 :   if (isnan(value) || isinf(value))
     250               0 :     return PDF_EBADDATA;
     251                 : 
     252              15 :   rv = pdf_token_new (PDF_TOKEN_REAL, token);
     253              15 :   if (rv == PDF_OK)
     254              15 :     (*token)->value.real = value;
     255                 : 
     256              15 :   return rv;
     257                 : }
     258                 : 
     259                 : pdf_real_t
     260                 : pdf_token_get_real_value (const pdf_token_t token)
     261              11 : {
     262              11 :   assert (token && token->type == PDF_TOKEN_REAL);
     263              11 :   return token->value.real;
     264                 : }
     265                 : 
     266                 : 
     267                 : /** names *****/
     268                 : 
     269                 : pdf_status_t
     270                 : pdf_token_name_new (const pdf_char_t *value,
     271                 :                     pdf_size_t size,
     272                 :                     pdf_token_t *token)
     273             698 : {
     274                 :   pdf_size_t i;
     275            1422 :   for (i = 0; i < size; ++i)
     276                 :     {
     277             724 :       if (value[i] == 0)  /* names can't include null bytes */
     278               0 :         return PDF_EBADDATA;
     279                 :     }
     280                 : 
     281             698 :   return pdf_token_buffer_new (PDF_TOKEN_NAME, value, size, 1, token);
     282                 : }
     283                 : 
     284                 : pdf_size_t
     285                 : pdf_token_get_name_size (const pdf_token_t name)
     286               0 : {
     287               0 :   assert (name && name->type == PDF_TOKEN_NAME);
     288               0 :   return name->value.buffer.size;
     289                 : }
     290                 : 
     291                 : const pdf_char_t *
     292                 : pdf_token_get_name_data (const pdf_token_t name)
     293              14 : {
     294              14 :   assert (name && name->type == PDF_TOKEN_NAME);
     295              14 :   return name->value.buffer.data;
     296                 : }
     297                 : 
     298                 : 
     299                 : /** strings *****/
     300                 : 
     301                 : pdf_status_t
     302                 : pdf_token_string_new (const pdf_char_t *value,
     303                 :                     pdf_size_t size,
     304                 :                     pdf_token_t *token)
     305              19 : {
     306              19 :   return pdf_token_buffer_new (PDF_TOKEN_STRING, value, size, 0, token);
     307                 : }
     308                 : 
     309                 : pdf_size_t
     310                 : pdf_token_get_string_size (const pdf_token_t token)
     311               1 : {
     312               1 :   assert (token && token->type == PDF_TOKEN_STRING);
     313               1 :   return token->value.buffer.size;
     314                 : }
     315                 : 
     316                 : const pdf_char_t *
     317                 : pdf_token_get_string_data (const pdf_token_t token)
     318               0 : {
     319               0 :   assert (token && token->type == PDF_TOKEN_STRING);
     320               0 :   return token->value.buffer.data;
     321                 : }
     322                 : 
     323                 : 
     324                 : /** comments *****/
     325                 : 
     326                 : pdf_status_t
     327                 : pdf_token_comment_new (const pdf_char_t *value,
     328                 :                        pdf_size_t size,
     329                 :                        pdf_token_t *token)
     330               0 : {
     331                 :   pdf_size_t i;
     332               0 :   for (i = 0; i < size; ++i)
     333                 :     {
     334                 :       /* comments can't span multiple lines */
     335               0 :       if (pdf_is_eol_char(value[i]))
     336               0 :         return PDF_EBADDATA;
     337                 :     }
     338                 : 
     339               0 :   return pdf_token_buffer_new (PDF_TOKEN_COMMENT, value, size, 0, token);
     340                 : }
     341                 : 
     342                 : pdf_size_t
     343                 : pdf_token_get_comment_size (const pdf_token_t comment)
     344               0 : {
     345               0 :   assert (comment && comment->type == PDF_TOKEN_COMMENT);
     346               0 :   return comment->value.buffer.size;
     347                 : }
     348                 : 
     349                 : const pdf_char_t *
     350                 : pdf_token_get_comment_data (const pdf_token_t comment)
     351               0 : {
     352               0 :   assert (comment && comment->type == PDF_TOKEN_COMMENT);
     353               0 :   return comment->value.buffer.data;
     354                 : }
     355                 : 
     356                 : 
     357                 : /** keywords *****/
     358                 : 
     359                 : pdf_status_t
     360                 : pdf_token_keyword_new (const pdf_char_t *value,
     361                 :                        pdf_size_t size,
     362                 :                        pdf_token_t *token)
     363             641 : {
     364                 :   pdf_size_t i;
     365            2856 :   for (i = 0; i < size; ++i)
     366                 :     {
     367                 :       /* keywords can only include regular characters */
     368            4430 :       if (!pdf_is_regular_char(value[i]))
     369               0 :         return PDF_EBADDATA;
     370                 :     }
     371                 : 
     372             641 :   return pdf_token_buffer_new (PDF_TOKEN_KEYWORD, value, size, 1, token);
     373                 : }
     374                 : 
     375                 : pdf_size_t
     376                 : pdf_token_get_keyword_size (const pdf_token_t keyword)
     377             637 : {
     378             637 :   assert (keyword && keyword->type == PDF_TOKEN_KEYWORD);
     379             637 :   return keyword->value.buffer.size;
     380                 : }
     381                 : 
     382                 : const pdf_char_t *
     383                 : pdf_token_get_keyword_data (const pdf_token_t keyword)
     384             637 : {
     385             637 :   assert (keyword && keyword->type == PDF_TOKEN_KEYWORD);
     386             637 :   return keyword->value.buffer.data;
     387                 : }
     388                 : 
     389                 : 
     390                 : /* End of pdf-token.c */

Generated by: LTP GCOV extension version 1.6