LCOV - code coverage report
Current view: top level - frmts/pcidsk/sdk/core - pcidskexception.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 27 44 61.4 %
Date: 2024-11-21 22:18:42 Functions: 5 7 71.4 %

          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         112 : PCIDSKException::~PCIDSKException() throw()
      96             : 
      97             : {
      98         112 : }
      99             : 
     100             : /************************************************************************/
     101             : /*                              vPrintf()                               */
     102             : /************************************************************************/
     103             : 
     104             : /**
     105             :  * Format a message.
     106             :  *
     107             :  * Assigns a message to an exception using printf style formatting
     108             :  * and va_list arguments (similar to vfprintf().
     109             :  *
     110             :  * @param fmt printf style format string.
     111             :  * @param args additional arguments as required.
     112             :  */
     113             : 
     114             : 
     115          56 : void PCIDSKException::vPrintf( const char *fmt, std::va_list args )
     116             : 
     117             : {
     118             : /* -------------------------------------------------------------------- */
     119             : /*      This implementation for platforms without vsnprintf() will      */
     120             : /*      just plain fail if the formatted contents are too large.        */
     121             : /* -------------------------------------------------------------------- */
     122             : 
     123             : #if defined(MISSING_VSNPRINTF)
     124             :     char *pszBuffer = (char *) malloc(30000);
     125             :     if( vsprintf( pszBuffer, fmt, args) > 29998 )
     126             :     {
     127             :         message = "PCIDSKException::vPrintf() ... buffer overrun.";
     128             :     }
     129             :     else
     130             :         message = pszBuffer;
     131             : 
     132             :     free( pszBuffer );
     133             : 
     134             : /* -------------------------------------------------------------------- */
     135             : /*      This should grow a big enough buffer to hold any formatted      */
     136             : /*      result.                                                         */
     137             : /* -------------------------------------------------------------------- */
     138             : #else
     139             :     char szModestBuffer[500];
     140             :     int nPR;
     141             :     va_list wrk_args;
     142             : 
     143             : #ifdef va_copy
     144          56 :     va_copy( wrk_args, args );
     145             : #else
     146             :     wrk_args = args;
     147             : #endif
     148             : 
     149          56 :     nPR = vsnprintf( szModestBuffer, sizeof(szModestBuffer), fmt,
     150             :                      wrk_args );
     151          56 :     if( nPR == -1 || nPR >= (int) sizeof(szModestBuffer)-1 )
     152             :     {
     153           0 :         int nWorkBufferSize = 2000;
     154           0 :         PCIDSKBuffer oWorkBuffer(nWorkBufferSize);
     155             : 
     156             : #ifdef va_copy
     157           0 :         va_end( wrk_args );
     158           0 :         va_copy( wrk_args, args );
     159             : #else
     160             :         wrk_args = args;
     161             : #endif
     162           0 :         while( (nPR=vsnprintf( oWorkBuffer.buffer, nWorkBufferSize, fmt, wrk_args))
     163           0 :                >= nWorkBufferSize-1
     164           0 :                || nPR == -1 )
     165             :         {
     166           0 :             nWorkBufferSize *= 4;
     167           0 :             oWorkBuffer.SetSize(nWorkBufferSize);
     168             : #ifdef va_copy
     169           0 :             va_end( wrk_args );
     170           0 :             va_copy( wrk_args, args );
     171             : #else
     172             :             wrk_args = args;
     173             : #endif
     174             :         }
     175           0 :         message = oWorkBuffer.buffer;
     176             :     }
     177             :     else
     178             :     {
     179          56 :         message = szModestBuffer;
     180             :     }
     181          56 :     va_end( wrk_args );
     182             : #endif
     183          56 : }
     184             : 
     185             : /**
     186             :  * \fn const char *PCIDSKException::what() const throw();
     187             :  *
     188             :  * \brief fetch exception message.
     189             :  *
     190             :  * @return a pointer to the internal message associated with the exception.
     191             :  */
     192             : 
     193             : #if defined(__clang__) && __clang_major__ == 3 && __clang_minor__ <= 2
     194             : #pragma clang diagnostic push
     195             : #pragma clang diagnostic ignored "-Wunknown-pragmas"
     196             : #pragma clang diagnostic ignored "-Wdocumentation"
     197             : #endif
     198             : 
     199             : /**
     200             :  * \brief throw a formatted exception.
     201             :  *
     202             :  * This function throws a PCIDSK Exception by reference after formatting
     203             :  * the message using the given printf style format and arguments.  This
     204             :  * function exists primarily so that throwing an exception can be done in
     205             :  * one line of code, instead of declaring an exception and then throwing it.
     206             :  *
     207             :  * @param fmt the printf style format (eg. "Illegal value:%d")
     208             :  * @param ... additional arguments as required by the format string.
     209             :  */
     210          40 : void PCIDSK::ThrowPCIDSKException( const char *fmt, ... )
     211             : 
     212             : {
     213             :     std::va_list args;
     214          80 :     PCIDSKException ex;
     215             : 
     216          40 :     va_start( args, fmt );
     217          40 :     ex.vPrintf( fmt, args );
     218          40 :     va_end( args );
     219             : 
     220          40 :     throw ex;
     221             : }
     222             : 
     223             : #if defined(__clang__) && __clang_major__ == 3 && __clang_minor__ <= 2
     224             : #pragma clang diagnostic pop
     225             : #endif
     226             : 
     227             : 
     228          15 : int PCIDSK::ThrowPCIDSKException( int /*ret_unused*/, const char *fmt, ... )
     229             : 
     230             : {
     231             :     std::va_list args;
     232          30 :     PCIDSKException ex;
     233             : 
     234          15 :     va_start( args, fmt );
     235          15 :     ex.vPrintf( fmt, args );
     236          15 :     va_end( args );
     237             : 
     238          15 :     throw ex;
     239             : }
     240             : 
     241           1 : void* PCIDSK::ThrowPCIDSKExceptionPtr( const char *fmt, ... )
     242             : 
     243             : {
     244             :     std::va_list args;
     245           2 :     PCIDSKException ex;
     246             : 
     247           1 :     va_start( args, fmt );
     248           1 :     ex.vPrintf( fmt, args );
     249           1 :     va_end( args );
     250             : 
     251           1 :     throw ex;
     252             : }

Generated by: LCOV version 1.14