LCOV - code coverage report
Current view: top level - frmts/null - nulldataset.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 48 155 31.0 %
Date: 2026-01-23 20:24:11 Functions: 11 37 29.7 %

          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           0 :     CPLErr SetCategoryNames(CPL_UNUSED char **papszNames) override
      66             :     {
      67           0 :         return CE_None;
      68             :     }
      69             : 
      70           0 :     CPLErr SetNoDataValue(CPL_UNUSED double dfNoData) override
      71             :     {
      72           0 :         return CE_None;
      73             :     }
      74             : 
      75           0 :     CPLErr SetNoDataValueAsInt64(CPL_UNUSED int64_t nNoData) override
      76             :     {
      77           0 :         return CE_None;
      78             :     }
      79             : 
      80           0 :     CPLErr SetNoDataValueAsUInt64(CPL_UNUSED uint64_t nNoData) override
      81             :     {
      82           0 :         return CE_None;
      83             :     }
      84             : 
      85           0 :     CPLErr DeleteNoDataValue() override
      86             :     {
      87           0 :         return CE_None;
      88             :     }
      89             : 
      90           0 :     CPLErr SetColorTable(CPL_UNUSED GDALColorTable *poCT) override
      91             :     {
      92           0 :         return CE_None;
      93             :     }
      94             : 
      95             :     CPLErr
      96           2 :     SetColorInterpretation(CPL_UNUSED GDALColorInterp eColorInterp) override
      97             :     {
      98           2 :         return CE_None;
      99             :     }
     100             : 
     101           0 :     CPLErr SetOffset(CPL_UNUSED double dfNewOffset) override
     102             :     {
     103           0 :         return CE_None;
     104             :     }
     105             : 
     106           0 :     CPLErr SetScale(CPL_UNUSED double dfNewScale) override
     107             :     {
     108           0 :         return CE_None;
     109             :     }
     110             : 
     111           0 :     CPLErr SetUnitType(CPL_UNUSED const char *pszNewValue) override
     112             :     {
     113           0 :         return CE_None;
     114             :     }
     115             : 
     116           0 :     CPLErr SetDefaultRAT(const GDALRasterAttributeTable *) override
     117             :     {
     118           0 :         return CE_None;
     119             :     }
     120             : 
     121             :     CPLErr IReadBlock(int, int, void *) override;
     122             :     CPLErr IWriteBlock(int, int, void *) override;
     123             :     CPLErr IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
     124             :                      int nYSize, void *pData, int nBufXSize, int nBufYSize,
     125             :                      GDALDataType eBufType, GSpacing nPixelSpace,
     126             :                      GSpacing nLineSpace,
     127             :                      GDALRasterIOExtraArg *psExtraArg) override;
     128             : };
     129             : 
     130             : /************************************************************************/
     131             : /*                           GDALNullLayer                              */
     132             : /************************************************************************/
     133             : 
     134             : class GDALNullLayer final : public OGRLayer
     135             : {
     136             :     OGRFeatureDefn *poFeatureDefn;
     137             :     OGRSpatialReference *poSRS = nullptr;
     138             : 
     139             :     CPL_DISALLOW_COPY_ASSIGN(GDALNullLayer)
     140             : 
     141             :   public:
     142             :     GDALNullLayer(const char *pszLayerName, const OGRSpatialReference *poSRS,
     143             :                   OGRwkbGeometryType eType);
     144             :     ~GDALNullLayer() override;
     145             : 
     146           0 :     const OGRFeatureDefn *GetLayerDefn() const override
     147             :     {
     148           0 :         return poFeatureDefn;
     149             :     }
     150             : 
     151           0 :     const OGRSpatialReference *GetSpatialRef() const override
     152             :     {
     153           0 :         return poSRS;
     154             :     }
     155             : 
     156           0 :     void ResetReading() override
     157             :     {
     158           0 :     }
     159             : 
     160             :     int TestCapability(const char *) const override;
     161             : 
     162           0 :     OGRFeature *GetNextFeature() override
     163             :     {
     164           0 :         return nullptr;
     165             :     }
     166             : 
     167           0 :     OGRErr ICreateFeature(OGRFeature *) override
     168             :     {
     169           0 :         return OGRERR_NONE;
     170             :     }
     171             : 
     172             :     virtual OGRErr CreateField(const OGRFieldDefn *poField,
     173             :                                int bApproxOK = TRUE) override;
     174             : };
     175             : 
     176             : /************************************************************************/
     177             : /*                           GDALNullRasterBand()                       */
     178             : /************************************************************************/
     179             : 
     180          94 : GDALNullRasterBand::GDALNullRasterBand(GDALDataType eDT)
     181             : {
     182          94 :     eDataType = eDT;
     183          94 :     nBlockXSize = 256;
     184          94 :     nBlockYSize = 256;
     185          94 : }
     186             : 
     187             : /************************************************************************/
     188             : /*                             IRasterIO()                              */
     189             : /************************************************************************/
     190             : 
     191          26 : CPLErr GDALNullRasterBand::IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff,
     192             :                                      int nXSize, int nYSize, void *pData,
     193             :                                      int nBufXSize, int nBufYSize,
     194             :                                      GDALDataType eBufType,
     195             :                                      GSpacing nPixelSpace, GSpacing nLineSpace,
     196             :                                      GDALRasterIOExtraArg *psExtraArg)
     197             : {
     198          26 :     if (eRWFlag == GF_Write)
     199          26 :         return CE_None;
     200           0 :     if (psExtraArg->eResampleAlg != GRIORA_NearestNeighbour &&
     201           0 :         (nBufXSize != nXSize || nBufYSize != nYSize))
     202             :     {
     203           0 :         return GDALRasterBand::IRasterIO(eRWFlag, nXOff, nYOff, nXSize, nYSize,
     204             :                                          pData, nBufXSize, nBufYSize, eBufType,
     205           0 :                                          nPixelSpace, nLineSpace, psExtraArg);
     206             :     }
     207           0 :     if (nPixelSpace == GDALGetDataTypeSizeBytes(eBufType) &&
     208           0 :         nLineSpace == nPixelSpace * nBufXSize)
     209             :     {
     210           0 :         memset(pData, 0, static_cast<size_t>(nLineSpace) * nBufYSize);
     211             :     }
     212             :     else
     213             :     {
     214           0 :         for (int iY = 0; iY < nBufYSize; iY++)
     215             :         {
     216           0 :             double dfZero = 0;
     217           0 :             GDALCopyWords(&dfZero, GDT_Float64, 0,
     218           0 :                           reinterpret_cast<GByte *>(pData) + iY * nLineSpace,
     219             :                           eBufType, static_cast<int>(nPixelSpace), nBufXSize);
     220             :         }
     221             :     }
     222           0 :     return CE_None;
     223             : }
     224             : 
     225             : /************************************************************************/
     226             : /*                             IReadBlock()                             */
     227             : /************************************************************************/
     228             : 
     229           0 : CPLErr GDALNullRasterBand::IReadBlock(int, int, void *pData)
     230             : {
     231           0 :     memset(pData, 0,
     232           0 :            static_cast<size_t>(nBlockXSize) * nBlockYSize *
     233           0 :                GDALGetDataTypeSizeBytes(eDataType));
     234           0 :     return CE_None;
     235             : }
     236             : 
     237             : /************************************************************************/
     238             : /*                             IWriteBlock()                            */
     239             : /************************************************************************/
     240             : 
     241           0 : CPLErr GDALNullRasterBand::IWriteBlock(int, int, void *)
     242             : {
     243           0 :     return CE_None;
     244             : }
     245             : 
     246             : /************************************************************************/
     247             : /*                          GDALNullDataset()                           */
     248             : /************************************************************************/
     249             : 
     250          50 : GDALNullDataset::GDALNullDataset() : m_nLayers(0), m_papoLayers(nullptr)
     251             : {
     252          50 :     eAccess = GA_Update;
     253          50 : }
     254             : 
     255             : /************************************************************************/
     256             : /*                         ~GDALNullDataset()                           */
     257             : /************************************************************************/
     258             : 
     259         100 : GDALNullDataset::~GDALNullDataset()
     260             : {
     261          50 :     for (int i = 0; i < m_nLayers; i++)
     262           0 :         delete m_papoLayers[i];
     263          50 :     CPLFree(m_papoLayers);
     264         100 : }
     265             : 
     266             : /************************************************************************/
     267             : /*                           ICreateLayer()                             */
     268             : /************************************************************************/
     269             : 
     270           0 : OGRLayer *GDALNullDataset::ICreateLayer(const char *pszLayerName,
     271             :                                         const OGRGeomFieldDefn *poGeomFieldDefn,
     272             :                                         CSLConstList /*papszOptions */)
     273             : {
     274           0 :     const auto eType = poGeomFieldDefn ? poGeomFieldDefn->GetType() : wkbNone;
     275             :     const auto poSRS =
     276           0 :         poGeomFieldDefn ? poGeomFieldDefn->GetSpatialRef() : nullptr;
     277             : 
     278           0 :     m_papoLayers = static_cast<OGRLayer **>(
     279           0 :         CPLRealloc(m_papoLayers, sizeof(OGRLayer *) * (m_nLayers + 1)));
     280           0 :     m_papoLayers[m_nLayers] = new GDALNullLayer(pszLayerName, poSRS, eType);
     281           0 :     m_nLayers++;
     282           0 :     return m_papoLayers[m_nLayers - 1];
     283             : }
     284             : 
     285             : /************************************************************************/
     286             : /*                           TestCapability()                           */
     287             : /************************************************************************/
     288             : 
     289           0 : int GDALNullDataset::TestCapability(const char *pszCap) const
     290             : 
     291             : {
     292           0 :     if (EQUAL(pszCap, ODsCCreateLayer))
     293           0 :         return TRUE;
     294           0 :     if (EQUAL(pszCap, ODsCRandomLayerWrite))
     295           0 :         return TRUE;
     296           0 :     return FALSE;
     297             : }
     298             : 
     299             : /************************************************************************/
     300             : /*                              GetLayer()                              */
     301             : /************************************************************************/
     302             : 
     303           0 : const OGRLayer *GDALNullDataset::GetLayer(int iLayer) const
     304             : 
     305             : {
     306           0 :     if (iLayer < 0 || iLayer >= m_nLayers)
     307           0 :         return nullptr;
     308             :     else
     309           0 :         return m_papoLayers[iLayer];
     310             : }
     311             : 
     312             : /************************************************************************/
     313             : /*                           SetSpatialRef()                            */
     314             : /************************************************************************/
     315             : 
     316          50 : CPLErr GDALNullDataset::SetSpatialRef(const OGRSpatialReference *)
     317             : 
     318             : {
     319          50 :     return CE_None;
     320             : }
     321             : 
     322             : /************************************************************************/
     323             : /*                          SetGeoTransform()                           */
     324             : /************************************************************************/
     325             : 
     326          50 : CPLErr GDALNullDataset::SetGeoTransform(const GDALGeoTransform &)
     327             : 
     328             : {
     329          50 :     return CE_None;
     330             : }
     331             : 
     332             : /************************************************************************/
     333             : /*                               Open()                                 */
     334             : /************************************************************************/
     335             : 
     336       45953 : GDALDataset *GDALNullDataset::Open(GDALOpenInfo *poOpenInfo)
     337             : {
     338       45953 :     if (!STARTS_WITH_CI(poOpenInfo->pszFilename, "NULL:"))
     339       45953 :         return nullptr;
     340             : 
     341           0 :     const char *pszStr = poOpenInfo->pszFilename + strlen("NULL:");
     342           0 :     char **papszTokens = CSLTokenizeString2(pszStr, ",", 0);
     343           0 :     int nXSize = atoi(CSLFetchNameValueDef(papszTokens, "width", "512"));
     344           0 :     int nYSize = atoi(CSLFetchNameValueDef(papszTokens, "height", "512"));
     345           0 :     int nBands = atoi(CSLFetchNameValueDef(papszTokens, "bands", "1"));
     346           0 :     const char *pszDTName = CSLFetchNameValueDef(papszTokens, "type", "Byte");
     347           0 :     GDALDataType eDT = GDT_UInt8;
     348           0 :     for (int iType = 1; iType < GDT_TypeCount; iType++)
     349             :     {
     350           0 :         if (GDALGetDataTypeName(static_cast<GDALDataType>(iType)) != nullptr &&
     351           0 :             EQUAL(GDALGetDataTypeName(static_cast<GDALDataType>(iType)),
     352             :                   pszDTName))
     353             :         {
     354           0 :             eDT = static_cast<GDALDataType>(iType);
     355           0 :             break;
     356             :         }
     357             :     }
     358           0 :     CSLDestroy(papszTokens);
     359             : 
     360           0 :     return Create("", nXSize, nYSize, nBands, eDT, nullptr);
     361             : }
     362             : 
     363             : /************************************************************************/
     364             : /*                              Create()                                */
     365             : /************************************************************************/
     366             : 
     367          50 : GDALDataset *GDALNullDataset::Create(const char *, int nXSize, int nYSize,
     368             :                                      int nBandsIn, GDALDataType eType, char **)
     369             : {
     370          50 :     GDALNullDataset *poDS = new GDALNullDataset();
     371          50 :     poDS->nRasterXSize = nXSize;
     372          50 :     poDS->nRasterYSize = nYSize;
     373         144 :     for (int i = 0; i < nBandsIn; i++)
     374          94 :         poDS->SetBand(i + 1, new GDALNullRasterBand(eType));
     375          50 :     return poDS;
     376             : }
     377             : 
     378             : /************************************************************************/
     379             : /*                           GDALNullLayer()                            */
     380             : /************************************************************************/
     381             : 
     382           0 : GDALNullLayer::GDALNullLayer(const char *pszLayerName,
     383             :                              const OGRSpatialReference *poSRSIn,
     384           0 :                              OGRwkbGeometryType eType)
     385           0 :     : poFeatureDefn(new OGRFeatureDefn(pszLayerName))
     386             : {
     387           0 :     SetDescription(poFeatureDefn->GetName());
     388           0 :     poFeatureDefn->SetGeomType(eType);
     389           0 :     poFeatureDefn->Reference();
     390             : 
     391           0 :     if (poSRSIn)
     392           0 :         poSRS = poSRSIn->Clone();
     393           0 : }
     394             : 
     395             : /************************************************************************/
     396             : /*                           ~GDALNullLayer()                           */
     397             : /************************************************************************/
     398             : 
     399           0 : GDALNullLayer::~GDALNullLayer()
     400             : {
     401           0 :     poFeatureDefn->Release();
     402             : 
     403           0 :     if (poSRS)
     404           0 :         poSRS->Release();
     405           0 : }
     406             : 
     407             : /************************************************************************/
     408             : /*                           TestCapability()                           */
     409             : /************************************************************************/
     410             : 
     411           0 : int GDALNullLayer::TestCapability(const char *pszCap) const
     412             : 
     413             : {
     414           0 :     if (EQUAL(pszCap, OLCSequentialWrite))
     415           0 :         return TRUE;
     416           0 :     if (EQUAL(pszCap, OLCCreateField))
     417           0 :         return TRUE;
     418           0 :     return FALSE;
     419             : }
     420             : 
     421             : /************************************************************************/
     422             : /*                             CreateField()                            */
     423             : /************************************************************************/
     424             : 
     425           0 : OGRErr GDALNullLayer::CreateField(const OGRFieldDefn *poField, int)
     426             : {
     427           0 :     poFeatureDefn->AddFieldDefn(poField);
     428           0 :     return OGRERR_NONE;
     429             : }
     430             : 
     431             : /************************************************************************/
     432             : /*                        GDALRegister_NULL()                           */
     433             : /************************************************************************/
     434             : 
     435        2058 : void GDALRegister_NULL()
     436             : 
     437             : {
     438        2058 :     if (GDALGetDriverByName("NULL") != nullptr)
     439         283 :         return;
     440             : 
     441             :     GDALDriver *poDriver;
     442        1775 :     poDriver = new GDALDriver();
     443             : 
     444        1775 :     poDriver->SetDescription("NULL");
     445        1775 :     poDriver->SetMetadataItem(GDAL_DMD_CONNECTION_PREFIX, "NULL:");
     446        1775 :     poDriver->SetMetadataItem(GDAL_DCAP_RASTER, "YES");
     447        1775 :     poDriver->SetMetadataItem(GDAL_DCAP_VECTOR, "YES");
     448        1775 :     poDriver->SetMetadataItem(GDAL_DCAP_CREATE_LAYER, "YES");
     449        1775 :     poDriver->SetMetadataItem(GDAL_DCAP_CREATE_FIELD, "YES");
     450        1775 :     poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "NULL");
     451             : 
     452        1775 :     poDriver->SetMetadataItem(GDAL_DMD_CREATIONFIELDDATATYPES,
     453             :                               "Integer Integer64 Real String Date DateTime "
     454             :                               "Binary IntegerList Integer64List "
     455        1775 :                               "RealList StringList");
     456             : 
     457        1775 :     poDriver->SetMetadataItem(GDAL_DMD_SUPPORTED_SQL_DIALECTS, "OGRSQL SQLITE");
     458             : 
     459        1775 :     poDriver->pfnOpen = GDALNullDataset::Open;
     460        1775 :     poDriver->pfnCreate = GDALNullDataset::Create;
     461             : 
     462        1775 :     GetGDALDriverManager()->RegisterDriver(poDriver);
     463             : }

Generated by: LCOV version 1.14