LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/pds - ogrpdsdatasource.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 152 98 64.5 %
Date: 2011-12-18 Functions: 12 8 66.7 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrpdsdatasource.cpp 23042 2011-09-04 15:07:22Z rouault $
       3                 :  *
       4                 :  * Project:  PDS Translator
       5                 :  * Purpose:  Implements OGRPDSDataSource class
       6                 :  * Author:   Even Rouault, even dot rouault at mines dash paris dot org
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2010, Even Rouault <even dot rouault at mines dash paris dot 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 "ogr_pds.h"
      31                 : #include "cpl_conv.h"
      32                 : #include "cpl_string.h"
      33                 : 
      34                 : CPL_CVSID("$Id: ogrpdsdatasource.cpp 23042 2011-09-04 15:07:22Z rouault $");
      35                 : 
      36                 : /************************************************************************/
      37                 : /*                           OGRPDSDataSource()                         */
      38                 : /************************************************************************/
      39                 : 
      40              85 : OGRPDSDataSource::OGRPDSDataSource()
      41                 : 
      42                 : {
      43              85 :     papoLayers = NULL;
      44              85 :     nLayers = 0;
      45                 : 
      46              85 :     pszName = NULL;
      47              85 : }
      48                 : 
      49                 : /************************************************************************/
      50                 : /*                        ~OGRPDSDataSource()                           */
      51                 : /************************************************************************/
      52                 : 
      53              85 : OGRPDSDataSource::~OGRPDSDataSource()
      54                 : 
      55                 : {
      56              86 :     for( int i = 0; i < nLayers; i++ )
      57               1 :         delete papoLayers[i];
      58              85 :     CPLFree( papoLayers );
      59                 : 
      60              85 :     CPLFree( pszName );
      61              85 : }
      62                 : 
      63                 : /************************************************************************/
      64                 : /*                           TestCapability()                           */
      65                 : /************************************************************************/
      66                 : 
      67               0 : int OGRPDSDataSource::TestCapability( const char * pszCap )
      68                 : 
      69                 : {
      70               0 :     return FALSE;
      71                 : }
      72                 : 
      73                 : /************************************************************************/
      74                 : /*                              GetLayer()                              */
      75                 : /************************************************************************/
      76                 : 
      77               1 : OGRLayer *OGRPDSDataSource::GetLayer( int iLayer )
      78                 : 
      79                 : {
      80               1 :     if( iLayer < 0 || iLayer >= nLayers )
      81               0 :         return NULL;
      82                 :     else
      83               1 :         return papoLayers[iLayer];
      84                 : }
      85                 : 
      86                 : 
      87                 : /************************************************************************/
      88                 : /*                          GetKeywordSub()                             */
      89                 : /************************************************************************/
      90                 : 
      91               2 : const char * OGRPDSDataSource::GetKeywordSub( const char *pszPath, 
      92                 :                                                    int iSubscript,
      93                 :                                                    const char *pszDefault )
      94                 : 
      95                 : {
      96               2 :     const char *pszResult = oKeywords.GetKeyword( pszPath, NULL );
      97                 :     
      98               2 :     if( pszResult == NULL )
      99               0 :         return pszDefault;
     100                 : 
     101               2 :     if( pszResult[0] != '(' ) 
     102               0 :         return pszDefault;
     103                 : 
     104                 :     char **papszTokens = CSLTokenizeString2( pszResult, "(,)", 
     105               2 :                                              CSLT_HONOURSTRINGS );
     106                 : 
     107               2 :     if( iSubscript <= CSLCount(papszTokens) )
     108                 :     {
     109               2 :         osTempResult = papszTokens[iSubscript-1];
     110               2 :         CSLDestroy( papszTokens );
     111               2 :         return osTempResult.c_str();
     112                 :     }
     113                 :     else
     114                 :     {
     115               0 :         CSLDestroy( papszTokens );
     116               0 :         return pszDefault;
     117                 :     }
     118                 : }
     119                 : 
     120                 : /************************************************************************/
     121                 : /*                            CleanString()                             */
     122                 : /*                                                                      */
     123                 : /* Removes single or double quotes, and converts spaces to underscores. */
     124                 : /* The change is made in-place to CPLString.                            */
     125                 : /************************************************************************/
     126                 : 
     127              55 : void OGRPDSDataSource::CleanString( CPLString &osInput )
     128                 : 
     129                 : {
     130              55 :    if(  ( osInput.size() < 2 ) ||
     131                 :         ((osInput.at(0) != '"'   || osInput.at(osInput.size()-1) != '"' ) &&
     132                 :         ( osInput.at(0) != '\'' || osInput.at(osInput.size()-1) != '\'')) )
     133              29 :         return;
     134                 : 
     135              26 :     char *pszWrk = CPLStrdup(osInput.c_str() + 1);
     136                 :     int i;
     137                 : 
     138              26 :     pszWrk[strlen(pszWrk)-1] = '\0';
     139                 :     
     140             410 :     for( i = 0; pszWrk[i] != '\0'; i++ )
     141                 :     {
     142             384 :         if( pszWrk[i] == ' ' )
     143               0 :             pszWrk[i] = '_';
     144                 :     }
     145                 : 
     146              26 :     osInput = pszWrk;
     147              26 :     CPLFree( pszWrk );
     148                 : }
     149                 : 
     150                 : /************************************************************************/
     151                 : /*                           LoadTable()                                */
     152                 : /************************************************************************/
     153                 : 
     154               4 : static CPLString MakeAttr(CPLString os1, CPLString os2)
     155                 : {
     156               4 :     return os1 + "." + os2;
     157                 : }
     158                 : 
     159               1 : int OGRPDSDataSource::LoadTable(const char* pszFilename,
     160                 :                                      int nRecordSize,
     161                 :                                      CPLString osTableID )
     162                 : {
     163                 : 
     164               1 :     CPLString osTableFilename;
     165                 :     int nStartBytes;
     166                 :     
     167               1 :     CPLString osTableLink = "^";
     168               1 :     osTableLink += osTableID;
     169                 :     
     170               1 :     CPLString osTable = oKeywords.GetKeyword( osTableLink, "" );
     171               1 :     if( osTable[0] == '(' )
     172                 :     {
     173               1 :         osTableFilename = GetKeywordSub(osTableLink, 1, "");
     174               1 :         CPLString osStartRecord = GetKeywordSub(osTableLink, 2, "");
     175               1 :         nStartBytes = (atoi(osStartRecord.c_str()) - 1) * nRecordSize;
     176               1 :         if (osTableFilename.size() == 0 || osStartRecord.size() == 0 ||
     177                 :             nStartBytes < 0)
     178                 :         {
     179                 :             CPLError(CE_Failure, CPLE_NotSupported,
     180               0 :                     "Cannot parse %s line", osTableLink.c_str());
     181               0 :             return FALSE;
     182                 :         }
     183               1 :         CPLString osTPath = CPLGetPath(pszFilename);
     184               1 :         CleanString( osTableFilename );
     185               1 :         osTableFilename = CPLFormCIFilename( osTPath, osTableFilename, NULL );
     186                 :     }
     187                 :     else
     188                 :     {
     189               0 :         osTableFilename = oKeywords.GetKeyword( osTableLink, "" );
     190               0 :         if (osTableFilename.size() != 0 && osTableFilename[0] >= '0' &&
     191                 :             osTableFilename[0] <= '9')
     192                 :         {
     193               0 :             nStartBytes = atoi(osTableFilename.c_str()) - 1;
     194               0 :             if (strstr(osTableFilename.c_str(), "<BYTES>") == NULL)
     195               0 :                 nStartBytes *= nRecordSize;
     196               0 :             osTableFilename = pszFilename;
     197                 :         }
     198                 :         else
     199                 :         {
     200               0 :             CPLString osTPath = CPLGetPath(pszFilename);
     201               0 :             CleanString( osTableFilename );
     202               0 :             osTableFilename = CPLFormCIFilename( osTPath, osTableFilename, NULL );
     203               0 :             nStartBytes = 0;
     204                 :         }
     205                 :     }
     206                 : 
     207               1 :     CPLString osTableName = oKeywords.GetKeyword( MakeAttr(osTableID, "NAME"), "" );
     208               1 :     if (osTableName.size() == 0)
     209                 :     {
     210               0 :         if (GetLayerByName(osTableID.c_str()) == NULL)
     211               0 :             osTableName = osTableID;
     212                 :         else
     213               0 :             osTableName = CPLSPrintf("Layer_%d", nLayers+1);
     214                 :     }
     215               1 :     CleanString(osTableName);
     216                 :     CPLString osTableInterchangeFormat =
     217               1 :             oKeywords.GetKeyword( MakeAttr(osTableID, "INTERCHANGE_FORMAT"), "" );
     218               1 :     CPLString osTableRows = oKeywords.GetKeyword( MakeAttr(osTableID, "ROWS"), "" );
     219               1 :     int nRecords = atoi(osTableRows);
     220               1 :     if (osTableInterchangeFormat.size() == 0 ||
     221                 :         osTableRows.size() == 0 || nRecords < 0)
     222                 :     {
     223                 :         CPLError(CE_Failure, CPLE_NotSupported,
     224               0 :                  "One of TABLE.INTERCHANGE_FORMAT or TABLE.ROWS is missing");
     225               0 :         return FALSE;
     226                 :     }
     227                 :     
     228               1 :     CleanString(osTableInterchangeFormat);
     229               1 :     if (osTableInterchangeFormat.compare("ASCII") != 0 &&
     230                 :         osTableInterchangeFormat.compare("BINARY") != 0)
     231                 :     {
     232                 :         CPLError(CE_Failure, CPLE_NotSupported,
     233               0 :                  "Only INTERCHANGE_FORMAT=ASCII or BINARY is supported");
     234               0 :         return FALSE;
     235                 :     }
     236                 : 
     237               1 :     VSILFILE* fp = VSIFOpenL(osTableFilename, "rb");
     238               1 :     if (fp == NULL)
     239                 :     {
     240                 :         CPLError(CE_Failure, CPLE_AppDefined, "Cannot open %s",
     241               0 :                  osTableFilename.c_str());
     242               0 :         return FALSE;
     243                 :     }
     244                 : 
     245               1 :     CPLString osTableStructure = oKeywords.GetKeyword( MakeAttr(osTableID, "^STRUCTURE"), "" );
     246               1 :     if (osTableStructure.size() != 0)
     247                 :     {
     248               1 :         CPLString osTPath = CPLGetPath(pszFilename);
     249               1 :         CleanString( osTableStructure );
     250               1 :         osTableStructure = CPLFormCIFilename( osTPath, osTableStructure, NULL );
     251                 :     }
     252                 : 
     253               1 :     GByte* pabyRecord = (GByte*) VSIMalloc(nRecordSize + 1);
     254               1 :     if (pabyRecord == NULL)
     255                 :     {
     256               0 :         VSIFCloseL(fp);
     257               0 :         return FALSE;
     258                 :     }
     259               1 :     pabyRecord[nRecordSize] = 0;
     260                 : 
     261               1 :     papoLayers = (OGRLayer**) CPLRealloc(papoLayers, (nLayers + 1) * sizeof(OGRLayer*));
     262               1 :     papoLayers[nLayers] = new OGRPDSLayer(osTableID, osTableName, fp,
     263                 :                                          pszFilename,
     264                 :                                          osTableStructure,
     265                 :                                          nRecords, nStartBytes,
     266                 :                                          nRecordSize, pabyRecord,
     267               1 :                                          osTableInterchangeFormat.compare("ASCII") == 0);
     268               1 :     nLayers++;
     269                 : 
     270               1 :     return TRUE;
     271                 : }
     272                 : 
     273                 : /************************************************************************/
     274                 : /*                                Open()                                */
     275                 : /************************************************************************/
     276                 : 
     277              85 : int OGRPDSDataSource::Open( const char * pszFilename, int bUpdateIn)
     278                 : 
     279                 : {
     280              85 :     if (bUpdateIn)
     281                 :     {
     282              13 :         return FALSE;
     283                 :     }
     284                 : 
     285              72 :     pszName = CPLStrdup( pszFilename );
     286                 : 
     287                 : // --------------------------------------------------------------------
     288                 : //      Does this appear to be a .PDS table file?
     289                 : // --------------------------------------------------------------------
     290                 : 
     291              72 :     VSILFILE* fp = VSIFOpenL(pszFilename, "rb");
     292              72 :     if (fp == NULL)
     293              36 :         return FALSE;
     294                 : 
     295                 :     char szBuffer[512];
     296              36 :     int nbRead = (int)VSIFReadL(szBuffer, 1, sizeof(szBuffer) - 1, fp);
     297              36 :     szBuffer[nbRead] = '\0';
     298                 : 
     299              36 :     const char* pszPos = strstr(szBuffer, "PDS_VERSION_ID");
     300              36 :     int bIsPDS = (pszPos != NULL);
     301                 : 
     302              36 :     if (!bIsPDS)
     303                 :     {
     304              35 :         VSIFCloseL(fp);
     305              35 :         return FALSE;
     306                 :     }
     307                 : 
     308               1 :     if (!oKeywords.Ingest(fp, pszPos - szBuffer))
     309                 :     {
     310               0 :         VSIFCloseL(fp);
     311               0 :         return FALSE;
     312                 :     }
     313                 : 
     314               1 :     VSIFCloseL(fp);
     315               1 :     CPLString osRecordType = oKeywords.GetKeyword( "RECORD_TYPE", "" );
     316               1 :     CPLString osFileRecords = oKeywords.GetKeyword( "FILE_RECORDS", "" );
     317               1 :     CPLString osRecordBytes = oKeywords.GetKeyword( "RECORD_BYTES", "" );
     318               1 :     int nRecordSize = atoi(osRecordBytes);
     319               1 :     if (osRecordType.size() == 0 || osFileRecords.size() == 0 ||
     320                 :         osRecordBytes.size() == 0 || nRecordSize <= 0)
     321                 :     {
     322                 :         CPLError(CE_Failure, CPLE_NotSupported,
     323               0 :                  "One of RECORD_TYPE, FILE_RECORDS or RECORD_BYTES is missing");
     324               0 :         return FALSE;
     325                 :     }
     326               1 :     CleanString(osRecordType);
     327               1 :     if (osRecordType.compare("FIXED_LENGTH") != 0)
     328                 :     {
     329                 :         CPLError(CE_Failure, CPLE_NotSupported,
     330               0 :                  "Only RECORD_TYPE=FIXED_LENGTH is supported");
     331               0 :         return FALSE;
     332                 :     }
     333                 : 
     334               1 :     CPLString osTable = oKeywords.GetKeyword( "^TABLE", "" );
     335               1 :     if (osTable.size() != 0)
     336               1 :         LoadTable(pszFilename, nRecordSize, "TABLE");
     337                 :     else
     338                 :     {
     339               0 :         VSILFILE* fp = VSIFOpenL(pszFilename, "rb");
     340               0 :         if (fp == NULL)
     341               0 :             return FALSE;
     342                 : 
     343               0 :         while(TRUE)
     344                 :         {
     345               0 :             CPLPushErrorHandler(CPLQuietErrorHandler);
     346               0 :             const char* pszLine = CPLReadLine2L(fp, 256, NULL);
     347               0 :             CPLPopErrorHandler();
     348               0 :             CPLErrorReset();
     349               0 :             if (pszLine == NULL)
     350                 :                 break;
     351                 :             char** papszTokens =
     352               0 :                 CSLTokenizeString2( pszLine, " =", CSLT_HONOURSTRINGS );
     353               0 :             int nTokens = CSLCount(papszTokens);
     354               0 :             if (nTokens == 2 &&
     355               0 :                 papszTokens[0][0] == '^' &&
     356                 :                 strstr(papszTokens[0], "TABLE") != NULL)
     357                 :             {
     358               0 :                 LoadTable(pszFilename, nRecordSize, papszTokens[0] + 1);
     359                 :             }
     360               0 :             CSLDestroy(papszTokens);
     361               0 :             papszTokens = NULL;
     362                 :         }
     363               0 :         VSIFCloseL(fp);
     364                 :     }
     365                 : 
     366               1 :     return nLayers != 0;
     367                 : }

Generated by: LCOV version 1.7