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

Generated by: LCOV version 1.14