LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/pds - ogrpdslayer.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 370 171 46.2 %
Date: 2012-04-28 Functions: 13 9 69.2 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrpdslayer.cpp 20996 2010-10-28 18:38:15Z rouault $
       3                 :  *
       4                 :  * Project:  PDS Translator
       5                 :  * Purpose:  Implements OGRPDSLayer 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                 : #include "ogr_p.h"
      34                 : 
      35                 : CPL_CVSID("$Id: ogrpdslayer.cpp 20996 2010-10-28 18:38:15Z rouault $");
      36                 : 
      37                 : /************************************************************************/
      38                 : /*                           OGRPDSLayer()                              */
      39                 : /************************************************************************/
      40                 : 
      41               2 : OGRPDSLayer::OGRPDSLayer(   CPLString osTableID,
      42                 :                             const char* pszLayerName, VSILFILE* fp,
      43                 :                             CPLString osLabelFilename,
      44                 :                             CPLString osStructureFilename,
      45                 :                             int nRecords,
      46                 :                             int nStartBytes, int nRecordSize,
      47               2 :                             GByte* pabyRecord, int bIsASCII)
      48                 : 
      49                 : {
      50               2 :     fpPDS = fp;
      51               2 :     this->osTableID = osTableID;
      52               2 :     this->nRecords = nRecords;
      53               2 :     this->nStartBytes = nStartBytes;
      54               2 :     this->nRecordSize = nRecordSize;
      55               2 :     nLongitudeIndex = -1;
      56               2 :     nLatitudeIndex = -1;
      57                 : 
      58               2 :     poFeatureDefn = new OGRFeatureDefn( pszLayerName );
      59               2 :     poFeatureDefn->Reference();
      60               2 :     poFeatureDefn->SetGeomType( wkbNone );
      61                 : 
      62               2 :     pasFieldDesc = NULL;
      63                 : 
      64               2 :     this->pabyRecord = pabyRecord;
      65                 : 
      66               2 :     if (osStructureFilename.size() != 0)
      67                 :     {
      68               2 :         ReadStructure(osStructureFilename);
      69                 :     }
      70                 :     else
      71                 :     {
      72               0 :         ReadStructure(osLabelFilename);
      73                 :     }
      74                 : 
      75               2 :     if (bIsASCII &&
      76                 :         poFeatureDefn->GetFieldCount() == 0)
      77                 :     {
      78               0 :         VSIFSeekL( fpPDS, nStartBytes, SEEK_SET );
      79               0 :         VSIFReadL( pabyRecord, nRecordSize, 1, fpPDS);
      80                 : 
      81                 :         char **papszTokens = CSLTokenizeString2(
      82               0 :                 (const char*)pabyRecord, " ", CSLT_HONOURSTRINGS );
      83               0 :         int nTokens = CSLCount(papszTokens);
      84                 :         int i;
      85               0 :         for(i=0;i<nTokens;i++)
      86                 :         {
      87               0 :             const char* pszStr = papszTokens[i];
      88                 :             char ch;
      89               0 :             OGRFieldType eFieldType = OFTInteger;
      90               0 :             while((ch = *pszStr) != 0)
      91                 :             {
      92               0 :                 if ((ch >= '0' && ch <= '9') || ch == '+' || ch == '-')
      93                 :                 {
      94                 :                 }
      95               0 :                 else if (ch == '.')
      96                 :                 {
      97               0 :                     eFieldType = OFTReal;
      98                 :                 }
      99                 :                 else
     100                 :                 {
     101               0 :                     eFieldType = OFTString;
     102               0 :                     break;
     103                 :                 }
     104               0 :                 pszStr ++;
     105                 :             }
     106                 :             char szFieldName[32];
     107                 :             sprintf(szFieldName, "field_%d",
     108               0 :                     poFeatureDefn->GetFieldCount() + 1);
     109               0 :             OGRFieldDefn oFieldDefn(szFieldName, eFieldType);
     110               0 :             poFeatureDefn->AddFieldDefn(&oFieldDefn);
     111                 :         }
     112               0 :         CSLDestroy(papszTokens);
     113                 :     }
     114                 : 
     115               2 :     if (nLongitudeIndex >= 0 && nLatitudeIndex >= 0)
     116                 :     {
     117               2 :         poFeatureDefn->SetGeomType( wkbPoint );
     118                 :     }
     119                 : 
     120               2 :     ResetReading();
     121               2 : }
     122                 : 
     123                 : /************************************************************************/
     124                 : /*                             ~OGRPDSLayer()                           */
     125                 : /************************************************************************/
     126                 : 
     127               2 : OGRPDSLayer::~OGRPDSLayer()
     128                 : 
     129                 : {
     130               2 :     CPLFree(pasFieldDesc);
     131               2 :     poFeatureDefn->Release();
     132               2 :     VSIFree(pabyRecord);
     133                 : 
     134               2 :     VSIFCloseL( fpPDS );
     135               2 : }
     136                 : 
     137                 : 
     138                 : /************************************************************************/
     139                 : /*                           ReadStructure()                            */
     140                 : /************************************************************************/
     141                 : 
     142               2 : void OGRPDSLayer::ReadStructure(CPLString osStructureFilename)
     143                 : 
     144                 : {
     145               2 :     int nFields = 0;
     146               2 :     VSILFILE* fpStructure = VSIFOpenL(osStructureFilename, "rb");
     147               2 :     if (fpStructure == NULL)
     148               0 :         return;
     149                 : 
     150                 :     const char* pszLine;
     151               2 :     int bInObjectColumn = FALSE;
     152               2 :     int nExpectedColumnNumber = 0;
     153               2 :     CPLString osColumnName, osColumnDataType, osColumnStartByte,
     154               2 :               osColumnBytes, osColumnFormat, osColumnUnit,
     155               2 :               osColumnItems, osColumnItemBytes;
     156               2 :     int nRowBytes = nRecordSize;
     157             732 :     while(TRUE)
     158                 :     {
     159             734 :         CPLPushErrorHandler(CPLQuietErrorHandler);
     160             734 :         pszLine = CPLReadLine2L(fpStructure, 256, NULL);
     161             734 :         CPLPopErrorHandler();
     162             734 :         CPLErrorReset();
     163             734 :         if (pszLine == NULL)
     164               2 :             break;
     165                 : 
     166                 :         char **papszTokens =
     167             732 :                 CSLTokenizeString2( pszLine, " =", CSLT_HONOURSTRINGS );
     168             732 :         int nTokens = CSLCount(papszTokens);
     169                 : 
     170            1368 :         if (bInObjectColumn && nTokens >= 1 &&
     171             586 :             EQUAL(papszTokens[0], "END_OBJECT"))
     172                 :         {
     173              50 :             if (osColumnName.size() != 0 &&
     174                 :                 osColumnDataType.size() != 0 &&
     175                 :                 osColumnStartByte.size() != 0 &&
     176                 :                 osColumnBytes.size() != 0)
     177                 :             {
     178                 :                 pasFieldDesc =
     179                 :                         (FieldDesc*) CPLRealloc(pasFieldDesc,
     180              50 :                                 (nFields + 1) * sizeof(FieldDesc));
     181              50 :                 pasFieldDesc[nFields].nStartByte = atoi(osColumnStartByte) - 1;
     182              50 :                 pasFieldDesc[nFields].nByteCount = atoi(osColumnBytes);
     183             200 :                 if (pasFieldDesc[nFields].nStartByte >= 0 && 
     184              50 :                     pasFieldDesc[nFields].nByteCount > 0 &&
     185              50 :                     pasFieldDesc[nFields].nStartByte +
     186              50 :                     pasFieldDesc[nFields].nByteCount <= nRecordSize)
     187                 :                 {
     188              50 :                     OGRFieldType eFieldType = OFTString;
     189              50 :                     pasFieldDesc[nFields].eFormat = CHARACTER;
     190              50 :                     pasFieldDesc[nFields].nItemBytes = atoi(osColumnItemBytes);
     191              50 :                     pasFieldDesc[nFields].nItems = atoi(osColumnItems);
     192              50 :                     if (pasFieldDesc[nFields].nItems == 0)
     193              50 :                         pasFieldDesc[nFields].nItems = 1;
     194             100 :                     if (pasFieldDesc[nFields].nItemBytes == 0 &&
     195              50 :                         pasFieldDesc[nFields].nItems == 1)
     196              50 :                         pasFieldDesc[nFields].nItemBytes = pasFieldDesc[nFields].nByteCount;
     197                 : 
     198              50 :                     if (osColumnDataType.compare("ASCII_REAL") == 0)
     199                 :                     {
     200              28 :                         eFieldType = OFTReal;
     201              28 :                         pasFieldDesc[nFields].eFormat = ASCII_REAL;
     202                 :                     }
     203              22 :                     else if (osColumnDataType.compare("ASCII_INTEGER") == 0)
     204                 :                     {
     205              22 :                         eFieldType = OFTInteger;
     206              22 :                         pasFieldDesc[nFields].eFormat = ASCII_INTEGER;
     207                 :                     }
     208               0 :                     else if (osColumnDataType.compare("MSB_UNSIGNED_INTEGER") == 0)
     209                 :                     {
     210               0 :                         if (pasFieldDesc[nFields].nItemBytes == 1 ||
     211               0 :                             pasFieldDesc[nFields].nItemBytes == 2)
     212                 :                         {
     213               0 :                             if (pasFieldDesc[nFields].nItems > 1)
     214               0 :                                 eFieldType = OFTIntegerList;
     215                 :                             else
     216               0 :                                 eFieldType = OFTInteger;
     217                 :                         }
     218                 :                         else
     219                 :                         {
     220               0 :                             pasFieldDesc[nFields].nItemBytes = 4;
     221               0 :                             if (pasFieldDesc[nFields].nItems > 1)
     222               0 :                                 eFieldType = OFTRealList;
     223                 :                             else
     224               0 :                                 eFieldType = OFTReal;
     225                 :                         }
     226               0 :                         pasFieldDesc[nFields].eFormat = MSB_UNSIGNED_INTEGER;
     227                 :                     }
     228               0 :                     else if (osColumnDataType.compare("MSB_INTEGER") == 0)
     229                 :                     {
     230               0 :                         if (pasFieldDesc[nFields].nItemBytes != 1 &&
     231               0 :                             pasFieldDesc[nFields].nItemBytes != 2)
     232               0 :                             pasFieldDesc[nFields].nItemBytes = 4;
     233               0 :                         if (pasFieldDesc[nFields].nItems > 1)
     234               0 :                             eFieldType = OFTIntegerList;
     235                 :                         else
     236               0 :                             eFieldType = OFTInteger;
     237               0 :                         pasFieldDesc[nFields].eFormat = MSB_INTEGER;
     238                 :                     }
     239               0 :                     else if (osColumnDataType.compare("IEEE_REAL") == 0)
     240                 :                     {
     241               0 :                         if (pasFieldDesc[nFields].nItemBytes != 4)
     242               0 :                             pasFieldDesc[nFields].nItemBytes = 4;
     243               0 :                         if (pasFieldDesc[nFields].nItems > 1)
     244               0 :                             eFieldType = OFTRealList;
     245                 :                         else
     246               0 :                             eFieldType = OFTReal;
     247               0 :                         pasFieldDesc[nFields].eFormat = IEEE_REAL;
     248                 :                     }
     249                 : 
     250              50 :                     OGRFieldDefn oFieldDefn(osColumnName, eFieldType);
     251              72 :                     if ((pasFieldDesc[nFields].eFormat == ASCII_REAL &&
     252                 :                             osColumnFormat.size() != 0 &&
     253                 :                             osColumnFormat[0] == 'F') ||
     254              22 :                         (pasFieldDesc[nFields].eFormat == ASCII_INTEGER &&
     255                 :                             osColumnFormat.size() != 0 &&
     256                 :                             osColumnFormat[0] == 'I'))
     257                 :                     {
     258              50 :                         const char* pszFormat = osColumnFormat.c_str();
     259              50 :                         int nWidth = atoi(pszFormat + 1);
     260              50 :                         oFieldDefn.SetWidth(nWidth);
     261              50 :                         const char* pszPoint = strchr(pszFormat, '.');
     262              50 :                         if (pszPoint)
     263                 :                         {
     264              28 :                             int nPrecision = atoi(pszPoint + 1);
     265              28 :                             oFieldDefn.SetPrecision(nPrecision);
     266                 :                         }
     267                 :                     }
     268               0 :                     else if (oFieldDefn.GetType() == OFTString &&
     269                 :                                 osColumnFormat.size() != 0 &&
     270                 :                                 osColumnFormat[0] == 'A')
     271                 :                     {
     272               0 :                         const char* pszFormat = osColumnFormat.c_str();
     273               0 :                         int nWidth = atoi(pszFormat + 1);
     274               0 :                         oFieldDefn.SetWidth(nWidth);
     275                 :                     }
     276              50 :                     poFeatureDefn->AddFieldDefn(&oFieldDefn);
     277                 : 
     278              50 :                     if (oFieldDefn.GetType() == OFTReal &&
     279                 :                         osColumnUnit.compare("DEGREE") == 0)
     280                 :                     {
     281              14 :                         if (osColumnName.compare("LONGITUDE") == 0)
     282               2 :                             nLongitudeIndex = nFields;
     283              12 :                         else if (osColumnName.compare("LATITUDE") == 0)
     284               2 :                             nLatitudeIndex = nFields;
     285                 :                     }
     286                 : 
     287              50 :                     nFields ++;
     288                 :                 }
     289                 :                 else
     290                 :                 {
     291                 :                     CPLError(CE_Failure, CPLE_AppDefined,
     292               0 :                                 "Field %d out of record extents", nFields);
     293               0 :                     CSLDestroy(papszTokens);
     294               0 :                     break;
     295                 :                 }
     296                 :             }
     297                 :             else
     298                 :             {
     299                 :                 CPLError(CE_Failure, CPLE_AppDefined,
     300               0 :                             "Did not get expected records for field %d", nFields);
     301               0 :                 CSLDestroy(papszTokens);
     302               0 :                 break;
     303                 :             }
     304              50 :             bInObjectColumn = FALSE;
     305                 :         }
     306             682 :         else if (nTokens == 2)
     307                 :         {
     308             434 :             if (EQUAL(papszTokens[0], "PDS_VERSION_ID"))
     309                 :             {
     310               0 :                 CSLDestroy(papszTokens);
     311               0 :                 papszTokens = NULL;
     312               0 :                 while(TRUE)
     313                 :                 {
     314               0 :                     CPLPushErrorHandler(CPLQuietErrorHandler);
     315               0 :                     pszLine = CPLReadLine2L(fpStructure, 256, NULL);
     316               0 :                     CPLPopErrorHandler();
     317               0 :                     CPLErrorReset();
     318               0 :                     if (pszLine == NULL)
     319               0 :                         break;
     320                 :                     papszTokens =
     321               0 :                         CSLTokenizeString2( pszLine, " =", CSLT_HONOURSTRINGS );
     322               0 :                     int nTokens = CSLCount(papszTokens);
     323               0 :                     if (nTokens == 2 &&
     324               0 :                         EQUAL(papszTokens[0], "OBJECT") &&
     325               0 :                         EQUAL(papszTokens[1], osTableID.c_str()))
     326                 :                     {
     327               0 :                         break;
     328                 :                     }
     329               0 :                     CSLDestroy(papszTokens);
     330               0 :                     papszTokens = NULL;
     331                 :                 }
     332               0 :                 CSLDestroy(papszTokens);
     333               0 :                 papszTokens = NULL;
     334               0 :                 if (pszLine == NULL)
     335               0 :                     break;
     336                 :             }
     337             434 :             else if (EQUAL(papszTokens[0], "ROW_BYTES"))
     338                 :             {
     339               2 :                 nRowBytes = atoi(papszTokens[1]);
     340                 :             }
     341             432 :             else if (EQUAL(papszTokens[0], "ROW_SUFFIX_BYTES"))
     342                 :             {
     343               0 :                 nRowBytes += atoi(papszTokens[1]);
     344                 :             }
     345             532 :             else if (EQUAL(papszTokens[0], "OBJECT") &&
     346              50 :                      EQUAL(papszTokens[1], "COLUMN"))
     347                 :             {
     348              50 :                 if (nRowBytes > nRecordSize)
     349                 :                 {
     350               0 :                     nRecordSize = nRowBytes;
     351               0 :                     VSIFree(pabyRecord);
     352               0 :                     pabyRecord = (GByte*) CPLMalloc(nRecordSize + 1);
     353               0 :                     pabyRecord[nRecordSize] = 0;
     354                 :                 }
     355                 :                 else
     356              50 :                     nRecordSize = nRowBytes;
     357                 : 
     358              50 :                 nExpectedColumnNumber ++;
     359              50 :                 bInObjectColumn = TRUE;
     360              50 :                 osColumnName = "";
     361              50 :                 osColumnDataType = "";
     362              50 :                 osColumnStartByte = "";
     363              50 :                 osColumnBytes = "";
     364              50 :                 osColumnItems = "";
     365              50 :                 osColumnItemBytes = "";
     366              50 :                 osColumnFormat = "";
     367              50 :                 osColumnUnit = "";
     368                 :             }
     369             432 :             else if (bInObjectColumn && EQUAL(papszTokens[0], "COLUMN_NUMBER"))
     370                 :             {
     371              50 :                 int nColumnNumber = atoi(papszTokens[1]);
     372              50 :                 if (nColumnNumber != nExpectedColumnNumber)
     373                 :                 {
     374                 :                     CPLError(CE_Failure, CPLE_AppDefined,
     375               0 :                                 "Did not get expected column number");
     376               0 :                     CSLDestroy(papszTokens);
     377               0 :                     break;
     378                 :                 }
     379                 :             }
     380             382 :             else if (bInObjectColumn && EQUAL(papszTokens[0], "NAME"))
     381                 :             {
     382              50 :                 osColumnName = "\"";
     383              50 :                 osColumnName += papszTokens[1];
     384              50 :                 osColumnName += "\"";
     385              50 :                 OGRPDSDataSource::CleanString(osColumnName);
     386                 :             }
     387             332 :             else if (bInObjectColumn && EQUAL(papszTokens[0], "DATA_TYPE"))
     388                 :             {
     389              50 :                 osColumnDataType = papszTokens[1];
     390              50 :                 OGRPDSDataSource::CleanString(osColumnDataType);
     391                 :             }
     392             282 :             else if (bInObjectColumn && EQUAL(papszTokens[0], "START_BYTE"))
     393                 :             {
     394              50 :                 osColumnStartByte = papszTokens[1];
     395                 :             }
     396             232 :             else if (bInObjectColumn && EQUAL(papszTokens[0], "BYTES"))
     397                 :             {
     398              50 :                 osColumnBytes = papszTokens[1];
     399                 :             }
     400             132 :             else if (bInObjectColumn && EQUAL(papszTokens[0], "ITEMS"))
     401                 :             {
     402               0 :                 osColumnItems = papszTokens[1];
     403                 :             }
     404             132 :             else if (bInObjectColumn && EQUAL(papszTokens[0], "ITEM_BYTES"))
     405                 :             {
     406               0 :                 osColumnItemBytes = papszTokens[1];
     407                 :             }
     408             182 :             else if (bInObjectColumn && EQUAL(papszTokens[0], "FORMAT"))
     409                 :             {
     410              50 :                 osColumnFormat = papszTokens[1];
     411                 :             }
     412              82 :             else if (bInObjectColumn && EQUAL(papszTokens[0], "UNIT"))
     413                 :             {
     414              22 :                 osColumnUnit = papszTokens[1];
     415                 :             }
     416                 :         }
     417             732 :         CSLDestroy(papszTokens);
     418                 :     }
     419               2 :     VSIFCloseL(fpStructure);
     420                 : }
     421                 : 
     422                 : 
     423                 : /************************************************************************/
     424                 : /*                            ResetReading()                            */
     425                 : /************************************************************************/
     426                 : 
     427               2 : void OGRPDSLayer::ResetReading()
     428                 : 
     429                 : {
     430               2 :     nNextFID = 0;
     431               2 :     VSIFSeekL( fpPDS, nStartBytes, SEEK_SET );
     432               2 : }
     433                 : 
     434                 : 
     435                 : /************************************************************************/
     436                 : /*                           GetNextFeature()                           */
     437                 : /************************************************************************/
     438                 : 
     439               2 : OGRFeature *OGRPDSLayer::GetNextFeature()
     440                 : {
     441                 :     OGRFeature  *poFeature;
     442                 : 
     443               0 :     while(TRUE)
     444                 :     {
     445               2 :         poFeature = GetNextRawFeature();
     446               2 :         if (poFeature == NULL)
     447               0 :             return NULL;
     448                 : 
     449               2 :         if((m_poFilterGeom == NULL
     450                 :             || FilterGeometry( poFeature->GetGeometryRef() ) )
     451                 :         && (m_poAttrQuery == NULL
     452                 :             || m_poAttrQuery->Evaluate( poFeature )) )
     453                 :         {
     454               2 :             return poFeature;
     455                 :         }
     456                 :         else
     457               0 :             delete poFeature;
     458                 :     }
     459                 : }
     460                 : 
     461                 : 
     462                 : /************************************************************************/
     463                 : /*                         GetNextRawFeature()                          */
     464                 : /************************************************************************/
     465                 : 
     466               4 : OGRFeature *OGRPDSLayer::GetNextRawFeature()
     467                 : {
     468               4 :     if (nNextFID == nRecords)
     469               0 :         return NULL;
     470               4 :     int nRead = (int)VSIFReadL( pabyRecord, 1, nRecordSize, fpPDS);
     471               4 :     if (nRead != nRecordSize)
     472               0 :         return NULL;
     473                 : 
     474               4 :     OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
     475               4 :     int nFieldCount = poFeatureDefn->GetFieldCount();
     476               4 :     if (pasFieldDesc != NULL)
     477                 :     {
     478                 :         int i, j;
     479             104 :         for(i=0;i<nFieldCount;i++)
     480                 :         {
     481             244 :             if (pasFieldDesc[i].eFormat == ASCII_REAL ||
     482              44 :                 pasFieldDesc[i].eFormat == ASCII_INTEGER ||
     483               0 :                 pasFieldDesc[i].eFormat == CHARACTER)
     484                 :             {
     485             100 :                 char* pchEnd = (char*) &pabyRecord[pasFieldDesc[i].nStartByte +
     486             200 :                                                 pasFieldDesc[i].nByteCount];
     487             100 :                 char chSaved = *pchEnd;
     488             100 :                 *pchEnd = 0;
     489                 :                 poFeature->SetField(i, (const char*)(pabyRecord +
     490             100 :                                                     pasFieldDesc[i].nStartByte));
     491             100 :                 *pchEnd = chSaved;
     492                 :             }
     493               0 :             else if (pasFieldDesc[i].eFormat == MSB_UNSIGNED_INTEGER &&
     494               0 :                      pasFieldDesc[i].nStartByte +
     495               0 :                      pasFieldDesc[i].nItemBytes * pasFieldDesc[i].nItems <= nRecordSize)
     496                 :             {
     497               0 :                 if (pasFieldDesc[i].nItemBytes == 1)
     498                 :                 {
     499               0 :                     if (pasFieldDesc[i].nItems > 1)
     500                 :                     {
     501               0 :                         int* panValues = (int*)CPLMalloc(sizeof(int) * pasFieldDesc[i].nItems);
     502               0 :                         for(j=0;j<pasFieldDesc[i].nItems;j++)
     503                 :                         {
     504               0 :                             panValues[j] = pabyRecord[pasFieldDesc[i].nStartByte + j];
     505                 :                         }
     506               0 :                         poFeature->SetField(i, pasFieldDesc[i].nItems, panValues);
     507               0 :                         CPLFree(panValues);
     508                 :                     }
     509                 :                     else
     510                 :                     {
     511               0 :                         poFeature->SetField(i, pabyRecord[pasFieldDesc[i].nStartByte]);
     512                 :                     }
     513                 :                 }
     514               0 :                 else if (pasFieldDesc[i].nItemBytes == 2)
     515                 :                 {
     516               0 :                     if (pasFieldDesc[i].nItems > 1)
     517                 :                     {
     518               0 :                         int* panValues = (int*)CPLMalloc(sizeof(int) * pasFieldDesc[i].nItems);
     519               0 :                         for(j=0;j<pasFieldDesc[i].nItems;j++)
     520                 :                         {
     521                 :                             unsigned short sVal;
     522               0 :                             memcpy(&sVal, pabyRecord + pasFieldDesc[i].nStartByte + 2 * j, 2);
     523               0 :                             CPL_MSBPTR16(&sVal);
     524               0 :                             panValues[j] = sVal;
     525                 :                         }
     526               0 :                         poFeature->SetField(i, pasFieldDesc[i].nItems, panValues);
     527               0 :                         CPLFree(panValues);
     528                 :                     }
     529                 :                     else
     530                 :                     {
     531                 :                         unsigned short sVal;
     532               0 :                         memcpy(&sVal, pabyRecord + pasFieldDesc[i].nStartByte, 2);
     533               0 :                         CPL_MSBPTR16(&sVal);
     534               0 :                         poFeature->SetField(i, (int)sVal);
     535                 :                     }
     536                 :                 }
     537               0 :                 else if (pasFieldDesc[i].nItemBytes == 4)
     538                 :                 {
     539               0 :                     if (pasFieldDesc[i].nItems > 1)
     540                 :                     {
     541               0 :                         double* padfValues = (double*)CPLMalloc(sizeof(double) * pasFieldDesc[i].nItems);
     542               0 :                         for(j=0;j<pasFieldDesc[i].nItems;j++)
     543                 :                         {
     544                 :                             unsigned int nVal;
     545               0 :                             memcpy(&nVal, pabyRecord + pasFieldDesc[i].nStartByte + 4 * j, 4);
     546               0 :                             CPL_MSBPTR32(&nVal);
     547               0 :                             padfValues[j] = (double)nVal;
     548                 :                         }
     549               0 :                         poFeature->SetField(i, pasFieldDesc[i].nItems, padfValues);
     550               0 :                         CPLFree(padfValues);
     551                 :                     }
     552                 :                     else
     553                 :                     {
     554                 :                         unsigned int nVal;
     555               0 :                         memcpy(&nVal, pabyRecord + pasFieldDesc[i].nStartByte, 4);
     556               0 :                         CPL_MSBPTR32(&nVal);
     557               0 :                         poFeature->SetField(i, (double)nVal);
     558                 :                     }
     559                 :                 }
     560                 :             }
     561               0 :             else if (pasFieldDesc[i].eFormat == MSB_INTEGER &&
     562               0 :                      pasFieldDesc[i].nStartByte +
     563               0 :                      pasFieldDesc[i].nItemBytes * pasFieldDesc[i].nItems <= nRecordSize)
     564                 :             {
     565               0 :                 if (pasFieldDesc[i].nItemBytes == 1)
     566                 :                 {
     567               0 :                     if (pasFieldDesc[i].nItems > 1)
     568                 :                     {
     569               0 :                         int* panValues = (int*)CPLMalloc(sizeof(int) * pasFieldDesc[i].nItems);
     570               0 :                         for(j=0;j<pasFieldDesc[i].nItems;j++)
     571                 :                         {
     572               0 :                             panValues[j] = ((char*)pabyRecord)[pasFieldDesc[i].nStartByte + j];
     573                 :                         }
     574               0 :                         poFeature->SetField(i, pasFieldDesc[i].nItems, panValues);
     575               0 :                         CPLFree(panValues);
     576                 :                     }
     577                 :                     else
     578                 :                     {
     579               0 :                         poFeature->SetField(i, ((char*)pabyRecord)[pasFieldDesc[i].nStartByte]);
     580                 :                     }
     581                 :                 }
     582               0 :                 else if (pasFieldDesc[i].nItemBytes == 2)
     583                 :                 {
     584               0 :                     if (pasFieldDesc[i].nItems > 1)
     585                 :                     {
     586               0 :                         int* panValues = (int*)CPLMalloc(sizeof(int) * pasFieldDesc[i].nItems);
     587               0 :                         for(j=0;j<pasFieldDesc[i].nItems;j++)
     588                 :                         {
     589                 :                             short sVal;
     590               0 :                             memcpy(&sVal, pabyRecord + pasFieldDesc[i].nStartByte + 2 * j, 2);
     591               0 :                             CPL_MSBPTR16(&sVal);
     592               0 :                             panValues[j] = sVal;
     593                 :                         }
     594               0 :                         poFeature->SetField(i, pasFieldDesc[i].nItems, panValues);
     595               0 :                         CPLFree(panValues);
     596                 :                     }
     597                 :                     else
     598                 :                     {
     599                 :                         short sVal;
     600               0 :                         memcpy(&sVal, pabyRecord + pasFieldDesc[i].nStartByte, 2);
     601               0 :                         CPL_MSBPTR16(&sVal);
     602               0 :                         poFeature->SetField(i, (int)sVal);
     603                 :                     }
     604                 :                 }
     605               0 :                 else if (pasFieldDesc[i].nItemBytes == 4)
     606                 :                 {
     607               0 :                     if (pasFieldDesc[i].nItems > 1)
     608                 :                     {
     609               0 :                         int* panValues = (int*)CPLMalloc(sizeof(int) * pasFieldDesc[i].nItems);
     610               0 :                         for(j=0;j<pasFieldDesc[i].nItems;j++)
     611                 :                         {
     612                 :                             int nVal;
     613               0 :                             memcpy(&nVal, pabyRecord + pasFieldDesc[i].nStartByte + 4 * j, 4);
     614               0 :                             CPL_MSBPTR32(&nVal);
     615               0 :                             panValues[j] = nVal;
     616                 :                         }
     617               0 :                         poFeature->SetField(i, pasFieldDesc[i].nItems, panValues);
     618               0 :                         CPLFree(panValues);
     619                 :                     }
     620                 :                     else
     621                 :                     {
     622                 :                         int nVal;
     623               0 :                         memcpy(&nVal, pabyRecord + pasFieldDesc[i].nStartByte, 4);
     624               0 :                         CPL_MSBPTR32(&nVal);
     625               0 :                         poFeature->SetField(i, nVal);
     626                 :                     }
     627                 :                 }
     628                 :             }
     629               0 :             else if (pasFieldDesc[i].eFormat == IEEE_REAL &&
     630               0 :                      pasFieldDesc[i].nStartByte +
     631               0 :                      pasFieldDesc[i].nItemBytes * pasFieldDesc[i].nItems <= nRecordSize &&
     632               0 :                      pasFieldDesc[i].nItemBytes == 4)
     633                 :             {
     634               0 :                 if (pasFieldDesc[i].nItems > 1)
     635                 :                 {
     636               0 :                     double* padfValues = (double*)CPLMalloc(sizeof(double) * pasFieldDesc[i].nItems);
     637               0 :                     for(j=0;j<pasFieldDesc[i].nItems;j++)
     638                 :                     {
     639                 :                         float fVal;
     640               0 :                         memcpy(&fVal, pabyRecord + pasFieldDesc[i].nStartByte + 4 * j, 4);
     641               0 :                         CPL_MSBPTR32(&fVal);
     642               0 :                         padfValues[j] = (double)fVal;
     643                 :                     }
     644               0 :                     poFeature->SetField(i, pasFieldDesc[i].nItems, padfValues);
     645               0 :                     CPLFree(padfValues);
     646                 :                 }
     647                 :                 else
     648                 :                 {
     649                 :                     float fVal;
     650               0 :                     memcpy(&fVal, pabyRecord + pasFieldDesc[i].nStartByte, 4);
     651               0 :                     CPL_MSBPTR32(&fVal);
     652               0 :                     poFeature->SetField(i, (double)fVal);
     653                 :                 }
     654                 :             }
     655                 :         }
     656                 :     }
     657                 :     else
     658                 :     {
     659                 :         char **papszTokens = CSLTokenizeString2(
     660               0 :                 (const char*)pabyRecord, " ", CSLT_HONOURSTRINGS );
     661               0 :         int nTokens = CSLCount(papszTokens);
     662               0 :         nTokens = MIN(nTokens, nFieldCount);
     663                 :         int i;
     664               0 :         for(i=0;i<nTokens;i++)
     665                 :         {
     666               0 :             poFeature->SetField(i, papszTokens[i]);
     667                 :         }
     668               0 :         CSLDestroy(papszTokens);
     669                 :     }
     670                 : 
     671               4 :     if (nLongitudeIndex >= 0 && nLatitudeIndex >= 0)
     672                 :         poFeature->SetGeometryDirectly(new OGRPoint(
     673                 :                                 poFeature->GetFieldAsDouble(nLongitudeIndex),
     674               4 :                                 poFeature->GetFieldAsDouble(nLatitudeIndex)));
     675                 : 
     676               4 :     poFeature->SetFID(nNextFID++);
     677                 : 
     678               4 :     return poFeature;
     679                 : }
     680                 : 
     681                 : /************************************************************************/
     682                 : /*                           TestCapability()                           */
     683                 : /************************************************************************/
     684                 : 
     685               2 : int OGRPDSLayer::TestCapability( const char * pszCap )
     686                 : 
     687                 : {
     688               2 :     if (EQUAL(pszCap,OLCFastFeatureCount) &&
     689                 :         m_poFilterGeom == NULL && m_poAttrQuery == NULL)
     690               2 :         return TRUE;
     691               0 :     else if (EQUAL(pszCap,OLCRandomRead))
     692               0 :         return TRUE;
     693               0 :     else if (EQUAL(pszCap,OLCFastSetNextByIndex) &&
     694                 :              m_poFilterGeom == NULL && m_poAttrQuery == NULL)
     695               0 :         return TRUE;
     696                 : 
     697               0 :     return FALSE;
     698                 : }
     699                 : 
     700                 : /************************************************************************/
     701                 : /*                          GetFeatureCount()                           */
     702                 : /************************************************************************/
     703                 : 
     704               2 : int OGRPDSLayer::GetFeatureCount(int bForce )
     705                 : {
     706               2 :     if (TestCapability(OLCFastFeatureCount))
     707               2 :         return nRecords;
     708                 : 
     709               0 :     return OGRLayer::GetFeatureCount(bForce);
     710                 : }
     711                 : 
     712                 : /************************************************************************/
     713                 : /*                             GetFeature()                             */
     714                 : /************************************************************************/
     715                 : 
     716               2 : OGRFeature *OGRPDSLayer::GetFeature( long nFID )
     717                 : {
     718               2 :     if (nFID < 0 || nFID >= nRecords)
     719               0 :         return NULL;
     720                 : 
     721               2 :     nNextFID = nFID;
     722               2 :     VSIFSeekL( fpPDS, nStartBytes + nNextFID * nRecordSize, SEEK_SET );
     723               2 :     return GetNextRawFeature();
     724                 : }
     725                 : 
     726                 : /************************************************************************/
     727                 : /*                         SetNextByIndex()                             */
     728                 : /************************************************************************/
     729                 : 
     730               0 : OGRErr OGRPDSLayer::SetNextByIndex( long nIndex )
     731                 : {
     732               0 :     if (!TestCapability(OLCFastSetNextByIndex))
     733               0 :         return OGRLayer::SetNextByIndex( nIndex );
     734                 : 
     735               0 :     if (nIndex < 0 || nIndex >= nRecords)
     736               0 :         return OGRERR_FAILURE;
     737                 : 
     738               0 :     nNextFID = nIndex;
     739               0 :     VSIFSeekL( fpPDS, nStartBytes + nNextFID * nRecordSize, SEEK_SET );
     740               0 :     return OGRERR_NONE;
     741                 : }

Generated by: LCOV version 1.7