LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/vfk - vfkreader.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 149 116 77.9 %
Date: 2011-12-18 Functions: 19 12 63.2 %

       1                 : /******************************************************************************
       2                 :  * $Id: vfkreader.cpp 18566 2010-01-16 16:36:45Z 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               1 : 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               1 : }
      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 :         m_pszWholeText = NULL;
     147               0 :         VSIFClose(fp);
     148                 :         CPLError(CE_Failure, CPLE_AppDefined, 
     149               0 :      "Read failed on %s.", m_pszFilename);
     150               0 :         return FALSE;
     151                 :     }
     152                 :     
     153               1 :     m_pszWholeText[nLength] = '\0';
     154                 : 
     155               1 :     VSIFClose(fp);
     156                 : 
     157                 :     /* split lines */
     158                 :     /* TODO: reduce chars */
     159           14369 :     for (char *poChar = m_pszWholeText; *poChar != '\0'; poChar++) {
     160           14368 :   if (*poChar == '\244' && *(poChar+1) != '\0' && *(poChar+2) != '\0') { 
     161               0 :       *(poChar++) = ' '; // \r
     162               0 :       *(poChar++) = ' '; // \n
     163               0 :       *poChar = ' ';
     164                 :   }
     165                 :     }
     166                 :     
     167               1 :     CPLDebug("OGR_VFK", "VFKReader::LoadData(): length=%ld", nLength);
     168                 : 
     169               1 :     return TRUE;
     170                 : }
     171                 : 
     172             114 : static char *GetDataBlockName(const char *pszLine)
     173                 : {
     174                 :     int         n;
     175                 :     const char *pszLineChar;
     176                 :     char       *pszBlockName;
     177                 : 
     178             114 :     for (pszLineChar = pszLine + 2, n = 0; *pszLineChar != '\0' && *pszLineChar != ';'; pszLineChar++, n++)
     179                 :   ;
     180                 : 
     181             114 :     if (*pszLineChar == '\0')
     182               0 :         return NULL;
     183                 : 
     184             114 :     pszBlockName = (char *) CPLMalloc(n+1);
     185             114 :     strncpy(pszBlockName, pszLine + 2, n);
     186             114 :     pszBlockName[n] = '\0';
     187                 : 
     188             114 :     return pszBlockName;
     189                 : }
     190                 : 
     191                 : /*!
     192                 :   \brief Get data blocks (&B)
     193                 : 
     194                 :   Call LoadData() before this function.
     195                 : 
     196                 :   \return FALSE on error
     197                 :   \return TRUE on success
     198                 : */
     199               1 : int VFKReader::LoadDataBlocks()
     200                 : { 
     201                 :     char         *pszChar;
     202                 :     char         *pszLine;
     203                 :     char         *pszBlockName;
     204                 :     int           nRow;
     205                 :     
     206                 :     VFKDataBlock *poNewDataBlock;
     207                 : 
     208               1 :     if (m_pszWholeText == NULL)
     209               0 :         return FALSE;
     210                 : 
     211               1 :     poNewDataBlock = NULL;
     212               1 :     pszBlockName = NULL;
     213               1 :     nRow = 0;
     214                 : 
     215                 :     /* read lines */
     216               1 :     pszChar = m_pszWholeText;
     217               1 :     pszLine = m_pszWholeText;
     218           14241 :     while (*pszChar != '\0') {
     219           14240 :   if (*pszChar == '\r' && *(pszChar+1) == '\n') {
     220             128 :       nRow++;
     221             189 :       if (*pszLine == '&' && *(pszLine+1) == 'B') {
     222                 :     /* add data block */
     223              61 :     pszBlockName = GetDataBlockName(pszLine);
     224              61 :                 if (pszBlockName == NULL)
     225               0 :                     break;
     226                 : 
     227              61 :     poNewDataBlock = new VFKDataBlock(pszBlockName, this);
     228              61 :     CPLFree(pszBlockName);
     229              61 :     pszBlockName = NULL;
     230              61 :     poNewDataBlock->SetGeometryType();
     231              61 :     poNewDataBlock->SetProperties(pszLine);
     232              61 :     AddDataBlock(poNewDataBlock);
     233                 :       }
     234             120 :       else if (*pszLine == '&' && *(pszLine+1) == 'D') {
     235                 :     /* data row */
     236              53 :     pszBlockName = GetDataBlockName(pszLine);
     237              53 :                 if (pszBlockName == NULL)
     238               0 :                     break;
     239                 : 
     240              53 :     poNewDataBlock = GetDataBlock(pszBlockName);
     241              53 :     if (poNewDataBlock == NULL) {
     242               0 :         if (!EQUAL(pszBlockName, "KATUZE")) {
     243                 :       /* ignore KATUZE block */
     244                 :       CPLError(CE_Warning, CPLE_AppDefined, 
     245               0 :          "Data block '%s' not found.\n", pszBlockName);
     246                 :         }
     247                 :     }
     248                 :     else 
     249              53 :         poNewDataBlock->AddFeature(pszLine);
     250                 : 
     251              53 :     CPLFree(pszBlockName);
     252              53 :     pszBlockName = NULL;
     253                 :       }
     254              27 :       else if (*pszLine == '&' && *(pszLine+1) == 'H') {
     255                 :     /* header - metadata */
     256              13 :     AddInfo(pszLine);
     257                 :       }
     258               1 :       else if (*pszLine == '&' && *(pszLine+1) == 'K') {
     259                 :     /* end of file */
     260               1 :     break;
     261                 :       }
     262             127 :       pszChar++;
     263             127 :       pszLine = pszChar + 1;
     264                 :   }
     265           14239 :   pszChar++;
     266                 :     }
     267                 : 
     268               1 :     return TRUE;
     269                 : }
     270                 : 
     271                 : /*!
     272                 :   \brief Add new data block
     273                 : 
     274                 :   \param poNewDataBlock pointer to VFKDataBlock instance
     275                 : 
     276                 :   \return number of registred data blocks
     277                 : */
     278              61 : int VFKReader::AddDataBlock(VFKDataBlock *poNewDataBlock)
     279                 : {
     280              61 :     m_nDataBlockCount++;
     281                 :     
     282                 :     // CPLDebug("OGR_VFK", "VFKReader::AddDataBlock(): i=%d", m_nDataBlockCount);
     283                 : 
     284                 :     m_papoDataBlock = (VFKDataBlock **)
     285              61 :   CPLRealloc(m_papoDataBlock, sizeof (VFKDataBlock *) * m_nDataBlockCount);
     286              61 :     m_papoDataBlock[m_nDataBlockCount-1] = poNewDataBlock;
     287                 : 
     288              61 :     return m_nDataBlockCount;
     289                 : }
     290                 : 
     291                 : /*!
     292                 :   \brief Get data block
     293                 : 
     294                 :   \param i index (starting with 0)
     295                 : 
     296                 :   \return pointer to VFKDataBlock instance
     297                 :   \return NULL on failure
     298                 : */
     299            4587 : VFKDataBlock *VFKReader::GetDataBlock(int i) const
     300                 : {
     301            4587 :     if (i < 0 || i >= m_nDataBlockCount)
     302               0 :         return NULL;
     303                 :     
     304            4587 :     return m_papoDataBlock[i];
     305                 : }
     306                 : 
     307                 : /*!
     308                 :   \brief Get data block
     309                 : 
     310                 :   \param pszName data block name
     311                 : 
     312                 :   \return pointer to VFKDataBlock instance
     313                 :   \return NULL on failure
     314                 : */
     315             117 : VFKDataBlock *VFKReader::GetDataBlock(const char *pszName) const
     316                 : {
     317            4409 :     for (int i = 0; i < m_nDataBlockCount; i++) {
     318            4409 :         if (EQUAL(GetDataBlock(i)->GetName(), pszName))
     319             117 :             return GetDataBlock(i);
     320                 :     }
     321                 : 
     322               0 :     return NULL;
     323                 : }
     324                 : 
     325                 : /*!
     326                 :   \brief Load geometry (loop datablocks)
     327                 : 
     328                 :   \return number of processed features
     329                 : */
     330               0 : long VFKReader::LoadGeometry()
     331                 : {
     332                 :     long int nfeatures;
     333                 : 
     334               0 :     nfeatures = 0;
     335               0 :     for (int i = 0; i < m_nDataBlockCount; i++) {
     336               0 :   nfeatures += m_papoDataBlock[i]->LoadGeometry();
     337                 :     }
     338                 :     
     339               0 :     CPLDebug("OGR_VFK", "VFKReader::LoadGeometry(): n=%ld", nfeatures);
     340                 :     
     341               0 :     return nfeatures;
     342                 : }
     343                 : 
     344                 : /*!
     345                 :   \brief Add info
     346                 : 
     347                 :   \param pszLine pointer to line
     348                 : */
     349              13 : void VFKReader::AddInfo(const char *pszLine)
     350                 : {
     351                 :     int iKeyLength, iValueLength;
     352                 :     char *pszKey, *pszValue;
     353                 :     const char *poChar, *poKey, *poValue;
     354              13 :     std::string key, value;
     355                 :     
     356              13 :     poChar = poKey = pszLine + 2; /* &H */
     357              13 :     iKeyLength = 0;
     358             103 :     while (*poChar != '\0' && *poChar != ';')
     359                 :     {
     360              77 :   iKeyLength++;
     361              77 :         poChar ++;
     362                 :     }
     363              13 :     if( *poChar == '\0' )
     364                 :         return;
     365                 : 
     366              13 :     pszKey = (char *) CPLMalloc(iKeyLength + 1);
     367              13 :     strncpy(pszKey, poKey, iKeyLength);
     368              13 :     pszKey[iKeyLength] = '\0';
     369                 : 
     370              13 :     poValue = poChar;
     371              13 :     iValueLength = 0;
     372            1190 :     while(*poChar != '\0' && !(*poChar == '\r' && *(poChar+1) == '\n')) {
     373            1164 :   iValueLength++;
     374            1164 :   poChar++;
     375                 :     }
     376              13 :     if( *poChar == '\0' )
     377                 :     {
     378               0 :         CPLFree(pszKey);
     379                 :         return;
     380                 :     }
     381                 : 
     382              13 :     pszValue = (char *) CPLMalloc(iValueLength + 1);
     383              13 :     strncpy(pszValue, poValue, iValueLength);
     384              13 :     pszValue[iValueLength] = '\0';
     385                 : 
     386              13 :     poInfo[pszKey] = pszValue;
     387                 : 
     388              13 :     CPLFree(pszKey);
     389              13 :     CPLFree(pszValue);
     390                 : }
     391                 : 
     392                 : /*!
     393                 :   \brief Get info
     394                 : 
     395                 :   \param key key string
     396                 : 
     397                 :   \return pointer to value string
     398                 :   \return NULL if key not found
     399                 : */
     400               0 : const char *VFKReader::GetInfo(const char *key)
     401                 : {
     402               0 :     if (poInfo.find(key) == poInfo.end())
     403               0 :   return NULL;
     404                 : 
     405               0 :     return poInfo[key].c_str();
     406                 : }

Generated by: LCOV version 1.7