LCOV - code coverage report
Current view: top level - frmts/null - nulldataset.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 48 133 36.1 %
Date: 2025-07-12 19:59:49 Functions: 10 26 38.5 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL
       4             :  * Purpose:  NULL driver.
       5             :  * Author:   Even Rouault, <even dot rouault at spatialys dot org>
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2012-2017, Even Rouault, <even dot rouault at spatialys dot
       9             :  *org>
      10             :  *
      11             :  * SPDX-License-Identifier: MIT
      12             :  ****************************************************************************/
      13             : 
      14             : #include "gdal_priv.h"
      15             : #include "ogrsf_frmts.h"
      16             : 
      17             : extern "C" void GDALRegister_NULL();
      18             : 
      19             : /************************************************************************/
      20             : /*                          GDALNullDataset                             */
      21             : /************************************************************************/
      22             : 
      23             : class GDALNullDataset final : public GDALDataset
      24             : {
      25             :     int m_nLayers;
      26             :     OGRLayer **m_papoLayers;
      27             : 
      28             :     CPL_DISALLOW_COPY_ASSIGN(GDALNullDataset)
      29             : 
      30             :   public:
      31             :     GDALNullDataset();
      32             :     virtual ~GDALNullDataset();
      33             : 
      34           0 :     virtual int GetLayerCount() override
      35             :     {
      36           0 :         return m_nLayers;
      37             :     }
      38             : 
      39             :     virtual OGRLayer *GetLayer(int) override;
      40             : 
      41             :     OGRLayer *ICreateLayer(const char *pszName,
      42             :                            const OGRGeomFieldDefn *poGeomFieldDefn,
      43             :                            CSLConstList papszOptions) override;
      44             : 
      45             :     virtual int TestCapability(const char *) override;
      46             : 
      47             :     CPLErr SetSpatialRef(const OGRSpatialReference *poSRS) override;
      48             : 
      49             :     virtual CPLErr SetGeoTransform(const GDALGeoTransform &gt) override;
      50             : 
      51             :     static GDALDataset *Open(GDALOpenInfo *poOpenInfo);
      52             :     static GDALDataset *Create(const char *pszFilename, int nXSize, int nYSize,
      53             :                                int nBands, GDALDataType eType,
      54             :                                char **papszOptions);
      55             : };
      56             : 
      57             : /************************************************************************/
      58             : /*                           GDALNullLayer                              */
      59             : /************************************************************************/
      60             : 
      61             : class GDALNullRasterBand final : public GDALRasterBand
      62             : {
      63             :   public:
      64             :     explicit GDALNullRasterBand(GDALDataType eDT);
      65             : 
      66             :     virtual CPLErr IReadBlock(int, int, void *) override;
      67             :     virtual CPLErr IWriteBlock(int, int, void *) override;
      68             :     virtual CPLErr IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff,
      69             :                              int nXSize, int nYSize, void *pData, int nBufXSize,
      70             :                              int nBufYSize, GDALDataType eBufType,
      71             :                              GSpacing nPixelSpace, GSpacing nLineSpace,
      72             :                              GDALRasterIOExtraArg *psExtraArg) override;
      73             : };
      74             : 
      75             : /************************************************************************/
      76             : /*                           GDALNullLayer                              */
      77             : /************************************************************************/
      78             : 
      79             : class GDALNullLayer final : public OGRLayer
      80             : {
      81             :     OGRFeatureDefn *poFeatureDefn;
      82             :     OGRSpatialReference *poSRS = nullptr;
      83             : 
      84             :     CPL_DISALLOW_COPY_ASSIGN(GDALNullLayer)
      85             : 
      86             :   public:
      87             :     GDALNullLayer(const char *pszLayerName, const OGRSpatialReference *poSRS,
      88             :                   OGRwkbGeometryType eType);
      89             :     virtual ~GDALNullLayer();
      90             : 
      91           0 :     virtual OGRFeatureDefn *GetLayerDefn() override
      92             :     {
      93           0 :         return poFeatureDefn;
      94             :     }
      95             : 
      96           0 :     virtual OGRSpatialReference *GetSpatialRef() override
      97             :     {
      98           0 :         return poSRS;
      99             :     }
     100             : 
     101           0 :     virtual void ResetReading() override
     102             :     {
     103           0 :     }
     104             : 
     105             :     virtual int TestCapability(const char *) override;
     106             : 
     107           0 :     virtual OGRFeature *GetNextFeature() override
     108             :     {
     109           0 :         return nullptr;
     110             :     }
     111             : 
     112           0 :     virtual OGRErr ICreateFeature(OGRFeature *) override
     113             :     {
     114           0 :         return OGRERR_NONE;
     115             :     }
     116             : 
     117             :     virtual OGRErr CreateField(const OGRFieldDefn *poField,
     118             :                                int bApproxOK = TRUE) override;
     119             : };
     120             : 
     121             : /************************************************************************/
     122             : /*                           GDALNullRasterBand()                       */
     123             : /************************************************************************/
     124             : 
     125          94 : GDALNullRasterBand::GDALNullRasterBand(GDALDataType eDT)
     126             : {
     127          94 :     eDataType = eDT;
     128          94 :     nBlockXSize = 256;
     129          94 :     nBlockYSize = 256;
     130          94 : }
     131             : 
     132             : /************************************************************************/
     133             : /*                             IRasterIO()                              */
     134             : /************************************************************************/
     135             : 
     136          25 : CPLErr GDALNullRasterBand::IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff,
     137             :                                      int nXSize, int nYSize, void *pData,
     138             :                                      int nBufXSize, int nBufYSize,
     139             :                                      GDALDataType eBufType,
     140             :                                      GSpacing nPixelSpace, GSpacing nLineSpace,
     141             :                                      GDALRasterIOExtraArg *psExtraArg)
     142             : {
     143          25 :     if (eRWFlag == GF_Write)
     144          25 :         return CE_None;
     145           0 :     if (psExtraArg->eResampleAlg != GRIORA_NearestNeighbour &&
     146           0 :         (nBufXSize != nXSize || nBufYSize != nYSize))
     147             :     {
     148           0 :         return GDALRasterBand::IRasterIO(eRWFlag, nXOff, nYOff, nXSize, nYSize,
     149             :                                          pData, nBufXSize, nBufYSize, eBufType,
     150           0 :                                          nPixelSpace, nLineSpace, psExtraArg);
     151             :     }
     152           0 :     if (nPixelSpace == GDALGetDataTypeSizeBytes(eBufType) &&
     153           0 :         nLineSpace == nPixelSpace * nBufXSize)
     154             :     {
     155           0 :         memset(pData, 0, static_cast<size_t>(nLineSpace) * nBufYSize);
     156             :     }
     157             :     else
     158             :     {
     159           0 :         for (int iY = 0; iY < nBufYSize; iY++)
     160             :         {
     161           0 :             double dfZero = 0;
     162           0 :             GDALCopyWords(&dfZero, GDT_Float64, 0,
     163           0 :                           reinterpret_cast<GByte *>(pData) + iY * nLineSpace,
     164             :                           eBufType, static_cast<int>(nPixelSpace), nBufXSize);
     165             :         }
     166             :     }
     167           0 :     return CE_None;
     168             : }
     169             : 
     170             : /************************************************************************/
     171             : /*                             IReadBlock()                             */
     172             : /************************************************************************/
     173             : 
     174           0 : CPLErr GDALNullRasterBand::IReadBlock(int, int, void *pData)
     175             : {
     176           0 :     memset(pData, 0,
     177           0 :            static_cast<size_t>(nBlockXSize) * nBlockYSize *
     178           0 :                GDALGetDataTypeSizeBytes(eDataType));
     179           0 :     return CE_None;
     180             : }
     181             : 
     182             : /************************************************************************/
     183             : /*                             IWriteBlock()                            */
     184             : /************************************************************************/
     185             : 
     186           0 : CPLErr GDALNullRasterBand::IWriteBlock(int, int, void *)
     187             : {
     188           0 :     return CE_None;
     189             : }
     190             : 
     191             : /************************************************************************/
     192             : /*                          GDALNullDataset()                           */
     193             : /************************************************************************/
     194             : 
     195          50 : GDALNullDataset::GDALNullDataset() : m_nLayers(0), m_papoLayers(nullptr)
     196             : {
     197          50 :     eAccess = GA_Update;
     198          50 : }
     199             : 
     200             : /************************************************************************/
     201             : /*                         ~GDALNullDataset()                           */
     202             : /************************************************************************/
     203             : 
     204         100 : GDALNullDataset::~GDALNullDataset()
     205             : {
     206          50 :     for (int i = 0; i < m_nLayers; i++)
     207           0 :         delete m_papoLayers[i];
     208          50 :     CPLFree(m_papoLayers);
     209         100 : }
     210             : 
     211             : /************************************************************************/
     212             : /*                           ICreateLayer()                             */
     213             : /************************************************************************/
     214             : 
     215           0 : OGRLayer *GDALNullDataset::ICreateLayer(const char *pszLayerName,
     216             :                                         const OGRGeomFieldDefn *poGeomFieldDefn,
     217             :                                         CSLConstList /*papszOptions */)
     218             : {
     219           0 :     const auto eType = poGeomFieldDefn ? poGeomFieldDefn->GetType() : wkbNone;
     220             :     const auto poSRS =
     221           0 :         poGeomFieldDefn ? poGeomFieldDefn->GetSpatialRef() : nullptr;
     222             : 
     223           0 :     m_papoLayers = static_cast<OGRLayer **>(
     224           0 :         CPLRealloc(m_papoLayers, sizeof(OGRLayer *) * (m_nLayers + 1)));
     225           0 :     m_papoLayers[m_nLayers] = new GDALNullLayer(pszLayerName, poSRS, eType);
     226           0 :     m_nLayers++;
     227           0 :     return m_papoLayers[m_nLayers - 1];
     228             : }
     229             : 
     230             : /************************************************************************/
     231             : /*                           TestCapability()                           */
     232             : /************************************************************************/
     233             : 
     234           0 : int GDALNullDataset::TestCapability(const char *pszCap)
     235             : 
     236             : {
     237           0 :     if (EQUAL(pszCap, ODsCCreateLayer))
     238           0 :         return TRUE;
     239           0 :     if (EQUAL(pszCap, ODsCRandomLayerWrite))
     240           0 :         return TRUE;
     241           0 :     return FALSE;
     242             : }
     243             : 
     244             : /************************************************************************/
     245             : /*                              GetLayer()                              */
     246             : /************************************************************************/
     247             : 
     248           0 : OGRLayer *GDALNullDataset::GetLayer(int iLayer)
     249             : 
     250             : {
     251           0 :     if (iLayer < 0 || iLayer >= m_nLayers)
     252           0 :         return nullptr;
     253             :     else
     254           0 :         return m_papoLayers[iLayer];
     255             : }
     256             : 
     257             : /************************************************************************/
     258             : /*                           SetSpatialRef()                            */
     259             : /************************************************************************/
     260             : 
     261          50 : CPLErr GDALNullDataset::SetSpatialRef(const OGRSpatialReference *)
     262             : 
     263             : {
     264          50 :     return CE_None;
     265             : }
     266             : 
     267             : /************************************************************************/
     268             : /*                          SetGeoTransform()                           */
     269             : /************************************************************************/
     270             : 
     271          50 : CPLErr GDALNullDataset::SetGeoTransform(const GDALGeoTransform &)
     272             : 
     273             : {
     274          50 :     return CE_None;
     275             : }
     276             : 
     277             : /************************************************************************/
     278             : /*                               Open()                                 */
     279             : /************************************************************************/
     280             : 
     281       42878 : GDALDataset *GDALNullDataset::Open(GDALOpenInfo *poOpenInfo)
     282             : {
     283       42878 :     if (!STARTS_WITH_CI(poOpenInfo->pszFilename, "NULL:"))
     284       42874 :         return nullptr;
     285             : 
     286           4 :     const char *pszStr = poOpenInfo->pszFilename + strlen("NULL:");
     287           4 :     char **papszTokens = CSLTokenizeString2(pszStr, ",", 0);
     288           0 :     int nXSize = atoi(CSLFetchNameValueDef(papszTokens, "width", "512"));
     289           0 :     int nYSize = atoi(CSLFetchNameValueDef(papszTokens, "height", "512"));
     290           0 :     int nBands = atoi(CSLFetchNameValueDef(papszTokens, "bands", "1"));
     291           0 :     const char *pszDTName = CSLFetchNameValueDef(papszTokens, "type", "Byte");
     292           0 :     GDALDataType eDT = GDT_Byte;
     293           0 :     for (int iType = 1; iType < GDT_TypeCount; iType++)
     294             :     {
     295           0 :         if (GDALGetDataTypeName(static_cast<GDALDataType>(iType)) != nullptr &&
     296           0 :             EQUAL(GDALGetDataTypeName(static_cast<GDALDataType>(iType)),
     297             :                   pszDTName))
     298             :         {
     299           0 :             eDT = static_cast<GDALDataType>(iType);
     300           0 :             break;
     301             :         }
     302             :     }
     303           0 :     CSLDestroy(papszTokens);
     304             : 
     305           0 :     return Create("", nXSize, nYSize, nBands, eDT, nullptr);
     306             : }
     307             : 
     308             : /************************************************************************/
     309             : /*                              Create()                                */
     310             : /************************************************************************/
     311             : 
     312          50 : GDALDataset *GDALNullDataset::Create(const char *, int nXSize, int nYSize,
     313             :                                      int nBandsIn, GDALDataType eType, char **)
     314             : {
     315          50 :     GDALNullDataset *poDS = new GDALNullDataset();
     316          50 :     poDS->nRasterXSize = nXSize;
     317          50 :     poDS->nRasterYSize = nYSize;
     318         144 :     for (int i = 0; i < nBandsIn; i++)
     319          94 :         poDS->SetBand(i + 1, new GDALNullRasterBand(eType));
     320          50 :     return poDS;
     321             : }
     322             : 
     323             : /************************************************************************/
     324             : /*                           GDALNullLayer()                            */
     325             : /************************************************************************/
     326             : 
     327           0 : GDALNullLayer::GDALNullLayer(const char *pszLayerName,
     328             :                              const OGRSpatialReference *poSRSIn,
     329           0 :                              OGRwkbGeometryType eType)
     330           0 :     : poFeatureDefn(new OGRFeatureDefn(pszLayerName))
     331             : {
     332           0 :     SetDescription(poFeatureDefn->GetName());
     333           0 :     poFeatureDefn->SetGeomType(eType);
     334           0 :     poFeatureDefn->Reference();
     335             : 
     336           0 :     if (poSRSIn)
     337           0 :         poSRS = poSRSIn->Clone();
     338           0 : }
     339             : 
     340             : /************************************************************************/
     341             : /*                           ~GDALNullLayer()                           */
     342             : /************************************************************************/
     343             : 
     344           0 : GDALNullLayer::~GDALNullLayer()
     345             : {
     346           0 :     poFeatureDefn->Release();
     347             : 
     348           0 :     if (poSRS)
     349           0 :         poSRS->Release();
     350           0 : }
     351             : 
     352             : /************************************************************************/
     353             : /*                           TestCapability()                           */
     354             : /************************************************************************/
     355             : 
     356           0 : int GDALNullLayer::TestCapability(const char *pszCap)
     357             : 
     358             : {
     359           0 :     if (EQUAL(pszCap, OLCSequentialWrite))
     360           0 :         return TRUE;
     361           0 :     if (EQUAL(pszCap, OLCCreateField))
     362           0 :         return TRUE;
     363           0 :     return FALSE;
     364             : }
     365             : 
     366             : /************************************************************************/
     367             : /*                             CreateField()                            */
     368             : /************************************************************************/
     369             : 
     370           0 : OGRErr GDALNullLayer::CreateField(const OGRFieldDefn *poField, int)
     371             : {
     372           0 :     poFeatureDefn->AddFieldDefn(poField);
     373           0 :     return OGRERR_NONE;
     374             : }
     375             : 
     376             : /************************************************************************/
     377             : /*                        GDALRegister_NULL()                           */
     378             : /************************************************************************/
     379             : 
     380        1935 : void GDALRegister_NULL()
     381             : 
     382             : {
     383        1935 :     if (GDALGetDriverByName("NULL") != nullptr)
     384         282 :         return;
     385             : 
     386             :     GDALDriver *poDriver;
     387        1653 :     poDriver = new GDALDriver();
     388             : 
     389        1653 :     poDriver->SetDescription("NULL");
     390        1653 :     poDriver->SetMetadataItem(GDAL_DMD_CONNECTION_PREFIX, "NULL: ");
     391        1653 :     poDriver->SetMetadataItem(GDAL_DCAP_RASTER, "YES");
     392        1653 :     poDriver->SetMetadataItem(GDAL_DCAP_VECTOR, "YES");
     393        1653 :     poDriver->SetMetadataItem(GDAL_DCAP_CREATE_LAYER, "YES");
     394        1653 :     poDriver->SetMetadataItem(GDAL_DCAP_CREATE_FIELD, "YES");
     395        1653 :     poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "NULL");
     396             : 
     397        1653 :     poDriver->SetMetadataItem(GDAL_DMD_CREATIONFIELDDATATYPES,
     398             :                               "Integer Integer64 Real String Date DateTime "
     399             :                               "Binary IntegerList Integer64List "
     400        1653 :                               "RealList StringList");
     401             : 
     402        1653 :     poDriver->SetMetadataItem(GDAL_DMD_SUPPORTED_SQL_DIALECTS, "OGRSQL SQLITE");
     403             : 
     404        1653 :     poDriver->pfnOpen = GDALNullDataset::Open;
     405        1653 :     poDriver->pfnCreate = GDALNullDataset::Create;
     406             : 
     407        1653 :     GetGDALDriverManager()->RegisterDriver(poDriver);
     408             : }

Generated by: LCOV version 1.14