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

Generated by: LCOV version 1.14