LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/miramon - ogrmiramondatasource.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 76 84 90.5 %
Date: 2024-05-18 15:15:27 Functions: 9 9 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  OpenGIS Simple Features Reference Implementation
       4             :  * Purpose:  Implements OGRMiraMonDataSource class.
       5             :  * Author:   Abel Pau
       6             :  ******************************************************************************
       7             :  * Copyright (c) 2024, Xavier Pons
       8             :  *
       9             :  * Permission is hereby granted, free of charge, to any person obtaining a
      10             :  * copy of this software and associated documentation files (the "Software"),
      11             :  * to deal in the Software without restriction, including without limitation
      12             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      13             :  * and/or sell copies of the Software, and to permit persons to whom the
      14             :  * Software is furnished to do so, subject to the following conditions:
      15             :  *
      16             :  * The above copyright notice and this permission notice shall be included
      17             :  * in all copies or substantial portions of the Software.
      18             :  *
      19             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      20             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      21             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      22             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      23             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      24             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      25             :  * DEALINGS IN THE SOFTWARE.
      26             :  ****************************************************************************/
      27             : 
      28             : #include "ogrmiramon.h"
      29             : 
      30             : /****************************************************************************/
      31             : /*                          OGRMiraMonDataSource()                          */
      32             : /****************************************************************************/
      33         184 : OGRMiraMonDataSource::OGRMiraMonDataSource()
      34             : {
      35         184 :     memset(&m_MMMap, 0, sizeof(m_MMMap));
      36         184 : }
      37             : 
      38             : /****************************************************************************/
      39             : /*                         ~OGRMiraMonDataSource()                          */
      40             : /****************************************************************************/
      41             : 
      42         368 : OGRMiraMonDataSource::~OGRMiraMonDataSource()
      43             : 
      44             : {
      45         184 :     m_apoLayers.clear();
      46             : 
      47         184 :     if (m_MMMap.fMMMap)
      48          45 :         VSIFCloseL(m_MMMap.fMMMap);
      49         368 : }
      50             : 
      51             : /****************************************************************************/
      52             : /*                                Open()                                    */
      53             : /****************************************************************************/
      54             : 
      55         199 : bool OGRMiraMonDataSource::Open(const char *pszFilename, VSILFILE *fp,
      56             :                                 const OGRSpatialReference *poSRS,
      57             :                                 CSLConstList papszOpenOptionsUsr)
      58             : 
      59             : {
      60             :     auto poLayer = std::make_unique<OGRMiraMonLayer>(
      61         398 :         this, pszFilename, fp, poSRS, m_bUpdate, papszOpenOptionsUsr, &m_MMMap);
      62         199 :     if (!poLayer->bValidFile)
      63             :     {
      64           8 :         return false;
      65             :     }
      66             : 
      67         191 :     if (!m_osRootName.empty())
      68             :     {
      69          81 :         const char *pszExtension = CPLGetExtension(m_osRootName.c_str());
      70          81 :         if (!EQUAL(pszExtension, "pol") && !EQUAL(pszExtension, "arc") &&
      71          70 :             !EQUAL(pszExtension, "pnt"))
      72             :         {
      73          61 :             CPLStrlcpy(m_MMMap.pszMapName,
      74             :                        CPLFormFilename(m_osRootName.c_str(),
      75             :                                        CPLGetBasename(m_osRootName.c_str()),
      76             :                                        "mmm"),
      77             :                        sizeof(m_MMMap.pszMapName));
      78          61 :             if (!m_MMMap.nNumberOfLayers)
      79             :             {
      80          45 :                 m_MMMap.fMMMap = VSIFOpenL(m_MMMap.pszMapName, "w+");
      81          45 :                 if (!m_MMMap.fMMMap)
      82             :                 {
      83             :                     // It could be an error but it is not so important
      84             :                     // to stop the process. This map is an extra element
      85             :                     // to open all layers in one click, at least in MiraMon
      86             :                     // software.
      87           0 :                     *m_MMMap.pszMapName = '\0';
      88             :                 }
      89             :                 else
      90             :                 {
      91          45 :                     VSIFPrintfL(m_MMMap.fMMMap, "[VERSIO]\n");
      92          45 :                     VSIFPrintfL(m_MMMap.fMMMap, "Vers=2\n");
      93          45 :                     VSIFPrintfL(m_MMMap.fMMMap, "SubVers=0\n");
      94          45 :                     VSIFPrintfL(m_MMMap.fMMMap, "variant=b\n");
      95          45 :                     VSIFPrintfL(m_MMMap.fMMMap, "\n");
      96          45 :                     VSIFPrintfL(m_MMMap.fMMMap, "[DOCUMENT]\n");
      97          45 :                     VSIFPrintfL(m_MMMap.fMMMap, "Titol= %s(map)\n",
      98          45 :                                 CPLGetBasename(poLayer->GetName()));
      99          45 :                     VSIFPrintfL(m_MMMap.fMMMap, "\n");
     100             :                 }
     101             :             }
     102             :         }
     103             :         else
     104          20 :             *m_MMMap.pszMapName = '\0';
     105             :     }
     106             :     else
     107         110 :         *m_MMMap.pszMapName = '\0';
     108             : 
     109         191 :     m_apoLayers.emplace_back(std::move(poLayer));
     110             : 
     111         191 :     return true;
     112             : }
     113             : 
     114             : /****************************************************************************/
     115             : /*                               Create()                                   */
     116             : /*                                                                          */
     117             : /*      Create a new datasource.  This does not really do anything          */
     118             : /*      currently but save the name.                                        */
     119             : /****************************************************************************/
     120             : 
     121          66 : bool OGRMiraMonDataSource::Create(const char *pszDataSetName,
     122             :                                   CSLConstList /* papszOptions */)
     123             : 
     124             : {
     125          66 :     m_bUpdate = true;
     126          66 :     m_osRootName = pszDataSetName;
     127             : 
     128          66 :     return true;
     129             : }
     130             : 
     131             : /****************************************************************************/
     132             : /*                           ICreateLayer()                                 */
     133             : /****************************************************************************/
     134             : 
     135             : OGRLayer *
     136          82 : OGRMiraMonDataSource::ICreateLayer(const char *pszLayerName,
     137             :                                    const OGRGeomFieldDefn *poGeomFieldDefn,
     138             :                                    CSLConstList papszOptions)
     139             : {
     140          82 :     CPLAssert(nullptr != pszLayerName);
     141             : 
     142          82 :     const auto eType = poGeomFieldDefn ? poGeomFieldDefn->GetType() : wkbNone;
     143             :     const auto poSRS =
     144          82 :         poGeomFieldDefn ? poGeomFieldDefn->GetSpatialRef() : nullptr;
     145             : 
     146             :     // It's a seed to be able to generate a random identifier in
     147             :     // MMGenerateFileIdentifierFromMetadataFileName() function
     148          82 :     srand((unsigned int)time(nullptr));
     149             : 
     150          82 :     if (OGR_GT_HasM(eType))
     151             :     {
     152           0 :         CPLError(CE_Warning, CPLE_NotSupported,
     153             :                  "Measures in this layer will be ignored.");
     154             :     }
     155             : 
     156             :     /* -------------------------------------------------------------------- */
     157             :     /*    If the dataset has an extension, it is understood that the path   */
     158             :     /*       of the file is where to write, and the layer name is the       */
     159             :     /*       dataset name (without extension).                              */
     160             :     /* -------------------------------------------------------------------- */
     161          82 :     const char *pszExtension = CPLGetExtension(m_osRootName.c_str());
     162         164 :     std::string osFullMMLayerName;
     163          82 :     if (EQUAL(pszExtension, "pol") || EQUAL(pszExtension, "arc") ||
     164          71 :         EQUAL(pszExtension, "pnt"))
     165             :     {
     166          20 :         osFullMMLayerName = CPLResetExtension(m_osRootName.c_str(), "");
     167          20 :         if (!osFullMMLayerName.empty())
     168          20 :             osFullMMLayerName.pop_back();
     169             : 
     170             :         // Checking that the folder where to write exists
     171             :         const std::string osDestFolder =
     172          20 :             CPLGetDirname(osFullMMLayerName.c_str());
     173          20 :         if (!STARTS_WITH(osDestFolder.c_str(), "/vsimem"))
     174             :         {
     175             :             VSIStatBufL sStat;
     176           0 :             if (VSIStatL(osDestFolder.c_str(), &sStat) != 0 ||
     177           0 :                 !VSI_ISDIR(sStat.st_mode))
     178             :             {
     179           0 :                 CPLError(CE_Failure, CPLE_AppDefined,
     180             :                          "The folder %s does not exist.", osDestFolder.c_str());
     181           0 :                 return nullptr;
     182             :             }
     183          20 :         }
     184             :     }
     185             :     else
     186             :     {
     187             :         osFullMMLayerName =
     188          62 :             CPLFormFilename(m_osRootName.c_str(), pszLayerName, "");
     189             : 
     190             :         /* -------------------------------------------------------------------- */
     191             :         /*      Let's create the folder if it's not already created.            */
     192             :         /*      (only the las level of the folder)                              */
     193             :         /* -------------------------------------------------------------------- */
     194          62 :         if (!STARTS_WITH(m_osRootName.c_str(), "/vsimem"))
     195             :         {
     196             :             VSIStatBufL sStat;
     197          14 :             if (VSIStatL(m_osRootName.c_str(), &sStat) != 0 ||
     198           0 :                 !VSI_ISDIR(sStat.st_mode))
     199             :             {
     200          14 :                 if (VSIMkdir(m_osRootName.c_str(), 0755) != 0)
     201             :                 {
     202           1 :                     CPLError(CE_Failure, CPLE_AppDefined,
     203             :                              "Unable to create the folder %s.",
     204             :                              m_osRootName.c_str());
     205           1 :                     return nullptr;
     206             :                 }
     207             :             }
     208             :         }
     209             :     }
     210             : 
     211             :     /* -------------------------------------------------------------------- */
     212             :     /*      Return open layer handle.                                       */
     213             :     /* -------------------------------------------------------------------- */
     214          81 :     if (Open(osFullMMLayerName.c_str(), nullptr, poSRS, papszOptions))
     215             :     {
     216          81 :         return m_apoLayers.back().get();
     217             :     }
     218             : 
     219           0 :     return nullptr;
     220             : }
     221             : 
     222             : /****************************************************************************/
     223             : /*                           TestCapability()                               */
     224             : /****************************************************************************/
     225             : 
     226         198 : int OGRMiraMonDataSource::TestCapability(const char *pszCap)
     227             : 
     228             : {
     229         198 :     if (EQUAL(pszCap, ODsCCreateLayer))
     230          62 :         return m_bUpdate;
     231         136 :     else if (EQUAL(pszCap, ODsCZGeometries))
     232          20 :         return TRUE;
     233             : 
     234         116 :     return FALSE;
     235             : }
     236             : 
     237             : /****************************************************************************/
     238             : /*                              GetLayer()                                  */
     239             : /****************************************************************************/
     240             : 
     241         360 : OGRLayer *OGRMiraMonDataSource::GetLayer(int iLayer)
     242             : 
     243             : {
     244         360 :     if (iLayer < 0 || iLayer >= static_cast<int>(m_apoLayers.size()))
     245          20 :         return nullptr;
     246             : 
     247         340 :     return m_apoLayers[iLayer].get();
     248             : }
     249             : 
     250             : /************************************************************************/
     251             : /*                            GetFileList()                             */
     252             : /************************************************************************/
     253             : 
     254          10 : char **OGRMiraMonDataSource::GetFileList()
     255             : {
     256          20 :     CPLStringList oFileList;
     257          20 :     for (auto &poLayer : m_apoLayers)
     258             :     {
     259          10 :         poLayer->AddToFileList(oFileList);
     260             :     }
     261          20 :     return oFileList.StealList();
     262             : }

Generated by: LCOV version 1.14