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-11-21 22:18:42 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             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #include "pcidsk_config.h"
      14             : #include "pcidsk_buffer.h"
      15             : #include "pcidsk_exception.h"
      16             : #include "core/pcidsk_utils.h"
      17             : 
      18             : #include <cstdlib>
      19             : #include <cstring>
      20             : #include <cstdio>
      21             : #include <sstream>
      22             : 
      23             : using namespace PCIDSK;
      24             : 
      25             : /************************************************************************/
      26             : /*                            PCIDSKBuffer()                            */
      27             : /************************************************************************/
      28             : 
      29       13220 : PCIDSKBuffer::PCIDSKBuffer( int size )
      30             : 
      31             : {
      32       13220 :     buffer_size = 0;
      33       13220 :     buffer = nullptr;
      34             : 
      35       13220 :     if( size > 0 )
      36        7609 :         SetSize( size );
      37       13220 : }
      38             : 
      39             : /************************************************************************/
      40             : /*                            PCIDSKBuffer()                            */
      41             : /************************************************************************/
      42             : 
      43        2648 : PCIDSKBuffer::PCIDSKBuffer( const char *src, int size )
      44             : 
      45             : {
      46        2648 :     buffer_size = 0;
      47        2648 :     buffer = nullptr;
      48             : 
      49        2648 :     SetSize( size );
      50        2648 :     memcpy( buffer, src, size );
      51        2648 : }
      52             : 
      53             : /************************************************************************/
      54             : /*                           ~PCIDSKBuffer()                            */
      55             : /************************************************************************/
      56             : 
      57       31736 : PCIDSKBuffer::~PCIDSKBuffer()
      58             : 
      59             : {
      60       15868 :     free( buffer );
      61       15868 : }
      62             : 
      63             : /************************************************************************/
      64             : /*                              SetSize()                               */
      65             : /************************************************************************/
      66             : 
      67       14305 : void PCIDSKBuffer::SetSize( int size )
      68             : 
      69             : {
      70       14305 :     if( size < 0 )
      71             :     {
      72           0 :         free( buffer );
      73           0 :         buffer = nullptr;
      74           0 :         buffer_size = 0;
      75           0 :         throw PCIDSKException( "Invalid buffer size: %d", size );
      76             :     }
      77       14305 :     buffer_size = size;
      78       14305 :     char* new_buffer = (char *) realloc(buffer,size+1);
      79             : 
      80       14305 :     if( new_buffer == nullptr )
      81             :     {
      82           0 :         free( buffer );
      83           0 :         buffer = nullptr;
      84           0 :         buffer_size = 0;
      85             :         throw PCIDSKException( "Out of memory allocating %d byte PCIDSKBuffer.",
      86           0 :                                size );
      87             :     }
      88             : 
      89       14305 :     buffer = new_buffer;
      90       14305 :     buffer[size] = '\0';
      91       14305 : }
      92             : 
      93             : /************************************************************************/
      94             : /*                                Get()                                 */
      95             : /************************************************************************/
      96             : 
      97       13788 : const char *PCIDSKBuffer::Get( int offset, int size ) const
      98             : 
      99             : {
     100       13788 :     Get( offset, size, work_field, 0 );
     101       13788 :     return work_field.c_str();
     102             : }
     103             : 
     104             : /************************************************************************/
     105             : /*                                Get()                                 */
     106             : /************************************************************************/
     107             : 
     108       32982 : void PCIDSKBuffer::Get( int offset, int size, std::string &target, int unpad ) const
     109             : 
     110             : {
     111       32982 :     if( offset + size > buffer_size )
     112           0 :         return ThrowPCIDSKException( "Get() past end of PCIDSKBuffer." );
     113             : 
     114       32982 :     if( unpad )
     115             :     {
     116     1161210 :         while( size > 0 && buffer[offset+size-1] == ' ' )
     117     1143200 :             size--;
     118             :     }
     119             : 
     120       32982 :     target.assign( buffer + offset, size );
     121             : }
     122             : 
     123             : /************************************************************************/
     124             : /*                             GetUInt64()                              */
     125             : /************************************************************************/
     126             : 
     127      535824 : uint64 PCIDSKBuffer::GetUInt64( int offset, int size ) const
     128             : 
     129             : {
     130     1071650 :     std::string value_str;
     131             : 
     132      535824 :     if( offset + size > buffer_size )
     133           0 :         return ThrowPCIDSKException(0, "GetUInt64() past end of PCIDSKBuffer." );
     134             : 
     135      535824 :     value_str.assign( buffer + offset, size );
     136             : 
     137      535824 :     return atouint64(value_str.c_str());
     138             : }
     139             : 
     140             : /************************************************************************/
     141             : /*                               GetInt()                               */
     142             : /************************************************************************/
     143             : 
     144        5958 : int PCIDSKBuffer::GetInt( int offset, int size ) const
     145             : 
     146             : {
     147       11916 :     std::string value_str;
     148             : 
     149        5958 :     if( offset + size > buffer_size )
     150           0 :         return ThrowPCIDSKException(0, "GetInt() past end of PCIDSKBuffer." );
     151             : 
     152        5958 :     value_str.assign( buffer + offset, size );
     153             : 
     154        5958 :     return atoi(value_str.c_str());
     155             : }
     156             : 
     157             : /************************************************************************/
     158             : /*                             GetDouble()                              */
     159             : /************************************************************************/
     160             : 
     161        5903 : double PCIDSKBuffer::GetDouble( int offset, int size ) const
     162             : 
     163             : {
     164       11806 :     std::string value_str;
     165             : 
     166        5903 :     if( offset + size > buffer_size )
     167           0 :         return ThrowPCIDSKException(0, "GetDouble() past end of PCIDSKBuffer." );
     168             : 
     169        5903 :     value_str.assign( buffer + offset, size );
     170             : 
     171             : /* -------------------------------------------------------------------- */
     172             : /*      PCIDSK uses FORTRAN 'D' format for doubles - convert to 'E'     */
     173             : /*      (C style) before calling CPLAtof.                                  */
     174             : /* -------------------------------------------------------------------- */
     175             :     int i;
     176             : 
     177      159381 :     for( i = 0; i < size; i++ )
     178             :     {
     179      153478 :         if( value_str[i] == 'D' )
     180        4883 :             value_str[i] = 'E';
     181             :     }
     182             : 
     183        5903 :     return CPLAtof(value_str.c_str());
     184             : }
     185             : 
     186             : /************************************************************************/
     187             : /*                                Put()                                 */
     188             : /************************************************************************/
     189             : 
     190       43010 : void PCIDSKBuffer::Put( const char *value, int offset, int size, bool null_term )
     191             : 
     192             : {
     193       43010 :     if( offset + size > buffer_size )
     194           0 :         return ThrowPCIDSKException( "Put() past end of PCIDSKBuffer." );
     195             : 
     196       43010 :     int v_size = static_cast<int>(strlen(value));
     197       43010 :     if( v_size > size )
     198          51 :         v_size = size;
     199             : 
     200       43010 :     if( v_size < size )
     201       10941 :         memset( buffer + offset, ' ', size );
     202             : 
     203       43010 :     memcpy( buffer + offset, value, v_size );
     204             : 
     205       43010 :     if (null_term)
     206             :     {
     207           0 :         *(buffer + offset + v_size) = '\0';
     208             :     }
     209             : }
     210             : 
     211             : /************************************************************************/
     212             : /*                            PutBin(double)                            */
     213             : /************************************************************************/
     214             : 
     215           0 : void PCIDSKBuffer::PutBin(double value, int offset)
     216             : {
     217           0 :     const char* pszValue = (const char*)&value;
     218           0 :     memcpy( buffer + offset, pszValue, 8 );
     219           0 : }
     220             : 
     221             : /************************************************************************/
     222             : /*                              PutBin(int16)                           */
     223             : /************************************************************************/
     224             : 
     225         833 : void PCIDSKBuffer::PutBin(int16 value, int offset)
     226             : {
     227         833 :     const char * pszValue = (const char *) &value;
     228             : 
     229         833 :     memcpy(buffer + offset, pszValue, sizeof(int16));
     230         833 : }
     231             : 
     232             : /************************************************************************/
     233             : /*                             Put(uint64)                              */
     234             : /************************************************************************/
     235             : 
     236       16116 : void PCIDSKBuffer::Put( uint64 value, int offset, int size )
     237             : 
     238             : {
     239             :     char fmt[64];
     240             :     char wrk[128];
     241             : 
     242       16116 :     snprintf( fmt, sizeof(fmt), "%%%d%sd", size, PCIDSK_FRMT_64_WITHOUT_PREFIX );
     243       16116 :     snprintf( wrk, sizeof(wrk), fmt, value );
     244             : 
     245       16116 :     Put( wrk, offset, size );
     246       16116 : }
     247             : 
     248             : /************************************************************************/
     249             : /*                             Put(double)                              */
     250             : /************************************************************************/
     251             : 
     252       12386 : void PCIDSKBuffer::Put( double value, int offset, int size,
     253             :                         const char *fmt )
     254             : 
     255             : {
     256       12386 :     if( fmt == nullptr )
     257        1088 :         fmt = "%g";
     258             : 
     259             :     char wrk[128];
     260       12386 :     CPLsnprintf( wrk, 127, fmt, value );
     261             : 
     262       12386 :     char *exponent = strstr(wrk,"E");
     263       12386 :     if( exponent != nullptr )
     264       10346 :         *exponent = 'D';
     265             : 
     266       12386 :     Put( wrk, offset, size );
     267       12386 : }
     268             : 
     269             : /************************************************************************/
     270             : /*                             operator=()                              */
     271             : /************************************************************************/
     272             : 
     273           0 : PCIDSKBuffer &PCIDSKBuffer::operator=( const PCIDSKBuffer &src )
     274             : 
     275             : {
     276           0 :     if( this != &src )
     277             :     {
     278           0 :         SetSize( src.buffer_size );
     279           0 :         memcpy( buffer, src.buffer, buffer_size );
     280             :     }
     281             : 
     282           0 :     return *this;
     283             : }

Generated by: LCOV version 1.14