LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/vfk - vfkreader.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 139 111 79.9 %
Date: 2010-01-09 Functions: 16 13 81.2 %

       1                 : /******************************************************************************
       2                 :  * $Id: vfkreader.cpp 18470 2010-01-07 21:41:20Z martinl $
       3                 :  *
       4                 :  * Project:  VFK Reader
       5                 :  * Purpose:  Implements VFKReader class.
       6                 :  * Author:   Martin Landa, landa.martin gmail.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2009-2010, Martin Landa <landa.martin gmail.com>
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person
      12                 :  * obtaining a copy of this software and associated documentation
      13                 :  * files (the "Software"), to deal in the Software without
      14                 :  * restriction, including without limitation the rights to use, copy,
      15                 :  * modify, merge, publish, distribute, sublicense, and/or sell copies
      16                 :  * of the Software, and to permit persons to whom the Software is
      17                 :  * furnished to do so, subject to the following conditions:
      18                 :  *
      19                 :  * The above copyright notice and this permission notice shall be
      20                 :  * included in all copies or substantial portions of the Software.
      21                 :  *
      22                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
      23                 :  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
      24                 :  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
      25                 :  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
      26                 :  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
      27                 :  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
      28                 :  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
      29                 :  * SOFTWARE.
      30                 :  ****************************************************************************/
      31                 : 
      32                 : #include "vfkreader.h"
      33                 : #include "vfkreaderp.h"
      34                 : 
      35                 : #include "cpl_conv.h"
      36                 : #include "cpl_error.h"
      37                 : 
      38                 : #define SUPPORT_GEOMETRY
      39                 : 
      40                 : #ifdef SUPPORT_GEOMETRY
      41                 : #  include "ogr_geometry.h"
      42                 : #endif
      43                 : 
      44                 : /*!
      45                 :   \brief IVFKReader desctructor
      46                 : */
      47               1 : IVFKReader::~IVFKReader()
      48                 : {
      49               1 : }
      50                 : 
      51                 : /*!
      52                 :   \brief Create new instance of VFKReader
      53                 : 
      54                 :   \return pointer to VFKReader instance
      55                 : */
      56               1 : IVFKReader *CreateVFKReader()
      57                 : {
      58               1 :     return new VFKReader();
      59                 : }
      60                 : 
      61                 : /*!
      62                 :   \brief VFKReader constructor
      63                 : */
      64               1 : VFKReader::VFKReader()
      65                 : {
      66               1 :     m_pszFilename     = NULL;
      67                 : 
      68               1 :     m_pszWholeText    = NULL;
      69                 :     
      70               1 :     m_nDataBlockCount = 0;
      71               1 :     m_papoDataBlock   = NULL;
      72               1 : }
      73                 : 
      74                 : /*!
      75                 :   \brief VFKReader destructor
      76                 : */
      77               2 : VFKReader::~VFKReader()
      78                 : {
      79               1 :     CPLFree(m_pszFilename);
      80                 : 
      81               1 :     VSIFree(m_pszWholeText);
      82                 :     
      83                 :     /* clear data blocks */
      84              62 :     for (int i = 0; i < m_nDataBlockCount; i++)
      85              61 :         delete m_papoDataBlock[i];
      86               1 :     CPLFree(m_papoDataBlock);
      87                 : 
      88               1 :     m_nDataBlockCount = 0;
      89               1 :     m_papoDataBlock = NULL;
      90               2 : }
      91                 : 
      92                 : /*!
      93                 :   \brief Set source file
      94                 : 
      95                 :   \param pszFilename source filename
      96                 : */
      97               1 : void VFKReader::SetSourceFile(const char *pszFilename)
      98                 : {
      99               1 :     CPLFree(m_pszFilename);
     100               1 :     m_pszFilename = CPLStrdup(pszFilename);
     101               1 : }
     102                 : 
     103                 : /*!
     104                 :   \brief Read the file & load the data
     105                 : 
     106                 :   \param pszFile pointer to a filename
     107                 : 
     108                 :   \return TRUE on success
     109                 :   \return FALSE on error
     110                 : */
     111               1 : int VFKReader::LoadData()
     112                 : {
     113                 :     FILE *fp;
     114                 :     long          nLength;
     115                 : 
     116               1 :     if (m_pszFilename == NULL)
     117               0 :   return FALSE;
     118                 : 
     119                 :     /* load vfk file */
     120               1 :     fp = VSIFOpen(m_pszFilename, "rb");
     121               1 :     if (fp == NULL) {
     122                 :   CPLError(CE_Failure, CPLE_OpenFailed, 
     123               0 :      "Failed to open file %s.", m_pszFilename);
     124               0 :         return FALSE;
     125                 :     }
     126                 : 
     127                 :     /* get file length */
     128               1 :     VSIFSeek(fp, 0, SEEK_END);
     129               1 :     nLength = VSIFTell(fp);
     130               1 :     VSIFSeek(fp, 0, SEEK_SET);
     131                 : 
     132                 :     /* read file - is necessary to read the whole file? */
     133               1 :     m_pszWholeText = (char *) VSIMalloc(nLength+1);
     134                 :     
     135               1 :     if (m_pszWholeText == NULL) {
     136                 :         CPLError(CE_Failure, CPLE_AppDefined, 
     137                 :      "Failed to allocate %ld byte buffer for %s,\n"
     138                 :      "is this really a VFK file?",
     139               0 :      nLength, m_pszFilename);
     140               0 :         VSIFClose(fp);
     141               0 :         return FALSE;
     142                 :     }
     143                 :     
     144               1 :     if (VSIFRead(m_pszWholeText, nLength, 1, fp) != 1) {
     145               0 :         VSIFree(m_pszWholeText);
     146               0 :         VSIFClose(fp);
     147                 :         CPLError(CE_Failure, CPLE_AppDefined, 
     148               0 :      "Read failed on %s.", m_pszFilename);
     149               0 :         return FALSE;
     150                 :     }
     151                 :     
     152               1 :     m_pszWholeText[nLength] = '\0';
     153                 : 
     154               1 :     VSIFClose(fp);
     155                 : 
     156                 :     /* split lines */
     157                 :     /* TODO: reduce chars */
     158           14369 :     for (char *poChar = m_pszWholeText; *poChar != '\0'; poChar++) {
     159           14368 :   if (*poChar == '\244') { 
     160               0 :       *(poChar++) = ' '; // \r
     161               0 :       *(poChar++) = ' '; // \n
     162               0 :       *poChar = ' ';
     163                 :   }
     164                 :     }
     165                 :     
     166               1 :     CPLDebug("OGR_VFK", "VFKReader::LoadData(): length=%ld", nLength);
     167                 : 
     168               1 :     return TRUE;
     169                 : }
     170                 : 
     171             114 : static const char *GetDataBlockName(const char *pszLine)
     172                 : {
     173                 :     int         n;
     174                 :     const char *pszLineChar;
     175                 :     char       *pszBlockName;
     176                 : 
     177             114 :     for (pszLineChar = pszLine + 2, n = 0; *pszLineChar != ';'; pszLineChar++, n++)
     178                 :   ;
     179             114 :     pszBlockName = (char *) CPLMalloc(n+1);
     180             114 :     strncpy(pszBlockName, pszLine + 2, n);
     181             114 :     pszBlockName[n] = '\0';
     182                 : 
     183             114 :     return pszBlockName;
     184                 : }
     185                 : 
     186                 : /*!
     187                 :   \brief Get data blocks (&B)
     188                 : 
     189                 :   Call LoadData() before this function.
     190                 : 
     191                 :   \return FALSE on error
     192                 :   \return TRUE on success
     193                 : */
     194               1 : int VFKReader::LoadDataBlocks()
     195                 : { 
     196                 :     char         *pszChar;
     197                 :     char         *pszLine;
     198                 :     char         *pszBlockName;
     199                 :     int           nRow;
     200                 :     
     201                 :     VFKDataBlock *poNewDataBlock;
     202                 : 
     203               1 :     poNewDataBlock = NULL;
     204               1 :     pszBlockName = NULL;
     205               1 :     nRow = 0;
     206                 : 
     207                 :     /* read lines */
     208               1 :     pszChar = m_pszWholeText;
     209               1 :     pszLine = m_pszWholeText;
     210           14241 :     while (pszLine) {
     211           14240 :   if (*pszChar == '\r' && *(pszChar+1) == '\n') {
     212             128 :       nRow++;
     213             189 :       if (*pszLine == '&' && *(pszLine+1) == 'B') {
     214                 :     /* add data block */
     215              61 :     pszBlockName = (char *) GetDataBlockName(pszLine);
     216              61 :     poNewDataBlock = new VFKDataBlock(pszBlockName, this);
     217              61 :     CPLFree(pszBlockName);
     218              61 :     pszBlockName = NULL;
     219              61 :     poNewDataBlock->SetGeometryType();
     220              61 :     poNewDataBlock->SetProperties(pszLine);
     221              61 :     AddDataBlock(poNewDataBlock);
     222                 :       }
     223             120 :       else if (*pszLine == '&' && *(pszLine+1) == 'D') {
     224                 :     /* data row */
     225              53 :     pszBlockName = (char*) GetDataBlockName(pszLine);
     226              53 :     poNewDataBlock = GetDataBlock(pszBlockName);
     227              53 :     if (poNewDataBlock == NULL) {
     228               0 :         if (!EQUAL(pszBlockName, "KATUZE")) {
     229                 :       /* ignore KATUZE block */
     230                 :       CPLError(CE_Warning, CPLE_AppDefined, 
     231               0 :          "Data block '%s' not found.\n", pszBlockName);
     232                 :         }
     233                 :     }
     234                 :     else {
     235              53 :         poNewDataBlock->AddFeature(pszLine);
     236              53 :         CPLFree(pszBlockName);
     237              53 :         pszBlockName = NULL;
     238                 :     }
     239                 :       }
     240              27 :       else if (*pszLine == '&' && *(pszLine+1) == 'H') {
     241                 :     /* header - metadata */
     242              13 :     AddInfo(pszLine);
     243                 :       }
     244               1 :       else if (*pszLine == '&' && *(pszLine+1) == 'K') {
     245                 :     /* end of file */
     246               1 :     break;
     247                 :       }
     248             127 :       pszChar++;
     249             127 :       pszLine = pszChar + 1;
     250                 :   }
     251           14239 :   pszChar++;
     252                 :     }
     253                 : 
     254               1 :     if (pszBlockName)
     255               0 :   CPLFree(pszBlockName);
     256                 : 
     257               1 :     return TRUE;
     258                 : }
     259                 : 
     260                 : /*!
     261                 :   \brief Add new data block
     262                 : 
     263                 :   \param poNewDataBlock pointer to VFKDataBlock instance
     264                 : 
     265                 :   \return number of registred data blocks
     266                 : */
     267              61 : int VFKReader::AddDataBlock(VFKDataBlock *poNewDataBlock)
     268                 : {
     269              61 :     m_nDataBlockCount++;
     270                 :     
     271                 :     // CPLDebug("OGR_VFK", "VFKReader::AddDataBlock(): i=%d", m_nDataBlockCount);
     272                 : 
     273                 :     m_papoDataBlock = (VFKDataBlock **)
     274              61 :   CPLRealloc(m_papoDataBlock, sizeof (VFKDataBlock *) * m_nDataBlockCount);
     275              61 :     m_papoDataBlock[m_nDataBlockCount-1] = poNewDataBlock;
     276                 : 
     277              61 :     return m_nDataBlockCount;
     278                 : }
     279                 : 
     280                 : /*!
     281                 :   \brief Get data block
     282                 : 
     283                 :   \param i index (starting with 0)
     284                 : 
     285                 :   \return pointer to VFKDataBlock instance
     286                 :   \return NULL on failure
     287                 : */
     288            4587 : VFKDataBlock *VFKReader::GetDataBlock(int i) const
     289                 : {
     290            4587 :     if (i < 0 || i >= m_nDataBlockCount)
     291               0 :         return NULL;
     292                 :     
     293            4587 :     return m_papoDataBlock[i];
     294                 : }
     295                 : 
     296                 : /*!
     297                 :   \brief Get data block
     298                 : 
     299                 :   \param pszName data block name
     300                 : 
     301                 :   \return pointer to VFKDataBlock instance
     302                 :   \return NULL on failure
     303                 : */
     304             117 : VFKDataBlock *VFKReader::GetDataBlock(const char *pszName) const
     305                 : {
     306            4409 :     for (int i = 0; i < m_nDataBlockCount; i++) {
     307            4409 :         if (EQUAL(GetDataBlock(i)->GetName(), pszName))
     308             117 :             return GetDataBlock(i);
     309                 :     }
     310                 : 
     311               0 :     return NULL;
     312                 : }
     313                 : 
     314                 : /*!
     315                 :   \brief Load geometry (loop datablocks)
     316                 : 
     317                 :   \return number of processed features
     318                 : */
     319               0 : long VFKReader::LoadGeometry()
     320                 : {
     321                 :     long int nfeatures;
     322                 : 
     323               0 :     nfeatures = 0;
     324               0 :     for (int i = 0; i < m_nDataBlockCount; i++) {
     325               0 :   nfeatures += m_papoDataBlock[i]->LoadGeometry();
     326                 :     }
     327                 :     
     328               0 :     CPLDebug("OGR_VFK", "VFKReader::LoadGeometry(): n=%ld", nfeatures);
     329                 :     
     330               0 :     return nfeatures;
     331                 : }
     332                 : 
     333                 : /*!
     334                 :   \brief Add info
     335                 : 
     336                 :   \param pszLine pointer to line
     337                 : */
     338              13 : void VFKReader::AddInfo(const char *pszLine)
     339                 : {
     340                 :     int iKeyLength, iValueLength;
     341                 :     char *pszKey, *pszValue;
     342                 :     const char *poChar, *poKey, *poValue;
     343              13 :     std::string key, value;
     344                 :     
     345              13 :     poChar = poKey = pszLine + 2; /* &H */
     346              13 :     iKeyLength = 0;
     347             103 :     while (*(poChar++) != ';')
     348              77 :   iKeyLength++;
     349              13 :     pszKey = (char *) CPLMalloc(iKeyLength + 1);
     350              13 :     strncpy(pszKey, poKey, iKeyLength);
     351              13 :     pszKey[iKeyLength] = '\0';
     352                 : 
     353              13 :     poValue = poChar;
     354              13 :     iValueLength = 0;
     355            1177 :     while(*poChar != '\r' && *(poChar+1) != '\n') {
     356            1151 :   iValueLength++;
     357            1151 :   poChar++;
     358                 :     }
     359              13 :     pszValue = (char *) CPLMalloc(iValueLength + 1);
     360              13 :     strncpy(pszValue, poValue, iValueLength);
     361              13 :     pszValue[iValueLength] = '\0';
     362                 : 
     363              13 :     poInfo[pszKey] = pszValue;
     364                 : 
     365              13 :     CPLFree(pszKey);
     366              13 :     CPLFree(pszValue);
     367              13 : }
     368                 : 
     369                 : /*!
     370                 :   \brief Get info
     371                 : 
     372                 :   \param key key string
     373                 : 
     374                 :   \return pointer to value string
     375                 :   \return NULL if key not found
     376                 : */
     377               0 : const char *VFKReader::GetInfo(const char *key)
     378                 : {
     379               0 :     if (poInfo.find(key) == poInfo.end())
     380               0 :   return NULL;
     381                 : 
     382               0 :     return poInfo[key].c_str();
     383                 : }

Generated by: LCOV version 1.7