LCOV - code coverage report
Current view: top level - frmts/pcidsk/sdk/core - pcidskexception.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 25 42 59.5 %
Date: 2025-06-28 21:28:23 Functions: 4 5 80.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Purpose:  Implementation of the PCIDSKException class.
       4             :  *
       5             :  ******************************************************************************
       6             :  * Copyright (c) 2009
       7             :  * PCI Geomatics, 90 Allstate Parkway, Markham, Ontario, Canada.
       8             :  *
       9             :  * SPDX-License-Identifier: MIT
      10             :  ****************************************************************************/
      11             : 
      12             : #include "pcidsk_config.h"
      13             : #include "pcidsk_types.h"
      14             : #include "pcidsk_buffer.h"
      15             : #include "pcidsk_exception.h"
      16             : #include <cstdlib>
      17             : #include <cstring>
      18             : #include <cstdio>
      19             : #include <cstdarg>
      20             : 
      21             : #if !defined(va_copy) && defined(__va_copy)
      22             : #define va_copy __va_copy
      23             : #endif
      24             : 
      25             : using PCIDSK::PCIDSKException;
      26             : 
      27             : /**
      28             : 
      29             : \class PCIDSK::PCIDSKException
      30             : 
      31             : \brief Generic SDK Exception
      32             : 
      33             : The PCIDSKException class is used for all errors thrown by the PCIDSK
      34             : library.  It includes a formatted message and is derived from std::exception.
      35             : The PCIDSK library throws all exceptions as pointers, and library exceptions
      36             : should be caught like this:
      37             : 
      38             : @code
      39             :     try
      40             :     {
      41             :          PCIDSKFile *file = PCIDSK::Open( "irvine.pix, "r", NULL );
      42             :     }
      43             :     catch( PCIDSK::PCIDSKException &ex )
      44             :     {
      45             :         fprintf( stderr, "PCIDSKException:\n%s\n", ex.what() );
      46             :         exit( 1 );
      47             :     }
      48             : @endcode
      49             : 
      50             : */
      51             : 
      52             : /************************************************************************/
      53             : /*                          PCIDSKException()                           */
      54             : /************************************************************************/
      55             : 
      56             : #if defined(__clang__) && __clang_major__ == 3 && __clang_minor__ <= 2
      57             : #pragma clang diagnostic push
      58             : #pragma clang diagnostic ignored "-Wunknown-pragmas"
      59             : #pragma clang diagnostic ignored "-Wdocumentation"
      60             : #endif
      61             : 
      62             : 
      63             : /**
      64             :  * Create exception with formatted message.
      65             :  *
      66             :  * This constructor supports formatting of an exception message
      67             :  * using printf style format and additional arguments.
      68             :  *
      69             :  * @param fmt the printf style format (eg. "Illegal value:%d")
      70             :  * @param ... additional arguments as required by the format string.
      71             :  */
      72             : 
      73           0 : PCIDSKException::PCIDSKException( const char *fmt, ... )
      74             : 
      75             : {
      76             :     std::va_list args;
      77             : 
      78           0 :     va_start( args, fmt );
      79           0 :     vPrintf( fmt, args );
      80           0 :     va_end( args );
      81           0 : }
      82             : 
      83             : #if defined(__clang__) && __clang_major__ == 3 && __clang_minor__ <= 2
      84             : #pragma clang diagnostic pop
      85             : #endif
      86             : 
      87             : /************************************************************************/
      88             : /*                          ~PCIDSKException()                          */
      89             : /************************************************************************/
      90             : 
      91             : /**
      92             :  * Destructor.
      93             :  */
      94             : 
      95             : PCIDSKException::~PCIDSKException() = default;
      96             : 
      97             : /************************************************************************/
      98             : /*                              vPrintf()                               */
      99             : /************************************************************************/
     100             : 
     101             : /**
     102             :  * Format a message.
     103             :  *
     104             :  * Assigns a message to an exception using printf style formatting
     105             :  * and va_list arguments (similar to vfprintf().
     106             :  *
     107             :  * @param fmt printf style format string.
     108             :  * @param args additional arguments as required.
     109             :  */
     110             : 
     111             : 
     112          56 : void PCIDSKException::vPrintf( const char *fmt, std::va_list args )
     113             : 
     114             : {
     115             : /* -------------------------------------------------------------------- */
     116             : /*      This implementation for platforms without vsnprintf() will      */
     117             : /*      just plain fail if the formatted contents are too large.        */
     118             : /* -------------------------------------------------------------------- */
     119             : 
     120             : #if defined(MISSING_VSNPRINTF)
     121             :     char *pszBuffer = (char *) malloc(30000);
     122             :     if( vsprintf( pszBuffer, fmt, args) > 29998 )
     123             :     {
     124             :         message = "PCIDSKException::vPrintf() ... buffer overrun.";
     125             :     }
     126             :     else
     127             :         message = pszBuffer;
     128             : 
     129             :     free( pszBuffer );
     130             : 
     131             : /* -------------------------------------------------------------------- */
     132             : /*      This should grow a big enough buffer to hold any formatted      */
     133             : /*      result.                                                         */
     134             : /* -------------------------------------------------------------------- */
     135             : #else
     136             :     char szModestBuffer[500];
     137             :     int nPR;
     138             :     va_list wrk_args;
     139             : 
     140             : #ifdef va_copy
     141          56 :     va_copy( wrk_args, args );
     142             : #else
     143             :     wrk_args = args;
     144             : #endif
     145             : 
     146          56 :     nPR = vsnprintf( szModestBuffer, sizeof(szModestBuffer), fmt,
     147             :                      wrk_args );
     148          56 :     if( nPR == -1 || nPR >= (int) sizeof(szModestBuffer)-1 )
     149             :     {
     150           0 :         int nWorkBufferSize = 2000;
     151           0 :         PCIDSKBuffer oWorkBuffer(nWorkBufferSize);
     152             : 
     153             : #ifdef va_copy
     154           0 :         va_end( wrk_args );
     155           0 :         va_copy( wrk_args, args );
     156             : #else
     157             :         wrk_args = args;
     158             : #endif
     159           0 :         while( (nPR=vsnprintf( oWorkBuffer.buffer, nWorkBufferSize, fmt, wrk_args))
     160           0 :                >= nWorkBufferSize-1
     161           0 :                || nPR == -1 )
     162             :         {
     163           0 :             nWorkBufferSize *= 4;
     164           0 :             oWorkBuffer.SetSize(nWorkBufferSize);
     165             : #ifdef va_copy
     166           0 :             va_end( wrk_args );
     167           0 :             va_copy( wrk_args, args );
     168             : #else
     169             :             wrk_args = args;
     170             : #endif
     171             :         }
     172           0 :         message = oWorkBuffer.buffer;
     173             :     }
     174             :     else
     175             :     {
     176          56 :         message = szModestBuffer;
     177             :     }
     178          56 :     va_end( wrk_args );
     179             : #endif
     180          56 : }
     181             : 
     182             : /**
     183             :  * \fn const char *PCIDSKException::what() const throw();
     184             :  *
     185             :  * \brief fetch exception message.
     186             :  *
     187             :  * @return a pointer to the internal message associated with the exception.
     188             :  */
     189             : 
     190             : #if defined(__clang__) && __clang_major__ == 3 && __clang_minor__ <= 2
     191             : #pragma clang diagnostic push
     192             : #pragma clang diagnostic ignored "-Wunknown-pragmas"
     193             : #pragma clang diagnostic ignored "-Wdocumentation"
     194             : #endif
     195             : 
     196             : /**
     197             :  * \brief throw a formatted exception.
     198             :  *
     199             :  * This function throws a PCIDSK Exception by reference after formatting
     200             :  * the message using the given printf style format and arguments.  This
     201             :  * function exists primarily so that throwing an exception can be done in
     202             :  * one line of code, instead of declaring an exception and then throwing it.
     203             :  *
     204             :  * @param fmt the printf style format (eg. "Illegal value:%d")
     205             :  * @param ... additional arguments as required by the format string.
     206             :  */
     207          40 : void PCIDSK::ThrowPCIDSKException( const char *fmt, ... )
     208             : 
     209             : {
     210             :     std::va_list args;
     211          80 :     PCIDSKException ex;
     212             : 
     213          40 :     va_start( args, fmt );
     214          40 :     ex.vPrintf( fmt, args );
     215          40 :     va_end( args );
     216             : 
     217          40 :     throw ex;
     218             : }
     219             : 
     220             : #if defined(__clang__) && __clang_major__ == 3 && __clang_minor__ <= 2
     221             : #pragma clang diagnostic pop
     222             : #endif
     223             : 
     224             : 
     225          15 : int PCIDSK::ThrowPCIDSKException( int /*ret_unused*/, const char *fmt, ... )
     226             : 
     227             : {
     228             :     std::va_list args;
     229          30 :     PCIDSKException ex;
     230             : 
     231          15 :     va_start( args, fmt );
     232          15 :     ex.vPrintf( fmt, args );
     233          15 :     va_end( args );
     234             : 
     235          15 :     throw ex;
     236             : }
     237             : 
     238           1 : void* PCIDSK::ThrowPCIDSKExceptionPtr( const char *fmt, ... )
     239             : 
     240             : {
     241             :     std::va_list args;
     242           2 :     PCIDSKException ex;
     243             : 
     244           1 :     va_start( args, fmt );
     245           1 :     ex.vPrintf( fmt, args );
     246           1 :     va_end( args );
     247             : 
     248           1 :     throw ex;
     249             : }

Generated by: LCOV version 1.14