LCOV - code coverage report
Current view: top level - frmts/rcm - rcmdrivercore.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 38 44 86.4 %
Date: 2025-10-27 00:14:23 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  DRDC Ottawa GEOINT
       4             :  * Purpose:  Radarsat Constellation Mission - XML Products (product.xml) driver
       5             :  * Author:   Roberto Caron, MDA
       6             :  *           on behalf of DRDC Ottawa
       7             :  *
       8             :  ******************************************************************************
       9             :  * Copyright (c) 2020, DRDC Ottawa
      10             :  *
      11             :  * Based on the RS2 Dataset Class
      12             :  *
      13             :  * SPDX-License-Identifier: MIT
      14             :  ****************************************************************************/
      15             : 
      16             : #include "gdal_frmts.h"
      17             : #include "gdalplugindriverproxy.h"
      18             : 
      19             : #include "rcmdrivercore.h"
      20             : 
      21       55689 : int RCMDatasetIdentify(GDALOpenInfo *poOpenInfo)
      22             : {
      23             :     /* Check for the case where we're trying to read the calibrated data: */
      24       55689 :     if (STARTS_WITH_CI(poOpenInfo->pszFilename, szLayerCalibration) &&
      25          12 :         poOpenInfo->pszFilename[strlen(szLayerCalibration)] == chLayerSeparator)
      26             :     {
      27          12 :         return TRUE;
      28             :     }
      29             : 
      30       55677 :     if (poOpenInfo->bIsDirectory)
      31             :     {
      32           4 :         const auto IsRCM = [](const std::string &osMDFilename)
      33             :         {
      34           4 :             CPLXMLNode *psProduct = CPLParseXMLFile(osMDFilename.c_str());
      35           4 :             if (psProduct == nullptr)
      36           0 :                 return FALSE;
      37             : 
      38             :             CPLXMLNode *psProductAttributes =
      39           4 :                 CPLGetXMLNode(psProduct, "=product");
      40           4 :             if (psProductAttributes == nullptr)
      41             :             {
      42           0 :                 CPLDestroyXMLNode(psProduct);
      43           0 :                 return FALSE;
      44             :             }
      45             : 
      46             :             /* Check the namespace only, should be rcm */
      47             :             const char *szNamespace =
      48           4 :                 CPLGetXMLValue(psProductAttributes, "xmlns", "");
      49             : 
      50           4 :             if (strstr(szNamespace, "rcm") == nullptr)
      51             :             {
      52             :                 /* Invalid namespace */
      53           0 :                 CPLDestroyXMLNode(psProduct);
      54           0 :                 return FALSE;
      55             :             }
      56             : 
      57           4 :             CPLDestroyXMLNode(psProduct);
      58           4 :             return TRUE;
      59             :         };
      60             : 
      61             :         /* Check for directory access when there is a product.xml file in the
      62             :         directory. */
      63             :         const std::string osMDFilename = CPLFormCIFilenameSafe(
      64         560 :             poOpenInfo->pszFilename, "product.xml", nullptr);
      65             : 
      66             :         VSIStatBufL sStat;
      67         280 :         if (VSIStatL(osMDFilename.c_str(), &sStat) == 0)
      68             :         {
      69           2 :             return IsRCM(osMDFilename);
      70             :         }
      71             : 
      72             :         /* If not, check for directory extra 'metadata' access when there is a
      73             :         product.xml file in the directory. */
      74             : 
      75             :         const std::string osMDFilenameMetadata = CPLFormCIFilenameSafe(
      76         556 :             poOpenInfo->pszFilename, GetMetadataProduct(), nullptr);
      77             : 
      78             :         VSIStatBufL sStatMetadata;
      79         278 :         if (VSIStatL(osMDFilenameMetadata.c_str(), &sStatMetadata) == 0)
      80             :         {
      81           2 :             return IsRCM(osMDFilenameMetadata);
      82             :         }
      83             : 
      84         276 :         return FALSE;
      85             :     }
      86             : 
      87             :     /* otherwise, do our normal stuff */
      88       55397 :     if (strlen(poOpenInfo->pszFilename) < 11 ||
      89       53581 :         !EQUAL(poOpenInfo->pszFilename + strlen(poOpenInfo->pszFilename) - 11,
      90             :                "product.xml"))
      91       55394 :         return FALSE;
      92             : 
      93           3 :     if (poOpenInfo->nHeaderBytes < 100)
      94           0 :         return FALSE;
      95             : 
      96             :     /* The RCM schema location is rcm_prod_product.xsd */
      97           3 :     const char *pszHeader =
      98             :         reinterpret_cast<const char *>(poOpenInfo->pabyHeader);
      99           3 :     return strstr(pszHeader, "/rcm") && strstr(pszHeader, "<product");
     100             : }
     101             : 
     102             : /************************************************************************/
     103             : /*                    RCMDriverSetCommonMetadata()                      */
     104             : /************************************************************************/
     105             : 
     106        1755 : void RCMDriverSetCommonMetadata(GDALDriver *poDriver)
     107             : {
     108        1755 :     poDriver->SetDescription(RCM_DRIVER_NAME);
     109        1755 :     poDriver->SetMetadataItem(GDAL_DCAP_RASTER, "YES");
     110        1755 :     poDriver->SetMetadataItem(GDAL_DMD_LONGNAME,
     111        1755 :                               "Radarsat Constellation Mission XML Product");
     112        1755 :     poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/raster/rcm.html");
     113        1755 :     poDriver->SetMetadataItem(GDAL_DMD_SUBDATASETS, "YES");
     114        1755 :     poDriver->pfnIdentify = RCMDatasetIdentify;
     115        1755 :     poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES");
     116        1755 :     poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES");
     117        1755 : }
     118             : 
     119             : /************************************************************************/
     120             : /*                     DeclareDeferredRCMPlugin()                       */
     121             : /************************************************************************/
     122             : 
     123             : #ifdef PLUGIN_FILENAME
     124             : void DeclareDeferredRCMPlugin()
     125             : {
     126             :     if (GDALGetDriverByName(RCM_DRIVER_NAME) != nullptr)
     127             :     {
     128             :         return;
     129             :     }
     130             : 
     131             :     auto poDriver = new GDALPluginDriverProxy(PLUGIN_FILENAME);
     132             : #ifdef PLUGIN_INSTALLATION_MESSAGE
     133             :     poDriver->SetMetadataItem(GDAL_DMD_PLUGIN_INSTALLATION_MESSAGE,
     134             :                               PLUGIN_INSTALLATION_MESSAGE);
     135             : #endif
     136             :     RCMDriverSetCommonMetadata(poDriver);
     137             :     GetGDALDriverManager()->DeclareDeferredPluginDriver(poDriver);
     138             : }
     139             : #endif

Generated by: LCOV version 1.14