LCOV - code coverage report
Current view: top level - frmts/null - nulldataset.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 48 132 36.4 %
Date: 2024-04-27 17:22:41 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             :  * Permission is hereby granted, free of charge, to any person obtaining a
      12             :  * copy of this software and associated documentation files (the "Software"),
      13             :  * to deal in the Software without restriction, including without limitation
      14             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15             :  * and/or sell copies of the Software, and to permit persons to whom the
      16             :  * Software is furnished to do so, subject to the following conditions:
      17             :  *
      18             :  * The above copyright notice and this permission notice shall be included
      19             :  * in all copies or substantial portions of the Software.
      20             :  *
      21             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27             :  * DEALINGS IN THE SOFTWARE.
      28             :  ****************************************************************************/
      29             : 
      30             : #include "gdal_priv.h"
      31             : #include "ogrsf_frmts.h"
      32             : 
      33             : extern "C" void GDALRegister_NULL();
      34             : 
      35             : /************************************************************************/
      36             : /*                          GDALNullDataset                             */
      37             : /************************************************************************/
      38             : 
      39             : class GDALNullDataset final : public GDALDataset
      40             : {
      41             :     int m_nLayers;
      42             :     OGRLayer **m_papoLayers;
      43             : 
      44             :   public:
      45             :     GDALNullDataset();
      46             :     virtual ~GDALNullDataset();
      47             : 
      48           0 :     virtual int GetLayerCount() override
      49             :     {
      50           0 :         return m_nLayers;
      51             :     }
      52             : 
      53             :     virtual OGRLayer *GetLayer(int) override;
      54             : 
      55             :     OGRLayer *ICreateLayer(const char *pszName,
      56             :                            const OGRGeomFieldDefn *poGeomFieldDefn,
      57             :                            CSLConstList papszOptions) override;
      58             : 
      59             :     virtual int TestCapability(const char *) override;
      60             : 
      61             :     CPLErr SetSpatialRef(const OGRSpatialReference *poSRS) override;
      62             : 
      63             :     virtual CPLErr SetGeoTransform(double *) override;
      64             : 
      65             :     static GDALDataset *Open(GDALOpenInfo *poOpenInfo);
      66             :     static GDALDataset *Create(const char *pszFilename, int nXSize, int nYSize,
      67             :                                int nBands, GDALDataType eType,
      68             :                                char **papszOptions);
      69             : };
      70             : 
      71             : /************************************************************************/
      72             : /*                           GDALNullLayer                              */
      73             : /************************************************************************/
      74             : 
      75             : class GDALNullRasterBand final : public GDALRasterBand
      76             : {
      77             :   public:
      78             :     explicit GDALNullRasterBand(GDALDataType eDT);
      79             : 
      80             :     virtual CPLErr IReadBlock(int, int, void *) override;
      81             :     virtual CPLErr IWriteBlock(int, int, void *) override;
      82             :     virtual CPLErr IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff,
      83             :                              int nXSize, int nYSize, void *pData, int nBufXSize,
      84             :                              int nBufYSize, GDALDataType eBufType,
      85             :                              GSpacing nPixelSpace, GSpacing nLineSpace,
      86             :                              GDALRasterIOExtraArg *psExtraArg) override;
      87             : };
      88             : 
      89             : /************************************************************************/
      90             : /*                           GDALNullLayer                              */
      91             : /************************************************************************/
      92             : 
      93             : class GDALNullLayer final : public OGRLayer
      94             : {
      95             :     OGRFeatureDefn *poFeatureDefn;
      96             :     OGRSpatialReference *poSRS = nullptr;
      97             : 
      98             :   public:
      99             :     GDALNullLayer(const char *pszLayerName, const OGRSpatialReference *poSRS,
     100             :                   OGRwkbGeometryType eType);
     101             :     virtual ~GDALNullLayer();
     102             : 
     103           0 :     virtual OGRFeatureDefn *GetLayerDefn() override
     104             :     {
     105           0 :         return poFeatureDefn;
     106             :     }
     107             : 
     108           0 :     virtual OGRSpatialReference *GetSpatialRef() override
     109             :     {
     110           0 :         return poSRS;
     111             :     }
     112             : 
     113           0 :     virtual void ResetReading() override
     114             :     {
     115           0 :     }
     116             : 
     117             :     virtual int TestCapability(const char *) override;
     118             : 
     119           0 :     virtual OGRFeature *GetNextFeature() override
     120             :     {
     121           0 :         return nullptr;
     122             :     }
     123             : 
     124           0 :     virtual OGRErr ICreateFeature(OGRFeature *) override
     125             :     {
     126           0 :         return OGRERR_NONE;
     127             :     }
     128             : 
     129             :     virtual OGRErr CreateField(const OGRFieldDefn *poField,
     130             :                                int bApproxOK = TRUE) override;
     131             : };
     132             : 
     133             : /************************************************************************/
     134             : /*                           GDALNullRasterBand()                       */
     135             : /************************************************************************/
     136             : 
     137          95 : GDALNullRasterBand::GDALNullRasterBand(GDALDataType eDT)
     138             : {
     139          95 :     eDataType = eDT;
     140          95 :     nBlockXSize = 256;
     141          95 :     nBlockYSize = 256;
     142          95 : }
     143             : 
     144             : /************************************************************************/
     145             : /*                             IRasterIO()                              */
     146             : /************************************************************************/
     147             : 
     148          26 : CPLErr GDALNullRasterBand::IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff,
     149             :                                      int nXSize, int nYSize, void *pData,
     150             :                                      int nBufXSize, int nBufYSize,
     151             :                                      GDALDataType eBufType,
     152             :                                      GSpacing nPixelSpace, GSpacing nLineSpace,
     153             :                                      GDALRasterIOExtraArg *psExtraArg)
     154             : {
     155          26 :     if (eRWFlag == GF_Write)
     156          26 :         return CE_None;
     157           0 :     if (psExtraArg->eResampleAlg != GRIORA_NearestNeighbour &&
     158           0 :         (nBufXSize != nXSize || nBufYSize != nYSize))
     159             :     {
     160           0 :         return GDALRasterBand::IRasterIO(eRWFlag, nXOff, nYOff, nXSize, nYSize,
     161             :                                          pData, nBufXSize, nBufYSize, eBufType,
     162           0 :                                          nPixelSpace, nLineSpace, psExtraArg);
     163             :     }
     164           0 :     if (nPixelSpace == GDALGetDataTypeSizeBytes(eBufType) &&
     165           0 :         nLineSpace == nPixelSpace * nBufXSize)
     166             :     {
     167           0 :         memset(pData, 0, nLineSpace * nBufYSize);
     168             :     }
     169             :     else
     170             :     {
     171           0 :         for (int iY = 0; iY < nBufYSize; iY++)
     172             :         {
     173           0 :             double dfZero = 0;
     174           0 :             GDALCopyWords(&dfZero, GDT_Float64, 0,
     175           0 :                           reinterpret_cast<GByte *>(pData) + iY * nLineSpace,
     176             :                           eBufType, static_cast<int>(nPixelSpace), nBufXSize);
     177             :         }
     178             :     }
     179           0 :     return CE_None;
     180             : }
     181             : 
     182             : /************************************************************************/
     183             : /*                             IReadBlock()                             */
     184             : /************************************************************************/
     185             : 
     186           0 : CPLErr GDALNullRasterBand::IReadBlock(int, int, void *pData)
     187             : {
     188           0 :     memset(pData, 0,
     189           0 :            nBlockXSize * nBlockYSize * GDALGetDataTypeSizeBytes(eDataType));
     190           0 :     return CE_None;
     191             : }
     192             : 
     193             : /************************************************************************/
     194             : /*                             IWriteBlock()                            */
     195             : /************************************************************************/
     196             : 
     197           0 : CPLErr GDALNullRasterBand::IWriteBlock(int, int, void *)
     198             : {
     199           0 :     return CE_None;
     200             : }
     201             : 
     202             : /************************************************************************/
     203             : /*                          GDALNullDataset()                           */
     204             : /************************************************************************/
     205             : 
     206          51 : GDALNullDataset::GDALNullDataset() : m_nLayers(0), m_papoLayers(nullptr)
     207             : {
     208          51 :     eAccess = GA_Update;
     209          51 : }
     210             : 
     211             : /************************************************************************/
     212             : /*                         ~GDALNullDataset()                           */
     213             : /************************************************************************/
     214             : 
     215         102 : GDALNullDataset::~GDALNullDataset()
     216             : {
     217          51 :     for (int i = 0; i < m_nLayers; i++)
     218           0 :         delete m_papoLayers[i];
     219          51 :     CPLFree(m_papoLayers);
     220         102 : }
     221             : 
     222             : /************************************************************************/
     223             : /*                           ICreateLayer()                             */
     224             : /************************************************************************/
     225             : 
     226           0 : OGRLayer *GDALNullDataset::ICreateLayer(const char *pszLayerName,
     227             :                                         const OGRGeomFieldDefn *poGeomFieldDefn,
     228             :                                         CSLConstList /*papszOptions */)
     229             : {
     230           0 :     const auto eType = poGeomFieldDefn ? poGeomFieldDefn->GetType() : wkbNone;
     231             :     const auto poSRS =
     232           0 :         poGeomFieldDefn ? poGeomFieldDefn->GetSpatialRef() : nullptr;
     233             : 
     234           0 :     m_papoLayers = static_cast<OGRLayer **>(
     235           0 :         CPLRealloc(m_papoLayers, sizeof(OGRLayer *) * (m_nLayers + 1)));
     236           0 :     m_papoLayers[m_nLayers] = new GDALNullLayer(pszLayerName, poSRS, eType);
     237           0 :     m_nLayers++;
     238           0 :     return m_papoLayers[m_nLayers - 1];
     239             : }
     240             : 
     241             : /************************************************************************/
     242             : /*                           TestCapability()                           */
     243             : /************************************************************************/
     244             : 
     245           0 : int GDALNullDataset::TestCapability(const char *pszCap)
     246             : 
     247             : {
     248           0 :     if (EQUAL(pszCap, ODsCCreateLayer))
     249           0 :         return TRUE;
     250           0 :     if (EQUAL(pszCap, ODsCRandomLayerWrite))
     251           0 :         return TRUE;
     252           0 :     return FALSE;
     253             : }
     254             : 
     255             : /************************************************************************/
     256             : /*                              GetLayer()                              */
     257             : /************************************************************************/
     258             : 
     259           0 : OGRLayer *GDALNullDataset::GetLayer(int iLayer)
     260             : 
     261             : {
     262           0 :     if (iLayer < 0 || iLayer >= m_nLayers)
     263           0 :         return nullptr;
     264             :     else
     265           0 :         return m_papoLayers[iLayer];
     266             : }
     267             : 
     268             : /************************************************************************/
     269             : /*                           SetSpatialRef()                            */
     270             : /************************************************************************/
     271             : 
     272          51 : CPLErr GDALNullDataset::SetSpatialRef(const OGRSpatialReference *)
     273             : 
     274             : {
     275          51 :     return CE_None;
     276             : }
     277             : 
     278             : /************************************************************************/
     279             : /*                          SetGeoTransform()                           */
     280             : /************************************************************************/
     281             : 
     282          51 : CPLErr GDALNullDataset::SetGeoTransform(double *)
     283             : 
     284             : {
     285          51 :     return CE_None;
     286             : }
     287             : 
     288             : /************************************************************************/
     289             : /*                               Open()                                 */
     290             : /************************************************************************/
     291             : 
     292       37187 : GDALDataset *GDALNullDataset::Open(GDALOpenInfo *poOpenInfo)
     293             : {
     294       37187 :     if (!STARTS_WITH_CI(poOpenInfo->pszFilename, "NULL:"))
     295       37182 :         return nullptr;
     296             : 
     297           5 :     const char *pszStr = poOpenInfo->pszFilename + strlen("NULL:");
     298           5 :     char **papszTokens = CSLTokenizeString2(pszStr, ",", 0);
     299           0 :     int nXSize = atoi(CSLFetchNameValueDef(papszTokens, "width", "512"));
     300           0 :     int nYSize = atoi(CSLFetchNameValueDef(papszTokens, "height", "512"));
     301           0 :     int nBands = atoi(CSLFetchNameValueDef(papszTokens, "bands", "1"));
     302           0 :     const char *pszDTName = CSLFetchNameValueDef(papszTokens, "type", "Byte");
     303           0 :     GDALDataType eDT = GDT_Byte;
     304           0 :     for (int iType = 1; iType < GDT_TypeCount; iType++)
     305             :     {
     306           0 :         if (GDALGetDataTypeName((GDALDataType)iType) != nullptr &&
     307           0 :             EQUAL(GDALGetDataTypeName((GDALDataType)iType), pszDTName))
     308             :         {
     309           0 :             eDT = (GDALDataType)iType;
     310           0 :             break;
     311             :         }
     312             :     }
     313           0 :     CSLDestroy(papszTokens);
     314             : 
     315           0 :     return Create("", nXSize, nYSize, nBands, eDT, nullptr);
     316             : }
     317             : 
     318             : /************************************************************************/
     319             : /*                              Create()                                */
     320             : /************************************************************************/
     321             : 
     322          51 : GDALDataset *GDALNullDataset::Create(const char *, int nXSize, int nYSize,
     323             :                                      int nBandsIn, GDALDataType eType, char **)
     324             : {
     325          51 :     GDALNullDataset *poDS = new GDALNullDataset();
     326          51 :     poDS->nRasterXSize = nXSize;
     327          51 :     poDS->nRasterYSize = nYSize;
     328         146 :     for (int i = 0; i < nBandsIn; i++)
     329          95 :         poDS->SetBand(i + 1, new GDALNullRasterBand(eType));
     330          51 :     return poDS;
     331             : }
     332             : 
     333             : /************************************************************************/
     334             : /*                           GDALNullLayer()                            */
     335             : /************************************************************************/
     336             : 
     337           0 : GDALNullLayer::GDALNullLayer(const char *pszLayerName,
     338             :                              const OGRSpatialReference *poSRSIn,
     339           0 :                              OGRwkbGeometryType eType)
     340           0 :     : poFeatureDefn(new OGRFeatureDefn(pszLayerName))
     341             : {
     342           0 :     SetDescription(poFeatureDefn->GetName());
     343           0 :     poFeatureDefn->SetGeomType(eType);
     344           0 :     poFeatureDefn->Reference();
     345             : 
     346           0 :     if (poSRSIn)
     347           0 :         poSRS = poSRSIn->Clone();
     348           0 : }
     349             : 
     350             : /************************************************************************/
     351             : /*                           ~GDALNullLayer()                           */
     352             : /************************************************************************/
     353             : 
     354           0 : GDALNullLayer::~GDALNullLayer()
     355             : {
     356           0 :     poFeatureDefn->Release();
     357             : 
     358           0 :     if (poSRS)
     359           0 :         poSRS->Release();
     360           0 : }
     361             : 
     362             : /************************************************************************/
     363             : /*                           TestCapability()                           */
     364             : /************************************************************************/
     365             : 
     366           0 : int GDALNullLayer::TestCapability(const char *pszCap)
     367             : 
     368             : {
     369           0 :     if (EQUAL(pszCap, OLCSequentialWrite))
     370           0 :         return TRUE;
     371           0 :     if (EQUAL(pszCap, OLCCreateField))
     372           0 :         return TRUE;
     373           0 :     return FALSE;
     374             : }
     375             : 
     376             : /************************************************************************/
     377             : /*                             CreateField()                            */
     378             : /************************************************************************/
     379             : 
     380           0 : OGRErr GDALNullLayer::CreateField(const OGRFieldDefn *poField, int)
     381             : {
     382           0 :     poFeatureDefn->AddFieldDefn(poField);
     383           0 :     return OGRERR_NONE;
     384             : }
     385             : 
     386             : /************************************************************************/
     387             : /*                        GDALRegister_NULL()                           */
     388             : /************************************************************************/
     389             : 
     390        1509 : void GDALRegister_NULL()
     391             : 
     392             : {
     393        1509 :     if (GDALGetDriverByName("NULL") != nullptr)
     394         295 :         return;
     395             : 
     396             :     GDALDriver *poDriver;
     397        1214 :     poDriver = new GDALDriver();
     398             : 
     399        1214 :     poDriver->SetDescription("NULL");
     400        1214 :     poDriver->SetMetadataItem(GDAL_DMD_CONNECTION_PREFIX, "NULL: ");
     401        1214 :     poDriver->SetMetadataItem(GDAL_DCAP_RASTER, "YES");
     402        1214 :     poDriver->SetMetadataItem(GDAL_DCAP_VECTOR, "YES");
     403        1214 :     poDriver->SetMetadataItem(GDAL_DCAP_CREATE_LAYER, "YES");
     404        1214 :     poDriver->SetMetadataItem(GDAL_DCAP_CREATE_FIELD, "YES");
     405        1214 :     poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "NULL");
     406             : 
     407        1214 :     poDriver->SetMetadataItem(GDAL_DMD_CREATIONFIELDDATATYPES,
     408             :                               "Integer Integer64 Real String Date DateTime "
     409             :                               "Binary IntegerList Integer64List "
     410        1214 :                               "RealList StringList");
     411             : 
     412        1214 :     poDriver->SetMetadataItem(GDAL_DMD_SUPPORTED_SQL_DIALECTS, "OGRSQL SQLITE");
     413             : 
     414        1214 :     poDriver->pfnOpen = GDALNullDataset::Open;
     415        1214 :     poDriver->pfnCreate = GDALNullDataset::Create;
     416             : 
     417        1214 :     GetGDALDriverManager()->RegisterDriver(poDriver);
     418             : }

Generated by: LCOV version 1.14