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-12-26 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             442 : void BNA_FreeRecord(BNARecord* record)
      36                 : {
      37             442 :   if (record)
      38                 :   {
      39                 :     int i;
      40            2210 :     for(i=0;i<NB_MAX_BNA_IDS;i++)
      41                 :     {
      42            1768 :         if (record->ids[i]) VSIFree(record->ids[i]);
      43            1768 :         record->ids[i] = NULL;
      44                 :     }
      45             442 :     CPLFree(record->tabCoords);
      46             442 :     record->tabCoords = NULL;
      47             442 :     CPLFree(record);
      48                 :   }
      49             442 : }
      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            3049 : static int BNA_GetLine(char szLineBuffer[LINE_BUFFER_SIZE+1], VSILFILE* f)
     150                 : {
     151            3049 :     char* ptrCurLine = szLineBuffer;
     152            3049 :     int nRead = VSIFReadL(szLineBuffer, 1, LINE_BUFFER_SIZE, f);
     153            3049 :     szLineBuffer[nRead] = 0;
     154            3049 :     if (nRead == 0)
     155                 :     {
     156                 :         /* EOF */
     157              73 :         return BNA_LINE_EOF;
     158                 :     }
     159                 : 
     160            2976 :     int bFoundEOL = FALSE;
     161           69482 :     while (*ptrCurLine)
     162                 :     {
     163           66506 :         if (*ptrCurLine == 0x0d || *ptrCurLine == 0x0a)
     164                 :         {
     165            2976 :             bFoundEOL = TRUE;
     166            2976 :             break;
     167                 :         }
     168           63530 :         ptrCurLine ++;
     169                 :     }
     170            2976 :     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            2976 :     if (*ptrCurLine == 0x0d)
     179                 :     {
     180            2224 :         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            2224 :         else if (ptrCurLine[1] == 0x0a)
     197                 :         {
     198            2224 :             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             752 :         VSIFSeekL(f, VSIFTellL(f) + ptrCurLine + 1 - (szLineBuffer + nRead), SEEK_SET);
     208                 :     }
     209            2976 :     *ptrCurLine = 0;
     210                 : 
     211            2976 :     return BNA_LINE_OK;
     212                 : }
     213                 : 
     214                 : 
     215             442 : 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             442 :     int inQuotes = FALSE;
     224             442 :     int numField = 0;
     225             442 :     char* ptrBeginningOfNumber = NULL;
     226             442 :     int exponentFound = 0;
     227             442 :     int exponentSignFound = 0;
     228             442 :     int dotFound = 0;
     229             442 :     int numChar = 0;
     230             442 :     const char* detailedErrorMsg = NULL;
     231             442 :     BNAFeatureType currentFeatureType = (BNAFeatureType) -1;
     232             442 :     int nbExtraId = 0;
     233                 :     char tmpBuffer[NB_MAX_BNA_IDS][TMP_BUFFER_SIZE+1];
     234             442 :     int  tmpBufferLength[NB_MAX_BNA_IDS] = {0, 0, 0};
     235                 :     char szLineBuffer[LINE_BUFFER_SIZE + 1];
     236                 : 
     237             442 :     record = (BNARecord*)CPLMalloc(sizeof(BNARecord));
     238             442 :     memset(record, 0, sizeof(BNARecord));
     239                 : 
     240            2607 :     while (TRUE)
     241                 :     {
     242            3049 :       numChar = 0;
     243            3049 :       (*curLine)++;
     244                 : 
     245            3049 :       int retGetLine = BNA_GetLine(szLineBuffer, f);
     246            3049 :       if (retGetLine == BNA_LINE_TOO_LONG)
     247                 :       {
     248               0 :           detailedErrorMsg = LINE_TOO_LONG;
     249               0 :           goto error;
     250                 :       }
     251            3049 :       else if (retGetLine == BNA_LINE_EOF)
     252                 :       {
     253                 :           break;
     254                 :       }
     255                 : 
     256            2976 :       char* ptrCurLine = szLineBuffer;
     257            2976 :       const char* ptrBeginLine = szLineBuffer;
     258                 : 
     259            2976 :       if (*ptrCurLine == 0)
     260               0 :         continue;
     261                 : 
     262           63530 :       while(1)
     263                 :       {
     264           66506 :         numChar = ptrCurLine - ptrBeginLine;
     265           66506 :         c = *ptrCurLine;
     266           66506 :         if (c == 0) c = 10;
     267           66506 :         if (inQuotes)
     268                 :         {
     269            3700 :           if (c == 10)
     270                 :           {
     271               0 :             detailedErrorMsg = STRING_NOT_TERMINATED;
     272               0 :             goto error;
     273                 :           }
     274            3700 :           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            3700 :           else if (c == '"')
     286                 :           {
     287             740 :             inQuotes = FALSE;
     288                 :           }
     289                 :           else
     290                 :           {
     291            2960 :             if (tmpBufferLength[numField] == TMP_BUFFER_SIZE)
     292                 :             {
     293               0 :               detailedErrorMsg = TOO_LONG_ID; 
     294               0 :               goto error;
     295                 :             }
     296            2960 :             tmpBuffer[numField][tmpBufferLength[numField]++] = c;
     297                 :           }
     298                 :         }
     299           62806 :         else if (c == ' ' || c == '\t')
     300                 :         {
     301            1162 :           if (numField > NB_MIN_BNA_IDS + nbExtraId && ptrBeginningOfNumber != NULL)
     302                 :           {
     303               0 :             do
     304                 :             {
     305            1162 :               ptrCurLine++;
     306            1162 :               numChar = ptrCurLine - ptrBeginLine;
     307            1162 :               c = *ptrCurLine;
     308            1162 :               if (!(c == ' ' || c == '\t'))
     309            1162 :                 break;
     310                 :             } while(c);
     311            1162 :             if (c == 0) c = 10;
     312                 : 
     313            1162 :             if (interestFeatureType == BNA_READ_ALL ||
     314                 :                 interestFeatureType == currentFeatureType)
     315                 :             {
     316             332 :               char* pszComma = strchr(ptrBeginningOfNumber, ',');
     317             332 :               if (pszComma)
     318             332 :                   *pszComma = '\0';
     319             332 :               record->tabCoords[(numField - nbExtraId - NB_MIN_BNA_IDS - 1) / 2]
     320             332 :                                [1 - ((numField - nbExtraId) % 2)] =
     321             332 :                   CPLAtof(ptrBeginningOfNumber);
     322             332 :               if (pszComma)
     323             332 :                   *pszComma = ',';
     324                 :             }
     325            1162 :             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            1162 :             ptrBeginningOfNumber = NULL;
     341            1162 :             exponentFound = 0;
     342            1162 :             exponentSignFound = 0;
     343            1162 :             dotFound = 0;
     344            1162 :             numField++;
     345                 : 
     346            1162 :             if (c == 10)
     347               0 :               break;
     348                 : 
     349            1162 :             if (c != ',')
     350                 :             {
     351                 :               /* don't increment ptrCurLine */
     352            1162 :               continue;
     353                 :             }
     354                 :           }
     355                 :           else
     356                 :           {
     357                 :             /* ignore */
     358                 :           }
     359                 :         }
     360           66421 :         else if (c == 10 || c == ',')
     361                 :         {
     362                 :           /* Eat a comma placed at end of line */
     363            7753 :           if (c == ',')
     364                 :           {
     365            4777 :               const char* ptr = ptrCurLine+1;
     366            9554 :               while(*ptr)
     367                 :               {
     368            4777 :                   if (*ptr != ' ' && *ptr != '\t')
     369            4777 :                       break;
     370               0 :                   ptr++;
     371                 :               }
     372            4777 :               if (*ptr == 0)
     373                 :               {
     374               0 :                   c = 10;
     375                 :               }
     376                 :           }
     377                 : 
     378            7753 :           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            7384 :           else if (numField == NB_MIN_BNA_IDS + nbExtraId)
     390                 :           {
     391                 :             int nCoords;
     392             369 :             if (ptrBeginningOfNumber == NULL)
     393                 :             {
     394               0 :               detailedErrorMsg = INTEGER_NUMBER_EXPECTED;
     395               0 :               goto error;
     396                 :             }
     397             369 :             nCoords = atoi(ptrBeginningOfNumber);
     398             369 :             if (nCoords == 0 || nCoords == -1)
     399                 :             {
     400               0 :               detailedErrorMsg = INVALID_GEOMETRY_TYPE;
     401               0 :               goto error;
     402                 :             }
     403             369 :             else if (nCoords == 1)
     404                 :             {
     405              72 :               currentFeatureType = record->featureType = BNA_POINT;
     406              72 :               record->nCoords = 1;
     407                 :             }
     408             297 :             else if (nCoords == 2)
     409                 :             {
     410              62 :               currentFeatureType = record->featureType = BNA_ELLIPSE;
     411              62 :               record->nCoords = 2;
     412                 :             }
     413             235 :             else if (nCoords > 0)
     414                 :             {
     415             205 :               currentFeatureType = record->featureType = BNA_POLYGON;
     416             205 :               record->nCoords = nCoords;
     417                 :             }
     418                 :             else
     419                 :             {
     420              30 :               currentFeatureType = record->featureType = BNA_POLYLINE;
     421              30 :               record->nCoords = -nCoords;
     422                 :             }
     423                 : 
     424             369 :             record->nIDs = NB_MIN_BNA_IDS + nbExtraId;
     425                 : 
     426             369 :             if (interestFeatureType == BNA_READ_ALL ||
     427                 :                 interestFeatureType == currentFeatureType)
     428                 :             {
     429                 :               int i;
     430             695 :               for(i=0;i<NB_MAX_BNA_IDS;i++)
     431                 :               {
     432             556 :                 if (tmpBufferLength[i] && tmpBuffer[i][0])
     433                 :                 {
     434             279 :                   record->ids[i] = (char*)CPLMalloc(tmpBufferLength[i] + 1);
     435             279 :                   tmpBuffer[i][tmpBufferLength[i]] = 0;
     436             279 :                   memcpy(record->ids[i], tmpBuffer[i], tmpBufferLength[i] + 1);
     437                 :                 }
     438                 :               }
     439                 : 
     440                 :               record->tabCoords =
     441             139 :                   (double(*)[2])VSIMalloc(record->nCoords * 2 * sizeof(double));
     442             139 :               if (record->tabCoords == NULL)
     443                 :               {
     444               0 :                   detailedErrorMsg = NOT_ENOUGH_MEMORY;
     445               0 :                   goto error;
     446                 :               }
     447                 :             }
     448                 :           }
     449            7015 :           else if (numField > NB_MIN_BNA_IDS + nbExtraId)
     450                 :           {
     451            6644 :             if (ptrBeginningOfNumber == NULL)
     452                 :             {
     453               0 :               detailedErrorMsg = FLOAT_NUMBER_EXPECTED;
     454               0 :               goto error;
     455                 :             }
     456            6644 :             if (interestFeatureType == BNA_READ_ALL ||
     457                 :                 interestFeatureType == currentFeatureType)
     458                 :             {
     459            2878 :               char* pszComma = strchr(ptrBeginningOfNumber, ',');
     460            2878 :               if (pszComma)
     461            1617 :                   *pszComma = '\0';
     462            2878 :               record->tabCoords[(numField - nbExtraId - NB_MIN_BNA_IDS - 1) / 2]
     463            2878 :                                [1 - ((numField - nbExtraId) % 2)] =
     464            2878 :                   CPLAtof(ptrBeginningOfNumber);
     465            2878 :               if (pszComma)
     466            1617 :                   *pszComma = ',';
     467                 :             }
     468            6644 :             if (numField == NB_MIN_BNA_IDS + 1 + nbExtraId + 2 * record->nCoords - 1)
     469                 :             {
     470             369 :               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             369 :               *ok = 1;
     480             369 :               return record;
     481                 :             }
     482                 :           }
     483                 : 
     484            7384 :           ptrBeginningOfNumber = NULL;
     485            7384 :           exponentFound = 0;
     486            7384 :           exponentSignFound = 0;
     487            7384 :           dotFound = 0;
     488            7384 :           numField++;
     489                 : 
     490            7384 :           if (c == 10)
     491            2607 :             break;
     492                 :         }
     493           53891 :         else if (c == '"')
     494                 :         {
     495             740 :           if (numField < NB_MIN_BNA_IDS)
     496                 :           {
     497             738 :             inQuotes = TRUE;
     498                 :           }
     499               4 :           else if (numField >= NB_MIN_BNA_IDS && currentFeatureType == -1)
     500                 :           {
     501               2 :             if (ptrBeginningOfNumber == NULL)
     502                 :             {
     503               2 :               if (nbExtraId == NB_MAX_BNA_IDS - NB_MIN_BNA_IDS)
     504                 :               {
     505               0 :                 detailedErrorMsg = MAX_BNA_IDS_REACHED;
     506               0 :                 goto error;
     507                 :               }
     508               2 :               nbExtraId ++;
     509               2 :               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           53151 :           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           53151 :           else if (numField == NB_MIN_BNA_IDS + nbExtraId)
     531                 :           {
     532             537 :             if (c >= '0' && c <= '9')
     533                 :             {
     534                 :             }
     535              60 :             else if (c == '+' || c == '-')
     536                 :             {
     537              30 :               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             537 :             if (ptrBeginningOfNumber == NULL)
     549             369 :               ptrBeginningOfNumber = ptrCurLine;
     550                 :           }
     551                 :           else
     552                 :           {
     553           52614 :             if (c >= '0' && c <= '9')
     554                 :             {
     555                 :             }
     556            7198 :             else if (c == '.')
     557                 :             {
     558            7198 :               if (dotFound || exponentFound)
     559                 :               {
     560               0 :                 detailedErrorMsg = BAD_FLOAT_NUMBER_FORMAT;
     561               0 :                 goto error;
     562                 :               }
     563            7198 :               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           52614 :             if (ptrBeginningOfNumber == NULL)
     607            7806 :               ptrBeginningOfNumber = ptrCurLine;
     608                 :           }
     609                 :         }
     610           62368 :         ptrCurLine++;
     611                 :       }
     612                 :     }
     613                 : 
     614              73 :     if (numField == 0)
     615                 :     {
     616                 :         /* End of file */
     617              73 :         *ok = 1;
     618              73 :         BNA_FreeRecord(record);
     619              73 :         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