LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/bna - ogrbnaparser.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 263 169 64.3 %
Date: 2012-04-28 Functions: 5 3 60.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrbnaparser.cpp 20996 2010-10-28 18:38:15Z rouault $
       3                 :  *
       4                 :  * Project:  BNA Parser
       5                 :  * Purpose:  Parse a BNA record
       6                 :  * Author:   Even Rouault, even dot rouault at mines dash paris dot org
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2007, Even Rouault
      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 "ogrbnaparser.h"
      31                 : 
      32                 : #include "cpl_conv.h"
      33                 : #include "cpl_string.h"
      34                 : 
      35             884 : void BNA_FreeRecord(BNARecord* record)
      36                 : {
      37             884 :   if (record)
      38                 :   {
      39                 :     int i;
      40            4420 :     for(i=0;i<NB_MAX_BNA_IDS;i++)
      41                 :     {
      42            3536 :         if (record->ids[i]) VSIFree(record->ids[i]);
      43            3536 :         record->ids[i] = NULL;
      44                 :     }
      45             884 :     CPLFree(record->tabCoords);
      46             884 :     record->tabCoords = NULL;
      47             884 :     CPLFree(record);
      48                 :   }
      49             884 : }
      50                 : 
      51               0 : const char* BNA_FeatureTypeToStr(BNAFeatureType featureType)
      52                 : {
      53               0 :   switch (featureType)
      54                 :   {
      55                 :     case BNA_POINT:
      56               0 :       return "point";
      57                 :     case BNA_POLYGON:
      58               0 :       return "polygon";
      59                 :     case BNA_POLYLINE:
      60               0 :       return "polyline";
      61                 :     case BNA_ELLIPSE:
      62               0 :       return "ellipse";
      63                 :     default:
      64               0 :       return "unknown";
      65                 :   }
      66                 : }
      67                 : 
      68               0 : void BNA_Display(BNARecord* record)
      69                 : {
      70                 :   int i;
      71                 :   fprintf(stderr, "\"%s\", \"%s\", \"%s\", %s\n",
      72               0 :           record->ids[0] ? record->ids[0] : "",
      73               0 :           record->ids[1] ? record->ids[1] : "",
      74               0 :           record->ids[2] ? record->ids[2] : "",
      75               0 :           BNA_FeatureTypeToStr(record->featureType));
      76               0 :   for(i=0;i<record->nCoords;i++)
      77               0 :     fprintf(stderr, "%f, %f\n", record->tabCoords[i][0], record->tabCoords[i][1]);
      78               0 : }
      79                 : 
      80                 : /*
      81                 : For a description of the format, see http://www.softwright.com/faq/support/boundary_file_bna_format.html
      82                 : and http://64.145.236.125/forum/topic.asp?topic_id=1930&forum_id=1&Topic_Title=how+to+edit+*.bna+files%3F&forum_title=Surfer+Support&M=False
      83                 : */
      84                 : 
      85                 : /* The following lines are a valid BNA file (for this parser) :
      86                 : "PID1","SID1",1
      87                 : -0,0
      88                 : "PID2","SID2",-2,   -1e-5,-1e2   ,-2,-2
      89                 : "PID3""a","SID3",4
      90                 : 5,5
      91                 : 6,5
      92                 : 6,6
      93                 : 5,5
      94                 : "PID4","SID4",2
      95                 : 10,10
      96                 : 5,4
      97                 : 
      98                 : "PID4","SID4",2
      99                 : 
     100                 : 10,10
     101                 : 5,4
     102                 : */
     103                 : 
     104                 : /* The following lines are a valid BNA file (for this parser) :
     105                 :   (small extract from ftp://ftp.ciesin.org/pub/census/usa/tiger/ct/bnablk/b09001.zip)
     106                 : "090010000.00099A","099A","090010000.00099A","blk",21
     107                 : -73.049337, 41.125000 -73.093761, 41.157780 -73.107900, 41.168300
     108                 : -73.106878, 41.166459 -73.095800, 41.146500 -73.114553, 41.146331
     109                 : -73.138922, 41.147993 -73.166200, 41.154200 -73.198497, 41.085988
     110                 : -73.232241, 41.029986 -73.229548, 41.030507 -73.183922, 41.041955
     111                 : -73.178678, 41.043239 -73.177951, 41.043417 -73.147888, 41.050781
     112                 : -73.118658, 41.057942 -73.052399, 41.074174 -73.024976, 41.080892
     113                 : -73.000000, 41.087010 -73.035597, 41.114420 -73.049337, 41.125000
     114                 : */
     115                 : 
     116                 : /* We are (and must be) a bit tolerant : BNA files format has several variations */
     117                 : /* and most don't follow strictly the 'specification' */
     118                 : /* Extra spaces, tabulations or line feed are accepted and ignored */
     119                 : /* We allow one line format and several line format in the same file */
     120                 : /* We allow from NB_MIN_BNA_IDS to NB_MAX_BNA_IDS ids */
     121                 : /* We allow that couples of coordinates on the same line may be separated only by spaces */
     122                 : /* (instead of being separated by a comma) */
     123                 : 
     124                 : #define STRING_NOT_TERMINATED      "string not terminated when end of line occured"
     125                 : #define MISSING_FIELDS             "missing fields"
     126                 : #define BAD_INTEGER_NUMBER_FORMAT  "bad integer number format"
     127                 : #define BAD_FLOAT_NUMBER_FORMAT    "bad float number format"
     128                 : #define PRIMARY_ID_MANDATORY       "primary ID can't be empty or missing"
     129                 : #define STRING_EXPECTED            "string expected"
     130                 : #define NUMBER_EXPECTED            "number expected"
     131                 : #define INTEGER_NUMBER_EXPECTED    "integer number expected"
     132                 : #define FLOAT_NUMBER_EXPECTED      "float number expected"
     133                 : #define INVALID_GEOMETRY_TYPE      "invalid geometry type"
     134                 : #define TOO_LONG_ID                "too long id (> 256 characters)"
     135                 : #define MAX_BNA_IDS_REACHED        "maximum number of IDs reached"
     136                 : #define NOT_ENOUGH_MEMORY          "not enough memory for request number of coordinates"
     137                 : #define LINE_TOO_LONG              "line too long"
     138                 : 
     139                 : #define TMP_BUFFER_SIZE             256
     140                 : #define LINE_BUFFER_SIZE            1024
     141                 : 
     142                 : enum
     143                 : {
     144                 :     BNA_LINE_OK,
     145                 :     BNA_LINE_EOF,
     146                 :     BNA_LINE_TOO_LONG
     147                 : };
     148                 : 
     149            6098 : static int BNA_GetLine(char szLineBuffer[LINE_BUFFER_SIZE+1], VSILFILE* f)
     150                 : {
     151            6098 :     char* ptrCurLine = szLineBuffer;
     152            6098 :     int nRead = VSIFReadL(szLineBuffer, 1, LINE_BUFFER_SIZE, f);
     153            6098 :     szLineBuffer[nRead] = 0;
     154            6098 :     if (nRead == 0)
     155                 :     {
     156                 :         /* EOF */
     157             146 :         return BNA_LINE_EOF;
     158                 :     }
     159                 : 
     160            5952 :     int bFoundEOL = FALSE;
     161          138964 :     while (*ptrCurLine)
     162                 :     {
     163          133012 :         if (*ptrCurLine == 0x0d || *ptrCurLine == 0x0a)
     164                 :         {
     165            5952 :             bFoundEOL = TRUE;
     166            5952 :             break;
     167                 :         }
     168          127060 :         ptrCurLine ++;
     169                 :     }
     170            5952 :     if (!bFoundEOL)
     171                 :     {
     172               0 :         if (nRead < LINE_BUFFER_SIZE)
     173               0 :             return BNA_LINE_OK;
     174                 :         else
     175               0 :             return BNA_LINE_TOO_LONG;
     176                 :     }
     177                 : 
     178            5952 :     if (*ptrCurLine == 0x0d)
     179                 :     {
     180            4448 :         if (ptrCurLine == szLineBuffer + LINE_BUFFER_SIZE - 1)
     181                 :         {
     182                 :             char c;
     183               0 :             nRead = VSIFReadL(&c, 1, 1, f);
     184               0 :             if (nRead == 1)
     185                 :             {
     186               0 :                 if (c == 0x0a)
     187                 :                 {
     188                 :                     /* Do nothing */
     189                 :                 }
     190                 :                 else
     191                 :                 {
     192               0 :                     VSIFSeekL(f, VSIFTellL(f) - 1, SEEK_SET);
     193                 :                 }
     194                 :             }
     195                 :         }
     196            4448 :         else if (ptrCurLine[1] == 0x0a)
     197                 :         {
     198            4448 :             VSIFSeekL(f, VSIFTellL(f) + ptrCurLine + 2 - (szLineBuffer + nRead), SEEK_SET);
     199                 :         }
     200                 :         else
     201                 :         {
     202               0 :             VSIFSeekL(f, VSIFTellL(f) + ptrCurLine + 1 - (szLineBuffer + nRead), SEEK_SET);
     203                 :         }
     204                 :     }
     205                 :     else /* *ptrCurLine == 0x0a */
     206                 :     {
     207            1504 :         VSIFSeekL(f, VSIFTellL(f) + ptrCurLine + 1 - (szLineBuffer + nRead), SEEK_SET);
     208                 :     }
     209            5952 :     *ptrCurLine = 0;
     210                 : 
     211            5952 :     return BNA_LINE_OK;
     212                 : }
     213                 : 
     214                 : 
     215             884 : BNARecord* BNA_GetNextRecord(VSILFILE* f,
     216                 :                              int* ok,
     217                 :                              int* curLine,
     218                 :                              int verbose,
     219                 :                              BNAFeatureType interestFeatureType)
     220                 : {
     221                 :     BNARecord* record;
     222                 :     char c;
     223             884 :     int inQuotes = FALSE;
     224             884 :     int numField = 0;
     225             884 :     char* ptrBeginningOfNumber = NULL;
     226             884 :     int exponentFound = 0;
     227             884 :     int exponentSignFound = 0;
     228             884 :     int dotFound = 0;
     229             884 :     int numChar = 0;
     230             884 :     const char* detailedErrorMsg = NULL;
     231             884 :     BNAFeatureType currentFeatureType = (BNAFeatureType) -1;
     232             884 :     int nbExtraId = 0;
     233                 :     char tmpBuffer[NB_MAX_BNA_IDS][TMP_BUFFER_SIZE+1];
     234             884 :     int  tmpBufferLength[NB_MAX_BNA_IDS] = {0, 0, 0};
     235                 :     char szLineBuffer[LINE_BUFFER_SIZE + 1];
     236                 : 
     237             884 :     record = (BNARecord*)CPLMalloc(sizeof(BNARecord));
     238             884 :     memset(record, 0, sizeof(BNARecord));
     239                 : 
     240            5214 :     while (TRUE)
     241                 :     {
     242            6098 :       numChar = 0;
     243            6098 :       (*curLine)++;
     244                 : 
     245            6098 :       int retGetLine = BNA_GetLine(szLineBuffer, f);
     246            6098 :       if (retGetLine == BNA_LINE_TOO_LONG)
     247                 :       {
     248               0 :           detailedErrorMsg = LINE_TOO_LONG;
     249               0 :           goto error;
     250                 :       }
     251            6098 :       else if (retGetLine == BNA_LINE_EOF)
     252                 :       {
     253                 :           break;
     254                 :       }
     255                 : 
     256            5952 :       char* ptrCurLine = szLineBuffer;
     257            5952 :       const char* ptrBeginLine = szLineBuffer;
     258                 : 
     259            5952 :       if (*ptrCurLine == 0)
     260               0 :         continue;
     261                 : 
     262          127060 :       while(1)
     263                 :       {
     264          133012 :         numChar = ptrCurLine - ptrBeginLine;
     265          133012 :         c = *ptrCurLine;
     266          133012 :         if (c == 0) c = 10;
     267          133012 :         if (inQuotes)
     268                 :         {
     269            7400 :           if (c == 10)
     270                 :           {
     271               0 :             detailedErrorMsg = STRING_NOT_TERMINATED;
     272               0 :             goto error;
     273                 :           }
     274            7400 :           else if (c == '"' && ptrCurLine[1] == '"')
     275                 :           {
     276               0 :             if (tmpBufferLength[numField] == TMP_BUFFER_SIZE)
     277                 :             {
     278               0 :               detailedErrorMsg = TOO_LONG_ID; 
     279               0 :               goto error;
     280                 :             }
     281               0 :             tmpBuffer[numField][tmpBufferLength[numField]++] = c;
     282                 : 
     283               0 :             ptrCurLine++;
     284                 :           }
     285            7400 :           else if (c == '"')
     286                 :           {
     287            1480 :             inQuotes = FALSE;
     288                 :           }
     289                 :           else
     290                 :           {
     291            5920 :             if (tmpBufferLength[numField] == TMP_BUFFER_SIZE)
     292                 :             {
     293               0 :               detailedErrorMsg = TOO_LONG_ID; 
     294               0 :               goto error;
     295                 :             }
     296            5920 :             tmpBuffer[numField][tmpBufferLength[numField]++] = c;
     297                 :           }
     298                 :         }
     299          125612 :         else if (c == ' ' || c == '\t')
     300                 :         {
     301            2324 :           if (numField > NB_MIN_BNA_IDS + nbExtraId && ptrBeginningOfNumber != NULL)
     302                 :           {
     303               0 :             do
     304                 :             {
     305            2324 :               ptrCurLine++;
     306            2324 :               numChar = ptrCurLine - ptrBeginLine;
     307            2324 :               c = *ptrCurLine;
     308            2324 :               if (!(c == ' ' || c == '\t'))
     309            2324 :                 break;
     310                 :             } while(c);
     311            2324 :             if (c == 0) c = 10;
     312                 : 
     313            2324 :             if (interestFeatureType == BNA_READ_ALL ||
     314                 :                 interestFeatureType == currentFeatureType)
     315                 :             {
     316             664 :               char* pszComma = strchr(ptrBeginningOfNumber, ',');
     317             664 :               if (pszComma)
     318             664 :                   *pszComma = '\0';
     319             664 :               record->tabCoords[(numField - nbExtraId - NB_MIN_BNA_IDS - 1) / 2]
     320             664 :                                [1 - ((numField - nbExtraId) % 2)] =
     321             664 :                   CPLAtof(ptrBeginningOfNumber);
     322             664 :               if (pszComma)
     323             664 :                   *pszComma = ',';
     324                 :             }
     325            2324 :             if (numField == NB_MIN_BNA_IDS + 1 + nbExtraId + 2 * record->nCoords - 1)
     326                 :             {
     327               0 :               if (c != 10)
     328                 :               {
     329               0 :                 if (verbose)
     330                 :                 {
     331                 :                   CPLError(CE_Warning, CPLE_AppDefined, 
     332                 :                            "At line %d, at char %d, extra data will be ignored!\n",
     333               0 :                            *curLine, numChar+1);
     334                 :                 }
     335                 :               }
     336               0 :               *ok = 1;
     337               0 :               return record;
     338                 :             }
     339                 : 
     340            2324 :             ptrBeginningOfNumber = NULL;
     341            2324 :             exponentFound = 0;
     342            2324 :             exponentSignFound = 0;
     343            2324 :             dotFound = 0;
     344            2324 :             numField++;
     345                 : 
     346            2324 :             if (c == 10)
     347               0 :               break;
     348                 : 
     349            2324 :             if (c != ',')
     350                 :             {
     351                 :               /* don't increment ptrCurLine */
     352            2324 :               continue;
     353                 :             }
     354                 :           }
     355                 :           else
     356                 :           {
     357                 :             /* ignore */
     358                 :           }
     359                 :         }
     360          132842 :         else if (c == 10 || c == ',')
     361                 :         {
     362                 :           /* Eat a comma placed at end of line */
     363           15506 :           if (c == ',')
     364                 :           {
     365            9554 :               const char* ptr = ptrCurLine+1;
     366           19108 :               while(*ptr)
     367                 :               {
     368            9554 :                   if (*ptr != ' ' && *ptr != '\t')
     369            9554 :                       break;
     370               0 :                   ptr++;
     371                 :               }
     372            9554 :               if (*ptr == 0)
     373                 :               {
     374               0 :                   c = 10;
     375                 :               }
     376                 :           }
     377                 : 
     378           15506 :           if (numField == 0)
     379                 :           {
     380                 :             /* Maybe not so mandatory.. Atlas MapMaker(TM) exports BNA files with empty primaryID */
     381                 :             /*
     382                 :             if (record->primaryID == NULL || *(record->primaryID) == 0)
     383                 :             {
     384                 :               detailedErrorMsg = PRIMARY_ID_MANDATORY;
     385                 :               goto error;
     386                 :             }
     387                 :             */
     388                 :           }
     389           14768 :           else if (numField == NB_MIN_BNA_IDS + nbExtraId)
     390                 :           {
     391                 :             int nCoords;
     392             738 :             if (ptrBeginningOfNumber == NULL)
     393                 :             {
     394               0 :               detailedErrorMsg = INTEGER_NUMBER_EXPECTED;
     395               0 :               goto error;
     396                 :             }
     397             738 :             nCoords = atoi(ptrBeginningOfNumber);
     398             738 :             if (nCoords == 0 || nCoords == -1)
     399                 :             {
     400               0 :               detailedErrorMsg = INVALID_GEOMETRY_TYPE;
     401               0 :               goto error;
     402                 :             }
     403             738 :             else if (nCoords == 1)
     404                 :             {
     405             144 :               currentFeatureType = record->featureType = BNA_POINT;
     406             144 :               record->nCoords = 1;
     407                 :             }
     408             594 :             else if (nCoords == 2)
     409                 :             {
     410             124 :               currentFeatureType = record->featureType = BNA_ELLIPSE;
     411             124 :               record->nCoords = 2;
     412                 :             }
     413             470 :             else if (nCoords > 0)
     414                 :             {
     415             410 :               currentFeatureType = record->featureType = BNA_POLYGON;
     416             410 :               record->nCoords = nCoords;
     417                 :             }
     418                 :             else
     419                 :             {
     420              60 :               currentFeatureType = record->featureType = BNA_POLYLINE;
     421              60 :               record->nCoords = -nCoords;
     422                 :             }
     423                 : 
     424             738 :             record->nIDs = NB_MIN_BNA_IDS + nbExtraId;
     425                 : 
     426             738 :             if (interestFeatureType == BNA_READ_ALL ||
     427                 :                 interestFeatureType == currentFeatureType)
     428                 :             {
     429                 :               int i;
     430            1390 :               for(i=0;i<NB_MAX_BNA_IDS;i++)
     431                 :               {
     432            1112 :                 if (tmpBufferLength[i] && tmpBuffer[i][0])
     433                 :                 {
     434             558 :                   record->ids[i] = (char*)CPLMalloc(tmpBufferLength[i] + 1);
     435             558 :                   tmpBuffer[i][tmpBufferLength[i]] = 0;
     436             558 :                   memcpy(record->ids[i], tmpBuffer[i], tmpBufferLength[i] + 1);
     437                 :                 }
     438                 :               }
     439                 : 
     440                 :               record->tabCoords =
     441             278 :                   (double(*)[2])VSIMalloc(record->nCoords * 2 * sizeof(double));
     442             278 :               if (record->tabCoords == NULL)
     443                 :               {
     444               0 :                   detailedErrorMsg = NOT_ENOUGH_MEMORY;
     445               0 :                   goto error;
     446                 :               }
     447                 :             }
     448                 :           }
     449           14030 :           else if (numField > NB_MIN_BNA_IDS + nbExtraId)
     450                 :           {
     451           13288 :             if (ptrBeginningOfNumber == NULL)
     452                 :             {
     453               0 :               detailedErrorMsg = FLOAT_NUMBER_EXPECTED;
     454               0 :               goto error;
     455                 :             }
     456           13288 :             if (interestFeatureType == BNA_READ_ALL ||
     457                 :                 interestFeatureType == currentFeatureType)
     458                 :             {
     459            5756 :               char* pszComma = strchr(ptrBeginningOfNumber, ',');
     460            5756 :               if (pszComma)
     461            3234 :                   *pszComma = '\0';
     462            5756 :               record->tabCoords[(numField - nbExtraId - NB_MIN_BNA_IDS - 1) / 2]
     463            5756 :                                [1 - ((numField - nbExtraId) % 2)] =
     464            5756 :                   CPLAtof(ptrBeginningOfNumber);
     465            5756 :               if (pszComma)
     466            3234 :                   *pszComma = ',';
     467                 :             }
     468           13288 :             if (numField == NB_MIN_BNA_IDS + 1 + nbExtraId + 2 * record->nCoords - 1)
     469                 :             {
     470             738 :               if (c != 10)
     471                 :               {
     472               0 :                 if (verbose)
     473                 :                 {
     474                 :                   CPLError(CE_Warning, CPLE_AppDefined, 
     475                 :                            "At line %d, at char %d, extra data will be ignored!\n",
     476               0 :                            *curLine, numChar+1);
     477                 :                 }
     478                 :               }
     479             738 :               *ok = 1;
     480             738 :               return record;
     481                 :             }
     482                 :           }
     483                 : 
     484           14768 :           ptrBeginningOfNumber = NULL;
     485           14768 :           exponentFound = 0;
     486           14768 :           exponentSignFound = 0;
     487           14768 :           dotFound = 0;
     488           14768 :           numField++;
     489                 : 
     490           14768 :           if (c == 10)
     491            5214 :             break;
     492                 :         }
     493          107782 :         else if (c == '"')
     494                 :         {
     495            1480 :           if (numField < NB_MIN_BNA_IDS)
     496                 :           {
     497            1476 :             inQuotes = TRUE;
     498                 :           }
     499               8 :           else if (numField >= NB_MIN_BNA_IDS && currentFeatureType == -1)
     500                 :           {
     501               4 :             if (ptrBeginningOfNumber == NULL)
     502                 :             {
     503               4 :               if (nbExtraId == NB_MAX_BNA_IDS - NB_MIN_BNA_IDS)
     504                 :               {
     505               0 :                 detailedErrorMsg = MAX_BNA_IDS_REACHED;
     506               0 :                 goto error;
     507                 :               }
     508               4 :               nbExtraId ++;
     509               4 :               inQuotes = TRUE;
     510                 :             }
     511                 :             else
     512                 :             {
     513               0 :               detailedErrorMsg = BAD_INTEGER_NUMBER_FORMAT;
     514               0 :               goto error;
     515                 :             }
     516                 :           }
     517                 :           else
     518                 :           {
     519               0 :             detailedErrorMsg = NUMBER_EXPECTED;
     520               0 :             goto error;
     521                 :           }
     522                 :         }
     523                 :         else
     524                 :         {
     525          106302 :           if (numField < NB_MIN_BNA_IDS || (numField == NB_MIN_BNA_IDS + nbExtraId - 1))
     526                 :           {
     527               0 :             detailedErrorMsg = STRING_EXPECTED;
     528               0 :             goto error;
     529                 :           }
     530          106302 :           else if (numField == NB_MIN_BNA_IDS + nbExtraId)
     531                 :           {
     532            1074 :             if (c >= '0' && c <= '9')
     533                 :             {
     534                 :             }
     535             120 :             else if (c == '+' || c == '-')
     536                 :             {
     537              60 :               if (ptrBeginningOfNumber != NULL)
     538                 :               {
     539               0 :                 detailedErrorMsg = BAD_INTEGER_NUMBER_FORMAT;
     540               0 :                 goto error;
     541                 :               }
     542                 :             }
     543                 :             else
     544                 :             {
     545               0 :               detailedErrorMsg = BAD_INTEGER_NUMBER_FORMAT;
     546               0 :               goto error;
     547                 :             }
     548            1074 :             if (ptrBeginningOfNumber == NULL)
     549             738 :               ptrBeginningOfNumber = ptrCurLine;
     550                 :           }
     551                 :           else
     552                 :           {
     553          105228 :             if (c >= '0' && c <= '9')
     554                 :             {
     555                 :             }
     556           14396 :             else if (c == '.')
     557                 :             {
     558           14396 :               if (dotFound || exponentFound)
     559                 :               {
     560               0 :                 detailedErrorMsg = BAD_FLOAT_NUMBER_FORMAT;
     561               0 :                 goto error;
     562                 :               }
     563           14396 :               dotFound = 1;
     564                 :             }
     565               0 :             else if (c == '+' || c == '-')
     566                 :             {
     567               0 :               if (ptrBeginningOfNumber == NULL)
     568                 :               {
     569                 :               }
     570               0 :               else if (exponentFound)
     571                 :               {
     572               0 :                 if (exponentSignFound == 0 && ptrCurLine > ptrBeginLine &&
     573               0 :                     (ptrCurLine[-1] == 'e' || ptrCurLine[-1] == 'E' ||
     574               0 :                      ptrCurLine[-1] == 'd' || ptrCurLine[-1] == 'D'))
     575                 :                 {
     576               0 :                   exponentSignFound = 1;
     577                 :                 }
     578                 :                 else
     579                 :                 {
     580               0 :                   detailedErrorMsg = BAD_FLOAT_NUMBER_FORMAT;
     581               0 :                   goto error;
     582                 :                 }
     583                 :               }
     584                 :               else
     585                 :               {
     586               0 :                 detailedErrorMsg = BAD_FLOAT_NUMBER_FORMAT;
     587               0 :                 goto error;
     588                 :               }
     589                 :             }
     590               0 :             else if (c == 'e' || c == 'E' || c == 'd' || c == 'D')
     591                 :             {
     592               0 :               if (ptrBeginningOfNumber == NULL ||
     593               0 :                   !(ptrCurLine[-1] >= '0' && ptrCurLine[-1] <= '9') ||
     594                 :                   exponentFound == 1)
     595                 :               {
     596               0 :                 detailedErrorMsg = BAD_FLOAT_NUMBER_FORMAT;
     597               0 :                 goto error;
     598                 :               }
     599               0 :               exponentFound = 1;
     600                 :             }
     601                 :             else
     602                 :             {
     603               0 :               detailedErrorMsg = BAD_FLOAT_NUMBER_FORMAT;
     604               0 :               goto error;
     605                 :             }
     606          105228 :             if (ptrBeginningOfNumber == NULL)
     607           15612 :               ptrBeginningOfNumber = ptrCurLine;
     608                 :           }
     609                 :         }
     610          124736 :         ptrCurLine++;
     611                 :       }
     612                 :     }
     613                 : 
     614             146 :     if (numField == 0)
     615                 :     {
     616                 :         /* End of file */
     617             146 :         *ok = 1;
     618             146 :         BNA_FreeRecord(record);
     619             146 :         return NULL;
     620                 :     }
     621                 :     else
     622                 :     {
     623               0 :         detailedErrorMsg = MISSING_FIELDS;
     624                 :         goto error;
     625                 :     }
     626                 : error:
     627               0 :     if (verbose)
     628                 :     {
     629               0 :       if (detailedErrorMsg)
     630                 :       {
     631                 :         CPLError(CE_Failure, CPLE_AppDefined, 
     632                 :                 "Parsing failed at line %d, at char %d : %s!\n",
     633               0 :                  *curLine, numChar+1, detailedErrorMsg);
     634                 :       }
     635                 :       else
     636                 :       {
     637                 :         CPLError(CE_Failure, CPLE_AppDefined, 
     638                 :                 "Parsing failed at line %d, at char %d!\n",
     639               0 :                  *curLine, numChar+1);
     640                 :       }
     641                 :     }
     642               0 :     BNA_FreeRecord(record);
     643               0 :     return NULL;
     644                 : }

Generated by: LCOV version 1.7