LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/xls - ogrxlsdatasource.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 43 47 91.5 %
Date: 2024-11-21 22:18:42 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  XLS Translator
       4             :  * Purpose:  Implements OGRXLSDataSource class
       5             :  * Author:   Even Rouault, even dot rouault at spatialys.com
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2011, Even Rouault <even dot rouault at spatialys.com>
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #include "include_freexl.h"
      14             : 
      15             : #ifdef _WIN32
      16             : #include <windows.h>
      17             : #endif
      18             : 
      19             : #include "ogr_xls.h"
      20             : #include "cpl_conv.h"
      21             : #include "cpl_string.h"
      22             : 
      23             : /************************************************************************/
      24             : /*                          OGRXLSDataSource()                          */
      25             : /************************************************************************/
      26             : 
      27           5 : OGRXLSDataSource::OGRXLSDataSource()
      28           5 :     : papoLayers(nullptr), nLayers(0), xlshandle(nullptr)
      29             : {
      30           5 : }
      31             : 
      32             : /************************************************************************/
      33             : /*                         ~OGRXLSDataSource()                          */
      34             : /************************************************************************/
      35             : 
      36          10 : OGRXLSDataSource::~OGRXLSDataSource()
      37             : 
      38             : {
      39           9 :     for (int i = 0; i < nLayers; i++)
      40           4 :         delete papoLayers[i];
      41           5 :     CPLFree(papoLayers);
      42             : 
      43           5 :     if (xlshandle)
      44           4 :         freexl_close(xlshandle);
      45             : #ifdef _WIN32
      46             :     if (m_osTempFilename.empty())
      47             :     {
      48             :         VSIUnlink(m_osTempFilename);
      49             :     }
      50             : #endif
      51          10 : }
      52             : 
      53             : /************************************************************************/
      54             : /*                              GetLayer()                              */
      55             : /************************************************************************/
      56             : 
      57          28 : OGRLayer *OGRXLSDataSource::GetLayer(int iLayer)
      58             : 
      59             : {
      60          28 :     if (iLayer < 0 || iLayer >= nLayers)
      61           2 :         return nullptr;
      62             :     else
      63          26 :         return papoLayers[iLayer];
      64             : }
      65             : 
      66             : /************************************************************************/
      67             : /*                                Open()                                */
      68             : /************************************************************************/
      69             : 
      70           5 : int OGRXLSDataSource::Open(const char *pszFilename, int bUpdateIn)
      71             : 
      72             : {
      73           5 :     if (bUpdateIn)
      74             :     {
      75           0 :         return FALSE;
      76             :     }
      77             : 
      78           5 :     m_osANSIFilename = pszFilename;
      79             : #ifdef _WIN32
      80             :     if (CPLTestBool(CPLGetConfigOption("GDAL_FILENAME_IS_UTF8", "YES")))
      81             :     {
      82             :         CPLErrorReset();
      83             :         CPLPushErrorHandler(CPLQuietErrorHandler);
      84             :         char *pszTmpName = CPLRecode(pszFilename, CPL_ENC_UTF8,
      85             :                                      CPLString().Printf("CP%d", GetACP()));
      86             :         CPLPopErrorHandler();
      87             :         m_osANSIFilename = pszTmpName;
      88             :         CPLFree(pszTmpName);
      89             : 
      90             :         // In case recoding to the ANSI code page failed, then create a
      91             :         // temporary file in a "safe" location
      92             :         if (CPLGetLastErrorType() != CE_None)
      93             :         {
      94             :             CPLErrorReset();
      95             : 
      96             :             // FIXME: CPLGenerateTempFilename() would normally be expected to
      97             :             // return a UTF-8 filename but I doubt it does in all cases.
      98             :             m_osTempFilename = CPLGenerateTempFilename("temp_xls");
      99             :             m_osANSIFilename = m_osTempFilename;
     100             :             CPLCopyFile(m_osANSIFilename, pszFilename);
     101             :             CPLDebug("XLS", "Create temporary file: %s",
     102             :                      m_osTempFilename.c_str());
     103             :         }
     104             :     }
     105             : #endif
     106             : 
     107             :     // --------------------------------------------------------------------
     108             :     //      Does this appear to be a .xls file?
     109             :     // --------------------------------------------------------------------
     110             : 
     111             :     /* Open only for getting info. To get cell values, we have to use
     112             :      * freexl_open */
     113           5 :     if (!GetXLSHandle())
     114           1 :         return FALSE;
     115             : 
     116           4 :     unsigned int nSheets = 0;
     117           4 :     if (freexl_get_info(xlshandle, FREEXL_BIFF_SHEET_COUNT, &nSheets) !=
     118             :         FREEXL_OK)
     119           0 :         return FALSE;
     120             : 
     121          16 :     for (unsigned short i = 0; i < (unsigned short)nSheets; i++)
     122             :     {
     123          12 :         freexl_select_active_worksheet(xlshandle, i);
     124             : 
     125          12 :         const char *pszSheetname = nullptr;
     126          12 :         if (freexl_get_worksheet_name(xlshandle, i, &pszSheetname) != FREEXL_OK)
     127           0 :             return FALSE;
     128             : 
     129          12 :         unsigned int nRows = 0;
     130          12 :         unsigned short nCols = 0;
     131          12 :         if (freexl_worksheet_dimensions(xlshandle, &nRows, &nCols) != FREEXL_OK)
     132           0 :             return FALSE;
     133             : 
     134             :         /* Skip empty sheets */
     135          12 :         if (nRows == 0)
     136           8 :             continue;
     137             : 
     138           8 :         papoLayers = (OGRLayer **)CPLRealloc(
     139           4 :             papoLayers, (nLayers + 1) * sizeof(OGRLayer *));
     140           4 :         papoLayers[nLayers++] =
     141           4 :             new OGRXLSLayer(this, pszSheetname, i, (int)nRows, nCols);
     142             :     }
     143             : 
     144           4 :     freexl_close(xlshandle);
     145           4 :     xlshandle = nullptr;
     146             : 
     147           4 :     return TRUE;
     148             : }
     149             : 
     150             : /************************************************************************/
     151             : /*                           GetXLSHandle()                             */
     152             : /************************************************************************/
     153             : 
     154          69 : const void *OGRXLSDataSource::GetXLSHandle()
     155             : {
     156          69 :     if (xlshandle)
     157          61 :         return xlshandle;
     158             : 
     159           8 :     if (freexl_open(m_osANSIFilename, &xlshandle) != FREEXL_OK)
     160           1 :         return nullptr;
     161             : 
     162           7 :     return xlshandle;
     163             : }

Generated by: LCOV version 1.14