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: 2024-11-21 22:18:42 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 "rcmdrivercore.h"
      17             : 
      18       48340 : int RCMDatasetIdentify(GDALOpenInfo *poOpenInfo)
      19             : {
      20             :     /* Check for the case where we're trying to read the calibrated data: */
      21       48340 :     if (STARTS_WITH_CI(poOpenInfo->pszFilename, szLayerCalibration) &&
      22          12 :         poOpenInfo->pszFilename[strlen(szLayerCalibration)] == chLayerSeparator)
      23             :     {
      24          12 :         return TRUE;
      25             :     }
      26             : 
      27       48328 :     if (poOpenInfo->bIsDirectory)
      28             :     {
      29           4 :         const auto IsRCM = [](const CPLString &osMDFilename)
      30             :         {
      31           4 :             CPLXMLNode *psProduct = CPLParseXMLFile(osMDFilename);
      32           4 :             if (psProduct == nullptr)
      33           0 :                 return FALSE;
      34             : 
      35             :             CPLXMLNode *psProductAttributes =
      36           4 :                 CPLGetXMLNode(psProduct, "=product");
      37           4 :             if (psProductAttributes == nullptr)
      38             :             {
      39           0 :                 CPLDestroyXMLNode(psProduct);
      40           0 :                 return FALSE;
      41             :             }
      42             : 
      43             :             /* Check the namespace only, should be rcm */
      44             :             const char *szNamespace =
      45           4 :                 CPLGetXMLValue(psProductAttributes, "xmlns", "");
      46             : 
      47           4 :             if (strstr(szNamespace, "rcm") == nullptr)
      48             :             {
      49             :                 /* Invalid namespace */
      50           0 :                 CPLDestroyXMLNode(psProduct);
      51           0 :                 return FALSE;
      52             :             }
      53             : 
      54           4 :             CPLDestroyXMLNode(psProduct);
      55           4 :             return TRUE;
      56             :         };
      57             : 
      58             :         /* Check for directory access when there is a product.xml file in the
      59             :         directory. */
      60             :         CPLString osMDFilename =
      61         198 :             CPLFormCIFilename(poOpenInfo->pszFilename, "product.xml", nullptr);
      62             : 
      63             :         VSIStatBufL sStat;
      64          99 :         if (VSIStatL(osMDFilename, &sStat) == 0)
      65             :         {
      66           2 :             return IsRCM(osMDFilename);
      67             :         }
      68             : 
      69             :         /* If not, check for directory extra 'metadata' access when there is a
      70             :         product.xml file in the directory. */
      71             : 
      72             :         CPLString osMDFilenameMetadata = CPLFormCIFilename(
      73         194 :             poOpenInfo->pszFilename, GetMetadataProduct(), nullptr);
      74             : 
      75             :         VSIStatBufL sStatMetadata;
      76          97 :         if (VSIStatL(osMDFilenameMetadata, &sStatMetadata) == 0)
      77             :         {
      78           2 :             return IsRCM(osMDFilenameMetadata);
      79             :         }
      80             : 
      81          95 :         return FALSE;
      82             :     }
      83             : 
      84             :     /* otherwise, do our normal stuff */
      85       48229 :     if (strlen(poOpenInfo->pszFilename) < 11 ||
      86       47283 :         !EQUAL(poOpenInfo->pszFilename + strlen(poOpenInfo->pszFilename) - 11,
      87             :                "product.xml"))
      88       48224 :         return FALSE;
      89             : 
      90           5 :     if (poOpenInfo->nHeaderBytes < 100)
      91           0 :         return FALSE;
      92             : 
      93             :     /* The RCM schema location is rcm_prod_product.xsd */
      94           5 :     const char *pszHeader =
      95             :         reinterpret_cast<const char *>(poOpenInfo->pabyHeader);
      96           5 :     return strstr(pszHeader, "/rcm") && strstr(pszHeader, "<product");
      97             : }
      98             : 
      99             : /************************************************************************/
     100             : /*                    RCMDriverSetCommonMetadata()                      */
     101             : /************************************************************************/
     102             : 
     103        1293 : void RCMDriverSetCommonMetadata(GDALDriver *poDriver)
     104             : {
     105        1293 :     poDriver->SetDescription(RCM_DRIVER_NAME);
     106        1293 :     poDriver->SetMetadataItem(GDAL_DCAP_RASTER, "YES");
     107        1293 :     poDriver->SetMetadataItem(GDAL_DMD_LONGNAME,
     108        1293 :                               "Radarsat Constellation Mission XML Product");
     109        1293 :     poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/raster/rcm.html");
     110        1293 :     poDriver->SetMetadataItem(GDAL_DMD_SUBDATASETS, "YES");
     111        1293 :     poDriver->pfnIdentify = RCMDatasetIdentify;
     112        1293 :     poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES");
     113        1293 :     poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES");
     114        1293 : }
     115             : 
     116             : /************************************************************************/
     117             : /*                     DeclareDeferredRCMPlugin()                       */
     118             : /************************************************************************/
     119             : 
     120             : #ifdef PLUGIN_FILENAME
     121             : void DeclareDeferredRCMPlugin()
     122             : {
     123             :     if (GDALGetDriverByName(RCM_DRIVER_NAME) != nullptr)
     124             :     {
     125             :         return;
     126             :     }
     127             : 
     128             :     auto poDriver = new GDALPluginDriverProxy(PLUGIN_FILENAME);
     129             : #ifdef PLUGIN_INSTALLATION_MESSAGE
     130             :     poDriver->SetMetadataItem(GDAL_DMD_PLUGIN_INSTALLATION_MESSAGE,
     131             :                               PLUGIN_INSTALLATION_MESSAGE);
     132             : #endif
     133             :     RCMDriverSetCommonMetadata(poDriver);
     134             :     GetGDALDriverManager()->DeclareDeferredPluginDriver(poDriver);
     135             : }
     136             : #endif

Generated by: LCOV version 1.14