LTP GCOV extension - code coverage report
Current view: directory - ogr/ogrsf_frmts/avc - avc_rawbin.c
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 164
Code covered: 53.7 % Executed lines: 88

       1                 : /**********************************************************************
       2                 :  * $Id: avc_rawbin.c,v 1.14 2008/07/23 20:51:38 dmorissette Exp $
       3                 :  *
       4                 :  * Name:     avc_rawbin.c
       5                 :  * Project:  Arc/Info vector coverage (AVC)  BIN->E00 conversion library
       6                 :  * Language: ANSI C
       7                 :  * Purpose:  Raw Binary file access functions.
       8                 :  * Author:   Daniel Morissette, dmorissette@dmsolutions.ca
       9                 :  *
      10                 :  **********************************************************************
      11                 :  * Copyright (c) 1999-2005, Daniel Morissette
      12                 :  *
      13                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      14                 :  * copy of this software and associated documentation files (the "Software"),
      15                 :  * to deal in the Software without restriction, including without limitation
      16                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      17                 :  * and/or sell copies of the Software, and to permit persons to whom the
      18                 :  * Software is furnished to do so, subject to the following conditions:
      19                 :  * 
      20                 :  * The above copyright notice and this permission notice shall be included
      21                 :  * in all copies or substantial portions of the Software.
      22                 :  * 
      23                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      24                 :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      25                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
      26                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      27                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      28                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
      29                 :  * DEALINGS IN THE SOFTWARE.
      30                 :  **********************************************************************
      31                 :  *
      32                 :  * $Log: avc_rawbin.c,v $
      33                 :  * Revision 1.14  2008/07/23 20:51:38  dmorissette
      34                 :  * Fixed GCC 4.1.x compile warnings related to use of char vs unsigned char
      35                 :  * (GDAL/OGR ticket http://trac.osgeo.org/gdal/ticket/2495)
      36                 :  *
      37                 :  * Revision 1.13  2005/06/03 03:49:59  daniel
      38                 :  * Update email address, website url, and copyright dates
      39                 :  *
      40                 :  * Revision 1.12  2004/08/19 23:41:04  warmerda
      41                 :  * fixed pointer aliasing optimization bug
      42                 :  *
      43                 :  * Revision 1.11  2000/09/22 19:45:21  daniel
      44                 :  * Switch to MIT-style license
      45                 :  *
      46                 :  * Revision 1.10  2000/05/29 15:36:07  daniel
      47                 :  * Fixed compile warning
      48                 :  *
      49                 :  * Revision 1.9  2000/05/29 15:31:31  daniel
      50                 :  * Added Japanese DBCS support
      51                 :  *
      52                 :  * Revision 1.8  2000/01/10 02:59:11  daniel
      53                 :  * Fixed problem in AVCRawBinOpen() when file not found
      54                 :  *
      55                 :  * Revision 1.7  1999/12/24 07:18:34  daniel
      56                 :  * Added PC Arc/Info coverages support
      57                 :  *
      58                 :  * Revision 1.6  1999/08/29 15:05:43  daniel
      59                 :  * Added source filename in "Attempt to read past EOF" error message
      60                 :  *
      61                 :  * Revision 1.5  1999/06/08 22:09:03  daniel
      62                 :  * Allow opening file with "r+" (but no real random access support yet)
      63                 :  *
      64                 :  * Revision 1.4  1999/05/11 02:10:51  daniel
      65                 :  * Added write support
      66                 :  *
      67                 :  * Revision 1.3  1999/03/03 19:55:21  daniel
      68                 :  * Fixed syntax error in the CPL_MSB version of AVCRawBinReadInt32()
      69                 :  *
      70                 :  * Revision 1.2  1999/02/25 04:20:08  daniel
      71                 :  * Modified AVCRawBinEOF() to detect EOF even if AVCRawBinFSeek() was used.
      72                 :  *
      73                 :  * Revision 1.1  1999/01/29 16:28:52  daniel
      74                 :  * Initial revision
      75                 :  *
      76                 :  **********************************************************************/
      77                 : 
      78                 : #include "avc.h"
      79                 : #include "avc_mbyte.h"
      80                 : 
      81                 : /*---------------------------------------------------------------------
      82                 :  * Define a static flag and set it with the byte ordering on this machine
      83                 :  * we will then compare with this value to decide if we nned to swap
      84                 :  * bytes or not.
      85                 :  *
      86                 :  * CPL_MSB or CPL_LSB should be set in the makefile... the default is
      87                 :  * CPL_LSB.
      88                 :  *--------------------------------------------------------------------*/
      89                 : #ifndef CPL_LSB
      90                 : static AVCByteOrder geSystemByteOrder = AVCBigEndian;
      91                 : #else
      92                 : static AVCByteOrder geSystemByteOrder = AVCLittleEndian;
      93                 : #endif
      94                 : 
      95                 : /*=====================================================================
      96                 :  * Stuff related to buffered reading of raw binary files
      97                 :  *====================================================================*/
      98                 : 
      99                 : /**********************************************************************
     100                 :  *                          AVCRawBinOpen()
     101                 :  *
     102                 :  * Open a binary file for reading with buffering, or writing.
     103                 :  *
     104                 :  * Returns a valid AVCRawBinFile structure, or NULL if the file could
     105                 :  * not be opened or created.
     106                 :  *
     107                 :  * AVCRawBinClose() will eventually have to be called to release the 
     108                 :  * resources used by the AVCRawBinFile structure.
     109                 :  **********************************************************************/
     110                 : AVCRawBinFile *AVCRawBinOpen(const char *pszFname, const char *pszAccess,
     111                 :                              AVCByteOrder eFileByteOrder,
     112                 :                              AVCDBCSInfo *psDBCSInfo)
     113              10 : {
     114                 :     AVCRawBinFile *psFile;
     115                 : 
     116              10 :     psFile = (AVCRawBinFile*)CPLCalloc(1, sizeof(AVCRawBinFile));
     117                 : 
     118                 :     /*-----------------------------------------------------------------
     119                 :      * Validate access mode and open/create file.  
     120                 :      * For now we support only: "r" for read-only or "w" for write-only
     121                 :      * or "a" for append.
     122                 :      *
     123                 :      * A case for "r+" is included here, but random access is not
     124                 :      * properly supported yet... so this option should be used with care.
     125                 :      *----------------------------------------------------------------*/
     126              10 :     if (EQUALN(pszAccess, "r+", 2))
     127                 :     {
     128               0 :         psFile->eAccess = AVCReadWrite;
     129               0 :         psFile->fp = VSIFOpen(pszFname, "r+b");
     130                 :     }
     131              10 :     else if (EQUALN(pszAccess, "r", 1))
     132                 :     {
     133              10 :         psFile->eAccess = AVCRead;
     134              10 :         psFile->fp = VSIFOpen(pszFname, "rb");
     135                 :     }
     136               0 :     else if (EQUALN(pszAccess, "w", 1))
     137                 :     {
     138               0 :         psFile->eAccess = AVCWrite;
     139               0 :         psFile->fp = VSIFOpen(pszFname, "wb");
     140                 :     }
     141               0 :     else if (EQUALN(pszAccess, "a", 1))
     142                 :     {
     143               0 :         psFile->eAccess = AVCWrite;
     144               0 :         psFile->fp = VSIFOpen(pszFname, "ab");
     145                 :     }
     146                 :     else
     147                 :     {
     148               0 :         CPLError(CE_Failure, CPLE_IllegalArg,
     149                 :                  "Acces mode \"%s\" not supported.", pszAccess);
     150               0 :         CPLFree(psFile);
     151               0 :         return NULL;
     152                 :     }
     153                 : 
     154                 :     /*-----------------------------------------------------------------
     155                 :      * Check that file was opened succesfully, and init struct.
     156                 :      *----------------------------------------------------------------*/
     157              10 :     if (psFile->fp == NULL)
     158                 :     {
     159               0 :         CPLError(CE_Failure, CPLE_OpenFailed,
     160                 :                  "Failed to open file %s", pszFname);
     161               0 :         CPLFree(psFile);
     162               0 :         return NULL;
     163                 :     }
     164                 : 
     165                 :     /*-----------------------------------------------------------------
     166                 :      * OK... Init psFile struct
     167                 :      *----------------------------------------------------------------*/
     168              10 :     psFile->pszFname = CPLStrdup(pszFname);
     169                 : 
     170              10 :     psFile->eByteOrder = eFileByteOrder;
     171              10 :     psFile->psDBCSInfo = psDBCSInfo; /* Handle on dataset DBCS info */
     172                 : 
     173                 :     /*-----------------------------------------------------------------
     174                 :      * One can set nFileDataSize based on some header fields to force
     175                 :      * EOF beyond a given point in the file.  Useful for cases like
     176                 :      * PC Arc/Info where the physical file size is always a multiple of
     177                 :      * 256 bytes padded with some junk at the end.
     178                 :      *----------------------------------------------------------------*/
     179              10 :     psFile->nFileDataSize = -1;
     180                 : 
     181              10 :     return psFile;
     182                 : }
     183                 : 
     184                 : /**********************************************************************
     185                 :  *                          AVCRawBinClose()
     186                 :  *
     187                 :  * Close a binary file previously opened with AVCRawBinOpen() and release
     188                 :  * any memory used by the handle.
     189                 :  **********************************************************************/
     190                 : void AVCRawBinClose(AVCRawBinFile *psFile)
     191              11 : {
     192              11 :     if (psFile)
     193                 :     {
     194              10 :         if (psFile->fp)
     195              10 :             VSIFClose(psFile->fp);
     196              10 :         CPLFree(psFile->pszFname);
     197              10 :         CPLFree(psFile);
     198                 :     }
     199              11 : }
     200                 : 
     201                 : /**********************************************************************
     202                 :  *                          AVCRawBinSetFileDataSize()
     203                 :  *
     204                 :  * One can set nFileDataSize based on some header fields to force
     205                 :  * EOF beyond a given point in the file.  Useful for cases like
     206                 :  * PC Arc/Info where the physical file size is always a multiple of
     207                 :  * 256 bytes padded with some junk at the end.
     208                 :  *
     209                 :  * The default value is -1 which just looks for the real EOF. 
     210                 :  **********************************************************************/
     211                 : void AVCRawBinSetFileDataSize(AVCRawBinFile *psFile, int nFileDataSize)
     212               4 : {
     213               4 :     if (psFile)
     214                 :     {
     215               4 :         psFile->nFileDataSize = nFileDataSize;
     216                 :     }
     217               4 : }
     218                 : 
     219                 : /**********************************************************************
     220                 :  *                          AVCRawBinReadBytes()
     221                 :  *
     222                 :  * Copy the number of bytes from the input file to the specified 
     223                 :  * memory location.
     224                 :  **********************************************************************/
     225                 : static GBool bDisableReadBytesEOFError = FALSE;
     226                 : 
     227                 : void AVCRawBinReadBytes(AVCRawBinFile *psFile, int nBytesToRead, GByte *pBuf)
     228            5510 : {
     229                 :     /* Make sure file is opened with Read access
     230                 :      */
     231            5510 :     if (psFile == NULL || 
     232                 :         (psFile->eAccess != AVCRead && psFile->eAccess != AVCReadWrite))
     233                 :     {
     234               0 :         CPLError(CE_Failure, CPLE_FileIO,
     235                 :                 "AVCRawBinReadBytes(): call not compatible with access mode.");
     236               0 :         return;
     237                 :     }
     238                 : 
     239                 :     /* Quick method: check to see if we can satisfy the request with a
     240                 :      * simple memcpy... most calls should take this path.
     241                 :      */
     242            5510 :     if (psFile->nCurPos + nBytesToRead <= psFile->nCurSize)
     243                 :     {
     244            5474 :         memcpy(pBuf, psFile->abyBuf+psFile->nCurPos, nBytesToRead);
     245            5474 :         psFile->nCurPos += nBytesToRead;
     246            5474 :         return;
     247                 :     }
     248                 : 
     249                 :     /* This is the long method... it supports reading data that 
     250                 :      * overlaps the input buffer boundaries.
     251                 :      */
     252             107 :     while(nBytesToRead > 0)
     253                 :     {
     254                 :         /* If we reached the end of our memory buffer then read another
     255                 :          * chunk from the file
     256                 :          */
     257              36 :         CPLAssert(psFile->nCurPos <= psFile->nCurSize);
     258              36 :         if (psFile->nCurPos == psFile->nCurSize)
     259                 :         {
     260              36 :             psFile->nOffset += psFile->nCurSize;
     261              36 :             psFile->nCurSize = VSIFRead(psFile->abyBuf, sizeof(GByte),
     262                 :                                         AVCRAWBIN_READBUFSIZE, psFile->fp);
     263              36 :             psFile->nCurPos = 0;
     264                 :         }
     265                 : 
     266              36 :         if (psFile->nCurSize == 0)
     267                 :         {
     268                 :             /* Attempt to read past EOF... generate an error.
     269                 :              *
     270                 :              * Note: AVCRawBinEOF() can set bDisableReadBytesEOFError=TRUE
     271                 :              *       to disable the error message whils it is testing
     272                 :              *       for EOF.
     273                 :              */
     274               1 :             if (bDisableReadBytesEOFError == FALSE)
     275               0 :                 CPLError(CE_Failure, CPLE_FileIO,
     276                 :                          "Attempt to read past EOF in %s.", psFile->pszFname);
     277               1 :             return;
     278                 :         }
     279                 : 
     280                 :         /* If the requested bytes are not all in the current buffer then
     281                 :          * just read the part that's in memory for now... the loop will 
     282                 :          * take care of the rest.
     283                 :          */
     284              35 :         if (psFile->nCurPos + nBytesToRead > psFile->nCurSize)
     285                 :         {
     286                 :             int nBytes;
     287               0 :             nBytes = psFile->nCurSize-psFile->nCurPos;
     288               0 :             memcpy(pBuf, psFile->abyBuf+psFile->nCurPos, nBytes);
     289               0 :             psFile->nCurPos += nBytes;
     290               0 :             pBuf += nBytes;
     291               0 :             nBytesToRead -= nBytes;
     292                 :         }
     293                 :         else
     294                 :         {
     295                 :             /* All the requested bytes are now in the buffer... 
     296                 :              * simply copy them and return.
     297                 :              */
     298              35 :             memcpy(pBuf, psFile->abyBuf+psFile->nCurPos, nBytesToRead);
     299              35 :             psFile->nCurPos += nBytesToRead;
     300                 : 
     301              35 :             nBytesToRead = 0;   /* Terminate the loop */
     302                 :         }
     303                 :     }
     304                 : }
     305                 : 
     306                 : /**********************************************************************
     307                 :  *                          AVCRawBinReadString()
     308                 :  *
     309                 :  * Same as AVCRawBinReadBytes() except that the string is run through
     310                 :  * the DBCS conversion function.
     311                 :  *
     312                 :  * pBuf should be allocated with a size of at least nBytesToRead+1 bytes.
     313                 :  **********************************************************************/
     314                 : void AVCRawBinReadString(AVCRawBinFile *psFile, int nBytesToRead, GByte *pBuf)
     315              22 : {
     316                 :     const GByte *pszConvBuf;
     317                 : 
     318              22 :     AVCRawBinReadBytes(psFile, nBytesToRead, pBuf);
     319                 : 
     320              22 :     pBuf[nBytesToRead] = '\0';
     321                 : 
     322              22 :     pszConvBuf = AVCE00ConvertFromArcDBCS(psFile->psDBCSInfo,
     323                 :                                           pBuf, 
     324                 :                                           nBytesToRead);
     325                 : 
     326              22 :     if (pszConvBuf != pBuf)
     327                 :     {
     328               0 :         memcpy(pBuf, pszConvBuf, nBytesToRead);
     329                 :     }
     330              22 : }
     331                 : 
     332                 : /**********************************************************************
     333                 :  *                          AVCRawBinFSeek()
     334                 :  *
     335                 :  * Move the read pointer to the specified location.
     336                 :  *
     337                 :  * As with fseek(), the specified position can be relative to the 
     338                 :  * beginning of the file (SEEK_SET), or the current position (SEEK_CUR).
     339                 :  * SEEK_END is not supported.
     340                 :  **********************************************************************/
     341                 : void AVCRawBinFSeek(AVCRawBinFile *psFile, int nOffset, int nFrom)
     342              53 : {
     343              53 :     int  nTarget = 0;
     344                 : 
     345              53 :     CPLAssert(nFrom == SEEK_SET || nFrom == SEEK_CUR);
     346                 : 
     347                 :     /* Supported only with read access for now
     348                 :      */
     349              53 :     CPLAssert(psFile && psFile->eAccess != AVCWrite);
     350              53 :     if (psFile == NULL || psFile->eAccess == AVCWrite)
     351               0 :         return;
     352                 : 
     353                 :     /* Compute destination relative to current memory buffer 
     354                 :      */
     355              53 :     if (nFrom == SEEK_SET)
     356              10 :         nTarget = nOffset - psFile->nOffset;
     357              43 :     else if (nFrom == SEEK_CUR)
     358              43 :         nTarget = nOffset + psFile->nCurPos;
     359                 : 
     360                 :     /* Is the destination located inside the current buffer?
     361                 :      */
     362              89 :     if (nTarget > 0 && nTarget <= psFile->nCurSize)
     363                 :     {
     364                 :         /* Requested location is already in memory... just move the 
     365                 :          * read pointer
     366                 :          */
     367              36 :         psFile->nCurPos = nTarget;
     368                 :     }
     369                 :     else
     370                 :     {
     371                 :         /* Requested location is not part of the memory buffer...
     372                 :          * move the FILE * to the right location and be ready to 
     373                 :          * read from there.
     374                 :          */
     375              17 :         VSIFSeek(psFile->fp, psFile->nOffset+nTarget, SEEK_SET);
     376              17 :         psFile->nCurPos = 0;
     377              17 :         psFile->nCurSize = 0;
     378              17 :         psFile->nOffset = psFile->nOffset+nTarget;
     379                 :     }
     380                 : 
     381                 : }
     382                 : 
     383                 : /**********************************************************************
     384                 :  *                          AVCRawBinEOF()
     385                 :  *
     386                 :  * Return TRUE if there is no more data to read from the file or
     387                 :  * FALSE otherwise.
     388                 :  **********************************************************************/
     389                 : GBool AVCRawBinEOF(AVCRawBinFile *psFile)
     390            7966 : {
     391            7966 :     if (psFile == NULL || psFile->fp == NULL)
     392               0 :         return TRUE;
     393                 : 
     394                 :     /* In write access mode, always return TRUE, since we always write
     395                 :      * at EOF for now.
     396                 :      */
     397            7966 :     if (psFile->eAccess != AVCRead && psFile->eAccess != AVCReadWrite)
     398               0 :         return TRUE;
     399                 : 
     400                 :     /* If file data size was specified, then check that we have not 
     401                 :      * passed that point yet...
     402                 :      */
     403            7966 :     if (psFile->nFileDataSize > 0 &&
     404                 :         (psFile->nOffset+psFile->nCurPos) >= psFile->nFileDataSize)
     405               1 :         return TRUE;
     406                 : 
     407                 :     /* If the file pointer has been moved by AVCRawBinFSeek(), then
     408                 :      * we may be at a position past EOF, but VSIFeof() would still
     409                 :      * return FALSE.
     410                 :      * To prevent this situation, if the memory buffer is empty,
     411                 :      * we will try to read 1 byte from the file to force the next
     412                 :      * chunk of data to be loaded (and we'll move the the read pointer
     413                 :      * back by 1 char after of course!).  
     414                 :      * If we are at the end of the file, this will trigger the EOF flag.
     415                 :      */
     416            7965 :     if (psFile->nCurPos == 0 && psFile->nCurSize == 0)
     417                 :     {
     418                 :         GByte c;
     419                 :         /* Set bDisableReadBytesEOFError=TRUE to temporarily disable 
     420                 :          * the EOF error message from AVCRawBinReadBytes().
     421                 :          */
     422               5 :         bDisableReadBytesEOFError = TRUE;
     423               5 :         AVCRawBinReadBytes(psFile, 1, &c);
     424               5 :         bDisableReadBytesEOFError = FALSE;
     425                 : 
     426               5 :         if (psFile->nCurPos > 0)
     427               4 :             AVCRawBinFSeek(psFile, -1, SEEK_CUR);
     428                 :     }
     429                 : 
     430            7965 :     return (psFile->nCurPos == psFile->nCurSize && 
     431                 :             VSIFEof(psFile->fp));
     432                 : }
     433                 : 
     434                 : 
     435                 : /**********************************************************************
     436                 :  *                          AVCRawBinRead<datatype>()
     437                 :  *
     438                 :  * Arc/Info files are binary files with MSB first (Motorola) byte 
     439                 :  * ordering.  The following functions will read from the input file
     440                 :  * and return a value with the bytes ordered properly for the current 
     441                 :  * platform.
     442                 :  **********************************************************************/
     443                 : GInt16  AVCRawBinReadInt16(AVCRawBinFile *psFile)
     444              55 : {
     445                 :     GInt16 n16Value;
     446                 : 
     447              55 :     AVCRawBinReadBytes(psFile, 2, (GByte*)(&n16Value));
     448                 : 
     449              55 :     if (psFile->eByteOrder != geSystemByteOrder)
     450                 :     {
     451              55 :         return (GInt16)CPL_SWAP16(n16Value);
     452                 :     }
     453                 : 
     454               0 :     return n16Value;
     455                 : }
     456                 : 
     457                 : GInt32  AVCRawBinReadInt32(AVCRawBinFile *psFile)
     458            5374 : {
     459                 :     GInt32 n32Value;
     460                 : 
     461            5374 :     AVCRawBinReadBytes(psFile, 4, (GByte*)(&n32Value));
     462                 : 
     463            5374 :     if (psFile->eByteOrder != geSystemByteOrder)
     464                 :     {
     465            5374 :         return (GInt32)CPL_SWAP32(n32Value);
     466                 :     }
     467                 : 
     468               0 :     return n32Value;
     469                 : }
     470                 : 
     471                 : float   AVCRawBinReadFloat(AVCRawBinFile *psFile)
     472              44 : {
     473                 :     float fValue;
     474                 : 
     475              44 :     AVCRawBinReadBytes(psFile, 4, (GByte*)(&fValue));
     476                 : 
     477              44 :     if (psFile->eByteOrder != geSystemByteOrder)
     478                 :     {
     479              44 :         CPL_SWAP32PTR( &fValue );
     480                 :     }
     481                 : 
     482              44 :     return fValue;
     483                 : }
     484                 : 
     485                 : double  AVCRawBinReadDouble(AVCRawBinFile *psFile)
     486               0 : {
     487                 :     double dValue;
     488                 : 
     489               0 :     AVCRawBinReadBytes(psFile, 8, (GByte*)(&dValue));
     490                 : 
     491               0 :     if (psFile->eByteOrder != geSystemByteOrder)
     492                 :     {
     493               0 :         CPL_SWAPDOUBLE(&dValue);
     494                 :     }
     495                 : 
     496               0 :     return dValue;
     497                 : }
     498                 : 
     499                 : 
     500                 : 
     501                 : /**********************************************************************
     502                 :  *                          AVCRawBinWriteBytes()
     503                 :  *
     504                 :  * Write the number of bytes from the buffer to the file.
     505                 :  *
     506                 :  * If a problem happens, then CPLError() will be called and 
     507                 :  * CPLGetLastErrNo() can be used to test if a write operation was 
     508                 :  * succesful.
     509                 :  **********************************************************************/
     510                 : void AVCRawBinWriteBytes(AVCRawBinFile *psFile, int nBytesToWrite, 
     511                 :                          const GByte *pBuf)
     512               0 : {
     513                 :     /*----------------------------------------------------------------
     514                 :      * Make sure file is opened with Write access
     515                 :      *---------------------------------------------------------------*/
     516               0 :     if (psFile == NULL || 
     517                 :         (psFile->eAccess != AVCWrite && psFile->eAccess != AVCReadWrite))
     518                 :     {
     519               0 :         CPLError(CE_Failure, CPLE_FileIO,
     520                 :               "AVCRawBinWriteBytes(): call not compatible with access mode.");
     521               0 :         return;
     522                 :     }
     523                 : 
     524               0 :     if (VSIFWrite((void*)pBuf, nBytesToWrite, 1, psFile->fp) != 1)
     525               0 :         CPLError(CE_Failure, CPLE_FileIO,
     526                 :                  "Writing to %s failed.", psFile->pszFname);
     527                 : 
     528                 :     /*----------------------------------------------------------------
     529                 :      * In write mode, we keep track of current file position ( =nbr of
     530                 :      * bytes written) through psFile->nCurPos
     531                 :      *---------------------------------------------------------------*/
     532               0 :     psFile->nCurPos += nBytesToWrite;
     533                 : }
     534                 : 
     535                 : 
     536                 : /**********************************************************************
     537                 :  *                          AVCRawBinWrite<datatype>()
     538                 :  *
     539                 :  * Arc/Info files are binary files with MSB first (Motorola) byte 
     540                 :  * ordering.  The following functions will reorder the byte for the
     541                 :  * value properly and write that to the output file.
     542                 :  *
     543                 :  * If a problem happens, then CPLError() will be called and 
     544                 :  * CPLGetLastErrNo() can be used to test if a write operation was 
     545                 :  * succesful.
     546                 :  **********************************************************************/
     547                 : void  AVCRawBinWriteInt16(AVCRawBinFile *psFile, GInt16 n16Value)
     548               0 : {
     549               0 :     if (psFile->eByteOrder != geSystemByteOrder)
     550                 :     {
     551               0 :         n16Value = (GInt16)CPL_SWAP16(n16Value);
     552                 :     }
     553                 : 
     554               0 :     AVCRawBinWriteBytes(psFile, 2, (GByte*)&n16Value);
     555               0 : }
     556                 : 
     557                 : void  AVCRawBinWriteInt32(AVCRawBinFile *psFile, GInt32 n32Value)
     558               0 : {
     559               0 :     if (psFile->eByteOrder != geSystemByteOrder)
     560                 :     {
     561               0 :         n32Value = (GInt32)CPL_SWAP32(n32Value);
     562                 :     }
     563                 : 
     564               0 :     AVCRawBinWriteBytes(psFile, 4, (GByte*)&n32Value);
     565               0 : }
     566                 : 
     567                 : void  AVCRawBinWriteFloat(AVCRawBinFile *psFile, float fValue)
     568               0 : {
     569               0 :     if (psFile->eByteOrder != geSystemByteOrder)
     570                 :     {
     571               0 :         CPL_SWAP32PTR( &fValue );
     572                 :     }
     573                 : 
     574               0 :     AVCRawBinWriteBytes(psFile, 4, (GByte*)&fValue);
     575               0 : }
     576                 : 
     577                 : void  AVCRawBinWriteDouble(AVCRawBinFile *psFile, double dValue)
     578               0 : {
     579               0 :     if (psFile->eByteOrder != geSystemByteOrder)
     580                 :     {
     581               0 :         CPL_SWAPDOUBLE(&dValue);
     582                 :     }
     583                 : 
     584               0 :     AVCRawBinWriteBytes(psFile, 8, (GByte*)&dValue);
     585               0 : }
     586                 : 
     587                 : 
     588                 : /**********************************************************************
     589                 :  *                          AVCRawBinWriteZeros()
     590                 :  *
     591                 :  * Write a number of zeros (sepcified in bytes) at the current position 
     592                 :  * in the file.
     593                 :  *
     594                 :  * If a problem happens, then CPLError() will be called and 
     595                 :  * CPLGetLastErrNo() can be used to test if a write operation was 
     596                 :  * succesful.
     597                 :  **********************************************************************/
     598                 : void AVCRawBinWriteZeros(AVCRawBinFile *psFile, int nBytesToWrite)
     599               0 : {
     600               0 :     char acZeros[8] = {0, 0, 0, 0, 0, 0, 0, 0};
     601                 :     int i;
     602                 : 
     603                 :     /* Write by 8 bytes chunks.  The last chunk may be less than 8 bytes 
     604                 :      */
     605               0 :     for(i=0; i< nBytesToWrite; i+=8)
     606                 :     {
     607               0 :         AVCRawBinWriteBytes(psFile, MIN(8,(nBytesToWrite-i)), 
     608                 :                             (GByte*)acZeros);
     609                 :     }
     610               0 : }
     611                 : 
     612                 : /**********************************************************************
     613                 :  *                          AVCRawBinWritePaddedString()
     614                 :  *
     615                 :  * Write a string and pad the end of the field (up to nFieldSize) with
     616                 :  * spaces number of spaces at the current position in the file.
     617                 :  *
     618                 :  * If a problem happens, then CPLError() will be called and 
     619                 :  * CPLGetLastErrNo() can be used to test if a write operation was 
     620                 :  * succesful.
     621                 :  **********************************************************************/
     622                 : void AVCRawBinWritePaddedString(AVCRawBinFile *psFile, int nFieldSize,
     623                 :                                 const GByte *pszString)
     624               0 : {
     625               0 :     char acSpaces[8] = {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '};
     626                 :     int i, nLen, numSpaces;
     627                 : 
     628                 :     /* If we're on a system with a multibyte codepage then we have to
     629                 :      * convert strings to the proper multibyte encoding.
     630                 :      */
     631               0 :     pszString = AVCE00Convert2ArcDBCS(psFile->psDBCSInfo,
     632                 :                                       pszString, nFieldSize);
     633                 : 
     634               0 :     nLen = strlen((const char *)pszString);
     635               0 :     nLen = MIN(nLen, nFieldSize);
     636               0 :     numSpaces = nFieldSize - nLen;
     637                 : 
     638               0 :     if (nLen > 0)
     639               0 :         AVCRawBinWriteBytes(psFile, nLen, pszString);
     640                 : 
     641                 :     /* Write spaces by 8 bytes chunks.  The last chunk may be less than 8 bytes
     642                 :      */
     643               0 :     for(i=0; i< numSpaces; i+=8)
     644                 :     {
     645               0 :         AVCRawBinWriteBytes(psFile, MIN(8,(numSpaces-i)), 
     646                 :                             (GByte*)acSpaces);
     647                 :     }
     648               0 : }
     649                 : 

Generated by: LTP GCOV extension version 1.5