LTP GCOV extension - code coverage report
Current view: directory - src/base - pdf-stm-be.c
Test: libgnupdf.info
Date: 2010-07-31 Instrumented lines: 130
Code covered: 66.9 % Executed lines: 87

       1                 : /* -*- mode: C -*-
       2                 :  *
       3                 :  *       File:         pdf-stm-be.c
       4                 :  *       Date:         Wed Jun 18 21:15:16 2008
       5                 :  *
       6                 :  *       GNU PDF Library - Stream backend
       7                 :  *
       8                 :  */
       9                 : 
      10                 : #include <config.h>
      11                 : 
      12                 : #include <string.h>
      13                 : 
      14                 : #include <pdf-stm-be.h>
      15                 : 
      16                 : /* Forward declarations */
      17                 : 
      18                 : static pdf_size_t pdf_stm_be_mem_read (pdf_stm_be_t be,
      19                 :                                        pdf_char_t *buffer,
      20                 :                                        pdf_size_t bytes);
      21                 : static pdf_size_t pdf_stm_be_mem_write (pdf_stm_be_t be,
      22                 :                                         pdf_char_t *buffer,
      23                 :                                         pdf_size_t bytes);
      24                 : static pdf_off_t pdf_stm_be_mem_seek (pdf_stm_be_t be,
      25                 :                                       pdf_off_t pos);
      26                 : static pdf_off_t pdf_stm_be_mem_tell (pdf_stm_be_t be);
      27                 : static pdf_size_t pdf_stm_be_file_read (pdf_stm_be_t be,
      28                 :                                         pdf_char_t *buffer,
      29                 :                                         pdf_size_t bytes);
      30                 : static pdf_size_t pdf_stm_be_file_write (pdf_stm_be_t be,
      31                 :                                          pdf_char_t *buffer,
      32                 :                                          pdf_size_t bytes);
      33                 : static pdf_off_t pdf_stm_be_file_seek (pdf_stm_be_t be,
      34                 :                                        pdf_off_t pos);
      35                 : static pdf_off_t pdf_stm_be_file_tell (pdf_stm_be_t be);
      36                 : static pdf_size_t pdf_stm_be_cfile_read (pdf_stm_be_t be,
      37                 :                                         pdf_char_t *buffer,
      38                 :                                         pdf_size_t bytes);
      39                 : static pdf_size_t pdf_stm_be_cfile_write (pdf_stm_be_t be,
      40                 :                                          pdf_char_t *buffer,
      41                 :                                          pdf_size_t bytes);
      42                 : static pdf_off_t pdf_stm_be_cfile_seek (pdf_stm_be_t be,
      43                 :                                        pdf_off_t pos);
      44                 : static pdf_off_t pdf_stm_be_cfile_tell (pdf_stm_be_t be);
      45                 : 
      46                 : /*
      47                 :  * Public functions
      48                 :  */
      49                 : 
      50                 : pdf_stm_be_t
      51                 : pdf_stm_be_new_cfile (FILE* file,
      52                 :                       pdf_off_t pos)
      53               0 : {
      54                 :   pdf_stm_be_t new;
      55                 : 
      56                 :   /* Allocate a new structure */
      57               0 :   new = (pdf_stm_be_t) pdf_alloc (sizeof(struct pdf_stm_be_s));
      58                 : 
      59                 :   /* Initialization */
      60               0 :   new->type = PDF_STM_BE_CFILE;
      61               0 :   new->data.cfile.file = file;
      62               0 :   new->data.cfile.pos = pos;
      63                 : 
      64               0 :   if (pos)
      65                 :     {
      66               0 :       pdf_stm_be_cfile_seek (new, pos);
      67                 :     }
      68                 : 
      69               0 :   return new;
      70                 : }
      71                 : 
      72                 : pdf_stm_be_t
      73                 : pdf_stm_be_new_file (pdf_fsys_file_t file,
      74                 :                      pdf_off_t pos)
      75              10 : {
      76                 :   pdf_stm_be_t new;
      77                 : 
      78                 :   /* Allocate a new structure */
      79              10 :   new = (pdf_stm_be_t) pdf_alloc(sizeof(struct pdf_stm_be_s));
      80                 : 
      81                 :   /* Initialization */
      82              10 :   new->type = PDF_STM_BE_FILE;
      83              10 :   new->data.file.file = file;
      84              10 :   new->data.file.pos = pos;
      85                 : 
      86              10 :   return new;
      87                 : }
      88                 : 
      89                 : pdf_stm_be_t
      90                 : pdf_stm_be_new_mem (pdf_char_t *buffer,
      91                 :                     pdf_size_t size,
      92                 :                     pdf_size_t pos)
      93             792 : {
      94                 :   pdf_stm_be_t new;
      95                 : 
      96                 :   /* Allocate a new structure */
      97             792 :   new = (pdf_stm_be_t) pdf_alloc(sizeof(struct pdf_stm_be_s));
      98                 :   
      99                 :   /* Initialization */
     100             792 :   new->type = PDF_STM_BE_MEM;
     101             792 :   new->data.mem.buffer = buffer;
     102             792 :   new->data.mem.size = size;
     103             792 :   new->data.mem.pos = pos;
     104                 : 
     105             792 :   return new;
     106                 : }
     107                 : 
     108                 : pdf_status_t
     109                 : pdf_stm_be_destroy (pdf_stm_be_t be)
     110             617 : {
     111             617 :   pdf_dealloc (be);
     112                 :   /* Note that we are not deallocating the internal buffer (in the
     113                 :      case of a memory backend) nor the open file (in the case of a
     114                 :      file backend) */
     115             617 :   return PDF_OK;
     116                 : }
     117                 : 
     118                 : pdf_size_t
     119                 : pdf_stm_be_read (pdf_stm_be_t be,
     120                 :                  pdf_char_t *buffer,
     121                 :                  pdf_size_t bytes)
     122            2536 : {
     123                 :   pdf_size_t readed_bytes;
     124                 : 
     125            2536 :   switch (be->type)
     126                 :     {
     127                 :     case PDF_STM_BE_MEM:
     128                 :       {
     129            2514 :         readed_bytes = pdf_stm_be_mem_read (be,
     130                 :                                             buffer,
     131                 :                                             bytes);
     132            2514 :         break;
     133                 :       }
     134                 :     case PDF_STM_BE_FILE:
     135                 :       {
     136              22 :         readed_bytes = pdf_stm_be_file_read (be,
     137                 :                                              buffer,
     138                 :                                              bytes);
     139              22 :         break;
     140                 :       }
     141                 :     case PDF_STM_BE_CFILE:
     142                 :       {
     143               0 :         readed_bytes = pdf_stm_be_cfile_read (be,
     144                 :                                               buffer,
     145                 :                                               bytes);
     146               0 :         break;
     147                 :       }
     148                 :     default:
     149                 :       {
     150                 :         /* Uh oh */
     151               0 :         readed_bytes = 0;
     152                 :         break;
     153                 :       }
     154                 :     }
     155                 : 
     156            2536 :   return readed_bytes;
     157                 : }
     158                 : 
     159                 : pdf_size_t
     160                 : pdf_stm_be_write (pdf_stm_be_t be,
     161                 :                   pdf_char_t *buffer,
     162                 :                   pdf_size_t bytes)
     163             140 : {
     164                 :   pdf_size_t written_bytes;
     165                 : 
     166             140 :   switch (be->type)
     167                 :     {
     168                 :     case PDF_STM_BE_MEM:
     169                 :       {
     170             138 :         written_bytes = pdf_stm_be_mem_write (be,
     171                 :                                               buffer,
     172                 :                                               bytes);
     173             138 :         break;
     174                 :       }
     175                 :     case PDF_STM_BE_FILE:
     176                 :       {
     177               2 :         written_bytes = pdf_stm_be_file_write (be,
     178                 :                                                buffer,
     179                 :                                                bytes);
     180               2 :         break;
     181                 :       }
     182                 :     case PDF_STM_BE_CFILE:
     183                 :       {
     184               0 :         written_bytes = pdf_stm_be_cfile_write (be,
     185                 :                                                 buffer,
     186                 :                                                 bytes);
     187               0 :         break;
     188                 :       }
     189                 :     default:
     190                 :       {
     191                 :         /* Uh oh */
     192               0 :         written_bytes = 0;
     193                 :         break;
     194                 :       }
     195                 :     }
     196                 : 
     197             140 :   return written_bytes;
     198                 : }
     199                 : 
     200                 : pdf_off_t
     201                 : pdf_stm_be_seek (pdf_stm_be_t be,
     202                 :                  pdf_off_t pos)
     203               7 : {
     204                 :   pdf_off_t result;
     205                 : 
     206               7 :   switch (be->type)
     207                 :     {
     208                 :     case PDF_STM_BE_MEM:
     209                 :       {
     210               4 :         result =  pdf_stm_be_mem_seek (be, pos);
     211               4 :         break;
     212                 :       }
     213                 :     case PDF_STM_BE_FILE:
     214                 :       {
     215               3 :         result = pdf_stm_be_file_seek (be, pos);
     216               3 :         break;
     217                 :       }
     218                 :     case PDF_STM_BE_CFILE:
     219                 :       {
     220               0 :         result = pdf_stm_be_cfile_seek (be, pos);
     221               0 :         break;
     222                 :       }
     223                 :     default:
     224                 :       {
     225                 :         /* Uh oh */
     226               0 :         return 0;
     227                 :       }
     228                 :     }
     229                 : 
     230               7 :   return result;
     231                 : }
     232                 : 
     233                 : pdf_off_t
     234                 : pdf_stm_be_tell (pdf_stm_be_t be)
     235               2 : {
     236                 :   pdf_off_t result;
     237                 : 
     238               2 :   switch (be->type)
     239                 :     {
     240                 :     case PDF_STM_BE_MEM:
     241                 :       {
     242               1 :         result =  pdf_stm_be_mem_tell (be);
     243               1 :         break;
     244                 :       }
     245                 :     case PDF_STM_BE_FILE:
     246                 :       {
     247               1 :         result = pdf_stm_be_file_tell (be);
     248               1 :         break;
     249                 :       }
     250                 :     case PDF_STM_BE_CFILE:
     251                 :       {
     252               0 :         result = pdf_stm_be_cfile_tell (be);
     253               0 :         break;
     254                 :       }
     255                 :     default:
     256                 :       {
     257                 :         /* Uh oh */
     258               0 :         return 0;
     259                 :       }
     260                 :     }
     261                 : 
     262               2 :   return result;
     263                 : }
     264                 : 
     265                 : /*
     266                 :  * Private functions
     267                 :  */
     268                 : 
     269                 : static pdf_size_t
     270                 : pdf_stm_be_mem_read (pdf_stm_be_t be,
     271                 :                      pdf_char_t *buffer,
     272                 :                      pdf_size_t bytes)
     273                 : {
     274                 :   pdf_size_t free_bytes;
     275                 :   pdf_size_t readed_bytes;
     276                 :   
     277            2514 :   if ((bytes == 0) || (bytes < 0))
     278                 :     {
     279               0 :       return 0;
     280                 :     }
     281                 :   
     282                 :   /* How many bytes can we read from the buffer? */
     283            2514 :   free_bytes = be->data.mem.size - be->data.mem.pos;
     284            2514 :   if (bytes < free_bytes)
     285                 :     {
     286              77 :       readed_bytes = bytes;
     287                 :     }
     288                 :   else
     289                 :     {
     290            2437 :       readed_bytes = free_bytes;
     291                 :     }
     292                 : 
     293            2514 :   if (readed_bytes != 0)
     294                 :     {
     295                 :       /* Copy the data */
     296             826 :       memcpy ((char *) buffer,
     297                 :               (char *) be->data.mem.buffer + be->data.mem.pos,
     298                 :               readed_bytes);
     299                 : 
     300             826 :       be->data.mem.pos += readed_bytes;
     301                 :     }
     302                 : 
     303                 :   /* Ok, bye bye */
     304            2514 :   return readed_bytes;
     305                 : }
     306                 : 
     307                 : static pdf_size_t
     308                 : pdf_stm_be_mem_write (pdf_stm_be_t be,
     309                 :                       pdf_char_t *buffer,
     310                 :                       pdf_size_t bytes)
     311                 : {
     312                 :   pdf_size_t free_bytes;
     313                 :   pdf_size_t written_bytes;
     314                 : 
     315                 :   /* Check boundaries of the buffer */
     316             138 :   if ((bytes == 0) || (bytes < 0))
     317                 :     {
     318               0 :       return 0;
     319                 :     }
     320                 : 
     321                 :   /* How many bytes can we write into the buffer? */
     322             138 :   free_bytes = be->data.mem.size - be->data.mem.pos;
     323             138 :   if (bytes < free_bytes)
     324                 :     {
     325             130 :       written_bytes = bytes;
     326                 :     }
     327                 :   else
     328                 :     {
     329               8 :       written_bytes = free_bytes;
     330                 :     }
     331                 : 
     332             138 :   if (written_bytes != 0)
     333                 :     {
     334                 :       /* Copy the data */
     335             135 :       memcpy ((char *) be->data.mem.buffer + be->data.mem.pos,
     336                 :               (char *) buffer,
     337                 :               written_bytes);
     338                 : 
     339             135 :       be->data.mem.pos += written_bytes;
     340                 :     }
     341                 : 
     342                 :   /* Ok, bye bye */
     343             138 :   return written_bytes;
     344                 : }
     345                 : 
     346                 : static pdf_size_t
     347                 : pdf_stm_be_file_read (pdf_stm_be_t be,
     348                 :                       pdf_char_t *buffer,
     349                 :                       pdf_size_t bytes)
     350                 : {
     351                 :   pdf_size_t readed_bytes;
     352                 :   pdf_size_t current_pos;
     353                 :   pdf_status_t ret;
     354                 : 
     355                 :   /* Seek in the file */
     356              22 :   pdf_fsys_file_get_pos (be->data.file.file,
     357                 :                          &current_pos);
     358              22 :   if (pdf_fsys_file_set_pos (be->data.file.file,
     359                 :                              be->data.file.pos) == PDF_ERROR)
     360                 :     {
     361                 :       /* Bad position */
     362               0 :       return 0;
     363                 :     }
     364                 : 
     365                 :   /* Read the requested number of bytes */
     366              22 :   ret = pdf_fsys_file_read (be->data.file.file,
     367                 :                             buffer,
     368                 :                             bytes,
     369                 :                             &readed_bytes);
     370                 : 
     371                 :   /* Restore the file position and update the position of the
     372                 :      stream */
     373              22 :   be->data.file.pos = be->data.file.pos + readed_bytes;
     374              22 :   if (pdf_fsys_file_set_pos (be->data.file.file,
     375                 :                              current_pos) == PDF_ERROR)
     376                 :     {
     377                 :       /* This should not happen, but just in case */
     378               0 :       return 0;
     379                 :     }
     380                 : 
     381              22 :   return readed_bytes;
     382                 : }
     383                 : 
     384                 : static pdf_size_t
     385                 : pdf_stm_be_file_write (pdf_stm_be_t be,
     386                 :                        pdf_char_t *buffer,
     387                 :                        pdf_size_t bytes)
     388                 : {
     389                 :   pdf_size_t written_bytes;
     390                 :   pdf_size_t current_pos;
     391                 :   pdf_status_t ret;
     392                 : 
     393                 :   /* Seek in the file */
     394               2 :   pdf_fsys_file_get_pos (be->data.file.file,
     395                 :                          &current_pos);
     396               2 :   if (pdf_fsys_file_set_pos (be->data.file.file,
     397                 :                              be->data.file.pos) == PDF_ERROR)
     398                 :     {
     399                 :       /* Bad position */
     400               0 :       return 0;
     401                 :     }
     402                 :   
     403                 :   /* Write the requested number of bytes */
     404               2 :   ret = pdf_fsys_file_write (be->data.file.file,
     405                 :                              buffer,
     406                 :                              bytes,
     407                 :                              &written_bytes);
     408                 :   
     409                 :   /* Restore the file position and update the position of the
     410                 :      stream */
     411               2 :   be->data.file.pos = be->data.file.pos + written_bytes;
     412               2 :   if (pdf_fsys_file_set_pos (be->data.file.file,
     413                 :                              current_pos) == PDF_ERROR)
     414                 :     {
     415                 :       /* This should not happen, but just in case */
     416               0 :       return 0;
     417                 :     }
     418                 :                                        
     419               2 :   return written_bytes;
     420                 : }
     421                 : 
     422                 : static pdf_off_t
     423                 : pdf_stm_be_mem_seek (pdf_stm_be_t be,
     424                 :                      pdf_off_t pos)
     425                 : {
     426                 :   /* Check the requested position */
     427               4 :   if (pos >= be->data.mem.size)
     428                 :     {
     429               1 :       pos = be->data.mem.size - 1;
     430                 :     }
     431               4 :   if (pos < 0)
     432                 :     {
     433               0 :       pos = 0;
     434                 :     }
     435                 : 
     436                 :   /* Move there */
     437               4 :   be->data.mem.pos = pos;
     438                 : 
     439               4 :   return pos;
     440                 : }
     441                 : 
     442                 : static pdf_off_t
     443                 : pdf_stm_be_mem_tell (pdf_stm_be_t be)
     444                 : {
     445               1 :   return be->data.mem.pos;
     446                 : }
     447                 : 
     448                 : static pdf_off_t
     449                 : pdf_stm_be_file_seek (pdf_stm_be_t be,
     450                 :                       pdf_off_t pos)
     451                 : {
     452                 :   pdf_size_t file_size;
     453                 : 
     454               3 :   file_size = pdf_fsys_file_get_size (be->data.file.file);
     455                 : 
     456                 :   /* Check the requested position */
     457               3 :   if (pos < 0)
     458                 :     {
     459               0 :       pos = 0;
     460                 :     }
     461               3 :   if (pos >= file_size)
     462                 :     {
     463               1 :       pos = file_size - 1;
     464                 :     }
     465                 : 
     466               3 :   be->data.file.pos = pos;
     467                 : 
     468               3 :   return pos;
     469                 : }
     470                 : 
     471                 : static pdf_off_t
     472                 : pdf_stm_be_file_tell (pdf_stm_be_t be)
     473                 : {
     474               1 :   return be->data.file.pos;
     475                 : }
     476                 : 
     477                 : /* cfile backend implementation */
     478                 : 
     479                 : static pdf_off_t
     480                 : pdf_stm_be_cfile_seek (pdf_stm_be_t be,
     481                 :                        pdf_off_t pos)
     482               0 : {
     483                 :   pdf_off_t max_pos;
     484                 :   
     485               0 :   fseek (be->data.cfile.file, 0, SEEK_END);
     486               0 :   max_pos = ftell (be->data.cfile.file);
     487                 : 
     488                 :   /* Check the requested position */
     489               0 :   if (pos < 0)
     490                 :     {
     491               0 :       pos = 0;
     492                 :     }
     493               0 :   if (pos > max_pos)
     494                 :     {
     495               0 :       pos = max_pos - 1;
     496                 :     }
     497                 : 
     498               0 :   be->data.cfile.pos = pos;
     499               0 :   fseek (be->data.cfile.file,
     500                 :          be->data.cfile.pos,
     501                 :          SEEK_SET);
     502                 : 
     503               0 :   return pos;
     504                 : }
     505                 : 
     506                 : static pdf_off_t
     507                 : pdf_stm_be_cfile_tell (pdf_stm_be_t be)
     508                 : {
     509               0 :   return be->data.cfile.pos;
     510                 : }
     511                 : 
     512                 : static pdf_size_t
     513                 : pdf_stm_be_cfile_read (pdf_stm_be_t be,
     514                 :                       pdf_char_t *buffer,
     515                 :                       pdf_size_t bytes)
     516                 : {
     517                 :   pdf_size_t readed_bytes;
     518                 : 
     519                 :   /* Read the requested number of bytes */
     520               0 :   readed_bytes = fread (buffer, 
     521                 :                         1, bytes,
     522                 :                         be->data.cfile.file);
     523                 : 
     524               0 :   return readed_bytes;
     525                 : }
     526                 : 
     527                 : static pdf_size_t
     528                 : pdf_stm_be_cfile_write (pdf_stm_be_t be,
     529                 :                         pdf_char_t *buffer,
     530                 :                         pdf_size_t bytes)
     531                 : {
     532                 :   pdf_size_t written_bytes;
     533                 : 
     534                 :   /* Write the requested number of bytes */
     535               0 :   written_bytes = fwrite (buffer,
     536                 :                           1, bytes,
     537                 :                           be->data.cfile.file);
     538                 :   
     539               0 :   return written_bytes;
     540                 : }
     541                 : 
     542                 : /* End of pdf-stm-be.c */

Generated by: LTP GCOV extension version 1.6