LCOV - code coverage report
Current view: top level - frmts/pcidsk/sdk/core - pcidskbuffer.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 77 100 77.0 %
Date: 2024-05-03 15:49:35 Functions: 13 15 86.7 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Purpose:  Implementation of the PCIDSKBuffer class.  This class is for
       4             :  *           convenient parsing and formatting of PCIDSK ASCII headers.
       5             :  *
       6             :  ******************************************************************************
       7             :  * Copyright (c) 2009
       8             :  * PCI Geomatics, 90 Allstate Parkway, Markham, Ontario, Canada.
       9             :  *
      10             :  * Permission is hereby granted, free of charge, to any person obtaining a
      11             :  * copy of this software and associated documentation files (the "Software"),
      12             :  * to deal in the Software without restriction, including without limitation
      13             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      14             :  * and/or sell copies of the Software, and to permit persons to whom the
      15             :  * Software is furnished to do so, subject to the following conditions:
      16             :  *
      17             :  * The above copyright notice and this permission notice shall be included
      18             :  * in all copies or substantial portions of the Software.
      19             :  *
      20             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      21             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      22             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      23             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      24             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      25             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      26             :  * DEALINGS IN THE SOFTWARE.
      27             :  ****************************************************************************/
      28             : 
      29             : #include "pcidsk_config.h"
      30             : #include "pcidsk_buffer.h"
      31             : #include "pcidsk_exception.h"
      32             : #include "core/pcidsk_utils.h"
      33             : 
      34             : #include <cstdlib>
      35             : #include <cstring>
      36             : #include <cstdio>
      37             : #include <sstream>
      38             : 
      39             : using namespace PCIDSK;
      40             : 
      41             : /************************************************************************/
      42             : /*                            PCIDSKBuffer()                            */
      43             : /************************************************************************/
      44             : 
      45       13220 : PCIDSKBuffer::PCIDSKBuffer( int size )
      46             : 
      47             : {
      48       13220 :     buffer_size = 0;
      49       13220 :     buffer = nullptr;
      50             : 
      51       13220 :     if( size > 0 )
      52        7609 :         SetSize( size );
      53       13220 : }
      54             : 
      55             : /************************************************************************/
      56             : /*                            PCIDSKBuffer()                            */
      57             : /************************************************************************/
      58             : 
      59        2648 : PCIDSKBuffer::PCIDSKBuffer( const char *src, int size )
      60             : 
      61             : {
      62        2648 :     buffer_size = 0;
      63        2648 :     buffer = nullptr;
      64             : 
      65        2648 :     SetSize( size );
      66        2648 :     memcpy( buffer, src, size );
      67        2648 : }
      68             : 
      69             : /************************************************************************/
      70             : /*                           ~PCIDSKBuffer()                            */
      71             : /************************************************************************/
      72             : 
      73       31736 : PCIDSKBuffer::~PCIDSKBuffer()
      74             : 
      75             : {
      76       15868 :     free( buffer );
      77       15868 : }
      78             : 
      79             : /************************************************************************/
      80             : /*                              SetSize()                               */
      81             : /************************************************************************/
      82             : 
      83       14305 : void PCIDSKBuffer::SetSize( int size )
      84             : 
      85             : {
      86       14305 :     if( size < 0 )
      87             :     {
      88           0 :         free( buffer );
      89           0 :         buffer = nullptr;
      90           0 :         buffer_size = 0;
      91           0 :         throw PCIDSKException( "Invalid buffer size: %d", size );
      92             :     }
      93       14305 :     buffer_size = size;
      94       14305 :     char* new_buffer = (char *) realloc(buffer,size+1);
      95             : 
      96       14305 :     if( new_buffer == nullptr )
      97             :     {
      98           0 :         free( buffer );
      99           0 :         buffer = nullptr;
     100           0 :         buffer_size = 0;
     101             :         throw PCIDSKException( "Out of memory allocating %d byte PCIDSKBuffer.",
     102           0 :                                size );
     103             :     }
     104             : 
     105       14305 :     buffer = new_buffer;
     106       14305 :     buffer[size] = '\0';
     107       14305 : }
     108             : 
     109             : /************************************************************************/
     110             : /*                                Get()                                 */
     111             : /************************************************************************/
     112             : 
     113       13788 : const char *PCIDSKBuffer::Get( int offset, int size ) const
     114             : 
     115             : {
     116       13788 :     Get( offset, size, work_field, 0 );
     117       13788 :     return work_field.c_str();
     118             : }
     119             : 
     120             : /************************************************************************/
     121             : /*                                Get()                                 */
     122             : /************************************************************************/
     123             : 
     124       32982 : void PCIDSKBuffer::Get( int offset, int size, std::string &target, int unpad ) const
     125             : 
     126             : {
     127       32982 :     if( offset + size > buffer_size )
     128           0 :         return ThrowPCIDSKException( "Get() past end of PCIDSKBuffer." );
     129             : 
     130       32982 :     if( unpad )
     131             :     {
     132     1161210 :         while( size > 0 && buffer[offset+size-1] == ' ' )
     133     1143200 :             size--;
     134             :     }
     135             : 
     136       32982 :     target.assign( buffer + offset, size );
     137             : }
     138             : 
     139             : /************************************************************************/
     140             : /*                             GetUInt64()                              */
     141             : /************************************************************************/
     142             : 
     143      535824 : uint64 PCIDSKBuffer::GetUInt64( int offset, int size ) const
     144             : 
     145             : {
     146     1071650 :     std::string value_str;
     147             : 
     148      535824 :     if( offset + size > buffer_size )
     149           0 :         return ThrowPCIDSKException(0, "GetUInt64() past end of PCIDSKBuffer." );
     150             : 
     151      535824 :     value_str.assign( buffer + offset, size );
     152             : 
     153      535824 :     return atouint64(value_str.c_str());
     154             : }
     155             : 
     156             : /************************************************************************/
     157             : /*                               GetInt()                               */
     158             : /************************************************************************/
     159             : 
     160        5958 : int PCIDSKBuffer::GetInt( int offset, int size ) const
     161             : 
     162             : {
     163       11916 :     std::string value_str;
     164             : 
     165        5958 :     if( offset + size > buffer_size )
     166           0 :         return ThrowPCIDSKException(0, "GetInt() past end of PCIDSKBuffer." );
     167             : 
     168        5958 :     value_str.assign( buffer + offset, size );
     169             : 
     170        5958 :     return atoi(value_str.c_str());
     171             : }
     172             : 
     173             : /************************************************************************/
     174             : /*                             GetDouble()                              */
     175             : /************************************************************************/
     176             : 
     177        5903 : double PCIDSKBuffer::GetDouble( int offset, int size ) const
     178             : 
     179             : {
     180       11806 :     std::string value_str;
     181             : 
     182        5903 :     if( offset + size > buffer_size )
     183           0 :         return ThrowPCIDSKException(0, "GetDouble() past end of PCIDSKBuffer." );
     184             : 
     185        5903 :     value_str.assign( buffer + offset, size );
     186             : 
     187             : /* -------------------------------------------------------------------- */
     188             : /*      PCIDSK uses FORTRAN 'D' format for doubles - convert to 'E'     */
     189             : /*      (C style) before calling CPLAtof.                                  */
     190             : /* -------------------------------------------------------------------- */
     191             :     int i;
     192             : 
     193      159381 :     for( i = 0; i < size; i++ )
     194             :     {
     195      153478 :         if( value_str[i] == 'D' )
     196        4883 :             value_str[i] = 'E';
     197             :     }
     198             : 
     199        5903 :     return CPLAtof(value_str.c_str());
     200             : }
     201             : 
     202             : /************************************************************************/
     203             : /*                                Put()                                 */
     204             : /************************************************************************/
     205             : 
     206       43010 : void PCIDSKBuffer::Put( const char *value, int offset, int size, bool null_term )
     207             : 
     208             : {
     209       43010 :     if( offset + size > buffer_size )
     210           0 :         return ThrowPCIDSKException( "Put() past end of PCIDSKBuffer." );
     211             : 
     212       43010 :     int v_size = static_cast<int>(strlen(value));
     213       43010 :     if( v_size > size )
     214          51 :         v_size = size;
     215             : 
     216       43010 :     if( v_size < size )
     217       10941 :         memset( buffer + offset, ' ', size );
     218             : 
     219       43010 :     memcpy( buffer + offset, value, v_size );
     220             : 
     221       43010 :     if (null_term)
     222             :     {
     223           0 :         *(buffer + offset + v_size) = '\0';
     224             :     }
     225             : }
     226             : 
     227             : /************************************************************************/
     228             : /*                            PutBin(double)                            */
     229             : /************************************************************************/
     230             : 
     231           0 : void PCIDSKBuffer::PutBin(double value, int offset)
     232             : {
     233           0 :     const char* pszValue = (const char*)&value;
     234           0 :     memcpy( buffer + offset, pszValue, 8 );
     235           0 : }
     236             : 
     237             : /************************************************************************/
     238             : /*                              PutBin(int16)                           */
     239             : /************************************************************************/
     240             : 
     241         833 : void PCIDSKBuffer::PutBin(int16 value, int offset)
     242             : {
     243         833 :     const char * pszValue = (const char *) &value;
     244             : 
     245         833 :     memcpy(buffer + offset, pszValue, sizeof(int16));
     246         833 : }
     247             : 
     248             : /************************************************************************/
     249             : /*                             Put(uint64)                              */
     250             : /************************************************************************/
     251             : 
     252       16116 : void PCIDSKBuffer::Put( uint64 value, int offset, int size )
     253             : 
     254             : {
     255             :     char fmt[64];
     256             :     char wrk[128];
     257             : 
     258       16116 :     snprintf( fmt, sizeof(fmt), "%%%d%sd", size, PCIDSK_FRMT_64_WITHOUT_PREFIX );
     259       16116 :     snprintf( wrk, sizeof(wrk), fmt, value );
     260             : 
     261       16116 :     Put( wrk, offset, size );
     262       16116 : }
     263             : 
     264             : /************************************************************************/
     265             : /*                             Put(double)                              */
     266             : /************************************************************************/
     267             : 
     268       12386 : void PCIDSKBuffer::Put( double value, int offset, int size,
     269             :                         const char *fmt )
     270             : 
     271             : {
     272       12386 :     if( fmt == nullptr )
     273        1088 :         fmt = "%g";
     274             : 
     275             :     char wrk[128];
     276       12386 :     CPLsnprintf( wrk, 127, fmt, value );
     277             : 
     278       12386 :     char *exponent = strstr(wrk,"E");
     279       12386 :     if( exponent != nullptr )
     280       10346 :         *exponent = 'D';
     281             : 
     282       12386 :     Put( wrk, offset, size );
     283       12386 : }
     284             : 
     285             : /************************************************************************/
     286             : /*                             operator=()                              */
     287             : /************************************************************************/
     288             : 
     289           0 : PCIDSKBuffer &PCIDSKBuffer::operator=( const PCIDSKBuffer &src )
     290             : 
     291             : {
     292           0 :     if( this != &src )
     293             :     {
     294           0 :         SetSize( src.buffer_size );
     295           0 :         memcpy( buffer, src.buffer, buffer_size );
     296             :     }
     297             : 
     298           0 :     return *this;
     299             : }

Generated by: LCOV version 1.14