LCOV - code coverage report
Current view: directory - frmts/grib/degrib18/degrib - fileendian.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 129 13 10.1 %
Date: 2011-12-18 Functions: 9 1 11.1 %

       1                 : /*****************************************************************************
       2                 :  * fileendian.c
       3                 :  *
       4                 :  * DESCRIPTION
       5                 :  *    This file contains all the utility functions that the Driver uses to
       6                 :  * solve endian'ness related issues.
       7                 :  *
       8                 :  * HISTORY
       9                 :  *   9/2002 Arthur Taylor (MDL / RSIS): Created.
      10                 :  *  12/2002 Rici Yu, Fangyu Chi, Mark Armstrong, & Tim Boyer
      11                 :  *          (RY,FC,MA,&TB): Code Review 2.
      12                 :  *
      13                 :  * NOTES
      14                 :  *****************************************************************************
      15                 :  */
      16                 : #include <stdio.h>
      17                 : #include <string.h>
      18                 : #include "fileendian.h"
      19                 : 
      20                 : /*****************************************************************************
      21                 :  * norfread() -- Review 12/2006
      22                 :  *
      23                 :  * Bas Retsios / ITC
      24                 :  *
      25                 :  * PURPOSE
      26                 :  *   To map the #defined FREAD_BIG and FREAD_LIT to DataSource fread instead of "fread"
      27                 :  *
      28                 :  * ARGUMENTS
      29                 :  *       Dst = The destination for the data. (Output)
      30                 :  * elem_size = The size of a single element. (Input)
      31                 :  *  num_elem = The number of elements in Src. (Input)
      32                 :  *        fp = The file to read from. (Input)
      33                 :  *
      34                 :  * FILES/DATABASES:
      35                 :  *   It is assumed that file is already opened and in the correct seek position.
      36                 :  *
      37                 :  * RETURNS: size_t
      38                 :  *   Number of elements read.
      39                 :  *
      40                 :  * HISTORY
      41                 :  *   12/2006 Bas Retsios (ITC): Created.
      42                 :  *****************************************************************************
      43                 :  */
      44                 : 
      45               0 : size_t norfread (void *Dst, size_t elem_size, size_t num_elem, DataSource &fp)
      46                 : {
      47               0 :   return fp.DataSourceFread(Dst, elem_size, num_elem);
      48                 : }
      49                 : 
      50                 : /*****************************************************************************
      51                 :  * revfread() -- Review 12/2002
      52                 :  *
      53                 :  * Arthur Taylor / MDL
      54                 :  *
      55                 :  * PURPOSE
      56                 :  *   To do an "fread", but in a reverse manner.
      57                 :  *
      58                 :  * ARGUMENTS
      59                 :  *       Dst = The destination for the data. (Output)
      60                 :  * elem_size = The size of a single element. (Input)
      61                 :  *  num_elem = The number of elements in Src. (Input)
      62                 :  *        fp = The file to read from. (Input)
      63                 :  *
      64                 :  * FILES/DATABASES:
      65                 :  *   It is assumed that file is already opened and in the correct place.
      66                 :  *
      67                 :  * RETURNS: size_t
      68                 :  *   Number of elements read.
      69                 :  *
      70                 :  * HISTORY
      71                 :  *   9/2002 Arthur Taylor (MDL/RSIS): Created.
      72                 :  *  12/2002 (RY,FC,MA,&TB): Code Review.
      73                 :  *
      74                 :  * NOTES
      75                 :  *   Decided to read it in and then swap.  The thought here being that it is
      76                 :  * faster than a bunch of fgetc.  This is the exact opposite method as
      77                 :  * revfwrite.
      78                 :  *****************************************************************************
      79                 :  */
      80              14 : size_t revfread (void *Dst, size_t elem_size, size_t num_elem, DataSource &fp)
      81                 : {
      82                 :    size_t ans;          /* The answer from fread. */
      83                 :    size_t j;            /* Byte count. */
      84                 :    char *dst;           /* Allows us to treat Dst as an array of char. */
      85                 :    char temp;           /* A temporary holder of a byte when swapping. */
      86                 :    char *ptr, *ptr2;    /* Pointers to the two bytes to swap. */
      87                 : 
      88              14 :    ans = fp.DataSourceFread(Dst, elem_size, num_elem);
      89              14 :    if (elem_size == 1) {
      90               0 :       return ans;
      91                 :    }
      92              14 :    if (ans == num_elem) {
      93              14 :       dst = (char *) Dst;
      94              28 :       for (j = 0; j < elem_size * num_elem; j += elem_size) {
      95              14 :          ptr = dst + j;
      96              14 :          ptr2 = ptr + elem_size - 1;
      97              56 :          while (ptr2 > ptr) {
      98              28 :             temp = *ptr;
      99              28 :             *(ptr++) = *ptr2;
     100              28 :             *(ptr2--) = temp;
     101                 :          }
     102                 :       }
     103                 :    }
     104              14 :    return ans;
     105                 : }
     106                 : 
     107                 : /*****************************************************************************
     108                 :  * revfwrite() -- Review 12/2002
     109                 :  *
     110                 :  * Arthur Taylor / MDL
     111                 :  *
     112                 :  * PURPOSE
     113                 :  *   To do an "fwrite", but in a reverse manner.
     114                 :  *
     115                 :  * ARGUMENTS
     116                 :  *       Src = The source of the data. (Input)
     117                 :  * elem_size = The size of a single element. (Input)
     118                 :  *  num_elem = The number of elements in Src. (Input)
     119                 :  *        fp = The file to write to. (Output)
     120                 :  *
     121                 :  * FILES/DATABASES:
     122                 :  *   It is assumed that file is already opened and in the correct place.
     123                 :  *
     124                 :  * RETURNS:
     125                 :  *   Returns number of elements written, or EOF on error.
     126                 :  *
     127                 :  * HISTORY
     128                 :  *   9/2002 Arthur Taylor (MDL/RSIS): Created.
     129                 :  *  11/2002 Arthur Taylor (MDL/RSIS): Updated.
     130                 :  *  12/2002 (RY,FC,MA,&TB): Code Review.
     131                 :  *
     132                 :  * NOTES
     133                 :  *   Decided to write using a bunch of fput, since this is buffered.  The
     134                 :  * thought here, is that it is faster than swapping memory and then writing.
     135                 :  * This is the exact opposite method as revfread.
     136                 :  *****************************************************************************
     137                 :  */
     138               0 : size_t revfwrite (void *Src, size_t elem_size, size_t num_elem, FILE * fp)
     139                 : {
     140                 :    char *ptr;           /* Current byte to put to file. */
     141                 :    size_t i;            /* Byte count */
     142                 :    size_t j;            /* Element count */
     143                 :    char *src;           /* Allows us to treat Src as an array of char. */
     144                 : 
     145               0 :    if (elem_size == 1) {
     146               0 :       return fwrite (Src, elem_size, num_elem, fp);
     147                 :    } else {
     148               0 :       src = (char *) Src;
     149               0 :       ptr = src - elem_size - 1;
     150               0 :       for (j = 0; j < num_elem; ++j) {
     151               0 :          ptr += 2 * elem_size;
     152               0 :          for (i = 0; i < elem_size; ++i) {
     153               0 :             if (fputc ((int) *(ptr--), fp) == EOF) {
     154               0 :                return 0;
     155                 :             }
     156                 :          }
     157                 :       }
     158               0 :       return num_elem;
     159                 :    }
     160                 : }
     161                 : 
     162                 : /*****************************************************************************
     163                 :  * FREAD_ODDINT_BIG() --
     164                 :  *
     165                 :  * Arthur Taylor / MDL
     166                 :  *
     167                 :  * PURPOSE
     168                 :  *   To do an "fread" into a sInt4, but in a reverse manner with not
     169                 :  * necessarily all 4 bytes.  It reads big endian data from disk.
     170                 :  *
     171                 :  * ARGUMENTS
     172                 :  * dst = Where to store the data. (Output)
     173                 :  * len = The number of bytes to read. (<= 4) (Input)
     174                 :  *  fp = The file to read from. (Input)
     175                 :  *
     176                 :  * FILES/DATABASES:
     177                 :  *   It is assumed that file is already opened and in the correct place.
     178                 :  *
     179                 :  * RETURNS:
     180                 :  *   Returns number of elements read, or EOF on error.
     181                 :  *
     182                 :  * HISTORY
     183                 :  *  12/2004 Arthur Taylor (MDL): Created.
     184                 :  *
     185                 :  * NOTES
     186                 :  *****************************************************************************
     187                 :  */
     188               0 : size_t FREAD_ODDINT_BIG (sInt4 * dst, uChar len, DataSource &fp)
     189                 : {
     190               0 :    *dst = 0;
     191                 : #ifdef LITTLE_ENDIAN
     192               0 :    return revfread (dst, len, 1, fp);
     193                 : #else
     194                 :    return norfread ((((char *) dst) + (4 - len)), len, 1, fp);
     195                 : #endif
     196                 : }
     197                 : 
     198                 : /*****************************************************************************
     199                 :  * FREAD_ODDINT_LIT() --
     200                 :  *
     201                 :  * Arthur Taylor / MDL
     202                 :  *
     203                 :  * PURPOSE
     204                 :  *   To do an "fread" into a sInt4, but in a reverse manner with not
     205                 :  * necessarily all 4 bytes.  It reads little endian data from disk.
     206                 :  *
     207                 :  * ARGUMENTS
     208                 :  * dst = Where to store the data. (Output)
     209                 :  * len = The number of bytes to read. (<= 4) (Input)
     210                 :  *  fp = The file to read from. (Input)
     211                 :  *
     212                 :  * FILES/DATABASES:
     213                 :  *   It is assumed that file is already opened and in the correct place.
     214                 :  *
     215                 :  * RETURNS:
     216                 :  *   Returns number of elements read, or EOF on error.
     217                 :  *
     218                 :  * HISTORY
     219                 :  *  12/2004 Arthur Taylor (MDL): Created.
     220                 :  *
     221                 :  * NOTES
     222                 :  *****************************************************************************
     223                 :  */
     224               0 : size_t FREAD_ODDINT_LIT (sInt4 * dst, uChar len, DataSource &fp)
     225                 : {
     226               0 :    *dst = 0;
     227                 : #ifdef LITTLE_ENDIAN
     228               0 :    return norfread (dst, len, 1, fp);
     229                 : #else
     230                 :    return revfread ((((char *) dst) + (4 - len)), len, 1, fp);
     231                 : #endif
     232                 : }
     233                 : 
     234                 : /*****************************************************************************
     235                 :  * FWRITE_ODDINT_BIG() --
     236                 :  *
     237                 :  * Arthur Taylor / MDL
     238                 :  *
     239                 :  * PURPOSE
     240                 :  *   To do an "fwrite" from a sInt4, but in a reverse manner with not
     241                 :  * necessarily all 4 bytes.  It writes big endian data to disk.
     242                 :  *
     243                 :  * ARGUMENTS
     244                 :  * src = Where to read the data from. (Output)
     245                 :  * len = The number of bytes to read. (<= 4) (Input)
     246                 :  *  fp = The file to write the data to. (Input)
     247                 :  *
     248                 :  * FILES/DATABASES:
     249                 :  *   It is assumed that file is already opened and in the correct place.
     250                 :  *
     251                 :  * RETURNS:
     252                 :  *   Returns number of elements written, or EOF on error.
     253                 :  *
     254                 :  * HISTORY
     255                 :  *  12/2004 Arthur Taylor (MDL): Created.
     256                 :  *
     257                 :  * NOTES
     258                 :  *****************************************************************************
     259                 :  */
     260               0 : size_t FWRITE_ODDINT_BIG (sInt4 * src, uChar len, FILE * fp)
     261                 : {
     262                 : #ifdef LITTLE_ENDIAN
     263               0 :    return revfwrite (src, len, 1, fp);
     264                 : #else
     265                 :    return fwrite ((((char *) src) + (4 - len)), len, 1, fp);
     266                 : #endif
     267                 : }
     268                 : 
     269                 : /*****************************************************************************
     270                 :  * FWRITE_ODDINT_LIT() --
     271                 :  *
     272                 :  * Arthur Taylor / MDL
     273                 :  *
     274                 :  * PURPOSE
     275                 :  *   To do an "fwrite" from a sInt4, but in a reverse manner with not
     276                 :  * necessarily all 4 bytes.  It writes little endian data to disk.
     277                 :  *
     278                 :  * ARGUMENTS
     279                 :  * src = Where to read the data from. (Output)
     280                 :  * len = The number of bytes to read. (<= 4) (Input)
     281                 :  *  fp = The file to write the data to. (Input)
     282                 :  *
     283                 :  * FILES/DATABASES:
     284                 :  *   It is assumed that file is already opened and in the correct place.
     285                 :  *
     286                 :  * RETURNS:
     287                 :  *   Returns number of elements written, or EOF on error.
     288                 :  *
     289                 :  * HISTORY
     290                 :  *  12/2004 Arthur Taylor (MDL): Created.
     291                 :  *
     292                 :  * NOTES
     293                 :  *****************************************************************************
     294                 :  */
     295               0 : size_t FWRITE_ODDINT_LIT (sInt4 * src, uChar len, FILE * fp)
     296                 : {
     297                 : #ifdef LITTLE_ENDIAN
     298               0 :    return fwrite (src, len, 1, fp);
     299                 : #else
     300                 :    return revfwrite ((((char *) src) + (4 - len)), len, 1, fp);
     301                 : #endif
     302                 : }
     303                 : 
     304                 : /*****************************************************************************
     305                 :  * fileBitRead() --
     306                 :  *
     307                 :  * Arthur Taylor / MDL
     308                 :  *
     309                 :  * PURPOSE
     310                 :  *   To get bits from the file.  Stores the current byte, and passes the
     311                 :  * bits that were requested to the user.  Leftover bits, are stored in a
     312                 :  * gbuf, which should be passed in for future reads.
     313                 :  *   If numBits == 0, then flush the gbuf.
     314                 :  *
     315                 :  * ARGUMENTS
     316                 :  *      dst = The storage place for the data read from file. (Output)
     317                 :  *   dstLen = The size of dst (in bytes) (Input)
     318                 :  * num_bits = The number of bits to read from the file. (Input)
     319                 :  *       fp = The open file to read from. (Input)
     320                 :  *     gbuf = The current bit buffer (Input/Output)
     321                 :  *  gbufLoc = Where we are in the current bit buffer. (Input/Output)
     322                 :  *
     323                 :  * RETURNS:
     324                 :  *   EOF if EOF, 1 if error, 0 otherwise.
     325                 :  *
     326                 :  * NOTES
     327                 :  *****************************************************************************
     328                 :  */
     329               0 : int fileBitRead (void *Dst, size_t dstLen, uShort2 num_bits, FILE * fp,
     330                 :                  uChar * gbuf, sChar * gbufLoc)
     331                 : {
     332                 :    static uChar BitRay[] = { 0, 1, 3, 7, 15, 31, 63, 127, 255 };
     333                 :    register uChar buf_loc, buf, *ptr;
     334               0 :    uChar *dst = (uChar*)Dst;
     335                 :    size_t num_bytes;
     336                 :    uChar dst_loc;
     337                 :    int c;
     338                 : 
     339               0 :    memset (Dst, 0, dstLen);
     340                 : 
     341               0 :    if (num_bits == 0) {
     342               0 :       *gbuf = 0;
     343               0 :       *gbufLoc = 0;
     344               0 :       return 0;
     345                 :    }
     346                 : 
     347                 :    /* Since num_bits is always used with -1, I might as well do --num_bits
     348                 :     * here. */
     349               0 :    num_bytes = ((--num_bits) / 8) + 1; /* 1..8 bits = 1 byte, ... */
     350                 :    /* Check if dst has enough room for num_bits. */
     351               0 :    if (dstLen < num_bytes) {
     352               0 :       return 1;
     353                 :    }
     354                 : 
     355                 :    /* num_bits was modified earlier. */
     356               0 :    dst_loc = (uChar) ((num_bits % 8) + 1);
     357               0 :    buf_loc = *gbufLoc;
     358               0 :    buf = *gbuf;
     359                 : 
     360                 : #ifdef LITTLE_ENDIAN
     361               0 :    ptr = dst + (num_bytes - 1);
     362                 : #else
     363                 :    ptr = dst + (dstLen - num_bytes);
     364                 : #endif
     365                 : 
     366                 :    /* Deal with initial "remainder" part (most significant byte) in dst. */
     367               0 :    if (buf_loc >= dst_loc) {
     368                 :       /* can now deal with entire "remainder". */
     369                 : #ifdef LITTLE_ENDIAN
     370               0 :       *(ptr--) |= (uChar) ((buf & BitRay[buf_loc]) >> (buf_loc - dst_loc));
     371                 : #else
     372                 :       *(ptr++) |= (uChar) ((buf & BitRay[buf_loc]) >> (buf_loc - dst_loc));
     373                 : #endif
     374               0 :       buf_loc -= dst_loc;
     375                 :    } else {
     376                 :       /* need to do 2 calls to deal with entire "remainder". */
     377               0 :       if (buf_loc != 0) {
     378               0 :          *ptr |= (uChar) ((buf & BitRay[buf_loc]) << (dst_loc - buf_loc));
     379                 :       }
     380                 :       /* buf_loc is now 0. so we need more data. */
     381                 :       /* dst_loc is now dst_loc - buf_loc. */
     382               0 :       if ((c = fgetc (fp)) == EOF) {
     383               0 :          *gbufLoc = buf_loc;
     384               0 :          *gbuf = buf;
     385               0 :          return EOF;
     386                 :       }
     387                 :       /* buf_loc should be 8 */
     388               0 :       buf = (uChar) c;
     389                 :       /* 8 - (dst_loc - buf_loc) */
     390               0 :       buf_loc += (uChar) (8 - dst_loc);
     391                 :       /* Need mask in case right shift with sign extension? Should be ok
     392                 :        * since buf is a uChar, so it fills with 0s. */
     393                 : #ifdef LITTLE_ENDIAN
     394               0 :       *(ptr--) |= (uChar) (buf >> buf_loc);
     395                 : #else
     396                 :       *(ptr++) |= (uChar) (buf >> buf_loc);
     397                 : #endif
     398                 :       /* buf_loc should now be 8 - (dst_loc - buf_loc) */
     399                 :    }
     400                 : 
     401                 :    /* Note buf_loc < dst_loc from here on.  Either it is 0 or < 8. */
     402                 :    /* Also dst_loc is always 8 from here out. */
     403                 : #ifdef LITTLE_ENDIAN
     404               0 :    while (ptr >= dst) {
     405                 : #else
     406                 :    while (ptr < dst + dstLen) {
     407                 : #endif
     408               0 :       if (buf_loc != 0) {
     409               0 :          *ptr |= (uChar) ((buf & BitRay[buf_loc]) << (8 - buf_loc));
     410                 :       }
     411                 :       /* buf_loc is now 0. so we need more data. */
     412               0 :       if ((c = fgetc (fp)) == EOF) {
     413               0 :          *gbufLoc = buf_loc;
     414               0 :          *gbuf = buf;
     415               0 :          return EOF;
     416                 :       }
     417               0 :       buf = (uChar) c;
     418                 :       /* Need mask in case right shift with sign extension? Should be ok
     419                 :        * since buf is a uChar, so it fills with 0s. */
     420                 : #ifdef LITTLE_ENDIAN
     421               0 :       *(ptr--) |= (uChar) (buf >> buf_loc);
     422                 : #else
     423                 :       *(ptr++) |= (uChar) (buf >> buf_loc);
     424                 : #endif
     425                 :    }
     426                 : 
     427               0 :    *gbufLoc = buf_loc;
     428               0 :    *gbuf = buf;
     429               0 :    return 0;
     430                 : }
     431                 : 
     432                 : /*****************************************************************************
     433                 :  * fileBitWrite() --
     434                 :  *
     435                 :  * Arthur Taylor / MDL
     436                 :  *
     437                 :  * PURPOSE
     438                 :  *   To write bits from src out to file.  First writes out any leftover bits
     439                 :  * in pbuf, then bits from src.  Any leftover bits that aren't on a full byte
     440                 :  * boundary, are stored in pbuf.
     441                 :  *   If numBits == 0, then flush the pbuf.
     442                 :  *
     443                 :  * ARGUMENTS
     444                 :  *     src = The data to put out to file. (Input)
     445                 :  *  srcLen = Length in bytes of src. (Input)
     446                 :  * numBits = The number of bits to write to file. (Input)
     447                 :  *      fp = The opened file ptr to write to. (Input)
     448                 :  *    pbuf = The extra bit buffer (Input/Output)
     449                 :  * pBufLoc = The location in the bit buffer.
     450                 :  *
     451                 :  * FILES/DATABASES: None
     452                 :  *
     453                 :  * RETURNS:
     454                 :  *   1 if error, 0 otherwise
     455                 :  *
     456                 :  * HISTORY
     457                 :  *   8/2004 Arthur Taylor (MDL): Created
     458                 :  *
     459                 :  * NOTES
     460                 :  *****************************************************************************
     461                 :  */
     462               0 : char fileBitWrite (void *Src, size_t srcLen, uShort2 numBits, FILE * fp,
     463                 :                    uChar * pbuf, sChar * pbufLoc)
     464                 : {
     465                 :    uChar buf_loc, buf, *ptr;
     466               0 :    uChar *src = (uChar*)Src;
     467                 :    size_t num_bytes;
     468                 :    uChar src_loc;
     469                 : 
     470               0 :    if (numBits == 0) {
     471               0 :       if (*pbufLoc != 8) {
     472               0 :          fputc ((int) *pbuf, fp);
     473               0 :          *pbuf = 0;
     474               0 :          *pbufLoc = 8;
     475               0 :          return 8;
     476                 :       } else {
     477               0 :          *pbuf = 0;
     478               0 :          *pbufLoc = 8;
     479               0 :          return 0;
     480                 :       }
     481                 :    }
     482                 :    /* Since numBits is always used with -1, I might as well do --numBits
     483                 :     * here. */
     484               0 :    num_bytes = ((--numBits) / 8) + 1; /* 1..8 bits = 1 byte, ... */
     485                 :    /* Check if src has enough bits for us to put out. */
     486               0 :    if (srcLen < num_bytes) {
     487               0 :       return 1;
     488                 :    }
     489                 : 
     490                 :    /* num_bits was modified earlier. */
     491               0 :    src_loc = (uChar) ((numBits % 8) + 1);
     492               0 :    buf_loc = *pbufLoc;
     493               0 :    buf = *pbuf;
     494                 : 
     495                 :    /* Get to start of interesting part of src. */
     496                 : #ifdef LITTLE_ENDIAN
     497               0 :    ptr = src + (num_bytes - 1);
     498                 : #else
     499                 :    ptr = src + (srcLen - num_bytes);
     500                 : #endif
     501                 : 
     502                 :    /* Deal with most significant byte in src. */
     503               0 :    if (buf_loc >= src_loc) {
     504                 :       /* can store entire MSB in buf. */
     505                 :       /* Mask? ... Safer to do so... Particularly if user has a number where
     506                 :        * she wants us to start saving half way through. */
     507                 : #ifdef LITTLE_ENDIAN
     508                 :       buf |= (uChar) ((*(ptr--) & ((1 << src_loc) - 1)) <<
     509               0 :                       (buf_loc - src_loc));
     510                 : #else
     511                 :       buf |= (uChar) ((*(ptr++) & ((1 << src_loc) - 1)) <<
     512                 :                       (buf_loc - src_loc));
     513                 : #endif
     514               0 :       buf_loc -= src_loc;
     515                 :    } else {
     516                 :       /* need to do 2 calls to store the MSB. */
     517               0 :       if (buf_loc != 0) {
     518                 :          buf |= (uChar) ((*ptr & ((1 << src_loc) - 1)) >>
     519               0 :                          (src_loc - buf_loc));
     520                 :       }
     521                 :       /* buf_loc is now 0, so we write it out. */
     522               0 :       if (fputc ((int) buf, fp) == EOF) {
     523               0 :          *pbufLoc = buf_loc;
     524               0 :          *pbuf = buf;
     525               0 :          return 1;
     526                 :       }
     527               0 :       buf = (uChar) 0;
     528                 :       /* src_loc is now src_loc - buf_loc */
     529                 :       /* store rest of ptr in buf. So left shift by 8 - (src_loc -buf_loc)
     530                 :        * and set buf_loc to 8 - (src_loc - buf_loc) */
     531               0 :       buf_loc += (uChar) (8 - src_loc);
     532                 : #ifdef LITTLE_ENDIAN
     533               0 :       buf |= (uChar) (*(ptr--) << buf_loc);
     534                 : #else
     535                 :       buf |= (uChar) (*(ptr++) << buf_loc);
     536                 : #endif
     537                 :    }
     538                 :    /* src_loc should always be considered 8 from now on.. */
     539                 : 
     540                 : #ifdef LITTLE_ENDIAN
     541               0 :    while (ptr >= src) {
     542                 : #else
     543                 :    while (ptr < src + srcLen) {
     544                 : #endif
     545               0 :       if (buf_loc == 0) {
     546                 :          /* Simple case where buf and src line up.. */
     547               0 :          if (fputc ((int) buf, fp) == EOF) {
     548               0 :             *pbufLoc = buf_loc;
     549               0 :             *pbuf = buf;
     550               0 :             return 1;
     551                 :          }
     552                 : #ifdef LITTLE_ENDIAN
     553               0 :          buf = (uChar) * (ptr--);
     554                 : #else
     555                 :          buf = (uChar) * (ptr++);
     556                 : #endif
     557                 :       } else {
     558                 :          /* No mask since src_loc is considered 8. */
     559                 :          /* Need mask in case right shift with sign extension? Should be ok
     560                 :           * since *ptr is a uChar so it fills with 0s. */
     561               0 :          buf |= (uChar) ((*ptr) >> (8 - buf_loc));
     562                 :          /* buf_loc is now 0, so we write it out. */
     563               0 :          if (fputc ((int) buf, fp) == EOF) {
     564               0 :             *pbufLoc = buf_loc;
     565               0 :             *pbuf = buf;
     566               0 :             return 1;
     567                 :          }
     568               0 :          buf = (uChar) 0;
     569                 :          /* src_loc is 8-buf_loc... */
     570                 :          /* need to left shift by 8 - (8-buf_loc) */
     571                 : #ifdef LITTLE_ENDIAN
     572               0 :          buf |= (uChar) (*(ptr--) << buf_loc);
     573                 : #else
     574                 :          buf |= (uChar) (*(ptr++) << buf_loc);
     575                 : #endif
     576                 :       }
     577                 :    }
     578                 :    /* We would rather not keep a full bit buffer. */
     579               0 :    if (buf_loc == 0) {
     580               0 :       if (fputc ((int) buf, fp) == EOF) {
     581               0 :          *pbufLoc = buf_loc;
     582               0 :          *pbuf = buf;
     583               0 :          return 1;
     584                 :       }
     585               0 :       buf_loc = 8;
     586               0 :       buf = (uChar) 0;
     587                 :    }
     588               0 :    *pbufLoc = buf_loc;
     589               0 :    *pbuf = buf;
     590               0 :    return 0;
     591                 : }

Generated by: LCOV version 1.7