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

Generated by: LTP GCOV extension version 1.6