LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/geoconcept - geoconcept.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 1108 2573 43.1 %
Date: 2024-04-28 21:03:45 Functions: 62 83 74.7 %

          Line data    Source code
       1             : /**********************************************************************
       2             :  * $Id$
       3             :  *
       4             :  * Name:     geoconcept.c
       5             :  * Project:  OpenGIS Simple Features Reference Implementation
       6             :  * Purpose:  Implements Physical Access class.
       7             :  * Language: C
       8             :  *
       9             :  **********************************************************************
      10             :  * Copyright (c) 2007,  Geoconcept and IGN
      11             :  * Copyright (c) 2008-2013, Even Rouault <even dot rouault at spatialys.com>
      12             :  *
      13             :  * Permission is hereby granted, free of charge, to any person obtaining a
      14             :  * copy of this software and associated documentation files (the "Software"),
      15             :  * to deal in the Software without restriction, including without limitation
      16             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      17             :  * and/or sell copies of the Software, and to permit persons to whom the
      18             :  * Software is furnished to do so, subject to the following conditions:
      19             :  *
      20             :  * The above copyright notice and this permission notice shall be included
      21             :  * in all copies or substantial portions of the Software.
      22             :  *
      23             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      24             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      25             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
      26             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      27             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      28             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      29             :  * DEALINGS IN THE SOFTWARE.
      30             :  **********************************************************************/
      31             : 
      32             : #include "cpl_port.h"
      33             : #include <math.h>
      34             : #include "geoconcept.h"
      35             : #include "cpl_conv.h"
      36             : #include "cpl_string.h"
      37             : #include "ogr_core.h"
      38             : 
      39             : #define kItemSize_GCIO 256
      40             : #define kExtraSize_GCIO 4096
      41             : #define kIdSize_GCIO 12
      42             : #define UNDEFINEDID_GCIO 199901L
      43             : 
      44             : static const char *const gkGCCharset[] = {
      45             :     /* 0 */ "",
      46             :     /* 1 */ "ANSI",
      47             :     /* 2 */ "DOS",
      48             :     /* 3 */ "MAC"};
      49             : 
      50             : static const char *const gkGCAccess[] = {
      51             :     /* 0 */ "",
      52             :     /* 1 */ "NO",
      53             :     /* 2 */ "READ",
      54             :     /* 3 */ "UPDATE",
      55             :     /* 4 */ "WRITE"};
      56             : 
      57             : static const char *const gkGCStatus[] = {
      58             :     /* 0 */ "NONE",
      59             :     /* 1 */ "MEMO",
      60             :     /* 2 */ "EOF"};
      61             : 
      62             : static const char *const gk3D[] = {
      63             :     /* 0 */ "",
      64             :     /* 1 */ "2D",
      65             :     /* 2 */ "3DM",
      66             :     /* 3 */ "3D"};
      67             : 
      68             : static const char *const gkGCTypeKind[] = {
      69             :     /* 0 */ "",
      70             :     /* 1 */ "POINT",
      71             :     /* 2 */ "LINE",
      72             :     /* 3 */ "TEXT",
      73             :     /* 4 */ "POLYGON",
      74             :     /* 5 */ "MEMO",
      75             :     /* 6 */ "INT",
      76             :     /* 7 */ "REAL",
      77             :     /* 8 */ "LENGTH",
      78             :     /* 9 */ "AREA",
      79             :     /*10 */ "POSITION",
      80             :     /*11 */ "DATE",
      81             :     /*12 */ "TIME",
      82             :     /*13 */ "CHOICE",
      83             :     /*14 */ "MEMO"};
      84             : 
      85             : /* -------------------------------------------------------------------- */
      86             : /*      GCIO API Prototypes                                             */
      87             : /* -------------------------------------------------------------------- */
      88             : 
      89             : /* -------------------------------------------------------------------- */
      90           0 : static char GCIOAPI_CALL1(*) _getHeaderValue_GCIO(const char *s)
      91             : {
      92             :     char *b, *e;
      93             : 
      94           0 :     if ((b = strchr(s, '=')) == NULL)
      95           0 :         return NULL;
      96           0 :     b++;
      97           0 :     while (isspace((unsigned char)*b))
      98           0 :         b++;
      99           0 :     e = b;
     100           0 :     while (*e != '\0' && !isspace((unsigned char)*e))
     101           0 :         e++;
     102           0 :     *e = '\0';
     103           0 :     return b;
     104             : } /* _getHeaderValue_GCIO */
     105             : 
     106             : /* -------------------------------------------------------------------- */
     107           9 : const char GCIOAPI_CALL1(*) GCCharset2str_GCIO(GCCharset cs)
     108             : {
     109           9 :     switch (cs)
     110             :     {
     111           9 :         case vANSI_GCIO:
     112             :         case vDOS_GCIO:
     113             :         case vMAC_GCIO:
     114           9 :             return gkGCCharset[cs];
     115           0 :         default:
     116           0 :             return gkGCCharset[vUnknownCharset_GCIO];
     117             :     }
     118             : } /* GCCharset2str_GCIO */
     119             : 
     120             : /* -------------------------------------------------------------------- */
     121           8 : GCCharset GCIOAPI_CALL str2GCCharset_GCIO(const char *s)
     122             : {
     123           8 :     if (strcmp(s, gkGCCharset[vANSI_GCIO]) == 0)
     124           8 :         return vANSI_GCIO;
     125           0 :     if (strcmp(s, gkGCCharset[vDOS_GCIO]) == 0)
     126           0 :         return vDOS_GCIO;
     127           0 :     if (strcmp(s, gkGCCharset[vMAC_GCIO]) == 0)
     128           0 :         return vMAC_GCIO;
     129           0 :     return vUnknownCharset_GCIO;
     130             : } /* str2GCCharset_GCIO */
     131             : 
     132             : /* -------------------------------------------------------------------- */
     133          25 : const char GCIOAPI_CALL1(*) GCAccessMode2str_GCIO(GCAccessMode mode)
     134             : {
     135          25 :     switch (mode)
     136             :     {
     137          25 :         case vNoAccess_GCIO:
     138             :         case vReadAccess_GCIO:
     139             :         case vUpdateAccess_GCIO:
     140             :         case vWriteAccess_GCIO:
     141          25 :             return gkGCAccess[mode];
     142           0 :         default:
     143           0 :             return gkGCAccess[vUnknownAccessMode_GCIO];
     144             :     }
     145             : } /* GCAccessMode2str_GCIO */
     146             : 
     147             : /* -------------------------------------------------------------------- */
     148           0 : GCAccessMode GCIOAPI_CALL str2GCAccessMode_GCIO(const char *s)
     149             : {
     150           0 :     if (strcmp(s, gkGCAccess[vNoAccess_GCIO]) == 0)
     151           0 :         return vNoAccess_GCIO;
     152           0 :     if (strcmp(s, gkGCAccess[vReadAccess_GCIO]) == 0)
     153           0 :         return vReadAccess_GCIO;
     154           0 :     if (strcmp(s, gkGCAccess[vUpdateAccess_GCIO]) == 0)
     155           0 :         return vUpdateAccess_GCIO;
     156           0 :     if (strcmp(s, gkGCAccess[vWriteAccess_GCIO]) == 0)
     157           0 :         return vWriteAccess_GCIO;
     158           0 :     return vUnknownAccessMode_GCIO;
     159             : } /* str2GCAccessMode_GCIO */
     160             : 
     161             : /* -------------------------------------------------------------------- */
     162          25 : const char GCIOAPI_CALL1(*) GCAccessStatus2str_GCIO(GCAccessStatus stts)
     163             : {
     164          25 :     switch (stts)
     165             :     {
     166           0 :         case vMemoStatus_GCIO:
     167             :         case vEof_GCIO:
     168           0 :             return gkGCStatus[stts];
     169          25 :         default:
     170          25 :             return gkGCStatus[vNoStatus_GCIO];
     171             :     }
     172             : } /* GCAccessStatus2str_GCIO */
     173             : 
     174             : /* -------------------------------------------------------------------- */
     175           0 : GCAccessStatus GCIOAPI_CALL str2GCAccessStatus_GCIO(const char *s)
     176             : {
     177           0 :     if (strcmp(s, gkGCStatus[vMemoStatus_GCIO]) == 0)
     178           0 :         return vMemoStatus_GCIO;
     179           0 :     if (strcmp(s, gkGCStatus[vEof_GCIO]) == 0)
     180           0 :         return vEof_GCIO;
     181           0 :     return vNoStatus_GCIO;
     182             : } /* str2GCAccessStatus_GCIO */
     183             : 
     184             : /* -------------------------------------------------------------------- */
     185           0 : const char GCIOAPI_CALL1(*) GCDim2str_GCIO(GCDim sys)
     186             : {
     187           0 :     switch (sys)
     188             :     {
     189           0 :         case v2D_GCIO:
     190             :         case v3D_GCIO:
     191             :         case v3DM_GCIO:
     192           0 :             return gk3D[sys];
     193           0 :         default:
     194           0 :             return gk3D[vUnknown3D_GCIO];
     195             :     }
     196             : } /* GCDim2str_GCIO */
     197             : 
     198             : /* -------------------------------------------------------------------- */
     199           0 : GCDim GCIOAPI_CALL str2GCDim(const char *s)
     200             : {
     201           0 :     if (strcmp(s, gk3D[v2D_GCIO]) == 0)
     202           0 :         return v2D_GCIO;
     203           0 :     if (strcmp(s, gk3D[v3D_GCIO]) == 0)
     204           0 :         return v3D_GCIO;
     205           0 :     if (strcmp(s, gk3D[v3DM_GCIO]) == 0)
     206           0 :         return v3DM_GCIO;
     207           0 :     return vUnknown3D_GCIO;
     208             : } /* str2GCDim */
     209             : 
     210             : /* -------------------------------------------------------------------- */
     211           0 : const char GCIOAPI_CALL1(*) GCTypeKind2str_GCIO(GCTypeKind item)
     212             : {
     213           0 :     switch (item)
     214             :     {
     215           0 :         case vPoint_GCIO:
     216             :         case vLine_GCIO:
     217             :         case vText_GCIO:
     218             :         case vPoly_GCIO:
     219             :         case vMemoFld_GCIO:
     220             :         case vIntFld_GCIO:
     221             :         case vRealFld_GCIO:
     222             :         case vLengthFld_GCIO:
     223             :         case vAreaFld_GCIO:
     224             :         case vPositionFld_GCIO:
     225             :         case vDateFld_GCIO:
     226             :         case vTimeFld_GCIO:
     227             :         case vChoiceFld_GCIO:
     228             :         case vInterFld_GCIO:
     229           0 :             return gkGCTypeKind[item];
     230           0 :         default:
     231           0 :             return gkGCTypeKind[vUnknownItemType_GCIO];
     232             :     }
     233             : } /* GCTypeKind2str_GCIO */
     234             : 
     235             : /* -------------------------------------------------------------------- */
     236           0 : GCTypeKind GCIOAPI_CALL str2GCTypeKind_GCIO(const char *s)
     237             : {
     238           0 :     if (strcmp(s, gkGCTypeKind[vPoint_GCIO]) == 0)
     239           0 :         return vPoint_GCIO;
     240           0 :     if (strcmp(s, gkGCTypeKind[vLine_GCIO]) == 0)
     241           0 :         return vLine_GCIO;
     242           0 :     if (strcmp(s, gkGCTypeKind[vText_GCIO]) == 0)
     243           0 :         return vText_GCIO;
     244           0 :     if (strcmp(s, gkGCTypeKind[vPoly_GCIO]) == 0)
     245           0 :         return vPoly_GCIO;
     246           0 :     if (strcmp(s, gkGCTypeKind[vMemoFld_GCIO]) == 0)
     247           0 :         return vMemoFld_GCIO;
     248           0 :     if (strcmp(s, gkGCTypeKind[vIntFld_GCIO]) == 0)
     249           0 :         return vIntFld_GCIO;
     250           0 :     if (strcmp(s, gkGCTypeKind[vRealFld_GCIO]) == 0)
     251           0 :         return vRealFld_GCIO;
     252           0 :     if (strcmp(s, gkGCTypeKind[vLengthFld_GCIO]) == 0)
     253           0 :         return vLengthFld_GCIO;
     254           0 :     if (strcmp(s, gkGCTypeKind[vAreaFld_GCIO]) == 0)
     255           0 :         return vAreaFld_GCIO;
     256           0 :     if (strcmp(s, gkGCTypeKind[vPositionFld_GCIO]) == 0)
     257           0 :         return vPositionFld_GCIO;
     258           0 :     if (strcmp(s, gkGCTypeKind[vDateFld_GCIO]) == 0)
     259           0 :         return vDateFld_GCIO;
     260           0 :     if (strcmp(s, gkGCTypeKind[vTimeFld_GCIO]) == 0)
     261           0 :         return vTimeFld_GCIO;
     262           0 :     if (strcmp(s, gkGCTypeKind[vChoiceFld_GCIO]) == 0)
     263           0 :         return vChoiceFld_GCIO;
     264           0 :     if (strcmp(s, gkGCTypeKind[vInterFld_GCIO]) == 0)
     265           0 :         return vInterFld_GCIO;
     266           0 :     return vUnknownItemType_GCIO;
     267             : } /* str2GCTypeKind_GCIO */
     268             : 
     269             : /* -------------------------------------------------------------------- */
     270           1 : static const char GCIOAPI_CALL1(*) _metaDelimiter2str_GCIO(char delim)
     271             : {
     272           1 :     switch (delim)
     273             :     {
     274           1 :         case '\t':
     275           1 :             return "tab";
     276           0 :         default:
     277           0 :             return "\t";
     278             :     }
     279             : } /* _metaDelimiter2str_GCIO */
     280             : 
     281             : /* -------------------------------------------------------------------- */
     282         174 : static long GCIOAPI_CALL _read_GCIO(GCExportFileH *hGXT)
     283             : {
     284             :     VSILFILE *h;
     285             :     long nread;
     286             :     unsigned char c;
     287             :     char *result;
     288             : 
     289         174 :     h = GetGCHandle_GCIO(hGXT);
     290         174 :     nread = 0L;
     291         174 :     result = GetGCCache_GCIO(hGXT);
     292         174 :     SetGCCurrentOffset_GCIO(
     293             :         hGXT, VSIFTellL(h)); /* keep offset of beginning of lines */
     294       11530 :     while (VSIFReadL(&c, 1, 1, h) == 1)
     295             :     {
     296       11516 :         if (c == '\r') /* PC '\r\n' line, MAC '\r' */
     297             :         {
     298           0 :             if (VSIFReadL(&c, 1, 1, h) != 1)
     299             :             {
     300           0 :                 c = '\n';
     301             :             }
     302           0 :             else if (c != '\n')
     303             :             {
     304           0 :                 VSIFSeekL(h, VSIFTellL(h) - 1, SEEK_SET);
     305           0 :                 c = '\n';
     306             :             }
     307             :         }
     308             : 
     309       11516 :         switch (c)
     310             :         {
     311           0 :             case 0X1A:
     312           0 :                 continue; /* PC end-of-file           */
     313         160 :             case '\n':
     314         160 :                 SetGCCurrentLinenum_GCIO(hGXT,
     315             :                                          GetGCCurrentLinenum_GCIO(hGXT) + 1L);
     316         160 :                 if (nread == 0L)
     317           0 :                     continue;
     318         160 :                 *result = '\0';
     319         160 :                 return nread;
     320       11356 :             default:
     321       11356 :                 *result = (char)c;
     322       11356 :                 result++;
     323       11356 :                 nread++;
     324       11356 :                 if (nread == kCacheSize_GCIO)
     325             :                 {
     326           0 :                     CPLError(CE_Failure, CPLE_OutOfMemory,
     327             :                              "Too many characters at line %lu.\n",
     328             :                              GetGCCurrentLinenum_GCIO(hGXT));
     329           0 :                     return EOF;
     330             :                 }
     331             :         } /* switch */
     332             :     }     /* while */
     333          14 :     *result = '\0';
     334             : 
     335          14 :     SetGCStatus_GCIO(hGXT, vEof_GCIO);
     336          14 :     if (nread == 0L)
     337             :     {
     338          14 :         return EOF;
     339             :     }
     340           0 :     return nread;
     341             : 
     342             : } /* _read_GCIO */
     343             : 
     344             : /* -------------------------------------------------------------------- */
     345         174 : static vsi_l_offset GCIOAPI_CALL _get_GCIO(GCExportFileH *hGXT)
     346             : {
     347         174 :     if (GetGCStatus_GCIO(hGXT) == vEof_GCIO)
     348             :     {
     349           0 :         SetGCCache_GCIO(hGXT, "");
     350           0 :         SetGCWhatIs_GCIO(hGXT, (GCTypeKind)vUnknownIO_ItemType_GCIO);
     351           0 :         return EOF;
     352             :     }
     353         174 :     if (GetGCStatus_GCIO(hGXT) == vMemoStatus_GCIO)
     354             :     {
     355           0 :         SetGCStatus_GCIO(hGXT, vNoStatus_GCIO);
     356           0 :         return GetGCCurrentOffset_GCIO(hGXT);
     357             :     }
     358         174 :     if (_read_GCIO(hGXT) == EOF)
     359             :     {
     360          14 :         SetGCWhatIs_GCIO(hGXT, (GCTypeKind)vUnknownIO_ItemType_GCIO);
     361          14 :         return (vsi_l_offset)EOF;
     362             :     }
     363         160 :     SetGCWhatIs_GCIO(hGXT, (GCTypeKind)vStdCol_GCIO);
     364         160 :     if (strstr(GetGCCache_GCIO(hGXT), kCom_GCIO) == GetGCCache_GCIO(hGXT))
     365             :     { /* // */
     366         105 :         SetGCWhatIs_GCIO(hGXT, (GCTypeKind)vComType_GCIO);
     367         105 :         if (strstr(GetGCCache_GCIO(hGXT), kHeader_GCIO) ==
     368             :             GetGCCache_GCIO(hGXT))
     369             :         { /* //# */
     370           0 :             SetGCWhatIs_GCIO(hGXT, (GCTypeKind)vHeader_GCIO);
     371             :         }
     372             :         else
     373             :         {
     374         105 :             if (strstr(GetGCCache_GCIO(hGXT), kPragma_GCIO) ==
     375             :                 GetGCCache_GCIO(hGXT))
     376             :             { /* //$ */
     377         105 :                 SetGCWhatIs_GCIO(hGXT, (GCTypeKind)vPragma_GCIO);
     378             :             }
     379             :         }
     380             :     }
     381         160 :     return GetGCCurrentOffset_GCIO(hGXT);
     382             : } /* _get_GCIO */
     383             : 
     384             : /* -------------------------------------------------------------------- */
     385          34 : static void GCIOAPI_CALL _InitExtent_GCIO(GCExtent *theExtent)
     386             : {
     387          34 :     theExtent->XUL = HUGE_VAL;
     388          34 :     theExtent->YUL = -HUGE_VAL;
     389          34 :     theExtent->XLR = -HUGE_VAL;
     390          34 :     theExtent->YLR = HUGE_VAL;
     391          34 : } /* _InitExtent_GCIO */
     392             : 
     393             : /* -------------------------------------------------------------------- */
     394             : GCExtent GCIOAPI_CALL1(*)
     395          17 :     CreateExtent_GCIO(double Xmin, double Ymin, double Xmax, double Ymax)
     396             : {
     397             :     GCExtent *theExtent;
     398             : 
     399          17 :     if (!(theExtent = VSI_MALLOC_VERBOSE(sizeof(GCExtent))))
     400             :     {
     401           0 :         return NULL;
     402             :     }
     403          17 :     _InitExtent_GCIO(theExtent);
     404          17 :     theExtent->XUL = Xmin;
     405          17 :     theExtent->YUL = Ymax;
     406          17 :     theExtent->XLR = Xmax;
     407          17 :     theExtent->YLR = Ymin;
     408             : 
     409          17 :     return theExtent;
     410             : } /* CreateExtent_GCIO */
     411             : 
     412             : /* -------------------------------------------------------------------- */
     413          17 : static void GCIOAPI_CALL _ReInitExtent_GCIO(GCExtent *theExtent)
     414             : {
     415          17 :     _InitExtent_GCIO(theExtent);
     416          17 : } /* _ReInitExtent_GCIO */
     417             : 
     418             : /* -------------------------------------------------------------------- */
     419          17 : void GCIOAPI_CALL DestroyExtent_GCIO(GCExtent **theExtent)
     420             : {
     421          17 :     _ReInitExtent_GCIO(*theExtent);
     422          17 :     CPLFree(*theExtent);
     423          17 :     *theExtent = NULL;
     424          17 : } /* DestroyExtent_GCIO */
     425             : 
     426             : /* -------------------------------------------------------------------- */
     427         180 : static void GCIOAPI_CALL _InitField_GCIO(GCField *theField)
     428             : {
     429         180 :     SetFieldName_GCIO(theField, NULL);
     430         180 :     SetFieldID_GCIO(theField, UNDEFINEDID_GCIO);
     431         180 :     SetFieldKind_GCIO(theField, vUnknownItemType_GCIO);
     432         180 :     SetFieldExtra_GCIO(theField, NULL);
     433         180 :     SetFieldList_GCIO(theField, NULL);
     434         180 : } /* _InitField_GCIO */
     435             : 
     436             : /* -------------------------------------------------------------------- */
     437          90 : static const char GCIOAPI_CALL1(*) _NormalizeFieldName_GCIO(const char *name)
     438             : {
     439          90 :     if (name[0] == '@')
     440             :     {
     441          71 :         if (EQUAL(name, "@Identificateur") || EQUAL(name, kIdentifier_GCIO))
     442             :         {
     443           9 :             return kIdentifier_GCIO;
     444             :         }
     445          62 :         else if (EQUAL(name, "@Type") || EQUAL(name, kClass_GCIO))
     446             :         {
     447           9 :             return kClass_GCIO;
     448             :         }
     449          53 :         else if (EQUAL(name, "@Sous-type") || EQUAL(name, kSubclass_GCIO))
     450             :         {
     451           9 :             return kSubclass_GCIO;
     452             :         }
     453          44 :         else if (EQUAL(name, "@Nom") || EQUAL(name, kName_GCIO))
     454             :         {
     455           9 :             return kName_GCIO;
     456             :         }
     457          35 :         else if (EQUAL(name, kNbFields_GCIO))
     458             :         {
     459           9 :             return kNbFields_GCIO;
     460             :         }
     461          26 :         else if (EQUAL(name, kX_GCIO))
     462             :         {
     463           9 :             return kX_GCIO;
     464             :         }
     465          17 :         else if (EQUAL(name, kY_GCIO))
     466             :         {
     467           9 :             return kY_GCIO;
     468             :         }
     469           8 :         else if (EQUAL(name, "@X'") || EQUAL(name, kXP_GCIO))
     470             :         {
     471           1 :             return kXP_GCIO;
     472             :         }
     473           7 :         else if (EQUAL(name, "@Y'") || EQUAL(name, kYP_GCIO))
     474             :         {
     475           1 :             return kYP_GCIO;
     476             :         }
     477           6 :         else if (EQUAL(name, kGraphics_GCIO))
     478             :         {
     479           6 :             return kGraphics_GCIO;
     480             :         }
     481           0 :         else if (EQUAL(name, kAngle_GCIO))
     482             :         {
     483           0 :             return kAngle_GCIO;
     484             :         }
     485             :         else
     486             :         {
     487           0 :             return name;
     488             :         }
     489             :     }
     490             :     else
     491             :     {
     492          19 :         return name;
     493             :     }
     494             : } /* _NormalizeFieldName_GCIO */
     495             : 
     496             : /* -------------------------------------------------------------------- */
     497             : static GCField GCIOAPI_CALL1(*)
     498          90 :     _CreateField_GCIO(const char *name, long id, GCTypeKind knd,
     499             :                       const char *extra, const char *enums)
     500             : {
     501             :     GCField *theField;
     502             : 
     503          90 :     if (!(theField = VSI_MALLOC_VERBOSE(sizeof(GCField))))
     504             :     {
     505           0 :         return NULL;
     506             :     }
     507          90 :     _InitField_GCIO(theField);
     508          90 :     SetFieldName_GCIO(theField, CPLStrdup(name));
     509          90 :     SetFieldID_GCIO(theField, id);
     510          90 :     SetFieldKind_GCIO(theField, knd);
     511          90 :     if (extra && extra[0] != '\0')
     512           0 :         SetFieldExtra_GCIO(theField, CPLStrdup(extra));
     513          90 :     if (enums && enums[0] != '\0')
     514           0 :         SetFieldList_GCIO(theField, CSLTokenizeString2(enums, ";", 0));
     515             : 
     516          90 :     return theField;
     517             : } /* _CreateField_GCIO */
     518             : 
     519             : /* -------------------------------------------------------------------- */
     520          90 : static void GCIOAPI_CALL _ReInitField_GCIO(GCField *theField)
     521             : {
     522          90 :     if (GetFieldName_GCIO(theField))
     523             :     {
     524          90 :         CPLFree(GetFieldName_GCIO(theField));
     525             :     }
     526          90 :     if (GetFieldExtra_GCIO(theField))
     527             :     {
     528           0 :         CPLFree(GetFieldExtra_GCIO(theField));
     529             :     }
     530          90 :     if (GetFieldList_GCIO(theField))
     531             :     {
     532           0 :         CSLDestroy(GetFieldList_GCIO(theField));
     533             :     }
     534          90 :     _InitField_GCIO(theField);
     535          90 : } /* _ReInitField_GCIO */
     536             : 
     537             : /* -------------------------------------------------------------------- */
     538          90 : static void GCIOAPI_CALL _DestroyField_GCIO(GCField **theField)
     539             : {
     540          90 :     _ReInitField_GCIO(*theField);
     541          90 :     CPLFree(*theField);
     542          90 :     *theField = NULL;
     543          90 : } /* _DestroyField_GCIO */
     544             : 
     545             : /* -------------------------------------------------------------------- */
     546         156 : static int GCIOAPI_CALL _findFieldByName_GCIO(CPLList *fields, const char *name)
     547             : {
     548             :     GCField *theField;
     549             : 
     550         156 :     if (fields)
     551             :     {
     552         147 :         int i = 0;
     553         147 :         CPLList *psIter = fields;
     554         811 :         for (; psIter; psIter = psIter->psNext, i++)
     555             :         {
     556         723 :             theField = (GCField *)psIter->pData;
     557         723 :             if (EQUAL(GetFieldName_GCIO(theField), name))
     558             :             {
     559          59 :                 return i;
     560             :             }
     561             :         }
     562             :     }
     563          97 :     return -1;
     564             : } /* _findFieldByName_GCIO */
     565             : 
     566             : /* -------------------------------------------------------------------- */
     567           0 : static GCField GCIOAPI_CALL1(*) _getField_GCIO(CPLList *fields, int where)
     568             : {
     569             :     CPLList *e;
     570             : 
     571           0 :     if ((e = CPLListGet(fields, where)))
     572           0 :         return (GCField *)CPLListGetData(e);
     573           0 :     return NULL;
     574             : } /* _getField_GCIO */
     575             : 
     576             : /* -------------------------------------------------------------------- */
     577          18 : static void GCIOAPI_CALL _InitSubType_GCIO(GCSubType *theSubType)
     578             : {
     579          18 :     SetSubTypeGCHandle_GCIO(theSubType, NULL);
     580          18 :     SetSubTypeType_GCIO(theSubType, NULL);
     581          18 :     SetSubTypeName_GCIO(theSubType, NULL);
     582          18 :     SetSubTypeFields_GCIO(theSubType, NULL); /* GCField */
     583          18 :     SetSubTypeFeatureDefn_GCIO(theSubType, NULL);
     584          18 :     SetSubTypeKind_GCIO(theSubType, vUnknownItemType_GCIO);
     585          18 :     SetSubTypeID_GCIO(theSubType, UNDEFINEDID_GCIO);
     586          18 :     SetSubTypeDim_GCIO(theSubType, v2D_GCIO);
     587          18 :     SetSubTypeNbFields_GCIO(theSubType, -1);
     588          18 :     SetSubTypeNbFeatures_GCIO(theSubType, 0L);
     589          18 :     SetSubTypeBOF_GCIO(theSubType, (vsi_l_offset)EOF);
     590          18 :     SetSubTypeBOFLinenum_GCIO(theSubType, 0L);
     591          18 :     SetSubTypeExtent_GCIO(theSubType, NULL);
     592          18 :     SetSubTypeHeaderWritten_GCIO(theSubType, FALSE);
     593          18 : } /* _InitSubType_GCIO */
     594             : 
     595             : /* -------------------------------------------------------------------- */
     596             : static GCSubType GCIOAPI_CALL1(*)
     597           9 :     _CreateSubType_GCIO(const char *subtypName, long id, GCTypeKind knd,
     598             :                         GCDim sys)
     599             : {
     600             :     GCSubType *theSubType;
     601             : 
     602           9 :     if (!(theSubType = VSI_MALLOC_VERBOSE(sizeof(GCSubType))))
     603             :     {
     604           0 :         return NULL;
     605             :     }
     606           9 :     _InitSubType_GCIO(theSubType);
     607           9 :     SetSubTypeName_GCIO(theSubType, CPLStrdup(subtypName));
     608           9 :     SetSubTypeID_GCIO(theSubType, id);
     609           9 :     SetSubTypeKind_GCIO(theSubType, knd);
     610           9 :     SetSubTypeDim_GCIO(theSubType, sys);
     611             : 
     612           9 :     return theSubType;
     613             : } /* _CreateSubType_GCIO */
     614             : 
     615             : /* -------------------------------------------------------------------- */
     616           9 : static void GCIOAPI_CALL _ReInitSubType_GCIO(GCSubType *theSubType)
     617             : {
     618           9 :     if (GetSubTypeFeatureDefn_GCIO(theSubType))
     619             :     {
     620           9 :         OGR_FD_Release(GetSubTypeFeatureDefn_GCIO(theSubType));
     621             :     }
     622           9 :     if (GetSubTypeFields_GCIO(theSubType))
     623             :     {
     624             :         CPLList *e;
     625             :         GCField *theField;
     626             :         int i, n;
     627           9 :         if ((n = CPLListCount(GetSubTypeFields_GCIO(theSubType))) > 0)
     628             :         {
     629          99 :             for (i = 0; i < n; i++)
     630             :             {
     631          90 :                 if ((e = CPLListGet(GetSubTypeFields_GCIO(theSubType), i)))
     632             :                 {
     633          90 :                     if ((theField = (GCField *)CPLListGetData(e)))
     634             :                     {
     635          90 :                         _DestroyField_GCIO(&theField);
     636             :                     }
     637             :                 }
     638             :             }
     639             :         }
     640           9 :         CPLListDestroy(GetSubTypeFields_GCIO(theSubType));
     641             :     }
     642           9 :     if (GetSubTypeName_GCIO(theSubType))
     643             :     {
     644           9 :         CPLFree(GetSubTypeName_GCIO(theSubType));
     645             :     }
     646           9 :     if (GetSubTypeExtent_GCIO(theSubType))
     647             :     {
     648           8 :         DestroyExtent_GCIO(&(GetSubTypeExtent_GCIO(theSubType)));
     649             :     }
     650           9 :     _InitSubType_GCIO(theSubType);
     651           9 : } /* _ReInitSubType_GCIO */
     652             : 
     653             : /* -------------------------------------------------------------------- */
     654           9 : static void GCIOAPI_CALL _DestroySubType_GCIO(GCSubType **theSubType)
     655             : {
     656           9 :     _ReInitSubType_GCIO(*theSubType);
     657           9 :     CPLFree(*theSubType);
     658           9 :     *theSubType = NULL;
     659           9 : } /* _DestroySubType_GCIO */
     660             : 
     661             : /* -------------------------------------------------------------------- */
     662         152 : static int GCIOAPI_CALL _findSubTypeByName_GCIO(GCType *theClass,
     663             :                                                 const char *subtypName)
     664             : {
     665             :     GCSubType *theSubType;
     666             : 
     667         152 :     if (theClass != NULL && GetTypeSubtypes_GCIO(theClass))
     668             :     {
     669             :         CPLList *e;
     670             :         int n, i;
     671         144 :         if ((n = CPLListCount(GetTypeSubtypes_GCIO(theClass))) > 0)
     672             :         {
     673         144 :             if (*subtypName == '*')
     674           0 :                 return 0;
     675         144 :             for (i = 0; i < n; i++)
     676             :             {
     677         144 :                 if ((e = CPLListGet(GetTypeSubtypes_GCIO(theClass), i)))
     678             :                 {
     679         144 :                     if ((theSubType = (GCSubType *)CPLListGetData(e)))
     680             :                     {
     681         144 :                         if (EQUAL(GetSubTypeName_GCIO(theSubType), subtypName))
     682             :                         {
     683         144 :                             return i;
     684             :                         }
     685             :                     }
     686             :                 }
     687             :             }
     688             :         }
     689             :     }
     690           8 :     return -1;
     691             : } /* _findSubTypeByName_GCIO */
     692             : 
     693             : /* -------------------------------------------------------------------- */
     694         144 : static GCSubType GCIOAPI_CALL1(*) _getSubType_GCIO(GCType *theClass, int where)
     695             : {
     696             :     CPLList *e;
     697             : 
     698         144 :     if ((e = CPLListGet(GetTypeSubtypes_GCIO(theClass), where)))
     699         144 :         return (GCSubType *)CPLListGetData(e);
     700           0 :     return NULL;
     701             : } /* _getSubType_GCIO */
     702             : 
     703             : /* -------------------------------------------------------------------- */
     704          18 : static void GCIOAPI_CALL _InitType_GCIO(GCType *theClass)
     705             : {
     706          18 :     SetTypeName_GCIO(theClass, NULL);
     707          18 :     SetTypeSubtypes_GCIO(theClass, NULL); /* GCSubType */
     708          18 :     SetTypeFields_GCIO(theClass, NULL);   /* GCField */
     709          18 :     SetTypeID_GCIO(theClass, UNDEFINEDID_GCIO);
     710          18 : } /* _InitType_GCIO */
     711             : 
     712             : /* -------------------------------------------------------------------- */
     713           9 : static GCType GCIOAPI_CALL1(*) _CreateType_GCIO(const char *typName, long id)
     714             : {
     715             :     GCType *theClass;
     716             : 
     717           9 :     if (!(theClass = VSI_MALLOC_VERBOSE(sizeof(GCType))))
     718             :     {
     719           0 :         return NULL;
     720             :     }
     721           9 :     _InitType_GCIO(theClass);
     722           9 :     SetTypeName_GCIO(theClass, CPLStrdup(typName));
     723           9 :     SetTypeID_GCIO(theClass, id);
     724             : 
     725           9 :     return theClass;
     726             : } /* _CreateType_GCIO */
     727             : 
     728             : /* -------------------------------------------------------------------- */
     729           9 : static void GCIOAPI_CALL _ReInitType_GCIO(GCType *theClass)
     730             : {
     731           9 :     if (GetTypeSubtypes_GCIO(theClass))
     732             :     {
     733             :         CPLList *e;
     734             :         GCSubType *theSubType;
     735             :         int i, n;
     736           9 :         if ((n = CPLListCount(GetTypeSubtypes_GCIO(theClass))) > 0)
     737             :         {
     738          18 :             for (i = 0; i < n; i++)
     739             :             {
     740           9 :                 if ((e = CPLListGet(GetTypeSubtypes_GCIO(theClass), i)))
     741             :                 {
     742           9 :                     if ((theSubType = (GCSubType *)CPLListGetData(e)))
     743             :                     {
     744           9 :                         _DestroySubType_GCIO(&theSubType);
     745             :                     }
     746             :                 }
     747             :             }
     748             :         }
     749           9 :         CPLListDestroy(GetTypeSubtypes_GCIO(theClass));
     750             :     }
     751           9 :     if (GetTypeFields_GCIO(theClass))
     752             :     {
     753             :         CPLList *e;
     754             :         GCField *theField;
     755             :         int i, n;
     756           0 :         if ((n = CPLListCount(GetTypeFields_GCIO(theClass))) > 0)
     757             :         {
     758           0 :             for (i = 0; i < n; i++)
     759             :             {
     760           0 :                 if ((e = CPLListGet(GetTypeFields_GCIO(theClass), i)))
     761             :                 {
     762           0 :                     if ((theField = (GCField *)CPLListGetData(e)))
     763             :                     {
     764           0 :                         _DestroyField_GCIO(&theField);
     765             :                     }
     766             :                 }
     767             :             }
     768             :         }
     769           0 :         CPLListDestroy(GetTypeFields_GCIO(theClass));
     770             :     }
     771           9 :     if (GetTypeName_GCIO(theClass))
     772             :     {
     773           9 :         CPLFree(GetTypeName_GCIO(theClass));
     774             :     }
     775           9 :     _InitType_GCIO(theClass);
     776           9 : } /* _ReInitType_GCIO */
     777             : 
     778             : /* -------------------------------------------------------------------- */
     779           9 : static void GCIOAPI_CALL _DestroyType_GCIO(GCType **theClass)
     780             : {
     781           9 :     _ReInitType_GCIO(*theClass);
     782           9 :     CPLFree(*theClass);
     783           9 :     *theClass = NULL;
     784           9 : } /* _DestroyType_GCIO */
     785             : 
     786             : /* -------------------------------------------------------------------- */
     787         171 : static int GCIOAPI_CALL _findTypeByName_GCIO(GCExportFileH *hGXT,
     788             :                                              const char *typName)
     789             : {
     790             :     GCType *theClass;
     791             :     GCExportFileMetadata *header;
     792             : 
     793         171 :     header = GetGCMeta_GCIO(hGXT);
     794         171 :     if (GetMetaTypes_GCIO(header))
     795             :     {
     796             :         CPLList *e;
     797             :         int n, i;
     798         153 :         if ((n = CPLListCount(GetMetaTypes_GCIO(header))) > 0)
     799             :         {
     800         153 :             if (*typName == '*')
     801           0 :                 return 0;
     802         153 :             for (i = 0; i < n; i++)
     803             :             {
     804         153 :                 if ((e = CPLListGet(GetMetaTypes_GCIO(header), i)))
     805             :                 {
     806         153 :                     if ((theClass = (GCType *)CPLListGetData(e)))
     807             :                     {
     808         153 :                         if (EQUAL(GetTypeName_GCIO(theClass), typName))
     809             :                         {
     810         153 :                             return i;
     811             :                         }
     812             :                     }
     813             :                 }
     814             :             }
     815             :         }
     816             :     }
     817          18 :     return -1;
     818             : } /* _findTypeByName_GCIO */
     819             : 
     820             : /* -------------------------------------------------------------------- */
     821         153 : static GCType GCIOAPI_CALL1(*) _getType_GCIO(GCExportFileH *hGXT, int where)
     822             : {
     823             :     CPLList *e;
     824             : 
     825         153 :     if ((e = CPLListGet(GetMetaTypes_GCIO(GetGCMeta_GCIO(hGXT)), where)))
     826         153 :         return (GCType *)CPLListGetData(e);
     827           0 :     return NULL;
     828             : } /* _getType_GCIO */
     829             : 
     830             : /* -------------------------------------------------------------------- */
     831          18 : static void GCIOAPI_CALL _InitHeader_GCIO(GCExportFileMetadata *header)
     832             : {
     833          18 :     SetMetaVersion_GCIO(header, NULL);
     834          18 :     SetMetaDelimiter_GCIO(header, kTAB_GCIO[0]);
     835          18 :     SetMetaQuotedText_GCIO(header, FALSE);
     836          18 :     SetMetaCharset_GCIO(header, vANSI_GCIO);
     837          18 :     SetMetaUnit_GCIO(header, "m");
     838          18 :     SetMetaFormat_GCIO(header, 2);
     839          18 :     SetMetaSysCoord_GCIO(header, NULL); /* GCSysCoord */
     840          18 :     SetMetaPlanarFormat_GCIO(header, 0);
     841          18 :     SetMetaHeightFormat_GCIO(header, 0);
     842          18 :     SetMetaSRS_GCIO(header, NULL);
     843          18 :     SetMetaTypes_GCIO(header, NULL);  /* GCType */
     844          18 :     SetMetaFields_GCIO(header, NULL); /* GCField */
     845          18 :     SetMetaResolution_GCIO(header, 0.1);
     846          18 :     SetMetaExtent_GCIO(header, NULL);
     847          18 : } /* _InitHeader_GCIO */
     848             : 
     849             : /* -------------------------------------------------------------------- */
     850           9 : GCExportFileMetadata GCIOAPI_CALL1(*) CreateHeader_GCIO(void)
     851             : {
     852             :     GCExportFileMetadata *m;
     853             : 
     854           9 :     if (!(m = VSI_MALLOC_VERBOSE(sizeof(GCExportFileMetadata))))
     855             :     {
     856           0 :         return NULL;
     857             :     }
     858           9 :     _InitHeader_GCIO(m);
     859             : 
     860           9 :     return m;
     861             : } /* CreateHeader_GCIO */
     862             : 
     863             : /* -------------------------------------------------------------------- */
     864           9 : static void GCIOAPI_CALL _ReInitHeader_GCIO(GCExportFileMetadata *header)
     865             : {
     866           9 :     if (GetMetaVersion_GCIO(header))
     867             :     {
     868           0 :         CPLFree(GetMetaVersion_GCIO(header));
     869             :     }
     870           9 :     if (GetMetaExtent_GCIO(header))
     871             :     {
     872           9 :         DestroyExtent_GCIO(&(GetMetaExtent_GCIO(header)));
     873             :     }
     874           9 :     if (GetMetaTypes_GCIO(header))
     875             :     {
     876             :         CPLList *e;
     877             :         GCType *theClass;
     878             :         int i, n;
     879           9 :         if ((n = CPLListCount(GetMetaTypes_GCIO(header))) > 0)
     880             :         {
     881          18 :             for (i = 0; i < n; i++)
     882             :             {
     883           9 :                 if ((e = CPLListGet(GetMetaTypes_GCIO(header), i)))
     884             :                 {
     885           9 :                     if ((theClass = (GCType *)CPLListGetData(e)))
     886             :                     {
     887           9 :                         _DestroyType_GCIO(&theClass);
     888             :                     }
     889             :                 }
     890             :             }
     891             :         }
     892           9 :         CPLListDestroy(GetMetaTypes_GCIO(header));
     893             :     }
     894           9 :     if (GetMetaFields_GCIO(header))
     895             :     {
     896             :         CPLList *e;
     897             :         GCField *theField;
     898             :         int i, n;
     899           0 :         if ((n = CPLListCount(GetMetaFields_GCIO(header))) > 0)
     900             :         {
     901           0 :             for (i = 0; i < n; i++)
     902             :             {
     903           0 :                 if ((e = CPLListGet(GetMetaFields_GCIO(header), i)))
     904             :                 {
     905           0 :                     if ((theField = (GCField *)CPLListGetData(e)))
     906             :                     {
     907           0 :                         _DestroyField_GCIO(&theField);
     908             :                     }
     909             :                 }
     910             :             }
     911             :         }
     912           0 :         CPLListDestroy(GetMetaFields_GCIO(header));
     913             :     }
     914           9 :     if (GetMetaSRS_GCIO(header))
     915             :     {
     916           9 :         OSRRelease(GetMetaSRS_GCIO(header));
     917             :     }
     918           9 :     if (GetMetaSysCoord_GCIO(header))
     919             :     {
     920           9 :         DestroySysCoord_GCSRS(&(GetMetaSysCoord_GCIO(header)));
     921             :     }
     922             : 
     923           9 :     _InitHeader_GCIO(header);
     924           9 : } /* _ReInitHeader_GCIO */
     925             : 
     926             : /* -------------------------------------------------------------------- */
     927           9 : void GCIOAPI_CALL DestroyHeader_GCIO(GCExportFileMetadata **m)
     928             : {
     929           9 :     _ReInitHeader_GCIO(*m);
     930           9 :     CPLFree(*m);
     931           9 :     *m = NULL;
     932           9 : } /* DestroyHeader_GCIO */
     933             : 
     934             : /* -------------------------------------------------------------------- */
     935          52 : static void GCIOAPI_CALL _Init_GCIO(GCExportFileH *H)
     936             : {
     937          52 :     SetGCCache_GCIO(H, "");
     938          52 :     SetGCPath_GCIO(H, NULL);
     939          52 :     SetGCBasename_GCIO(H, NULL);
     940          52 :     SetGCExtension_GCIO(H, NULL);
     941          52 :     SetGCHandle_GCIO(H, NULL);
     942          52 :     SetGCCurrentOffset_GCIO(H, 0L);
     943          52 :     SetGCCurrentLinenum_GCIO(H, 0L);
     944          52 :     SetGCNbObjects_GCIO(H, 0L);
     945          52 :     SetGCMeta_GCIO(H, NULL);
     946          52 :     SetGCMode_GCIO(H, vNoAccess_GCIO);
     947          52 :     SetGCStatus_GCIO(H, vNoStatus_GCIO);
     948          52 :     SetGCWhatIs_GCIO(H, (GCTypeKind)vUnknownIO_ItemType_GCIO);
     949          52 : } /* _Init_GCIO */
     950             : 
     951             : /* -------------------------------------------------------------------- */
     952             : static GCExportFileH GCIOAPI_CALL1(*)
     953          26 :     _Create_GCIO(const char *pszGeoconceptFile, const char *ext,
     954             :                  const char *mode)
     955             : {
     956             :     GCExportFileH *hGXT;
     957             : 
     958          26 :     CPLDebug("GEOCONCEPT", "allocating %d bytes for GCExportFileH",
     959             :              (int)sizeof(GCExportFileH));
     960          26 :     if (!(hGXT = VSI_MALLOC_VERBOSE(sizeof(GCExportFileH))))
     961             :     {
     962           0 :         return NULL;
     963             :     }
     964             : 
     965          26 :     _Init_GCIO(hGXT);
     966          26 :     SetGCPath_GCIO(hGXT, CPLStrdup(CPLGetDirname(pszGeoconceptFile)));
     967          26 :     SetGCBasename_GCIO(hGXT, CPLStrdup(CPLGetBasename(pszGeoconceptFile)));
     968          26 :     SetGCExtension_GCIO(hGXT, CPLStrdup(ext ? ext : "gxt"));
     969          26 :     SetGCMode_GCIO(
     970             :         hGXT, (mode[0] == 'w'
     971             :                    ? vWriteAccess_GCIO
     972             :                    : (mode[0] == 'a' ? vUpdateAccess_GCIO : vReadAccess_GCIO)));
     973             : 
     974          26 :     return hGXT;
     975             : } /* _Create_GCIO */
     976             : 
     977             : /* -------------------------------------------------------------------- */
     978          26 : static void GCIOAPI_CALL _ReInit_GCIO(GCExportFileH *hGXT)
     979             : {
     980          26 :     if (GetGCMeta_GCIO(hGXT))
     981             :     {
     982           9 :         DestroyHeader_GCIO(&(GetGCMeta_GCIO(hGXT)));
     983             :     }
     984          26 :     if (GetGCHandle_GCIO(hGXT))
     985             :     {
     986          26 :         VSIFCloseL(GetGCHandle_GCIO(hGXT));
     987             :     }
     988          26 :     if (GetGCExtension_GCIO(hGXT))
     989             :     {
     990          26 :         CPLFree(GetGCExtension_GCIO(hGXT));
     991             :     }
     992          26 :     if (GetGCBasename_GCIO(hGXT))
     993             :     {
     994          26 :         CPLFree(GetGCBasename_GCIO(hGXT));
     995             :     }
     996          26 :     if (GetGCPath_GCIO(hGXT))
     997             :     {
     998          26 :         CPLFree(GetGCPath_GCIO(hGXT));
     999             :     }
    1000          26 :     SetGCCache_GCIO(hGXT, "");
    1001          26 :     _Init_GCIO(hGXT);
    1002          26 : } /* _ReInit_GCIO */
    1003             : 
    1004             : /* -------------------------------------------------------------------- */
    1005          26 : static void GCIOAPI_CALL _Destroy_GCIO(GCExportFileH **hGXT, int delFile)
    1006             : {
    1007          26 :     if (delFile && GetGCMode_GCIO(*hGXT) == vWriteAccess_GCIO)
    1008             :     {
    1009           0 :         VSIFCloseL(GetGCHandle_GCIO(*hGXT));
    1010           0 :         SetGCHandle_GCIO(*hGXT, NULL);
    1011           0 :         VSIUnlink(CPLFormFilename(GetGCPath_GCIO(*hGXT),
    1012           0 :                                   GetGCBasename_GCIO(*hGXT),
    1013           0 :                                   GetGCExtension_GCIO(*hGXT)));
    1014             :     }
    1015          26 :     _ReInit_GCIO(*hGXT);
    1016          26 :     CPLFree(*hGXT);
    1017          26 :     *hGXT = NULL;
    1018          26 : } /* _Destroy_GCIO */
    1019             : 
    1020             : /* -------------------------------------------------------------------- */
    1021          25 : static int _checkSchema_GCIO(GCExportFileH *hGXT)
    1022             : {
    1023             :     GCExportFileMetadata *Meta;
    1024             :     int nT, iT, nS, iS, nF, iF, nU, iId, iCl, iSu, iNa, iNb, iX, iY, iXP, iYP,
    1025             :         iGr, iAn;
    1026             :     GCField *theField;
    1027             :     GCSubType *theSubType;
    1028             :     GCType *theClass;
    1029             :     CPLList *e;
    1030             : 
    1031          25 :     if (!(Meta = GetGCMeta_GCIO(hGXT)))
    1032             :     {
    1033          17 :         return TRUE; /* FIXME */
    1034             :     }
    1035           8 :     if ((nT = CPLListCount(GetMetaTypes_GCIO(Meta))) == 0)
    1036             :     {
    1037           0 :         CPLError(CE_Failure, CPLE_AppDefined,
    1038             :                  "Geoconcept schema without types!\n");
    1039           0 :         return FALSE;
    1040             :     }
    1041          16 :     for (iT = 0; iT < nT; iT++)
    1042             :     {
    1043           8 :         if ((e = CPLListGet(GetMetaTypes_GCIO(Meta), iT)))
    1044             :         {
    1045           8 :             if ((theClass = (GCType *)CPLListGetData(e)))
    1046             :             {
    1047           8 :                 if ((nS = CPLListCount(GetTypeSubtypes_GCIO(theClass))) == 0)
    1048             :                 {
    1049           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    1050             :                              "Geoconcept type %s without sub-types!\n",
    1051             :                              GetTypeName_GCIO(theClass));
    1052           0 :                     return FALSE;
    1053             :                 }
    1054          16 :                 for (iS = 0; iS < nS; iS++)
    1055             :                 {
    1056           8 :                     if ((e = CPLListGet(GetTypeSubtypes_GCIO(theClass), iS)))
    1057             :                     {
    1058           8 :                         if ((theSubType = (GCSubType *)CPLListGetData(e)))
    1059             :                         {
    1060           8 :                             if ((nF = CPLListCount(
    1061           8 :                                      GetSubTypeFields_GCIO(theSubType))) == 0)
    1062             :                             {
    1063           0 :                                 CPLError(CE_Failure, CPLE_AppDefined,
    1064             :                                          "Geoconcept sub-type %s.%s without "
    1065             :                                          "fields!\n",
    1066             :                                          GetTypeName_GCIO(theClass),
    1067             :                                          GetSubTypeName_GCIO(theSubType));
    1068           0 :                                 return FALSE;
    1069             :                             }
    1070           8 :                             nU = 0;
    1071           8 :                             iId = iCl = iSu = iNa = iNb = iX = iY = iXP = iYP =
    1072           8 :                                 iGr = iAn = -1;
    1073          88 :                             for (iF = 0; iF < nF; iF++)
    1074             :                             {
    1075          80 :                                 if ((e = CPLListGet(
    1076             :                                          GetSubTypeFields_GCIO(theSubType),
    1077             :                                          iF)))
    1078             :                                 {
    1079          80 :                                     if ((theField =
    1080          80 :                                              (GCField *)CPLListGetData(e)))
    1081             :                                     {
    1082          80 :                                         if (IsPrivateField_GCIO(theField))
    1083             :                                         {
    1084          64 :                                             if (EQUAL(
    1085             :                                                     GetFieldName_GCIO(theField),
    1086             :                                                     kIdentifier_GCIO))
    1087           8 :                                                 iId = iF;
    1088          56 :                                             else if (EQUAL(GetFieldName_GCIO(
    1089             :                                                                theField),
    1090             :                                                            kClass_GCIO))
    1091           8 :                                                 iCl = iF;
    1092          48 :                                             else if (EQUAL(GetFieldName_GCIO(
    1093             :                                                                theField),
    1094             :                                                            kSubclass_GCIO))
    1095           8 :                                                 iSu = iF;
    1096          40 :                                             else if (EQUAL(GetFieldName_GCIO(
    1097             :                                                                theField),
    1098             :                                                            kName_GCIO))
    1099           8 :                                                 iNa = iF;
    1100          32 :                                             else if (EQUAL(GetFieldName_GCIO(
    1101             :                                                                theField),
    1102             :                                                            kNbFields_GCIO))
    1103           8 :                                                 iNb = iF;
    1104          24 :                                             else if (EQUAL(GetFieldName_GCIO(
    1105             :                                                                theField),
    1106             :                                                            kX_GCIO))
    1107           8 :                                                 iX = iF;
    1108          16 :                                             else if (EQUAL(GetFieldName_GCIO(
    1109             :                                                                theField),
    1110             :                                                            kY_GCIO))
    1111           8 :                                                 iY = iF;
    1112           8 :                                             else if (EQUAL(GetFieldName_GCIO(
    1113             :                                                                theField),
    1114             :                                                            kXP_GCIO))
    1115           1 :                                                 iXP = iF;
    1116           7 :                                             else if (EQUAL(GetFieldName_GCIO(
    1117             :                                                                theField),
    1118             :                                                            kYP_GCIO))
    1119           1 :                                                 iYP = iF;
    1120           6 :                                             else if (EQUAL(GetFieldName_GCIO(
    1121             :                                                                theField),
    1122             :                                                            kGraphics_GCIO))
    1123           6 :                                                 iGr = iF;
    1124           0 :                                             else if (EQUAL(GetFieldName_GCIO(
    1125             :                                                                theField),
    1126             :                                                            kAngle_GCIO))
    1127           0 :                                                 iAn = iF;
    1128             :                                         }
    1129             :                                         else
    1130             :                                         {
    1131          16 :                                             nU++;
    1132             :                                         }
    1133             :                                     }
    1134             :                                 }
    1135             :                             }
    1136           8 :                             if (iId == -1)
    1137             :                             {
    1138           0 :                                 CPLError(CE_Failure, CPLE_AppDefined,
    1139             :                                          "Geoconcept mandatory field %s is "
    1140             :                                          "missing on %s.%s!\n",
    1141             :                                          kIdentifier_GCIO,
    1142             :                                          GetTypeName_GCIO(theClass),
    1143             :                                          GetSubTypeName_GCIO(theSubType));
    1144           0 :                                 return FALSE;
    1145             :                             }
    1146           8 :                             else if (iId != 0)
    1147             :                             {
    1148           0 :                                 CPLError(CE_Failure, CPLE_AppDefined,
    1149             :                                          "Geoconcept mandatory field %s must "
    1150             :                                          "be the first field of %s.%s!\n",
    1151             :                                          kIdentifier_GCIO,
    1152             :                                          GetTypeName_GCIO(theClass),
    1153             :                                          GetSubTypeName_GCIO(theSubType));
    1154           0 :                                 return FALSE;
    1155             :                             }
    1156           8 :                             if (iCl == -1)
    1157             :                             {
    1158           0 :                                 CPLError(CE_Failure, CPLE_AppDefined,
    1159             :                                          "Geoconcept mandatory field %s is "
    1160             :                                          "missing on %s.%s!\n",
    1161             :                                          kClass_GCIO,
    1162             :                                          GetTypeName_GCIO(theClass),
    1163             :                                          GetSubTypeName_GCIO(theSubType));
    1164           0 :                                 return FALSE;
    1165             :                             }
    1166           8 :                             else if (iCl - iId != 1)
    1167             :                             {
    1168           0 :                                 CPLError(CE_Failure, CPLE_AppDefined,
    1169             :                                          "Geoconcept mandatory field %s must "
    1170             :                                          "be the second field of %s.%s!\n",
    1171             :                                          kClass_GCIO,
    1172             :                                          GetTypeName_GCIO(theClass),
    1173             :                                          GetSubTypeName_GCIO(theSubType));
    1174           0 :                                 return FALSE;
    1175             :                             }
    1176           8 :                             if (iSu == -1)
    1177             :                             {
    1178           0 :                                 CPLError(CE_Failure, CPLE_AppDefined,
    1179             :                                          "Geoconcept mandatory field %s is "
    1180             :                                          "missing on %s.%s!\n",
    1181             :                                          kSubclass_GCIO,
    1182             :                                          GetTypeName_GCIO(theClass),
    1183             :                                          GetSubTypeName_GCIO(theSubType));
    1184           0 :                                 return FALSE;
    1185             :                             }
    1186           8 :                             else if (iSu - iCl != 1)
    1187             :                             {
    1188           0 :                                 CPLError(CE_Failure, CPLE_AppDefined,
    1189             :                                          "Geoconcept mandatory field %s must "
    1190             :                                          "be the third field of %s.%s!\n",
    1191             :                                          kSubclass_GCIO,
    1192             :                                          GetTypeName_GCIO(theClass),
    1193             :                                          GetSubTypeName_GCIO(theSubType));
    1194           0 :                                 return FALSE;
    1195             :                             }
    1196           8 :                             if (iNa == -1)
    1197             :                             {
    1198           0 :                                 CPLError(CE_Failure, CPLE_AppDefined,
    1199             :                                          "Geoconcept mandatory field %s is "
    1200             :                                          "missing on %s.%s!\n",
    1201             :                                          kName_GCIO, GetTypeName_GCIO(theClass),
    1202             :                                          GetSubTypeName_GCIO(theSubType));
    1203           0 :                                 return FALSE;
    1204             :                             }
    1205           8 :                             else if (iNa - iSu != 1)
    1206             :                             {
    1207           0 :                                 CPLError(CE_Failure, CPLE_AppDefined,
    1208             :                                          "Geoconcept mandatory field %s must "
    1209             :                                          "be the forth field of %s.%s!\n",
    1210             :                                          kName_GCIO, GetTypeName_GCIO(theClass),
    1211             :                                          GetSubTypeName_GCIO(theSubType));
    1212           0 :                                 return FALSE;
    1213             :                             }
    1214           8 :                             if (iNb == -1)
    1215             :                             {
    1216           0 :                                 CPLError(CE_Failure, CPLE_AppDefined,
    1217             :                                          "Geoconcept mandatory field %s is "
    1218             :                                          "missing on %s.%s!\n",
    1219             :                                          kNbFields_GCIO,
    1220             :                                          GetTypeName_GCIO(theClass),
    1221             :                                          GetSubTypeName_GCIO(theSubType));
    1222           0 :                                 return FALSE;
    1223             :                             }
    1224           8 :                             if (iX == -1)
    1225             :                             {
    1226           0 :                                 CPLError(CE_Failure, CPLE_AppDefined,
    1227             :                                          "Geoconcept mandatory field %s is "
    1228             :                                          "missing on %s.%s!\n",
    1229             :                                          kX_GCIO, GetTypeName_GCIO(theClass),
    1230             :                                          GetSubTypeName_GCIO(theSubType));
    1231           0 :                                 return FALSE;
    1232             :                             }
    1233           8 :                             if (iY == -1)
    1234             :                             {
    1235           0 :                                 CPLError(CE_Failure, CPLE_AppDefined,
    1236             :                                          "Geoconcept mandatory field %s is "
    1237             :                                          "missing on %s.%s!\n",
    1238             :                                          kY_GCIO, GetTypeName_GCIO(theClass),
    1239             :                                          GetSubTypeName_GCIO(theSubType));
    1240           0 :                                 return FALSE;
    1241             :                             }
    1242           8 :                             if (iY - iX != 1)
    1243             :                             {
    1244           0 :                                 CPLError(CE_Failure, CPLE_AppDefined,
    1245             :                                          "Geoconcept geometry fields %s, %s "
    1246             :                                          "must be consecutive for %s.%s!\n",
    1247             :                                          kX_GCIO, kY_GCIO,
    1248             :                                          GetTypeName_GCIO(theClass),
    1249             :                                          GetSubTypeName_GCIO(theSubType));
    1250           0 :                                 return FALSE;
    1251             :                             }
    1252           8 :                             if (GetSubTypeKind_GCIO(theSubType) == vLine_GCIO)
    1253             :                             {
    1254           1 :                                 if (iXP == -1)
    1255             :                                 {
    1256           0 :                                     CPLError(CE_Failure, CPLE_AppDefined,
    1257             :                                              "Geoconcept mandatory field %s is "
    1258             :                                              "missing on %s.%s!\n",
    1259             :                                              kXP_GCIO,
    1260             :                                              GetTypeName_GCIO(theClass),
    1261             :                                              GetSubTypeName_GCIO(theSubType));
    1262           0 :                                     return FALSE;
    1263             :                                 }
    1264           1 :                                 if (iYP == -1)
    1265             :                                 {
    1266           0 :                                     CPLError(CE_Failure, CPLE_AppDefined,
    1267             :                                              "Geoconcept mandatory field %s is "
    1268             :                                              "missing on %s.%s!\n",
    1269             :                                              kYP_GCIO,
    1270             :                                              GetTypeName_GCIO(theClass),
    1271             :                                              GetSubTypeName_GCIO(theSubType));
    1272           0 :                                     return FALSE;
    1273             :                                 }
    1274           1 :                                 if (iYP - iXP != 1)
    1275             :                                 {
    1276           0 :                                     CPLError(
    1277             :                                         CE_Failure, CPLE_AppDefined,
    1278             :                                         "Geoconcept geometry fields %s, %s "
    1279             :                                         "must be consecutive for %s.%s!\n",
    1280             :                                         kXP_GCIO, kYP_GCIO,
    1281             :                                         GetTypeName_GCIO(theClass),
    1282             :                                         GetSubTypeName_GCIO(theSubType));
    1283           0 :                                     return FALSE;
    1284             :                                 }
    1285           1 :                                 if (iXP - iY != 1)
    1286             :                                 {
    1287           0 :                                     CPLError(CE_Failure, CPLE_AppDefined,
    1288             :                                              "Geoconcept geometry fields %s, "
    1289             :                                              "%s, %s, %s must be consecutive "
    1290             :                                              "for %s.%s!\n",
    1291             :                                              kX_GCIO, kY_GCIO, kXP_GCIO,
    1292             :                                              kYP_GCIO,
    1293             :                                              GetTypeName_GCIO(theClass),
    1294             :                                              GetSubTypeName_GCIO(theSubType));
    1295           0 :                                     return FALSE;
    1296             :                                 }
    1297             :                             }
    1298             :                             else
    1299             :                             {
    1300           7 :                                 if (iXP != -1)
    1301             :                                 {
    1302           0 :                                     CPLError(CE_Failure, CPLE_AppDefined,
    1303             :                                              "Geoconcept sub-type %s.%s has a "
    1304             :                                              "mandatory field %s only required "
    1305             :                                              "on linear type!\n",
    1306             :                                              GetTypeName_GCIO(theClass),
    1307             :                                              GetSubTypeName_GCIO(theSubType),
    1308             :                                              kXP_GCIO);
    1309           0 :                                     return FALSE;
    1310             :                                 }
    1311           7 :                                 if (iYP != -1)
    1312             :                                 {
    1313           0 :                                     CPLError(CE_Failure, CPLE_AppDefined,
    1314             :                                              "Geoconcept sub-type %s.%s has a "
    1315             :                                              "mandatory field %s only required "
    1316             :                                              "on linear type!\n",
    1317             :                                              GetTypeName_GCIO(theClass),
    1318             :                                              GetSubTypeName_GCIO(theSubType),
    1319             :                                              kYP_GCIO);
    1320           0 :                                     return FALSE;
    1321             :                                 }
    1322             :                             }
    1323           8 :                             if (GetSubTypeKind_GCIO(theSubType) == vLine_GCIO ||
    1324           7 :                                 GetSubTypeKind_GCIO(theSubType) == vPoly_GCIO)
    1325             :                             {
    1326           6 :                                 if (iGr == -1)
    1327             :                                 {
    1328           0 :                                     CPLError(CE_Failure, CPLE_AppDefined,
    1329             :                                              "Geoconcept mandatory field %s is "
    1330             :                                              "missing on %s.%s!\n",
    1331             :                                              kGraphics_GCIO,
    1332             :                                              GetTypeName_GCIO(theClass),
    1333             :                                              GetSubTypeName_GCIO(theSubType));
    1334           0 :                                     return FALSE;
    1335             :                                 }
    1336             :                                 else
    1337             :                                 {
    1338           6 :                                     if (!(((iGr != -1) && ((iGr == iY + 1) ||
    1339           1 :                                                            (iGr == iYP + 1))) ||
    1340             :                                           (iGr == -1)))
    1341             : 
    1342             :                                     {
    1343           0 :                                         CPLError(
    1344             :                                             CE_Failure, CPLE_AppDefined,
    1345             :                                             "Geoconcept geometry fields %s, %s "
    1346             :                                             "must be consecutive for %s.%s!\n",
    1347             :                                             iYP != -1 ? kYP_GCIO : kY_GCIO,
    1348             :                                             kGraphics_GCIO,
    1349             :                                             GetTypeName_GCIO(theClass),
    1350             :                                             GetSubTypeName_GCIO(theSubType));
    1351           0 :                                         return FALSE;
    1352             :                                     }
    1353             :                                 }
    1354           6 :                                 if (iAn != -1)
    1355             :                                 {
    1356           0 :                                     CPLError(CE_Failure, CPLE_AppDefined,
    1357             :                                              "Geoconcept sub-type %s.%s has a "
    1358             :                                              "field %s only required on "
    1359             :                                              "ponctual or text type!\n",
    1360             :                                              GetTypeName_GCIO(theClass),
    1361             :                                              GetSubTypeName_GCIO(theSubType),
    1362             :                                              kAngle_GCIO);
    1363           0 :                                     return FALSE;
    1364             :                                 }
    1365             :                             }
    1366             :                             else
    1367             :                             {
    1368           2 :                                 if (iGr != -1)
    1369             :                                 {
    1370           0 :                                     CPLError(CE_Failure, CPLE_AppDefined,
    1371             :                                              "Geoconcept sub-type %s.%s has a "
    1372             :                                              "mandatory field %s only required "
    1373             :                                              "on linear or polygonal type!\n",
    1374             :                                              GetTypeName_GCIO(theClass),
    1375             :                                              GetSubTypeName_GCIO(theSubType),
    1376             :                                              kGraphics_GCIO);
    1377           0 :                                     return FALSE;
    1378             :                                 }
    1379             :                             }
    1380           8 :                             SetSubTypeNbFields_GCIO(theSubType, nU);
    1381           8 :                             SetSubTypeGCHandle_GCIO(theSubType, hGXT);
    1382             :                         }
    1383             :                     }
    1384             :                 }
    1385             :             }
    1386             :         }
    1387             :     }
    1388             : 
    1389           8 :     return TRUE;
    1390             : } /* _checkSchema_GCIO */
    1391             : 
    1392             : /* -------------------------------------------------------------------- */
    1393             : static GCExportFileMetadata GCIOAPI_CALL1(*)
    1394          48 :     _parsePragma_GCIO(GCExportFileH *hGXT)
    1395             : {
    1396             :     GCExportFileMetadata *Meta;
    1397             :     char *p, *e;
    1398             : 
    1399          48 :     Meta = GetGCMeta_GCIO(hGXT);
    1400             : 
    1401          48 :     if ((p = strstr(GetGCCache_GCIO(hGXT), kMetadataVERSION_GCIO)) != NULL)
    1402             :     {
    1403           0 :         if (GetMetaVersion_GCIO(Meta))
    1404             :         {
    1405           0 :             DestroyHeader_GCIO(&(GetGCMeta_GCIO(hGXT)));
    1406           0 :             return NULL;
    1407             :         }
    1408             : 
    1409             :         /* //$VERSION char* */
    1410           0 :         p += strlen(kMetadataVERSION_GCIO);
    1411           0 :         while (isspace((unsigned char)*p))
    1412           0 :             p++;
    1413           0 :         e = p;
    1414           0 :         while (isalpha((unsigned char)*p))
    1415           0 :             p++;
    1416           0 :         *p = '\0';
    1417           0 :         SetMetaVersion_GCIO(Meta, CPLStrdup(e));
    1418           0 :         return Meta;
    1419             :     }
    1420          48 :     if ((p = strstr(GetGCCache_GCIO(hGXT), kMetadataDELIMITER_GCIO)) != NULL)
    1421             :     {
    1422             :         /* //$DELIMITER "char*" */
    1423           0 :         if ((p = strchr(p, '"')))
    1424             :         {
    1425           0 :             p++;
    1426           0 :             e = p;
    1427           0 :             while (*p != '"' && *p != '\0')
    1428           0 :                 p++;
    1429           0 :             *p = '\0';
    1430           0 :             if (!(EQUAL(e, "tab") || EQUAL(e, kTAB_GCIO)))
    1431             :             {
    1432           0 :                 CPLDebug("GEOCONCEPT", "%s%s only supports \"tab\" value",
    1433             :                          kPragma_GCIO, kMetadataDELIMITER_GCIO);
    1434           0 :                 SetMetaDelimiter_GCIO(Meta, kTAB_GCIO[0]);
    1435             :             }
    1436             :             else
    1437             :             {
    1438           0 :                 SetMetaDelimiter_GCIO(Meta, kTAB_GCIO[0]);
    1439             :             }
    1440             :         }
    1441           0 :         return Meta;
    1442             :     }
    1443          48 :     if ((p = strstr(GetGCCache_GCIO(hGXT), kMetadataQUOTEDTEXT_GCIO)) != NULL)
    1444             :     {
    1445             :         /* //$QUOTED-TEXT "char*" */
    1446           8 :         if ((p = strchr(p, '"')))
    1447             :         {
    1448           8 :             p++;
    1449           8 :             e = p;
    1450          24 :             while (*p != '"' && *p != '\0')
    1451          16 :                 p++;
    1452           8 :             *p = '\0';
    1453           8 :             if (EQUAL(e, "no"))
    1454             :             {
    1455           8 :                 SetMetaQuotedText_GCIO(Meta, FALSE);
    1456             :             }
    1457             :             else
    1458             :             {
    1459           0 :                 SetMetaQuotedText_GCIO(Meta, TRUE);
    1460             :             }
    1461             :         }
    1462           8 :         return Meta;
    1463             :     }
    1464          40 :     if ((p = strstr(GetGCCache_GCIO(hGXT), kMetadataCHARSET_GCIO)) != NULL)
    1465             :     {
    1466             :         /* //$CHARSET char* */
    1467           8 :         p += strlen(kMetadataCHARSET_GCIO);
    1468          16 :         while (isspace((unsigned char)*p))
    1469           8 :             p++;
    1470           8 :         e = p;
    1471          40 :         while (isalpha((unsigned char)*p))
    1472          32 :             p++;
    1473           8 :         *p = '\0';
    1474           8 :         SetMetaCharset_GCIO(Meta, str2GCCharset_GCIO(e));
    1475           8 :         return Meta;
    1476             :     }
    1477          32 :     if ((p = strstr(GetGCCache_GCIO(hGXT), kMetadataUNIT_GCIO)) != NULL)
    1478             :     {
    1479             :         /* //$UNIT Distance|Angle:char* */
    1480           8 :         if ((p = strchr(p, ':')))
    1481             :         {
    1482           8 :             p++;
    1483           8 :             while (isspace((unsigned char)*p))
    1484           0 :                 p++;
    1485           8 :             e = p;
    1486          16 :             while (isalpha((unsigned char)*p) || *p == '.')
    1487           8 :                 p++;
    1488           8 :             *p = '\0';
    1489           8 :             SetMetaUnit_GCIO(Meta, e); /* FIXME : check value ? */
    1490             :         }
    1491           8 :         return Meta;
    1492             :     }
    1493          24 :     if ((p = strstr(GetGCCache_GCIO(hGXT), kMetadataFORMAT_GCIO)) != NULL)
    1494             :     {
    1495             :         /* //$FORMAT 1|2 */
    1496           8 :         p += strlen(kMetadataFORMAT_GCIO);
    1497          16 :         while (isspace((unsigned char)*p))
    1498           8 :             p++;
    1499           8 :         e = p;
    1500           8 :         if (*e == '1')
    1501             :         {
    1502           0 :             SetMetaFormat_GCIO(Meta, 1);
    1503             :         }
    1504             :         else
    1505             :         {
    1506           8 :             SetMetaFormat_GCIO(Meta, 2);
    1507             :         }
    1508           8 :         return Meta;
    1509             :     }
    1510          16 :     if ((p = strstr(GetGCCache_GCIO(hGXT), kMetadataSYSCOORD_GCIO)) != NULL)
    1511             :     {
    1512             :         int v, z;
    1513             :         GCSysCoord *syscoord;
    1514             : 
    1515           8 :         if (GetMetaSysCoord_GCIO(Meta))
    1516             :         {
    1517           0 :             DestroyHeader_GCIO(&(GetGCMeta_GCIO(hGXT)));
    1518           0 :             return NULL;
    1519             :         }
    1520             : 
    1521             :         /* //$SYSCOORD {Type: int} [ ; { TimeZone: TimeZoneValue } ] */
    1522           8 :         v = -1;
    1523           8 :         z = -1;
    1524           8 :         if ((p = strchr(p, ':')))
    1525             :         {
    1526           8 :             p++;
    1527          16 :             while (isspace((unsigned char)*p))
    1528           8 :                 p++;
    1529           8 :             e = p;
    1530           8 :             if (*p == '-')
    1531           0 :                 p++; /* allow -1 as SysCoord */
    1532          30 :             while (isdigit((unsigned char)*p))
    1533          22 :                 p++;
    1534           8 :             *p = '\0';
    1535           8 :             if (sscanf(e, "%d", &v) != 1)
    1536             :             {
    1537           0 :                 DestroyHeader_GCIO(&(GetGCMeta_GCIO(hGXT)));
    1538           0 :                 CPLError(CE_Failure, CPLE_AppDefined,
    1539             :                          "Invalid SRS identifier. "
    1540             :                          "Geoconcept export syntax error at line %ld.",
    1541             :                          GetGCCurrentLinenum_GCIO(hGXT));
    1542           0 :                 return NULL;
    1543             :             }
    1544           8 :             if ((p = strrchr(GetGCCache_GCIO(hGXT), ';')))
    1545             :             {
    1546           0 :                 if ((p = strchr(p, ':')))
    1547             :                 {
    1548           0 :                     p++;
    1549           0 :                     while (isspace((unsigned char)*p))
    1550           0 :                         p++;
    1551           0 :                     e = p;
    1552           0 :                     if (*p == '-')
    1553           0 :                         p++; /* allow -1 as TimeZone */
    1554           0 :                     while (isdigit((unsigned char)*p))
    1555           0 :                         p++;
    1556           0 :                     *p = '\0';
    1557           0 :                     if (sscanf(e, "%d", &z) != 1)
    1558             :                     {
    1559           0 :                         DestroyHeader_GCIO(&(GetGCMeta_GCIO(hGXT)));
    1560           0 :                         CPLError(CE_Failure, CPLE_AppDefined,
    1561             :                                  "Invalid TimeZone. "
    1562             :                                  "Geoconcept export syntax error at line %ld.",
    1563             :                                  GetGCCurrentLinenum_GCIO(hGXT));
    1564           0 :                         return NULL;
    1565             :                     }
    1566             :                 }
    1567             :             }
    1568           8 :             if (!(syscoord = CreateSysCoord_GCSRS(v, z)))
    1569             :             {
    1570           0 :                 DestroyHeader_GCIO(&(GetGCMeta_GCIO(hGXT)));
    1571           0 :                 return NULL;
    1572             :             }
    1573           8 :             SetMetaSysCoord_GCIO(Meta, syscoord);
    1574             :         }
    1575           8 :         return Meta;
    1576             :     }
    1577           8 :     if ((p = strstr(GetGCCache_GCIO(hGXT), kMetadataFIELDS_GCIO)) != NULL)
    1578             :     {
    1579             :         char **kv, **vl, *nm, **fl;
    1580             :         int whereClass, v, i, n,
    1581           8 :             mask =
    1582             :                 CSLT_HONOURSTRINGS | CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES;
    1583             :         GCType *theClass;
    1584             :         GCSubType *theSubType;
    1585             :         GCField *theField;
    1586             :         /* //$FIELDS +Class=char*; *Subclass=char*; *Kind=1..4;
    1587             :          * *Fields=(Private#)?char*(\t((Private#)?char*))* */
    1588           8 :         p += strlen(kMetadataFIELDS_GCIO);
    1589           8 :         kv = CSLTokenizeString2(p, ";", mask);
    1590           8 :         if (!kv || CSLCount(kv) != 4)
    1591             :         {
    1592           0 :             CSLDestroy(kv);
    1593           0 :             DestroyHeader_GCIO(&(GetGCMeta_GCIO(hGXT)));
    1594           0 :             CPLError(
    1595             :                 CE_Failure, CPLE_AppDefined,
    1596             :                 "Expected: //$FIELDS +Class=char*; *Subclass=char*; "
    1597             :                 "*Kind=1..4; *Fields=(Private#)?char*(\\t((Private#)?char*))*\n"
    1598             :                 "Found: [%s]\n"
    1599             :                 "Geoconcept export syntax error at line %ld.\n",
    1600             :                 p, GetGCCurrentLinenum_GCIO(hGXT));
    1601           0 :             return NULL;
    1602             :         }
    1603          40 :         for (i = 0; i < 4; i++)
    1604          32 :             CPLDebug("GEOCONCEPT", "%d kv[%d]=[%s]\n", __LINE__, i, kv[i]);
    1605             :         /* Class=char* */
    1606           8 :         vl = CSLTokenizeString2(kv[0], "=", 0);
    1607           8 :         if (!vl || CSLCount(vl) != 2)
    1608             :         {
    1609           0 :             CPLError(CE_Failure, CPLE_AppDefined,
    1610             :                      "Expected: Class=char*\n"
    1611             :                      "Found: [%s]\n"
    1612             :                      "Geoconcept export syntax error at line %ld.\n",
    1613             :                      kv[0], GetGCCurrentLinenum_GCIO(hGXT));
    1614           0 :             CSLDestroy(vl);
    1615           0 :             CSLDestroy(kv);
    1616           0 :             DestroyHeader_GCIO(&(GetGCMeta_GCIO(hGXT)));
    1617           0 :             return NULL;
    1618             :         }
    1619          24 :         for (i = 0; i < 2; i++)
    1620          16 :             CPLDebug("GEOCONCEPT", "%d vl[%d]=[%s]\n", __LINE__, i, vl[i]);
    1621           8 :         if (!EQUAL(vl[0], "Class"))
    1622             :         {
    1623           0 :             CPLError(CE_Failure, CPLE_AppDefined,
    1624             :                      "Expected: 'Class'\n"
    1625             :                      "Found: [%s]\n"
    1626             :                      "Geoconcept export syntax error at line %ld.\n",
    1627             :                      vl[0], GetGCCurrentLinenum_GCIO(hGXT));
    1628           0 :             CSLDestroy(vl);
    1629           0 :             CSLDestroy(kv);
    1630           0 :             DestroyHeader_GCIO(&(GetGCMeta_GCIO(hGXT)));
    1631           0 :             return NULL;
    1632             :         }
    1633           8 :         p = vl[1];
    1634           8 :         e = p;
    1635           8 :         if ((whereClass = _findTypeByName_GCIO(hGXT, e)) == -1)
    1636             :         {
    1637           8 :             if (!(theClass = AddType_GCIO(hGXT, e, -1)))
    1638             :             {
    1639           0 :                 CPLError(CE_Failure, CPLE_AppDefined,
    1640             :                          "Geoconcept export syntax error at line %ld.\n",
    1641             :                          GetGCCurrentLinenum_GCIO(hGXT));
    1642           0 :                 CSLDestroy(vl);
    1643           0 :                 CSLDestroy(kv);
    1644           0 :                 DestroyHeader_GCIO(&(GetGCMeta_GCIO(hGXT)));
    1645           0 :                 return NULL;
    1646             :             }
    1647             :         }
    1648             :         else
    1649             :         {
    1650           0 :             theClass = _getType_GCIO(hGXT, whereClass);
    1651             :         }
    1652           8 :         CSLDestroy(vl);
    1653             :         /* Subclass=char* */
    1654           8 :         vl = CSLTokenizeString2(kv[1], "=", mask);
    1655           8 :         if (!vl || CSLCount(vl) != 2)
    1656             :         {
    1657           0 :             CPLError(CE_Failure, CPLE_AppDefined,
    1658             :                      "Expected: Subclass=char*\n"
    1659             :                      "Found: [%s]\n"
    1660             :                      "Geoconcept export syntax error at line %ld.\n",
    1661           0 :                      kv[1], GetGCCurrentLinenum_GCIO(hGXT));
    1662           0 :             CSLDestroy(vl);
    1663           0 :             CSLDestroy(kv);
    1664           0 :             DestroyHeader_GCIO(&(GetGCMeta_GCIO(hGXT)));
    1665           0 :             return NULL;
    1666             :         }
    1667          24 :         for (i = 0; i < 2; i++)
    1668          16 :             CPLDebug("GEOCONCEPT", "%d vl[%d]=[%s]\n", __LINE__, i, vl[i]);
    1669           8 :         p = vl[0];
    1670           8 :         if (!EQUAL(p, "Subclass"))
    1671             :         {
    1672           0 :             CPLError(CE_Failure, CPLE_AppDefined,
    1673             :                      "Expected: 'Subclass'\n"
    1674             :                      "Found: [%s]\n"
    1675             :                      "Geoconcept export syntax error at line %ld.\n",
    1676             :                      p, GetGCCurrentLinenum_GCIO(hGXT));
    1677           0 :             CSLDestroy(vl);
    1678           0 :             CSLDestroy(kv);
    1679           0 :             DestroyHeader_GCIO(&(GetGCMeta_GCIO(hGXT)));
    1680           0 :             return NULL;
    1681             :         }
    1682           8 :         p = vl[1];
    1683           8 :         e = p;
    1684           8 :         if (_findSubTypeByName_GCIO(theClass, e) != -1)
    1685             :         {
    1686           0 :             CPLError(CE_Failure, CPLE_AppDefined,
    1687             :                      "[%s] already exists.\n"
    1688             :                      "Geoconcept export syntax error at line %ld.\n",
    1689             :                      e, GetGCCurrentLinenum_GCIO(hGXT));
    1690           0 :             CSLDestroy(vl);
    1691           0 :             CSLDestroy(kv);
    1692           0 :             DestroyHeader_GCIO(&(GetGCMeta_GCIO(hGXT)));
    1693           0 :             return NULL;
    1694             :         }
    1695           8 :         nm = CPLStrdup(e);
    1696           8 :         CSLDestroy(vl);
    1697             :         /* Kind=1..4 */
    1698           8 :         vl = CSLTokenizeString2(kv[2], "=", mask);
    1699           8 :         if (!vl || CSLCount(vl) != 2)
    1700             :         {
    1701           0 :             CPLError(CE_Failure, CPLE_AppDefined,
    1702             :                      "Expected: Kind=1..4\n"
    1703             :                      "Found: [%s]"
    1704             :                      "Geoconcept export syntax error at line %ld.\n",
    1705           0 :                      kv[2], GetGCCurrentLinenum_GCIO(hGXT));
    1706           0 :             CPLFree(nm);
    1707           0 :             CSLDestroy(vl);
    1708           0 :             CSLDestroy(kv);
    1709           0 :             DestroyHeader_GCIO(&(GetGCMeta_GCIO(hGXT)));
    1710           0 :             return NULL;
    1711             :         }
    1712          24 :         for (i = 0; i < 2; i++)
    1713          16 :             CPLDebug("GEOCONCEPT", "%d vl[%d]=[%s]\n", __LINE__, i, vl[i]);
    1714           8 :         p = vl[0];
    1715           8 :         if (!EQUAL(p, "Kind"))
    1716             :         {
    1717           0 :             CPLError(CE_Failure, CPLE_AppDefined,
    1718             :                      "Expected: 'Kind'\n"
    1719             :                      "Found: [%s]\n"
    1720             :                      "Geoconcept export syntax error at line %ld.\n",
    1721             :                      p, GetGCCurrentLinenum_GCIO(hGXT));
    1722           0 :             CPLFree(nm);
    1723           0 :             CSLDestroy(vl);
    1724           0 :             CSLDestroy(kv);
    1725           0 :             DestroyHeader_GCIO(&(GetGCMeta_GCIO(hGXT)));
    1726           0 :             return NULL;
    1727             :         }
    1728           8 :         p = vl[1];
    1729           8 :         e = p;
    1730          16 :         while (isdigit((unsigned char)*p))
    1731           8 :             p++;
    1732           8 :         *p = '\0';
    1733           8 :         if (sscanf(e, "%d", &v) != 1 || v < 1 || v > 4)
    1734             :         {
    1735           0 :             CPLError(CE_Failure, CPLE_AppDefined,
    1736             :                      "Invalid Geometry type.\n"
    1737             :                      "Geoconcept export syntax error at line %ld.\n",
    1738             :                      GetGCCurrentLinenum_GCIO(hGXT));
    1739           0 :             CPLFree(nm);
    1740           0 :             CSLDestroy(vl);
    1741           0 :             CSLDestroy(kv);
    1742           0 :             DestroyHeader_GCIO(&(GetGCMeta_GCIO(hGXT)));
    1743           0 :             return NULL;
    1744             :         }
    1745           8 :         CSLDestroy(vl);
    1746           8 :         if (!(theSubType = AddSubType_GCIO(hGXT, GetTypeName_GCIO(theClass), nm,
    1747             :                                            -1, (GCTypeKind)v, vUnknown3D_GCIO)))
    1748             :         {
    1749           0 :             CPLFree(nm);
    1750           0 :             CSLDestroy(kv);
    1751           0 :             DestroyHeader_GCIO(&(GetGCMeta_GCIO(hGXT)));
    1752           0 :             CPLError(CE_Failure, CPLE_AppDefined,
    1753             :                      "Geoconcept export syntax error at line %ld.\n",
    1754             :                      GetGCCurrentLinenum_GCIO(hGXT));
    1755           0 :             return NULL;
    1756             :         }
    1757           8 :         CPLFree(nm);
    1758             :         /* Fields=(Private#)?char*(\s((Private#)?char*))* */
    1759           8 :         vl = CSLTokenizeString2(kv[3], "=", mask);
    1760           8 :         if (!vl || CSLCount(vl) != 2)
    1761             :         {
    1762           0 :             CPLError(
    1763             :                 CE_Failure, CPLE_AppDefined,
    1764             :                 "Expected: Fields=(Private#)?char*(\\t((Private#)?char*))*\n"
    1765             :                 "Found: [%s]\n"
    1766             :                 "Geoconcept export syntax error at line %ld.\n",
    1767           0 :                 kv[3], GetGCCurrentLinenum_GCIO(hGXT));
    1768           0 :             CSLDestroy(vl);
    1769           0 :             CSLDestroy(kv);
    1770           0 :             DestroyHeader_GCIO(&(GetGCMeta_GCIO(hGXT)));
    1771           0 :             return NULL;
    1772             :         }
    1773          24 :         for (i = 0; i < 2; i++)
    1774          16 :             CPLDebug("GEOCONCEPT", "%d vl[%d]=[%s]\n", __LINE__, i, vl[i]);
    1775           8 :         CSLDestroy(kv);
    1776           8 :         p = vl[0];
    1777           8 :         if (!EQUAL(p, "Fields"))
    1778             :         {
    1779           0 :             CPLError(CE_Failure, CPLE_AppDefined,
    1780             :                      "Expected: 'Fields'\n"
    1781             :                      "Found: [%s]\n"
    1782             :                      "Geoconcept export syntax error at line %ld.\n",
    1783             :                      p, GetGCCurrentLinenum_GCIO(hGXT));
    1784           0 :             CSLDestroy(vl);
    1785           0 :             DestroyHeader_GCIO(&(GetGCMeta_GCIO(hGXT)));
    1786           0 :             return NULL;
    1787             :         }
    1788           8 :         fl = CSLTokenizeString2(vl[1], "\t", mask);
    1789           8 :         if (!fl || (n = CSLCount(fl)) == 0)
    1790             :         {
    1791           0 :             CPLError(CE_Failure, CPLE_AppDefined,
    1792             :                      "Expected: (Private#)?char*(\\t((Private#)?char*))*\n"
    1793             :                      "Found: [%s]\n"
    1794             :                      "Geoconcept export syntax error at line %ld.\n",
    1795           0 :                      vl[1], GetGCCurrentLinenum_GCIO(hGXT));
    1796           0 :             CSLDestroy(fl);
    1797           0 :             CSLDestroy(vl);
    1798           0 :             DestroyHeader_GCIO(&(GetGCMeta_GCIO(hGXT)));
    1799           0 :             return NULL;
    1800             :         }
    1801           8 :         CSLDestroy(vl);
    1802          88 :         for (i = 0; i < n; i++)
    1803             :         {
    1804          80 :             p = fl[i];
    1805          80 :             CPLDebug("GEOCONCEPT", "%d fl[%d]=[%s]\n", __LINE__, i, p);
    1806          80 :             e = p;
    1807          80 :             if (EQUALN(p, kPrivate_GCIO, strlen(kPrivate_GCIO)))
    1808             :             {
    1809          64 :                 p += strlen(kPrivate_GCIO);
    1810          64 :                 e = p - 1;
    1811          64 :                 *e = '@';
    1812             :             }
    1813          80 :             nm = CPLStrdup(e);
    1814          80 :             CPLDebug("GEOCONCEPT", "%d e=[%s]\n", __LINE__, e);
    1815             :             theField =
    1816          80 :                 AddSubTypeField_GCIO(hGXT, GetTypeName_GCIO(theClass),
    1817          80 :                                      GetSubTypeName_GCIO(theSubType), -1, nm,
    1818             :                                      -1, vUnknownItemType_GCIO, NULL, NULL);
    1819          80 :             if (theField == NULL)
    1820             :             {
    1821           0 :                 CPLError(CE_Failure, CPLE_AppDefined,
    1822             :                          "Geoconcept export syntax error at line %ld.\n",
    1823             :                          GetGCCurrentLinenum_GCIO(hGXT));
    1824           0 :                 CPLFree(nm);
    1825           0 :                 CSLDestroy(fl);
    1826           0 :                 DestroyHeader_GCIO(&(GetGCMeta_GCIO(hGXT)));
    1827           0 :                 return NULL;
    1828             :             }
    1829          80 :             CPLDebug("GEOCONCEPT", "%d %s.%s@%s-1 added\n", __LINE__,
    1830             :                      GetTypeName_GCIO(theClass),
    1831             :                      GetSubTypeName_GCIO(theSubType), nm);
    1832          80 :             CPLFree(nm);
    1833             :         }
    1834           8 :         CSLDestroy(fl);
    1835           8 :         SetSubTypeHeaderWritten_GCIO(theSubType, TRUE);
    1836           8 :         return Meta;
    1837             :     }
    1838             :     /* end of definitions ... */ /* FIXME */
    1839           0 :     if ((strstr(GetGCCache_GCIO(hGXT), k3DOBJECTMONO_GCIO)) ||
    1840           0 :         (strstr(GetGCCache_GCIO(hGXT), k3DOBJECT_GCIO)) ||
    1841           0 :         (strstr(GetGCCache_GCIO(hGXT), k2DOBJECT_GCIO)))
    1842             :         /* next reading will be in cache ! */
    1843           0 :         SetGCStatus_GCIO(hGXT, vMemoStatus_GCIO);
    1844             :     /* unknown pragma ... */
    1845           0 :     return Meta;
    1846             : } /* _parsePragma_GCIO */
    1847             : 
    1848             : /* -------------------------------------------------------------------- */
    1849          54 : static OGRGeometryH GCIOAPI_CALL _buildOGRGeometry_GCIO(
    1850             :     GCExportFileMetadata *Meta, GCSubType *theSubType, int i,
    1851             :     const char **papszFields, int nbtp, GCDim d, OGREnvelope *bbox)
    1852             : {
    1853             :     OGRGeometryH g;
    1854             :     OGRwkbGeometryType gt;
    1855             :     double x, y, z;
    1856             :     int ip, np, buildGeom;
    1857             : 
    1858          54 :     g = NULL;
    1859          54 :     if (bbox == NULL)
    1860             :     {
    1861          31 :         buildGeom = TRUE;
    1862             :     }
    1863             :     else
    1864             :     {
    1865          23 :         buildGeom = FALSE;
    1866             :     }
    1867          54 :     z = 0.0;
    1868          54 :     switch (GetSubTypeKind_GCIO(theSubType))
    1869             :     {
    1870          14 :         case vPoint_GCIO:
    1871             :         case vText_GCIO: /* FIXME : treat as point ? */
    1872          14 :             gt = wkbPoint;
    1873          14 :             break;
    1874           2 :         case vLine_GCIO:
    1875           2 :             gt = wkbLineString;
    1876           2 :             break;
    1877          38 :         case vPoly_GCIO:
    1878          38 :             gt = wkbMultiPolygon;
    1879          38 :             break;
    1880           0 :         default:
    1881           0 :             gt = wkbUnknown;
    1882           0 :             break;
    1883             :     }
    1884          54 :     if (buildGeom)
    1885             :     {
    1886          31 :         if (!(g = OGR_G_CreateGeometry(gt)))
    1887             :         {
    1888           0 :             return NULL;
    1889             :         }
    1890          62 :         OGR_G_SetCoordinateDimension(g,
    1891          31 :                                      d == v3D_GCIO || d == v3DM_GCIO ? 3 : 2);
    1892             :     }
    1893          54 :     if (!GetMetaSRS_GCIO(Meta) && GetMetaSysCoord_GCIO(Meta))
    1894             :     {
    1895           8 :         SetMetaSRS_GCIO(Meta, SysCoord2OGRSpatialReference_GCSRS(
    1896             :                                   GetMetaSysCoord_GCIO(Meta)));
    1897             :     }
    1898          54 :     if (buildGeom)
    1899             :     {
    1900          31 :         if (GetMetaSRS_GCIO(Meta))
    1901             :         {
    1902          31 :             OGR_G_AssignSpatialReference(g, GetMetaSRS_GCIO(Meta));
    1903             :         }
    1904             :     }
    1905             : 
    1906             :     /*
    1907             :      * General structure :
    1908             :      * X<>Y[<>Z]{<>More Graphics}
    1909             :      */
    1910             : 
    1911          54 :     if (gt == wkbPoint)
    1912             :     {
    1913          14 :         if (i + 2 + ((d == v3D_GCIO || d == v3DM_GCIO) ? 1 : 0) > nbtp)
    1914             :         {
    1915           0 :             OGR_G_DestroyGeometry(g);
    1916           0 :             return NULL;
    1917             :         }
    1918             :         /*
    1919             :          * More Graphics :
    1920             :          * Angle
    1921             :          * Angle in tenth of degrees (counterclockwise) of the symbol
    1922             :          * displayed to represent the ponctual entity or angle of the text
    1923             :          * entity NOT IMPLEMENTED
    1924             :          */
    1925          14 :         x = CPLAtof(papszFields[i]);
    1926          14 :         i++;
    1927          14 :         y = CPLAtof(papszFields[i]);
    1928          14 :         i++;
    1929          14 :         if (d == v3D_GCIO || d == v3DM_GCIO)
    1930             :         {
    1931           0 :             z = CPLAtof(papszFields[i]);
    1932           0 :             i++;
    1933             :         }
    1934          14 :         if (buildGeom)
    1935             :         {
    1936          10 :             if (OGR_G_GetCoordinateDimension(g) == 3)
    1937           0 :                 OGR_G_AddPoint(g, x, y, z);
    1938             :             else
    1939          10 :                 OGR_G_AddPoint_2D(g, x, y);
    1940             :         }
    1941             :         else
    1942             :         {
    1943           4 :             MergeOGREnvelope_GCIO(bbox, x, y);
    1944             :         }
    1945          14 :         return g;
    1946             :     }
    1947             : 
    1948          40 :     if (gt == wkbLineString)
    1949             :     {
    1950           2 :         if (i + 2 * (2 + ((d == v3D_GCIO || d == v3DM_GCIO) ? 1 : 0)) + 1 >
    1951             :             nbtp)
    1952             :         {
    1953           0 :             OGR_G_DestroyGeometry(g);
    1954           0 :             return NULL;
    1955             :         }
    1956             : 
    1957             :         /*
    1958             :          * More Graphics :
    1959             :          * XP<>YP[<>ZP]Nr points=k[<>X<>Y[<>Z]]k...
    1960             :          */
    1961           2 :         x = CPLAtof(papszFields[i]);
    1962           2 :         i++;
    1963           2 :         y = CPLAtof(papszFields[i]);
    1964           2 :         i++;
    1965           2 :         if (d == v3D_GCIO || d == v3DM_GCIO)
    1966             :         {
    1967           0 :             z = CPLAtof(papszFields[i]);
    1968           0 :             i++;
    1969             :         }
    1970           2 :         if (buildGeom)
    1971             :         {
    1972           1 :             if (OGR_G_GetCoordinateDimension(g) == 3)
    1973           0 :                 OGR_G_AddPoint(g, x, y, z);
    1974             :             else
    1975           1 :                 OGR_G_AddPoint_2D(g, x, y);
    1976             :         }
    1977             :         else
    1978             :         {
    1979           1 :             MergeOGREnvelope_GCIO(bbox, x, y);
    1980             :         }
    1981             :         /* skip XP<>YP[<>ZP] : the last point is in k[<>X<>Y[<>Z]]k */
    1982           2 :         i++;
    1983           2 :         i++;
    1984           2 :         if (d == v3D_GCIO || d == v3DM_GCIO)
    1985             :         {
    1986           0 :             i++;
    1987             :         }
    1988           2 :         np = atoi(papszFields[i]);
    1989           2 :         i++;
    1990           4 :         for (ip = 1; ip <= np; ip++)
    1991             :         {
    1992           2 :             if (i + 2 + ((d == v3D_GCIO || d == v3DM_GCIO) ? 1 : 0) > nbtp)
    1993             :             {
    1994           0 :                 OGR_G_DestroyGeometry(g);
    1995           0 :                 return NULL;
    1996             :             }
    1997           2 :             x = CPLAtof(papszFields[i]);
    1998           2 :             i++;
    1999           2 :             y = CPLAtof(papszFields[i]);
    2000           2 :             i++;
    2001           2 :             if (d == v3D_GCIO || d == v3DM_GCIO)
    2002             :             {
    2003           0 :                 z = CPLAtof(papszFields[i]);
    2004           0 :                 i++;
    2005             :             }
    2006           2 :             if (buildGeom)
    2007             :             {
    2008           1 :                 if (OGR_G_GetCoordinateDimension(g) == 3)
    2009           0 :                     OGR_G_AddPoint(g, x, y, z);
    2010             :                 else
    2011           1 :                     OGR_G_AddPoint_2D(g, x, y);
    2012             :             }
    2013             :             else
    2014             :             {
    2015           1 :                 MergeOGREnvelope_GCIO(bbox, x, y);
    2016             :             }
    2017             :         }
    2018           2 :         return g;
    2019             :     }
    2020             : 
    2021          38 :     if (gt == wkbMultiPolygon)
    2022             :     {
    2023             :         /*
    2024             :          * More Graphics :
    2025             :          * {Single Polygon{<>NrPolys=j[<>X<>Y[<>Z]<>Single Polygon]j}}
    2026             :          * with Single Polygon :
    2027             :          * Nr points=k[<>X<>Y[<>Z]]k...
    2028             :          */
    2029             :         CPLList *Lpo, *e;
    2030             :         OGRGeometryH outer, ring;
    2031             :         int npo, ipo, ilpo;
    2032             : 
    2033          38 :         Lpo = e = NULL;
    2034          38 :         outer = ring = NULL;
    2035          38 :         if (i + 2 + ((d == v3D_GCIO || d == v3DM_GCIO) ? 1 : 0) + 1 > nbtp)
    2036             :         {
    2037           0 :             goto onError;
    2038             :         }
    2039          38 :         if (buildGeom)
    2040             :         {
    2041          20 :             if (!(outer = OGR_G_CreateGeometry(wkbPolygon)))
    2042             :             {
    2043           0 :                 goto onError;
    2044             :             }
    2045          20 :             OGR_G_SetCoordinateDimension(outer,
    2046             :                                          OGR_G_GetCoordinateDimension(g));
    2047          20 :             if (GetMetaSRS_GCIO(Meta))
    2048             :             {
    2049          20 :                 OGR_G_AssignSpatialReference(outer, GetMetaSRS_GCIO(Meta));
    2050             :             }
    2051          20 :             if (!(ring = OGR_G_CreateGeometry(wkbLinearRing)))
    2052             :             {
    2053           0 :                 OGR_G_DestroyGeometry(outer);
    2054           0 :                 goto onError;
    2055             :             }
    2056          20 :             OGR_G_SetCoordinateDimension(ring, OGR_G_GetCoordinateDimension(g));
    2057          20 :             if (GetMetaSRS_GCIO(Meta))
    2058             :             {
    2059          20 :                 OGR_G_AssignSpatialReference(ring, GetMetaSRS_GCIO(Meta));
    2060             :             }
    2061             :         }
    2062          38 :         x = CPLAtof(papszFields[i]);
    2063          38 :         i++;
    2064          38 :         y = CPLAtof(papszFields[i]);
    2065          38 :         i++;
    2066          38 :         if (d == v3D_GCIO || d == v3DM_GCIO)
    2067             :         {
    2068           0 :             z = CPLAtof(papszFields[i]);
    2069           0 :             i++;
    2070             :         }
    2071          38 :         if (buildGeom)
    2072             :         {
    2073          20 :             if (OGR_G_GetCoordinateDimension(g) == 3)
    2074           0 :                 OGR_G_AddPoint(ring, x, y, z);
    2075             :             else
    2076          20 :                 OGR_G_AddPoint_2D(ring, x, y);
    2077             :         }
    2078             :         else
    2079             :         {
    2080          18 :             MergeOGREnvelope_GCIO(bbox, x, y);
    2081             :         }
    2082          38 :         np = atoi(papszFields[i]);
    2083          38 :         i++;
    2084          38 :         if (np < 0 ||
    2085          38 :             (np > 0 &&
    2086          38 :              i + (GIntBig)(2 + ((d == v3D_GCIO || d == v3DM_GCIO) ? 1 : 0)) *
    2087          38 :                          np >
    2088             :                  nbtp))
    2089             :         {
    2090           0 :             OGR_G_DestroyGeometry(outer);
    2091           0 :             OGR_G_DestroyGeometry(ring);
    2092           0 :             goto onError;
    2093             :         }
    2094         188 :         for (ip = 1; ip <= np; ip++)
    2095             :         {
    2096         150 :             x = CPLAtof(papszFields[i]);
    2097         150 :             i++;
    2098         150 :             y = CPLAtof(papszFields[i]);
    2099         150 :             i++;
    2100         150 :             if (d == v3D_GCIO || d == v3DM_GCIO)
    2101             :             {
    2102           0 :                 z = CPLAtof(papszFields[i]);
    2103           0 :                 i++;
    2104             :             }
    2105         150 :             if (buildGeom)
    2106             :             {
    2107          79 :                 if (OGR_G_GetCoordinateDimension(g) == 3)
    2108           0 :                     OGR_G_AddPoint(ring, x, y, z);
    2109             :                 else
    2110          79 :                     OGR_G_AddPoint_2D(ring, x, y);
    2111             :             }
    2112             :             else
    2113             :             {
    2114          71 :                 MergeOGREnvelope_GCIO(bbox, x, y);
    2115             :             }
    2116             :         }
    2117          38 :         if (buildGeom)
    2118             :         {
    2119          20 :             OGR_G_AddGeometryDirectly(outer, ring);
    2120          20 :             if ((Lpo = CPLListAppend(Lpo, outer)) == NULL)
    2121             :             {
    2122           0 :                 CPLError(CE_Failure, CPLE_OutOfMemory,
    2123             :                          "failed to add a polygon to subtype '%s.%s'.\n",
    2124           0 :                          GetTypeName_GCIO(GetSubTypeType_GCIO(theSubType)),
    2125             :                          GetSubTypeName_GCIO(theSubType));
    2126           0 :                 OGR_G_DestroyGeometry(outer);
    2127           0 :                 goto onError;
    2128             :             }
    2129             :         }
    2130             :         /* additional ring : either holes, or islands */
    2131          38 :         if (i < nbtp - 1)
    2132             :         {
    2133           4 :             npo = atoi(papszFields[i]);
    2134           4 :             i++;
    2135          10 :             for (ipo = 1; ipo <= npo; ipo++)
    2136             :             {
    2137           6 :                 if (i + (2 + ((d == v3D_GCIO || d == v3DM_GCIO) ? 1 : 0) + 1) >
    2138             :                     nbtp)
    2139             :                 {
    2140           0 :                     goto onError;
    2141             :                 }
    2142           6 :                 if (buildGeom)
    2143             :                 {
    2144           3 :                     if (!(ring = OGR_G_CreateGeometry(wkbLinearRing)))
    2145             :                     {
    2146           0 :                         goto onError;
    2147             :                     }
    2148           3 :                     OGR_G_SetCoordinateDimension(
    2149             :                         ring, OGR_G_GetCoordinateDimension(g));
    2150           3 :                     if (GetMetaSRS_GCIO(Meta))
    2151             :                     {
    2152           3 :                         OGR_G_AssignSpatialReference(ring,
    2153             :                                                      GetMetaSRS_GCIO(Meta));
    2154             :                     }
    2155             :                 }
    2156           6 :                 x = CPLAtof(papszFields[i]);
    2157           6 :                 i++;
    2158           6 :                 y = CPLAtof(papszFields[i]);
    2159           6 :                 i++;
    2160           6 :                 if (d == v3D_GCIO || d == v3DM_GCIO)
    2161             :                 {
    2162           0 :                     z = CPLAtof(papszFields[i]);
    2163           0 :                     i++;
    2164             :                 }
    2165           6 :                 if (buildGeom)
    2166             :                 {
    2167           3 :                     if (OGR_G_GetCoordinateDimension(g) == 3)
    2168           0 :                         OGR_G_AddPoint(ring, x, y, z);
    2169             :                     else
    2170           3 :                         OGR_G_AddPoint_2D(ring, x, y);
    2171             :                 }
    2172             :                 else
    2173             :                 {
    2174           3 :                     MergeOGREnvelope_GCIO(bbox, x, y);
    2175             :                 }
    2176           6 :                 np = atoi(papszFields[i]);
    2177           6 :                 i++;
    2178          26 :                 for (ip = 1; ip <= np; ip++)
    2179             :                 {
    2180          20 :                     if (i + (2 + ((d == v3D_GCIO || d == v3DM_GCIO) ? 1 : 0)) >
    2181             :                         nbtp)
    2182             :                     {
    2183           0 :                         OGR_G_DestroyGeometry(ring);
    2184           0 :                         goto onError;
    2185             :                     }
    2186          20 :                     x = CPLAtof(papszFields[i]);
    2187          20 :                     i++;
    2188          20 :                     y = CPLAtof(papszFields[i]);
    2189          20 :                     i++;
    2190          20 :                     if (d == v3D_GCIO || d == v3DM_GCIO)
    2191             :                     {
    2192           0 :                         z = CPLAtof(papszFields[i]);
    2193           0 :                         i++;
    2194             :                     }
    2195          20 :                     if (buildGeom)
    2196             :                     {
    2197          10 :                         if (OGR_G_GetCoordinateDimension(g) == 3)
    2198           0 :                             OGR_G_AddPoint(ring, x, y, z);
    2199             :                         else
    2200          10 :                             OGR_G_AddPoint_2D(ring, x, y);
    2201             :                     }
    2202             :                     else
    2203             :                     {
    2204          10 :                         MergeOGREnvelope_GCIO(bbox, x, y);
    2205             :                     }
    2206             :                 }
    2207           6 :                 if (buildGeom)
    2208             :                 {
    2209             :                     /* is the ring a hole or another polygon ? */
    2210           3 :                     const int nListCount = CPLListCount(Lpo);
    2211           5 :                     for (ilpo = 0; ilpo < nListCount; ilpo++)
    2212             :                     {
    2213           4 :                         if ((e = CPLListGet(Lpo, ilpo)))
    2214             :                         {
    2215           4 :                             if ((outer = (OGRGeometryH)CPLListGetData(e)))
    2216             :                             {
    2217             :                                 OGRGeometryH hPolyRing =
    2218           4 :                                     OGR_G_CreateGeometry(wkbPolygon);
    2219             :                                 int bRes;
    2220           4 :                                 if (OGR_G_AddGeometryDirectly(
    2221             :                                         hPolyRing, ring) != OGRERR_NONE)
    2222             :                                 {
    2223           0 :                                     OGR_G_DestroyGeometry(hPolyRing);
    2224           0 :                                     goto onError;
    2225             :                                 }
    2226           4 :                                 bRes = OGR_G_Contains(outer, hPolyRing);
    2227           4 :                                 OGR_G_RemoveGeometry(hPolyRing, 0, FALSE);
    2228           4 :                                 OGR_G_DestroyGeometry(hPolyRing);
    2229           4 :                                 if (bRes)
    2230             :                                 {
    2231           2 :                                     OGR_G_AddGeometryDirectly(outer, ring);
    2232           2 :                                     ring = NULL;
    2233           2 :                                     break;
    2234             :                                 }
    2235             :                             }
    2236             :                         }
    2237             :                     }
    2238           3 :                     if (ring)
    2239             :                     {
    2240             :                         /* new polygon */
    2241           1 :                         if (!(outer = OGR_G_CreateGeometry(wkbPolygon)))
    2242             :                         {
    2243           0 :                             OGR_G_DestroyGeometry(ring);
    2244           0 :                             goto onError;
    2245             :                         }
    2246           1 :                         OGR_G_SetCoordinateDimension(
    2247             :                             outer, OGR_G_GetCoordinateDimension(g));
    2248           1 :                         if (GetMetaSRS_GCIO(Meta))
    2249             :                         {
    2250           1 :                             OGR_G_AssignSpatialReference(outer,
    2251             :                                                          GetMetaSRS_GCIO(Meta));
    2252             :                         }
    2253           1 :                         OGR_G_AddGeometryDirectly(outer, ring);
    2254           1 :                         if ((Lpo = CPLListAppend(Lpo, outer)) == NULL)
    2255             :                         {
    2256           0 :                             CPLError(
    2257             :                                 CE_Failure, CPLE_OutOfMemory,
    2258             :                                 "failed to add a polygon to subtype '%s.%s'.\n",
    2259           0 :                                 GetTypeName_GCIO(
    2260             :                                     GetSubTypeType_GCIO(theSubType)),
    2261             :                                 GetSubTypeName_GCIO(theSubType));
    2262           0 :                             OGR_G_DestroyGeometry(outer);
    2263           0 :                             goto onError;
    2264             :                         }
    2265             :                     }
    2266             :                 }
    2267             :             }
    2268             :         }
    2269          38 :         if (Lpo)
    2270             :         {
    2271          20 :             if ((npo = CPLListCount(Lpo)) > 0)
    2272             :             {
    2273          41 :                 for (ipo = 0; ipo < npo; ipo++)
    2274             :                 {
    2275          21 :                     if ((e = CPLListGet(Lpo, ipo)))
    2276             :                     {
    2277          21 :                         if ((outer = (OGRGeometryH)CPLListGetData(e)))
    2278             :                         {
    2279          21 :                             OGR_G_AddGeometryDirectly(g, outer);
    2280             :                         }
    2281             :                     }
    2282             :                 }
    2283             :             }
    2284          20 :             CPLListDestroy(Lpo);
    2285             :         }
    2286          38 :         return g;
    2287             : 
    2288           0 :     onError:
    2289           0 :         if (Lpo)
    2290             :         {
    2291           0 :             if ((npo = CPLListCount(Lpo)) > 0)
    2292             :             {
    2293           0 :                 for (ipo = 0; ipo < npo; ipo++)
    2294             :                 {
    2295           0 :                     if ((e = CPLListGet(Lpo, ipo)))
    2296             :                     {
    2297           0 :                         if ((outer = (OGRGeometryH)CPLListGetData(e)))
    2298             :                         {
    2299           0 :                             OGR_G_DestroyGeometry(outer);
    2300             :                         }
    2301             :                     }
    2302             :                 }
    2303             :             }
    2304           0 :             CPLListDestroy(Lpo);
    2305             :         }
    2306           0 :         if (g)
    2307           0 :             OGR_G_DestroyGeometry(g);
    2308             :     }
    2309             : 
    2310           0 :     return NULL;
    2311             : } /* _buildOGRGeometry_GCIO */
    2312             : 
    2313             : /* -------------------------------------------------------------------- */
    2314          54 : static OGRFeatureH GCIOAPI_CALL _buildOGRFeature_GCIO(GCExportFileH *H,
    2315             :                                                       GCSubType **theSubType,
    2316             :                                                       GCDim d,
    2317             :                                                       OGREnvelope *bbox)
    2318             : {
    2319             :     GCExportFileMetadata *Meta;
    2320          54 :     char **papszFields, delim[2] = {0}, tdst[kItemSize_GCIO];
    2321             :     int whereClass, whereSubType, i, j, nbstf, nbf, nbtf, buildFeature;
    2322             :     GCType *theClass;
    2323             :     GCField *theField;
    2324             :     OGRFieldDefnH fld;
    2325             :     OGRFeatureDefnH fd;
    2326             :     OGRFeatureH f;
    2327             :     OGRGeometryH g;
    2328          54 :     int bTokenBehavior = CSLT_ALLOWEMPTYTOKENS;
    2329             : 
    2330          54 :     fd = NULL;
    2331          54 :     f = NULL;
    2332          54 :     Meta = GetGCMeta_GCIO(H);
    2333          54 :     delim[0] = GetMetaDelimiter_GCIO(Meta);
    2334          54 :     delim[1] = '\0';
    2335          54 :     if (d == vUnknown3D_GCIO)
    2336          54 :         d = v2D_GCIO;
    2337          54 :     if (bbox == NULL)
    2338             :     {
    2339          31 :         buildFeature = TRUE;
    2340             :     }
    2341             :     else
    2342             :     {
    2343          23 :         buildFeature = FALSE;
    2344             :     }
    2345          54 :     CPLDebug("GEOCONCEPT", "buildFeature is %s",
    2346             :              buildFeature ? "true" : "false");
    2347             : 
    2348             :     /* due to the order of fields, we know how to proceed : */
    2349             :     /* A.- Line syntax :                                    */
    2350             :     /* Object internal identifier <delimiter>               */
    2351             :     /* Class <delimiter>                                    */
    2352             :     /* Subclass <delimiter>                                 */
    2353             :     /* Name <delimiter>                                     */
    2354             :     /* NbFields <delimiter>                                 */
    2355             :     /* User's field <delimiter> [0..N]                      */
    2356             :     /* Graphics                                             */
    2357             :     /* Graphics depends on the Kind of the                  */
    2358             :     /* B.- Algorithm :                                      */
    2359             :     /*  1.- Get Class                                       */
    2360             :     /*  2.- Get Subclass                                    */
    2361             :     /*  3.- Find feature in schema                          */
    2362             :     /*  4.- Get Kind                                        */
    2363             :     /*  5.- Get NbFields                                    */
    2364             :     /*  6.- Get Geometry as 5+NbFields field                */
    2365             :     /*  7.- Parse Geometry and build OGRGeometryH           */
    2366             :     /*  8.- Compute extent and update file extent           */
    2367             :     /*   9.- increment number of features                   */
    2368             :     /* FIXME : add index when reading feature to            */
    2369             :     /*         allow direct access !                        */
    2370          54 :     if (GetMetaQuotedText_GCIO(Meta))
    2371             :     {
    2372           0 :         bTokenBehavior |= CSLT_HONOURSTRINGS;
    2373             :     }
    2374          54 :     CPLDebug("GEOCONCEPT", "Cache=[%s] delim=[%s]", GetGCCache_GCIO(H), delim);
    2375          54 :     if (!(papszFields =
    2376          54 :               CSLTokenizeString2(GetGCCache_GCIO(H), delim, bTokenBehavior)))
    2377             :     {
    2378           0 :         CPLError(CE_Failure, CPLE_AppDefined,
    2379             :                  "Line %ld, Geoconcept line syntax is wrong.\n",
    2380             :                  GetGCCurrentLinenum_GCIO(H));
    2381           0 :         return NULL;
    2382             :     }
    2383          54 :     if ((nbtf = CSLCount(papszFields)) <= 5)
    2384             :     {
    2385           0 :         CSLDestroy(papszFields);
    2386           0 :         CPLError(
    2387             :             CE_Failure, CPLE_AppDefined,
    2388             :             "Line %ld, Missing fields (at least 5 are expected, %d found).\n",
    2389             :             GetGCCurrentLinenum_GCIO(H), nbtf);
    2390           0 :         return NULL;
    2391             :     }
    2392             :     /* Class */
    2393          54 :     if ((whereClass = _findTypeByName_GCIO(H, papszFields[1])) == -1)
    2394             :     {
    2395           0 :         if (CPLListCount(GetMetaTypes_GCIO(Meta)) == 0)
    2396             :         {
    2397           0 :             CPLError(CE_Failure, CPLE_AppDefined,
    2398             :                      "Line %ld, %s%s pragma expected from type definition "
    2399             :                      "before objects dump.",
    2400             :                      GetGCCurrentLinenum_GCIO(H), kPragma_GCIO,
    2401             :                      kMetadataFIELDS_GCIO);
    2402             :         }
    2403             :         else
    2404             :         {
    2405           0 :             CPLError(CE_Failure, CPLE_AppDefined,
    2406             :                      "Line %ld, Unknown type '%s'.\n",
    2407           0 :                      GetGCCurrentLinenum_GCIO(H), papszFields[1]);
    2408             :         }
    2409           0 :         CSLDestroy(papszFields);
    2410           0 :         return NULL;
    2411             :     }
    2412          54 :     theClass = _getType_GCIO(H, whereClass);
    2413          54 :     if (theClass == NULL)
    2414             :     {
    2415           0 :         CSLDestroy(papszFields);
    2416           0 :         return NULL;
    2417             :     }
    2418          54 :     if (*theSubType)
    2419             :     {
    2420             :         /* reading ... */
    2421          31 :         if (!EQUAL(GetTypeName_GCIO(GetSubTypeType_GCIO(*theSubType)),
    2422             :                    GetTypeName_GCIO(theClass)))
    2423             :         {
    2424           0 :             CSLDestroy(papszFields);
    2425           0 :             return NULL;
    2426             :         }
    2427             :     }
    2428             :     /* Subclass */
    2429          54 :     if ((whereSubType = _findSubTypeByName_GCIO(theClass, papszFields[2])) ==
    2430             :         -1)
    2431             :     {
    2432           0 :         CPLError(CE_Failure, CPLE_AppDefined,
    2433             :                  "Line %ld, Unknown subtype found '%s' for type '%s'.\n",
    2434           0 :                  GetGCCurrentLinenum_GCIO(H), papszFields[2], papszFields[1]);
    2435           0 :         CSLDestroy(papszFields);
    2436           0 :         return NULL;
    2437             :     }
    2438          54 :     if (*theSubType)
    2439             :     {
    2440          31 :         GCSubType *psSubType = _getSubType_GCIO(theClass, whereSubType);
    2441          31 :         if (psSubType == NULL || !EQUAL(GetSubTypeName_GCIO(psSubType),
    2442             :                                         GetSubTypeName_GCIO(*theSubType)))
    2443             :         {
    2444           0 :             CSLDestroy(papszFields);
    2445           0 :             return NULL;
    2446             :         }
    2447             :     }
    2448             :     else
    2449             :     {
    2450          23 :         *theSubType = _getSubType_GCIO(theClass, whereSubType);
    2451          23 :         CPLAssert(*theSubType != NULL);
    2452             :     }
    2453          54 :     snprintf(tdst, kItemSize_GCIO - 1, "%s.%s", GetTypeName_GCIO(theClass),
    2454          54 :              GetSubTypeName_GCIO(*theSubType));
    2455          54 :     tdst[kItemSize_GCIO - 1] = '\0';
    2456             :     /* Name */
    2457          54 :     if (_findFieldByName_GCIO(GetSubTypeFields_GCIO(*theSubType), kName_GCIO) ==
    2458             :         -1)
    2459             :     {
    2460           0 :         CPLError(CE_Failure, CPLE_AppDefined,
    2461             :                  "Line %ld, missing mandatory field %s for type '%s'.\n",
    2462             :                  GetGCCurrentLinenum_GCIO(H), kName_GCIO, tdst);
    2463           0 :         CSLDestroy(papszFields);
    2464           0 :         return NULL;
    2465             :     }
    2466          54 :     nbf = 4;
    2467             :     /* NbFields */
    2468          54 :     nbstf = GetSubTypeNbFields_GCIO(*theSubType);
    2469          54 :     if (nbstf == -1)
    2470             :     {
    2471             :         /* figure out how many user's attributes we've got : */
    2472           8 :         i = 1 + nbf;
    2473           8 :         nbstf = 0;
    2474          24 :         while ((theField = GetSubTypeField_GCIO(*theSubType, i)))
    2475             :         {
    2476          24 :             if (IsPrivateField_GCIO(theField))
    2477             :             {
    2478           8 :                 break;
    2479             :             };  // FIXME: could count geometry private fields ...
    2480          16 :             nbstf++;
    2481          16 :             SetSubTypeNbFields_GCIO(*theSubType, nbstf);
    2482          16 :             i++;
    2483             :         }
    2484             :     }
    2485          54 :     if (nbtf < 1 + nbf + nbstf + 1)
    2486             :     {
    2487           0 :         CPLError(CE_Failure, CPLE_AppDefined,
    2488             :                  "Line %ld, Total number of fields differs with type "
    2489             :                  "definition '%s' (%d found, at least %d expected).\n",
    2490           0 :                  GetGCCurrentLinenum_GCIO(H), tdst, nbtf, 1 + nbf + nbstf + 1);
    2491           0 :         CSLDestroy(papszFields);
    2492           0 :         return NULL;
    2493             :     }
    2494          54 :     i = atoi(papszFields[nbf]);
    2495          54 :     if (i != nbstf)
    2496             :     {
    2497           0 :         CPLError(CE_Failure, CPLE_AppDefined,
    2498             :                  "Line %ld, Number of user's fields differs with type "
    2499             :                  "definition '%s' (%d found, %d expected).\n",
    2500             :                  GetGCCurrentLinenum_GCIO(H), tdst, i, nbstf);
    2501           0 :         CSLDestroy(papszFields);
    2502           0 :         return NULL;
    2503             :     }
    2504             :     /*
    2505             :      * the Subclass has no definition : let's build one
    2506             :      */
    2507          54 :     if (!(fd = GetSubTypeFeatureDefn_GCIO(*theSubType)))
    2508             :     {
    2509           8 :         if (!(fd = OGR_FD_Create(tdst)))
    2510             :         {
    2511           0 :             CSLDestroy(papszFields);
    2512           0 :             return NULL;
    2513             :         }
    2514             : 
    2515           8 :         switch (GetSubTypeKind_GCIO(*theSubType))
    2516             :         {
    2517           2 :             case vPoint_GCIO:
    2518             :             case vText_GCIO: /* FIXME : treat as point ? */
    2519             :                 switch (d)
    2520             :                 {
    2521           0 :                     case v3D_GCIO:
    2522             :                     case v3DM_GCIO:
    2523           0 :                         OGR_FD_SetGeomType(fd, wkbPoint25D);
    2524           0 :                         break;
    2525           2 :                     default:
    2526           2 :                         OGR_FD_SetGeomType(fd, wkbPoint);
    2527           2 :                         break;
    2528             :                 }
    2529           2 :                 break;
    2530           1 :             case vLine_GCIO:
    2531             :                 switch (d)
    2532             :                 {
    2533           0 :                     case v3D_GCIO:
    2534             :                     case v3DM_GCIO:
    2535           0 :                         OGR_FD_SetGeomType(fd, wkbLineString25D);
    2536           0 :                         break;
    2537           1 :                     default:
    2538           1 :                         OGR_FD_SetGeomType(fd, wkbLineString);
    2539           1 :                         break;
    2540             :                 }
    2541           1 :                 break;
    2542           5 :             case vPoly_GCIO:
    2543             :                 switch (d)
    2544             :                 {
    2545           0 :                     case v3D_GCIO:
    2546             :                     case v3DM_GCIO:
    2547           0 :                         OGR_FD_SetGeomType(fd, wkbMultiPolygon25D);
    2548           0 :                         break;
    2549           5 :                     default:
    2550           5 :                         OGR_FD_SetGeomType(fd, wkbMultiPolygon);
    2551           5 :                         break;
    2552             :                 }
    2553           5 :                 break;
    2554           0 :             default:
    2555           0 :                 CSLDestroy(papszFields);
    2556           0 :                 OGR_FD_Destroy(fd);
    2557           0 :                 CPLError(CE_Failure, CPLE_NotSupported,
    2558             :                          "Unknown Geoconcept type for '%s'.\n", tdst);
    2559           0 :                 return NULL;
    2560             :         }
    2561          24 :         for (i = 1 + nbf; i < 1 + nbf + nbstf; i++)
    2562             :         {
    2563          16 :             theField = GetSubTypeField_GCIO(*theSubType, i);
    2564          16 :             if (!(fld = OGR_Fld_Create(GetFieldName_GCIO(theField),
    2565             :                                        OFTString))) /* FIXME */
    2566             :             {
    2567           0 :                 CSLDestroy(papszFields);
    2568           0 :                 OGR_FD_Destroy(fd);
    2569           0 :                 return NULL;
    2570             :             }
    2571          16 :             OGR_FD_AddFieldDefn(fd, fld);
    2572          16 :             OGR_Fld_Destroy(fld);
    2573          16 :             fld = NULL;
    2574             :         }
    2575             :     }
    2576             : 
    2577             :     /*
    2578             :      * the Subclass is just under parsing via _parseObject_GCIO
    2579             :      */
    2580          54 :     if (buildFeature)
    2581             :     {
    2582          31 :         if (!(f = OGR_F_Create(fd)))
    2583             :         {
    2584           0 :             if (!GetSubTypeFeatureDefn_GCIO(*theSubType))
    2585           0 :                 OGR_FD_Destroy(fd);
    2586           0 :             CSLDestroy(papszFields);
    2587           0 :             return NULL;
    2588             :         }
    2589          31 :         OGR_F_SetFID(f, atol(papszFields[0])); /* FID */
    2590          31 :         if (OGR_F_GetFID(f) == OGRNullFID)
    2591             :         {
    2592          31 :             OGR_F_SetFID(f, GetGCCurrentLinenum_GCIO(H));
    2593             :         }
    2594         116 :         for (i = 1 + nbf, j = 0; i < 1 + nbf + nbstf; i++, j++)
    2595             :         {
    2596             :             /*theField= GetSubTypeField_GCIO(*theSubType,i); */ /* FIXME?*/
    2597          85 :             if (papszFields[i][0] == '\0')
    2598          22 :                 OGR_F_UnsetField(f, j);
    2599             :             else
    2600          63 :                 OGR_F_SetFieldString(f, j, papszFields[i]);
    2601             :         }
    2602             :     }
    2603             :     else
    2604             :     {
    2605          23 :         i = 1 + nbf + nbstf;
    2606             :     }
    2607          54 :     CPLDebug("GEOCONCEPT", "%d %d/%d/%d/%d\n", __LINE__, i, nbf, nbstf, nbtf);
    2608          54 :     if (!(g = _buildOGRGeometry_GCIO(
    2609             :               Meta, *theSubType, i, (const char **)papszFields, nbtf, d, bbox)))
    2610             :     {
    2611             :         /*
    2612             :          * the Subclass is under reading via ReadNextFeature_GCIO
    2613             :          */
    2614          23 :         if (buildFeature)
    2615             :         {
    2616           0 :             CSLDestroy(papszFields);
    2617           0 :             if (f)
    2618           0 :                 OGR_F_Destroy(f);
    2619           0 :             return NULL;
    2620             :         }
    2621             :     }
    2622          54 :     if (buildFeature)
    2623             :     {
    2624          31 :         if (OGR_F_SetGeometryDirectly(f, g) != OGRERR_NONE)
    2625             :         {
    2626           0 :             CSLDestroy(papszFields);
    2627           0 :             if (f)
    2628           0 :                 OGR_F_Destroy(f);
    2629           0 :             return NULL;
    2630             :         }
    2631             :     }
    2632          54 :     CSLDestroy(papszFields);
    2633             : 
    2634             :     /* Assign definition : */
    2635          54 :     if (!GetSubTypeFeatureDefn_GCIO(*theSubType))
    2636             :     {
    2637           8 :         SetSubTypeFeatureDefn_GCIO(*theSubType, fd);
    2638           8 :         OGR_FD_Reference(fd);
    2639             :     }
    2640             : 
    2641             :     /*
    2642             :      * returns either the built object for ReadNextFeature_GCIO or
    2643             :      *                the feature definition for _parseObject_GCIO :
    2644             :      */
    2645          54 :     return buildFeature ? f : (OGRFeatureH)fd;
    2646             : } /* _buildOGRFeature_GCIO */
    2647             : 
    2648             : /* -------------------------------------------------------------------- */
    2649          23 : static GCExportFileMetadata GCIOAPI_CALL1(*) _parseObject_GCIO(GCExportFileH *H)
    2650             : {
    2651             :     GCExportFileMetadata *Meta;
    2652             :     GCSubType *theSubType;
    2653             :     GCDim d;
    2654             :     vsi_l_offset coff;
    2655          23 :     OGREnvelope bbox, *pszBbox = &bbox;
    2656             : 
    2657          23 :     Meta = GetGCMeta_GCIO(H);
    2658             : 
    2659          23 :     InitOGREnvelope_GCIO(pszBbox);
    2660             : 
    2661          23 :     d = vUnknown3D_GCIO;
    2662          23 :     theSubType = NULL;
    2663          23 :     coff = (vsi_l_offset)EOF;
    2664          23 : reloop:
    2665             :     /* TODO: Switch to C++ casts below. */
    2666          23 :     if ((enum _tIO_MetadataType_GCIO)GetGCWhatIs_GCIO(H) == vComType_GCIO)
    2667             :     {
    2668           0 :         if (_get_GCIO(H) == (vsi_l_offset)EOF)
    2669           0 :             return Meta;
    2670           0 :         goto reloop;
    2671             :     }
    2672             :     /* analyze the line according to schema : */
    2673             :     /* coverity[mixed_enums] */ /* FIXME ? */
    2674          23 :     if ((enum _tIO_MetadataType_GCIO)GetGCWhatIs_GCIO(H) == vPragma_GCIO)
    2675             :     {
    2676           0 :         if (strstr(GetGCCache_GCIO(H), k3DOBJECTMONO_GCIO))
    2677             :         {
    2678           0 :             d = v3DM_GCIO;
    2679           0 :             coff = GetGCCurrentOffset_GCIO(H);
    2680             :         }
    2681           0 :         else if (strstr(GetGCCache_GCIO(H), k3DOBJECT_GCIO))
    2682             :         {
    2683           0 :             d = v3D_GCIO;
    2684           0 :             coff = GetGCCurrentOffset_GCIO(H);
    2685             :         }
    2686           0 :         else if (strstr(GetGCCache_GCIO(H), k2DOBJECT_GCIO))
    2687             :         {
    2688           0 :             d = v2D_GCIO;
    2689           0 :             coff = GetGCCurrentOffset_GCIO(H);
    2690             :         }
    2691             :         else
    2692             :         {
    2693             :             /* not an object pragma ... */
    2694           0 :             SetGCStatus_GCIO(H, vMemoStatus_GCIO);
    2695           0 :             return Meta;
    2696             :         }
    2697           0 :         if (_get_GCIO(H) == (vsi_l_offset)EOF)
    2698           0 :             return Meta;
    2699           0 :         goto reloop;
    2700             :     }
    2701          23 :     if (coff == (vsi_l_offset)EOF)
    2702          23 :         coff = GetGCCurrentOffset_GCIO(H);
    2703          23 :     if (!_buildOGRFeature_GCIO(H, &theSubType, d, pszBbox))
    2704             :     {
    2705           0 :         return NULL;
    2706             :     }
    2707          23 :     if (GetSubTypeBOF_GCIO(theSubType) == (vsi_l_offset)EOF)
    2708             :     {
    2709           8 :         SetSubTypeBOF_GCIO(theSubType,
    2710             :                            coff); /* Begin Of Features for the Class.Subclass */
    2711           8 :         SetSubTypeBOFLinenum_GCIO(theSubType, GetGCCurrentLinenum_GCIO(H));
    2712           8 :         CPLDebug("GEOCONCEPT", "Feature Type [%s] starts at #%ld, line %ld\n",
    2713           8 :                  GetSubTypeName_GCIO(theSubType),
    2714           8 :                  (long)GetSubTypeBOF_GCIO(theSubType),
    2715           8 :                  GetSubTypeBOFLinenum_GCIO(theSubType));
    2716             :     }
    2717          23 :     SetSubTypeNbFeatures_GCIO(theSubType,
    2718             :                               GetSubTypeNbFeatures_GCIO(theSubType) + 1L);
    2719          23 :     SetGCNbObjects_GCIO(H, GetGCNbObjects_GCIO(H) + 1L);
    2720             :     /* update bbox of both feature and file */
    2721          23 :     SetExtentULAbscissa_GCIO(GetMetaExtent_GCIO(Meta), pszBbox->MinX);
    2722          23 :     SetExtentULOrdinate_GCIO(GetMetaExtent_GCIO(Meta), pszBbox->MaxY);
    2723          23 :     SetExtentLRAbscissa_GCIO(GetMetaExtent_GCIO(Meta), pszBbox->MaxX);
    2724          23 :     SetExtentLROrdinate_GCIO(GetMetaExtent_GCIO(Meta), pszBbox->MinY);
    2725          23 :     if (!GetSubTypeExtent_GCIO(theSubType))
    2726             :     {
    2727           8 :         SetSubTypeExtent_GCIO(
    2728             :             theSubType,
    2729             :             CreateExtent_GCIO(HUGE_VAL, HUGE_VAL, -HUGE_VAL, -HUGE_VAL));
    2730             :     }
    2731          23 :     SetExtentULAbscissa_GCIO(GetSubTypeExtent_GCIO(theSubType), pszBbox->MinX);
    2732          23 :     SetExtentULOrdinate_GCIO(GetSubTypeExtent_GCIO(theSubType), pszBbox->MaxY);
    2733          23 :     SetExtentLRAbscissa_GCIO(GetSubTypeExtent_GCIO(theSubType), pszBbox->MaxX);
    2734          23 :     SetExtentLROrdinate_GCIO(GetSubTypeExtent_GCIO(theSubType), pszBbox->MinY);
    2735          23 :     if (d == vUnknown3D_GCIO &&
    2736          23 :         GetSubTypeDim_GCIO(theSubType) == vUnknown3D_GCIO)
    2737             :     {
    2738             :         /* FIXME ? */
    2739             : #ifdef notdef
    2740             :         switch (d)
    2741             :         {
    2742             :             case v3DM_GCIO:
    2743             :             case v3D_GCIO:
    2744             :                 SetSubTypeDim_GCIO(theSubType, v3D_GCIO);
    2745             :                 break;
    2746             :             default:
    2747             : #endif
    2748           8 :                 SetSubTypeDim_GCIO(theSubType, v2D_GCIO);
    2749             : #ifdef notdef
    2750             :                 break;
    2751             :         }
    2752             : #endif
    2753             :     }
    2754             :     /*d= vUnknown3D_GCIO;*/
    2755          23 :     theSubType = NULL;
    2756             : 
    2757          23 :     return Meta;
    2758             : } /* _parseObject_GCIO */
    2759             : 
    2760             : /* -------------------------------------------------------------------- */
    2761             : GCExportFileH GCIOAPI_CALL1(*)
    2762          26 :     Open_GCIO(const char *pszGeoconceptFile, const char *ext, /* gxt if NULL */
    2763             :               const char *mode, const char *gctPath /* if !NULL, mode=w */
    2764             :     )
    2765             : {
    2766             :     GCExportFileH *hGXT;
    2767             : 
    2768          26 :     CPLDebug(
    2769             :         "GEOCONCEPT", "filename '%s' - '%s' - mode '%s' - config path '%s'",
    2770             :         pszGeoconceptFile, ext ? ext : "gxt", mode, gctPath ? gctPath : "???");
    2771             : 
    2772          26 :     if (!(hGXT = _Create_GCIO(pszGeoconceptFile, ext, mode)))
    2773             :     {
    2774           0 :         return NULL;
    2775             :     }
    2776             : 
    2777          26 :     if (GetGCMode_GCIO(hGXT) == vUpdateAccess_GCIO)
    2778             :     {
    2779             :         VSILFILE *h;
    2780             : 
    2781             :         /* file must exists ... */
    2782           0 :         if (!(h = VSIFOpenL(CPLFormFilename(GetGCPath_GCIO(hGXT),
    2783           0 :                                             GetGCBasename_GCIO(hGXT),
    2784           0 :                                             GetGCExtension_GCIO(hGXT)),
    2785             :                             "rt")))
    2786             :         {
    2787           0 :             _Destroy_GCIO(&hGXT, FALSE);
    2788           0 :             return NULL;
    2789             :         }
    2790           0 :         VSIFCloseL(h);
    2791             :     }
    2792             : 
    2793          26 :     SetGCHandle_GCIO(hGXT, VSIFOpenL(CPLFormFilename(GetGCPath_GCIO(hGXT),
    2794             :                                                      GetGCBasename_GCIO(hGXT),
    2795             :                                                      GetGCExtension_GCIO(hGXT)),
    2796             :                                      mode));
    2797          26 :     if (!GetGCHandle_GCIO(hGXT))
    2798             :     {
    2799           0 :         _Destroy_GCIO(&hGXT, FALSE);
    2800           0 :         return NULL;
    2801             :     }
    2802             : 
    2803          26 :     if (GetGCMode_GCIO(hGXT) == vWriteAccess_GCIO)
    2804             :     {
    2805          17 :         if (gctPath != NULL)
    2806             :         {
    2807             :             /* load Metadata */
    2808             :             GCExportFileH *hGCT;
    2809             : 
    2810           0 :             hGCT = _Create_GCIO(gctPath, "gct", "-");
    2811           0 :             SetGCHandle_GCIO(
    2812             :                 hGCT, VSIFOpenL(CPLFormFilename(GetGCPath_GCIO(hGCT),
    2813             :                                                 GetGCBasename_GCIO(hGCT),
    2814             :                                                 GetGCExtension_GCIO(hGCT)),
    2815             :                                 "r"));
    2816           0 :             if (!GetGCHandle_GCIO(hGCT))
    2817             :             {
    2818           0 :                 CPLError(CE_Failure, CPLE_NotSupported,
    2819             :                          "opening a Geoconcept config file '%s' failed.\n",
    2820             :                          gctPath);
    2821           0 :                 _Destroy_GCIO(&hGCT, FALSE);
    2822           0 :                 _Destroy_GCIO(&hGXT, TRUE);
    2823           0 :                 return NULL;
    2824             :             }
    2825           0 :             if (ReadConfig_GCIO(hGCT) == NULL)
    2826             :             {
    2827           0 :                 _Destroy_GCIO(&hGCT, FALSE);
    2828           0 :                 _Destroy_GCIO(&hGXT, TRUE);
    2829           0 :                 return NULL;
    2830             :             }
    2831           0 :             SetGCMeta_GCIO(hGXT, GetGCMeta_GCIO(hGCT));
    2832           0 :             SetGCMeta_GCIO(hGCT, NULL);
    2833           0 :             _Destroy_GCIO(&hGCT, FALSE);
    2834           0 :             SetMetaExtent_GCIO(
    2835             :                 GetGCMeta_GCIO(hGXT),
    2836             :                 CreateExtent_GCIO(HUGE_VAL, HUGE_VAL, -HUGE_VAL, -HUGE_VAL));
    2837             :         }
    2838             :     }
    2839             :     else
    2840             :     {
    2841             :         /* read basic Metadata from export    */
    2842             :         /* read and parse the export file ... */
    2843           9 :         if (ReadHeader_GCIO(hGXT) == NULL)
    2844             :         {
    2845           1 :             _Destroy_GCIO(&hGXT, FALSE);
    2846           1 :             return NULL;
    2847             :         }
    2848             :     }
    2849             :     /* check schema */
    2850          25 :     if (!_checkSchema_GCIO(hGXT))
    2851             :     {
    2852           0 :         _Destroy_GCIO(&hGXT,
    2853           0 :                       GetGCMode_GCIO(hGXT) == vWriteAccess_GCIO ? TRUE : FALSE);
    2854           0 :         return NULL;
    2855             :     }
    2856             : 
    2857          75 :     CPLDebug("GEOCONCEPT",
    2858             :              "Export =(\n"
    2859             :              "  Path : %s\n"
    2860             :              "  Basename : %s\n"
    2861             :              "  Extension : %s\n"
    2862             :              "  Mode : %s\n"
    2863             :              "  Status : %s\n"
    2864             :              ")",
    2865          25 :              GetGCPath_GCIO(hGXT), GetGCBasename_GCIO(hGXT),
    2866          25 :              GetGCExtension_GCIO(hGXT),
    2867          25 :              GCAccessMode2str_GCIO(GetGCMode_GCIO(hGXT)),
    2868          25 :              GCAccessStatus2str_GCIO(GetGCStatus_GCIO(hGXT)));
    2869             : 
    2870          25 :     return hGXT;
    2871             : } /* Open_GCIO */
    2872             : 
    2873             : /* -------------------------------------------------------------------- */
    2874          25 : void GCIOAPI_CALL Close_GCIO(GCExportFileH **hGXT)
    2875             : {
    2876          25 :     _Destroy_GCIO(hGXT, FALSE);
    2877          25 : } /* Close_GCIO */
    2878             : 
    2879             : /* -------------------------------------------------------------------- */
    2880             : GCExportFileH GCIOAPI_CALL1(*)
    2881          20 :     Rewind_GCIO(GCExportFileH *hGXT, GCSubType *theSubType)
    2882             : {
    2883          20 :     if (hGXT)
    2884             :     {
    2885          20 :         if (GetGCHandle_GCIO(hGXT))
    2886             :         {
    2887          20 :             if (!theSubType)
    2888             :             {
    2889          14 :                 VSIRewindL(GetGCHandle_GCIO(hGXT));
    2890          14 :                 SetGCCurrentLinenum_GCIO(hGXT, 0L);
    2891             :             }
    2892             :             else
    2893             :             {
    2894           6 :                 if (VSIFSeekL(GetGCHandle_GCIO(hGXT),
    2895             :                               GetSubTypeBOF_GCIO(theSubType), SEEK_SET) == 0)
    2896           6 :                     SetGCCurrentLinenum_GCIO(
    2897             :                         hGXT, GetSubTypeBOFLinenum_GCIO(theSubType));
    2898             :             }
    2899          20 :             SetGCStatus_GCIO(hGXT, vNoStatus_GCIO);
    2900             :         }
    2901             :     }
    2902          20 :     return hGXT;
    2903             : } /* Rewind_GCIO */
    2904             : 
    2905             : /* -------------------------------------------------------------------- */
    2906           0 : GCExportFileH GCIOAPI_CALL1(*) FFlush_GCIO(GCExportFileH *hGXT)
    2907             : {
    2908           0 :     if (hGXT)
    2909             :     {
    2910           0 :         if (GetGCHandle_GCIO(hGXT))
    2911             :         {
    2912           0 :             VSIFFlushL(GetGCHandle_GCIO(hGXT));
    2913             :         }
    2914             :     }
    2915           0 :     return hGXT;
    2916             : } /* FFlush_GCIO */
    2917             : 
    2918             : #ifdef unused
    2919             : /* -------------------------------------------------------------------- */
    2920             : GCAccessMode GCIOAPI_CALL GetMode_GCIO(GCExportFileH *hGXT)
    2921             : {
    2922             :     return hGXT ? GetGCMode_GCIO(hGXT) : vUnknownAccessMode_GCIO;
    2923             : } /* GetMode_GCIO */
    2924             : #endif
    2925             : 
    2926             : /* -------------------------------------------------------------------- */
    2927             : GCSubType GCIOAPI_CALL1(*)
    2928           9 :     AddSubType_GCIO(GCExportFileH *H, const char *typName,
    2929             :                     const char *subtypName, long id, GCTypeKind knd, GCDim sys)
    2930             : {
    2931             :     int whereClass;
    2932             :     GCType *theClass;
    2933             :     GCSubType *theSubType;
    2934             :     CPLList *L;
    2935             : 
    2936           9 :     if ((whereClass = _findTypeByName_GCIO(H, typName)) == -1)
    2937             :     {
    2938           0 :         CPLError(CE_Failure, CPLE_AppDefined,
    2939             :                  "failed to find a Geoconcept type for '%s.%s#%ld'.\n", typName,
    2940             :                  subtypName, id);
    2941           0 :         return NULL;
    2942             :     }
    2943             : 
    2944           9 :     theClass = _getType_GCIO(H, whereClass);
    2945           9 :     if (theClass == NULL)
    2946           0 :         return NULL;
    2947           9 :     if (GetTypeSubtypes_GCIO(theClass))
    2948             :     {
    2949           0 :         if (_findSubTypeByName_GCIO(theClass, subtypName) != -1)
    2950             :         {
    2951           0 :             CPLError(CE_Failure, CPLE_AppDefined,
    2952             :                      "Geoconcept subtype '%s.%s#%ld' already exists.\n",
    2953             :                      typName, subtypName, id);
    2954           0 :             return NULL;
    2955             :         }
    2956             :     }
    2957             : 
    2958           9 :     if (!(theSubType = _CreateSubType_GCIO(subtypName, id, knd, sys)))
    2959             :     {
    2960           0 :         return NULL;
    2961             :     }
    2962           9 :     if ((L = CPLListAppend(GetTypeSubtypes_GCIO(theClass), theSubType)) == NULL)
    2963             :     {
    2964           0 :         _DestroySubType_GCIO(&theSubType);
    2965           0 :         CPLError(CE_Failure, CPLE_OutOfMemory,
    2966             :                  "failed to add a Geoconcept subtype for '%s.%s#%ld'.\n",
    2967             :                  typName, subtypName, id);
    2968           0 :         return NULL;
    2969             :     }
    2970           9 :     SetTypeSubtypes_GCIO(theClass, L);
    2971           9 :     SetSubTypeType_GCIO(theSubType, theClass);
    2972             : 
    2973           9 :     CPLDebug("GEOCONCEPT", "SubType '%s.%s#%ld' added.", typName, subtypName,
    2974             :              id);
    2975             : 
    2976           9 :     return theSubType;
    2977             : } /* AddSubType_GCIO */
    2978             : 
    2979             : /* -------------------------------------------------------------------- */
    2980           0 : static void GCIOAPI_CALL _dropSubType_GCIO(GCSubType **theSubType)
    2981             : {
    2982             :     GCType *theClass;
    2983             :     int where;
    2984             : 
    2985           0 :     if (!theSubType || !(*theSubType))
    2986           0 :         return;
    2987           0 :     if (!(theClass = GetSubTypeType_GCIO(*theSubType)))
    2988           0 :         return;
    2989           0 :     if ((where = _findSubTypeByName_GCIO(
    2990           0 :              theClass, GetSubTypeName_GCIO(*theSubType))) == -1)
    2991             :     {
    2992           0 :         CPLError(CE_Failure, CPLE_AppDefined, "subtype %s does not exist.\n",
    2993           0 :                  GetSubTypeName_GCIO(*theSubType)
    2994           0 :                      ? GetSubTypeName_GCIO(*theSubType)
    2995             :                      : "''");
    2996           0 :         return;
    2997             :     }
    2998           0 :     CPLListRemove(GetTypeSubtypes_GCIO(theClass), where);
    2999           0 :     _DestroySubType_GCIO(theSubType);
    3000             : 
    3001           0 :     return;
    3002             : } /* _dropSubType_GCIO */
    3003             : 
    3004             : /* -------------------------------------------------------------------- */
    3005             : GCType GCIOAPI_CALL1(*)
    3006           9 :     AddType_GCIO(GCExportFileH *H, const char *typName, long id)
    3007             : {
    3008             :     GCType *theClass;
    3009             :     CPLList *L;
    3010             : 
    3011           9 :     if (_findTypeByName_GCIO(H, typName) != -1)
    3012             :     {
    3013           0 :         CPLError(CE_Failure, CPLE_AppDefined, "type %s already exists.\n",
    3014             :                  typName);
    3015           0 :         return NULL;
    3016             :     }
    3017             : 
    3018           9 :     if (!(theClass = _CreateType_GCIO(typName, id)))
    3019             :     {
    3020           0 :         return NULL;
    3021             :     }
    3022           9 :     if ((L = CPLListAppend(GetMetaTypes_GCIO(GetGCMeta_GCIO(H)), theClass)) ==
    3023             :         NULL)
    3024             :     {
    3025           0 :         _DestroyType_GCIO(&theClass);
    3026           0 :         CPLError(CE_Failure, CPLE_OutOfMemory,
    3027             :                  "failed to add a Geoconcept type for '%s#%ld'.\n", typName,
    3028             :                  id);
    3029           0 :         return NULL;
    3030             :     }
    3031           9 :     SetMetaTypes_GCIO(GetGCMeta_GCIO(H), L);
    3032             : 
    3033           9 :     CPLDebug("GEOCONCEPT", "Type '%s#%ld' added.", typName, id);
    3034             : 
    3035           9 :     return theClass;
    3036             : } /* AddType_GCIO */
    3037             : 
    3038             : /* -------------------------------------------------------------------- */
    3039           0 : static void GCIOAPI_CALL _dropType_GCIO(GCExportFileH *H, GCType **theClass)
    3040             : {
    3041             :     int where;
    3042             : 
    3043           0 :     if (!theClass || !(*theClass))
    3044           0 :         return;
    3045           0 :     if ((where = _findTypeByName_GCIO(H, GetTypeName_GCIO(*theClass))) == -1)
    3046             :     {
    3047           0 :         CPLError(CE_Failure, CPLE_AppDefined, "type %s does not exist.\n",
    3048           0 :                  GetTypeName_GCIO(*theClass) ? GetTypeName_GCIO(*theClass)
    3049             :                                              : "''");
    3050           0 :         return;
    3051             :     }
    3052           0 :     CPLListRemove(GetMetaTypes_GCIO(GetGCMeta_GCIO(H)), where);
    3053           0 :     _DestroyType_GCIO(theClass);
    3054             : 
    3055           0 :     return;
    3056             : } /* _dropType_GCIO */
    3057             : 
    3058             : /* -------------------------------------------------------------------- */
    3059             : GCField GCIOAPI_CALL1(*)
    3060           0 :     AddTypeField_GCIO(GCExportFileH *H, const char *typName,
    3061             :                       int where, /* -1 : in the end */
    3062             :                       const char *name, long id, GCTypeKind knd,
    3063             :                       const char *extra, const char *enums)
    3064             : {
    3065             :     int whereClass;
    3066             :     GCType *theClass;
    3067             :     GCField *theField;
    3068             :     CPLList *L;
    3069             :     const char *normName;
    3070             : 
    3071           0 :     if ((whereClass = _findTypeByName_GCIO(H, typName)) == -1)
    3072             :     {
    3073           0 :         CPLError(CE_Failure, CPLE_AppDefined,
    3074             :                  "failed to find a Geoconcept type for '%s@%s#%ld'.\n", typName,
    3075             :                  name, id);
    3076           0 :         return NULL;
    3077             :     }
    3078           0 :     theClass = _getType_GCIO(H, whereClass);
    3079           0 :     if (theClass == NULL)
    3080             :     {
    3081           0 :         return NULL;
    3082             :     }
    3083           0 :     normName = _NormalizeFieldName_GCIO(name);
    3084           0 :     if (_findFieldByName_GCIO(GetTypeFields_GCIO(theClass), normName) != -1)
    3085             :     {
    3086           0 :         CPLError(CE_Failure, CPLE_AppDefined,
    3087             :                  "field '%s@%s#%ld' already exists.\n", typName, name, id);
    3088           0 :         return NULL;
    3089             :     }
    3090             : 
    3091           0 :     if (!(theField = _CreateField_GCIO(normName, id, knd, extra, enums)))
    3092             :     {
    3093           0 :         return NULL;
    3094             :     }
    3095           0 :     if (where == -1 ||
    3096           0 :         (where == 0 && CPLListCount(GetTypeFields_GCIO(theClass)) == 0))
    3097             :     {
    3098           0 :         L = CPLListAppend(GetTypeFields_GCIO(theClass), theField);
    3099             :     }
    3100             :     else
    3101             :     {
    3102           0 :         L = CPLListInsert(GetTypeFields_GCIO(theClass), theField, where);
    3103             :     }
    3104           0 :     if (!L)
    3105             :     {
    3106           0 :         _DestroyField_GCIO(&theField);
    3107           0 :         CPLError(CE_Failure, CPLE_OutOfMemory,
    3108             :                  "failed to add a Geoconcept field for '%s@%s#%ld'.\n", typName,
    3109             :                  name, id);
    3110           0 :         return NULL;
    3111             :     }
    3112           0 :     SetTypeFields_GCIO(theClass, L);
    3113             : 
    3114           0 :     CPLDebug("GEOCONCEPT", "Field '%s@%s#%ld' added.", typName, name, id);
    3115             : 
    3116           0 :     return theField;
    3117             : } /* AddTypeField_GCIO */
    3118             : 
    3119             : /* -------------------------------------------------------------------- */
    3120             : GCField GCIOAPI_CALL1(*)
    3121          90 :     AddSubTypeField_GCIO(GCExportFileH *H, const char *typName,
    3122             :                          const char *subtypName,
    3123             :                          int where, /* -1 : in the end */
    3124             :                          const char *name, long id, GCTypeKind knd,
    3125             :                          const char *extra, const char *enums)
    3126             : {
    3127             :     int whereClass, whereSubType;
    3128             :     GCType *theClass;
    3129             :     GCSubType *theSubType;
    3130             :     GCField *theField;
    3131             :     CPLList *L;
    3132             :     const char *normName;
    3133             : 
    3134          90 :     if ((whereClass = _findTypeByName_GCIO(H, typName)) == -1)
    3135             :     {
    3136           0 :         CPLError(CE_Failure, CPLE_AppDefined,
    3137             :                  "failed to find a Geoconcept type for '%s.%s@%s#%ld'.\n",
    3138             :                  typName, subtypName, name, id);
    3139           0 :         return NULL;
    3140             :     }
    3141          90 :     theClass = _getType_GCIO(H, whereClass);
    3142             : 
    3143          90 :     if ((whereSubType = _findSubTypeByName_GCIO(theClass, subtypName)) == -1)
    3144             :     {
    3145           0 :         CPLError(CE_Failure, CPLE_AppDefined,
    3146             :                  "failed to find a Geoconcept subtype for '%s.%s@%s#%ld'.\n",
    3147             :                  typName, subtypName, name, id);
    3148           0 :         return NULL;
    3149             :     }
    3150          90 :     theSubType = _getSubType_GCIO(theClass, whereSubType);
    3151          90 :     if (theSubType == NULL)
    3152             :     {
    3153           0 :         return NULL;
    3154             :     }
    3155             : 
    3156          90 :     normName = _NormalizeFieldName_GCIO(name);
    3157          90 :     if (_findFieldByName_GCIO(GetSubTypeFields_GCIO(theSubType), normName) !=
    3158             :         -1)
    3159             :     {
    3160           0 :         CPLError(CE_Failure, CPLE_AppDefined,
    3161             :                  "field '%s.%s@%s#%ld' already exists.\n", typName, subtypName,
    3162             :                  name, id);
    3163           0 :         return NULL;
    3164             :     }
    3165             : 
    3166          90 :     if (!(theField = _CreateField_GCIO(normName, id, knd, extra, enums)))
    3167             :     {
    3168           0 :         return NULL;
    3169             :     }
    3170          90 :     if (where == -1 ||
    3171           0 :         (where == 0 && CPLListCount(GetSubTypeFields_GCIO(theSubType)) == 0))
    3172             :     {
    3173          87 :         L = CPLListAppend(GetSubTypeFields_GCIO(theSubType), theField);
    3174             :     }
    3175             :     else
    3176             :     {
    3177           3 :         L = CPLListInsert(GetSubTypeFields_GCIO(theSubType), theField, where);
    3178             :     }
    3179          90 :     if (!L)
    3180             :     {
    3181           0 :         _DestroyField_GCIO(&theField);
    3182           0 :         CPLError(CE_Failure, CPLE_OutOfMemory,
    3183             :                  "failed to add a Geoconcept field for '%s.%s@%s#%ld'.\n",
    3184             :                  typName, subtypName, name, id);
    3185           0 :         return NULL;
    3186             :     }
    3187          90 :     SetSubTypeFields_GCIO(theSubType, L);
    3188             : 
    3189          90 :     CPLDebug("GEOCONCEPT", "Field '%s.%s@%s#%ld' added.", typName, subtypName,
    3190             :              name, id);
    3191             : 
    3192          90 :     return theField;
    3193             : } /* AddSubTypeField_GCIO */
    3194             : 
    3195             : /* -------------------------------------------------------------------- */
    3196           0 : static OGRErr GCIOAPI_CALL _readConfigField_GCIO(GCExportFileH *hGCT)
    3197             : {
    3198             :     int bEOF;
    3199             :     char *k;
    3200           0 :     char n[kItemSize_GCIO] = {0};
    3201           0 :     char x[kExtraSize_GCIO] = {0};
    3202           0 :     char e[kExtraSize_GCIO] = {0};
    3203             :     const char *normName;
    3204             :     long id;
    3205             :     GCTypeKind knd;
    3206             :     CPLList *L;
    3207             :     GCField *theField;
    3208             : 
    3209           0 :     bEOF = 0;
    3210           0 :     n[0] = '\0';
    3211           0 :     x[0] = '\0';
    3212           0 :     e[0] = '\0';
    3213           0 :     id = UNDEFINEDID_GCIO;
    3214           0 :     knd = vUnknownItemType_GCIO;
    3215           0 :     theField = NULL;
    3216           0 :     while (_get_GCIO(hGCT) != (vsi_l_offset)EOF)
    3217             :     {
    3218           0 :         if ((enum _tIO_MetadataType_GCIO)GetGCWhatIs_GCIO(hGCT) ==
    3219             :             vComType_GCIO)
    3220             :         {
    3221           0 :             continue;
    3222             :         }
    3223             :         /* coverity[mixed_enums] */ /* FIXME ? */
    3224           0 :         if ((enum _tIO_MetadataType_GCIO)GetGCWhatIs_GCIO(hGCT) == vHeader_GCIO)
    3225             :         {
    3226           0 :             if (strstr(GetGCCache_GCIO(hGCT), kConfigEndField_GCIO) != NULL)
    3227             :             {
    3228           0 :                 bEOF = 1;
    3229           0 :                 if (n[0] == '\0' || id == UNDEFINEDID_GCIO ||
    3230             :                     knd == vUnknownItemType_GCIO)
    3231             :                 {
    3232           0 :                     CPLError(CE_Failure, CPLE_AppDefined, "Missing %s.\n",
    3233           0 :                              n[0] == '\0'             ? "Name"
    3234           0 :                              : id == UNDEFINEDID_GCIO ? "ID"
    3235           0 :                                                       : "Kind");
    3236           0 :                     goto onError;
    3237             :                 }
    3238           0 :                 normName = _NormalizeFieldName_GCIO(n);
    3239           0 :                 if (_findFieldByName_GCIO(
    3240           0 :                         GetMetaFields_GCIO(GetGCMeta_GCIO(hGCT)), normName) !=
    3241             :                     -1)
    3242             :                 {
    3243           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3244             :                              "field '@%s#%ld' already exists.\n", n, id);
    3245           0 :                     goto onError;
    3246             :                 }
    3247           0 :                 if (!(theField = _CreateField_GCIO(normName, id, knd, x, e)))
    3248             :                 {
    3249           0 :                     goto onError;
    3250             :                 }
    3251           0 :                 if ((L = CPLListAppend(GetMetaFields_GCIO(GetGCMeta_GCIO(hGCT)),
    3252             :                                        theField)) == NULL)
    3253             :                 {
    3254           0 :                     _DestroyField_GCIO(&theField);
    3255           0 :                     CPLError(
    3256             :                         CE_Failure, CPLE_OutOfMemory,
    3257             :                         "failed to add a Geoconcept field for '@%s#%ld'.\n", n,
    3258             :                         id);
    3259           0 :                     goto onError;
    3260             :                 }
    3261           0 :                 SetMetaFields_GCIO(GetGCMeta_GCIO(hGCT), L);
    3262           0 :                 break;
    3263             :             }
    3264             : 
    3265           0 :             if ((k = strstr(GetGCCache_GCIO(hGCT), kConfigName_GCIO)) != NULL)
    3266             :             {
    3267           0 :                 if (n[0] != '\0')
    3268             :                 {
    3269           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3270             :                              "Duplicate Name found : '%s'.\n",
    3271           0 :                              GetGCCache_GCIO(hGCT));
    3272           0 :                     goto onError;
    3273             :                 }
    3274           0 :                 if ((k = _getHeaderValue_GCIO(k)) == NULL)
    3275             :                 {
    3276           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3277             :                              "Invalid Name found : '%s'.\n",
    3278           0 :                              GetGCCache_GCIO(hGCT));
    3279           0 :                     goto onError;
    3280             :                 }
    3281           0 :                 strncpy(n, k, kItemSize_GCIO - 1);
    3282           0 :                 n[kItemSize_GCIO - 1] = '\0';
    3283             :             }
    3284           0 :             else if ((k = strstr(GetGCCache_GCIO(hGCT), kConfigID_GCIO)) !=
    3285             :                      NULL)
    3286             :             {
    3287           0 :                 if (id != UNDEFINEDID_GCIO)
    3288             :                 {
    3289           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3290             :                              "Duplicate ID found : '%s'.\n",
    3291           0 :                              GetGCCache_GCIO(hGCT));
    3292           0 :                     goto onError;
    3293             :                 }
    3294           0 :                 if ((k = _getHeaderValue_GCIO(k)) == NULL)
    3295             :                 {
    3296           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3297             :                              "Invalid ID found : '%s'.\n",
    3298           0 :                              GetGCCache_GCIO(hGCT));
    3299           0 :                     goto onError;
    3300             :                 }
    3301           0 :                 if (sscanf(k, "%ld", &id) != 1)
    3302             :                 {
    3303           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3304             :                              "Invalid ID found : '%s'.\n",
    3305           0 :                              GetGCCache_GCIO(hGCT));
    3306           0 :                     goto onError;
    3307             :                 }
    3308             :             }
    3309           0 :             else if ((k = strstr(GetGCCache_GCIO(hGCT), kConfigKind_GCIO)) !=
    3310             :                      NULL)
    3311             :             {
    3312           0 :                 if (knd != vUnknownItemType_GCIO)
    3313             :                 {
    3314           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3315             :                              "Duplicate Kind found : '%s'.\n",
    3316           0 :                              GetGCCache_GCIO(hGCT));
    3317           0 :                     goto onError;
    3318             :                 }
    3319           0 :                 if ((k = _getHeaderValue_GCIO(k)) == NULL)
    3320             :                 {
    3321           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3322             :                              "Invalid Kind found : '%s'.\n",
    3323           0 :                              GetGCCache_GCIO(hGCT));
    3324           0 :                     goto onError;
    3325             :                 }
    3326           0 :                 if ((knd = str2GCTypeKind_GCIO(k)) == vUnknownItemType_GCIO)
    3327             :                 {
    3328           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3329             :                              "Not supported Kind found : '%s'.\n",
    3330           0 :                              GetGCCache_GCIO(hGCT));
    3331           0 :                     goto onError;
    3332             :                 }
    3333             :             }
    3334           0 :             else if ((k = strstr(GetGCCache_GCIO(hGCT), kConfigExtra_GCIO)) !=
    3335           0 :                          NULL ||
    3336           0 :                      (k = strstr(GetGCCache_GCIO(hGCT),
    3337             :                                  kConfigExtraText_GCIO)) != NULL)
    3338             :             {
    3339           0 :                 if (x[0] != '\0')
    3340             :                 {
    3341           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3342             :                              "Duplicate Extra information found : '%s'.\n",
    3343           0 :                              GetGCCache_GCIO(hGCT));
    3344           0 :                     goto onError;
    3345             :                 }
    3346           0 :                 if ((k = _getHeaderValue_GCIO(k)) == NULL)
    3347             :                 {
    3348           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3349             :                              "Invalid Extra information found : '%s'.\n",
    3350           0 :                              GetGCCache_GCIO(hGCT));
    3351           0 :                     goto onError;
    3352             :                 }
    3353           0 :                 strncpy(x, k, kExtraSize_GCIO - 1);
    3354           0 :                 x[kExtraSize_GCIO - 1] = '\0';
    3355             :             }
    3356           0 :             else if ((k = strstr(GetGCCache_GCIO(hGCT), kConfigList_GCIO)) !=
    3357             :                      NULL)
    3358             :             {
    3359           0 :                 if (e[0] != '\0')
    3360             :                 {
    3361           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3362             :                              "Duplicate List found : '%s'.\n",
    3363           0 :                              GetGCCache_GCIO(hGCT));
    3364           0 :                     goto onError;
    3365             :                 }
    3366           0 :                 if ((k = _getHeaderValue_GCIO(k)) == NULL)
    3367             :                 {
    3368           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3369             :                              "Invalid List found : '%s'.\n",
    3370           0 :                              GetGCCache_GCIO(hGCT));
    3371           0 :                     goto onError;
    3372             :                 }
    3373           0 :                 strncpy(e, k, kExtraSize_GCIO - 1);
    3374           0 :                 e[kExtraSize_GCIO - 1] = '\0';
    3375             :             }
    3376             :             else
    3377             :             { /* Skipping ... */
    3378             :             }
    3379             : 
    3380           0 :             continue;
    3381             :         }
    3382           0 :     onError:
    3383           0 :         return OGRERR_CORRUPT_DATA;
    3384             :     }
    3385           0 :     if (bEOF != 1)
    3386             :     {
    3387           0 :         CPLError(CE_Failure, CPLE_AppDefined,
    3388             :                  "Geoconcept config field end block %s not found.\n",
    3389             :                  kConfigEndField_GCIO);
    3390           0 :         return OGRERR_CORRUPT_DATA;
    3391             :     }
    3392             : 
    3393           0 :     return OGRERR_NONE;
    3394             : } /* _readConfigField_GCIO */
    3395             : 
    3396             : /* -------------------------------------------------------------------- */
    3397           0 : static OGRErr GCIOAPI_CALL _readConfigFieldType_GCIO(GCExportFileH *hGCT,
    3398             :                                                      GCType *theClass)
    3399             : {
    3400             :     int bEOF;
    3401             :     char *k;
    3402           0 :     char n[kItemSize_GCIO] = {0};
    3403           0 :     char x[kExtraSize_GCIO] = {0};
    3404           0 :     char e[kExtraSize_GCIO] = {0};
    3405             :     long id;
    3406             :     GCTypeKind knd;
    3407             : 
    3408           0 :     bEOF = 0;
    3409           0 :     n[0] = '\0';
    3410           0 :     x[0] = '\0';
    3411           0 :     e[0] = '\0';
    3412           0 :     id = UNDEFINEDID_GCIO;
    3413           0 :     knd = vUnknownItemType_GCIO;
    3414           0 :     while (_get_GCIO(hGCT) != (vsi_l_offset)EOF)
    3415             :     {
    3416             :         /* TODO: Switch to C++ casts below. */
    3417           0 :         if ((enum _tIO_MetadataType_GCIO)GetGCWhatIs_GCIO(hGCT) ==
    3418             :             vComType_GCIO)
    3419             :         {
    3420           0 :             continue;
    3421             :         }
    3422             :         /* coverity[mixed_enums] */ /* FIXME ? */
    3423           0 :         if ((enum _tIO_MetadataType_GCIO)GetGCWhatIs_GCIO(hGCT) == vHeader_GCIO)
    3424             :         {
    3425           0 :             if (strstr(GetGCCache_GCIO(hGCT), kConfigEndField_GCIO) != NULL)
    3426             :             {
    3427           0 :                 bEOF = 1;
    3428           0 :                 if (n[0] == '\0' || id == UNDEFINEDID_GCIO ||
    3429             :                     knd == vUnknownItemType_GCIO)
    3430             :                 {
    3431           0 :                     CPLError(CE_Failure, CPLE_AppDefined, "Missing %s.\n",
    3432           0 :                              n[0] == '\0'             ? "Name"
    3433           0 :                              : id == UNDEFINEDID_GCIO ? "ID"
    3434           0 :                                                       : "Kind");
    3435           0 :                     goto onError;
    3436             :                 }
    3437           0 :                 if (AddTypeField_GCIO(hGCT, GetTypeName_GCIO(theClass), -1, n,
    3438             :                                       id, knd, x, e) == NULL)
    3439             :                 {
    3440           0 :                     goto onError;
    3441             :                 }
    3442           0 :                 break;
    3443             :             }
    3444             : 
    3445           0 :             if ((k = strstr(GetGCCache_GCIO(hGCT), kConfigName_GCIO)) != NULL)
    3446             :             {
    3447           0 :                 if (n[0] != '\0')
    3448             :                 {
    3449           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3450             :                              "Duplicate Name found : '%s'.\n",
    3451           0 :                              GetGCCache_GCIO(hGCT));
    3452           0 :                     goto onError;
    3453             :                 }
    3454           0 :                 if ((k = _getHeaderValue_GCIO(k)) == NULL)
    3455             :                 {
    3456           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3457             :                              "Invalid Name found : '%s'.\n",
    3458           0 :                              GetGCCache_GCIO(hGCT));
    3459           0 :                     goto onError;
    3460             :                 }
    3461           0 :                 strncpy(n, k, kItemSize_GCIO - 1);
    3462           0 :                 n[kItemSize_GCIO - 1] = '\0';
    3463             :             }
    3464           0 :             else if ((k = strstr(GetGCCache_GCIO(hGCT), kConfigID_GCIO)) !=
    3465             :                      NULL)
    3466             :             {
    3467           0 :                 if (id != UNDEFINEDID_GCIO)
    3468             :                 {
    3469           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3470             :                              "Duplicate ID found : '%s'.\n",
    3471           0 :                              GetGCCache_GCIO(hGCT));
    3472           0 :                     goto onError;
    3473             :                 }
    3474           0 :                 if ((k = _getHeaderValue_GCIO(k)) == NULL)
    3475             :                 {
    3476           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3477             :                              "Invalid ID found : '%s'.\n",
    3478           0 :                              GetGCCache_GCIO(hGCT));
    3479           0 :                     goto onError;
    3480             :                 }
    3481           0 :                 if (sscanf(k, "%ld", &id) != 1)
    3482             :                 {
    3483           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3484             :                              "Invalid ID found : '%s'.\n",
    3485           0 :                              GetGCCache_GCIO(hGCT));
    3486           0 :                     goto onError;
    3487             :                 }
    3488             :             }
    3489           0 :             else if ((k = strstr(GetGCCache_GCIO(hGCT), kConfigKind_GCIO)) !=
    3490             :                      NULL)
    3491             :             {
    3492           0 :                 if (knd != vUnknownItemType_GCIO)
    3493             :                 {
    3494           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3495             :                              "Duplicate Kind found : '%s'.\n",
    3496           0 :                              GetGCCache_GCIO(hGCT));
    3497           0 :                     goto onError;
    3498             :                 }
    3499           0 :                 if ((k = _getHeaderValue_GCIO(k)) == NULL)
    3500             :                 {
    3501           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3502             :                              "Invalid Kind found : '%s'.\n",
    3503           0 :                              GetGCCache_GCIO(hGCT));
    3504           0 :                     goto onError;
    3505             :                 }
    3506           0 :                 if ((knd = str2GCTypeKind_GCIO(k)) == vUnknownItemType_GCIO)
    3507             :                 {
    3508           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3509             :                              "Not supported Kind found : '%s'.\n",
    3510           0 :                              GetGCCache_GCIO(hGCT));
    3511           0 :                     goto onError;
    3512             :                 }
    3513             :             }
    3514           0 :             else if ((k = strstr(GetGCCache_GCIO(hGCT), kConfigExtra_GCIO)) !=
    3515           0 :                          NULL ||
    3516           0 :                      (k = strstr(GetGCCache_GCIO(hGCT),
    3517             :                                  kConfigExtraText_GCIO)) != NULL)
    3518             :             {
    3519           0 :                 if (x[0] != '\0')
    3520             :                 {
    3521           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3522             :                              "Duplicate Extra information found : '%s'.\n",
    3523           0 :                              GetGCCache_GCIO(hGCT));
    3524           0 :                     goto onError;
    3525             :                 }
    3526           0 :                 if ((k = _getHeaderValue_GCIO(k)) == NULL)
    3527             :                 {
    3528           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3529             :                              "Invalid extra information found : '%s'.\n",
    3530           0 :                              GetGCCache_GCIO(hGCT));
    3531           0 :                     goto onError;
    3532             :                 }
    3533           0 :                 strncpy(x, k, kExtraSize_GCIO - 1);
    3534           0 :                 x[kExtraSize_GCIO - 1] = '\0';
    3535             :             }
    3536           0 :             else if ((k = strstr(GetGCCache_GCIO(hGCT), kConfigList_GCIO)) !=
    3537             :                      NULL)
    3538             :             {
    3539           0 :                 if (e[0] != '\0')
    3540             :                 {
    3541           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3542             :                              "Duplicate List found : '%s'.\n",
    3543           0 :                              GetGCCache_GCIO(hGCT));
    3544           0 :                     goto onError;
    3545             :                 }
    3546           0 :                 if ((k = _getHeaderValue_GCIO(k)) == NULL)
    3547             :                 {
    3548           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3549             :                              "Invalid List found : '%s'.\n",
    3550           0 :                              GetGCCache_GCIO(hGCT));
    3551           0 :                     goto onError;
    3552             :                 }
    3553           0 :                 strncpy(e, k, kExtraSize_GCIO - 1);
    3554           0 :                 e[kExtraSize_GCIO - 1] = '\0';
    3555             :             }
    3556             :             else
    3557             :             { /* Skipping ... */
    3558             :             }
    3559             : 
    3560           0 :             continue;
    3561             :         }
    3562           0 :     onError:
    3563           0 :         return OGRERR_CORRUPT_DATA;
    3564             :     }
    3565           0 :     if (bEOF != 1)
    3566             :     {
    3567           0 :         CPLError(CE_Failure, CPLE_AppDefined,
    3568             :                  "Geoconcept config field end block %s not found.\n",
    3569             :                  kConfigEndField_GCIO);
    3570           0 :         return OGRERR_CORRUPT_DATA;
    3571             :     }
    3572             : 
    3573           0 :     return OGRERR_NONE;
    3574             : } /* _readConfigFieldType_GCIO */
    3575             : 
    3576             : /* -------------------------------------------------------------------- */
    3577           0 : static OGRErr GCIOAPI_CALL _readConfigFieldSubType_GCIO(GCExportFileH *hGCT,
    3578             :                                                         GCType *theClass,
    3579             :                                                         GCSubType *theSubType)
    3580             : {
    3581             :     int bEOF;
    3582             :     char *k;
    3583           0 :     char n[kItemSize_GCIO] = {0};
    3584           0 :     char x[kExtraSize_GCIO] = {0};
    3585           0 :     char e[kExtraSize_GCIO] = {0};
    3586             :     long id;
    3587             :     GCTypeKind knd;
    3588             : 
    3589           0 :     bEOF = 0;
    3590           0 :     n[0] = '\0';
    3591           0 :     x[0] = '\0';
    3592           0 :     e[0] = '\0';
    3593           0 :     id = UNDEFINEDID_GCIO;
    3594           0 :     knd = vUnknownItemType_GCIO;
    3595           0 :     while (_get_GCIO(hGCT) != (vsi_l_offset)EOF)
    3596             :     {
    3597           0 :         if ((enum _tIO_MetadataType_GCIO)GetGCWhatIs_GCIO(hGCT) ==
    3598             :             vComType_GCIO)
    3599             :         {
    3600           0 :             continue;
    3601             :         }
    3602             :         /* coverity[mixed_enums] */ /* FIXME ? */
    3603           0 :         if ((enum _tIO_MetadataType_GCIO)GetGCWhatIs_GCIO(hGCT) == vHeader_GCIO)
    3604             :         {
    3605           0 :             if (strstr(GetGCCache_GCIO(hGCT), kConfigEndField_GCIO) != NULL)
    3606             :             {
    3607           0 :                 bEOF = 1;
    3608           0 :                 if (n[0] == '\0' || id == UNDEFINEDID_GCIO ||
    3609             :                     knd == vUnknownItemType_GCIO)
    3610             :                 {
    3611           0 :                     CPLError(CE_Failure, CPLE_AppDefined, "Missing %s.\n",
    3612           0 :                              n[0] == '\0'             ? "Name"
    3613           0 :                              : id == UNDEFINEDID_GCIO ? "ID"
    3614           0 :                                                       : "Kind");
    3615           0 :                     goto onError;
    3616             :                 }
    3617           0 :                 if (AddSubTypeField_GCIO(hGCT, GetTypeName_GCIO(theClass),
    3618           0 :                                          GetSubTypeName_GCIO(theSubType), -1, n,
    3619             :                                          id, knd, x, e) == NULL)
    3620             :                 {
    3621           0 :                     goto onError;
    3622             :                 }
    3623           0 :                 break;
    3624             :             }
    3625             : 
    3626           0 :             if ((k = strstr(GetGCCache_GCIO(hGCT), kConfigName_GCIO)) != NULL)
    3627             :             {
    3628           0 :                 if (n[0] != '\0')
    3629             :                 {
    3630           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3631             :                              "Duplicate Name found : '%s'.\n",
    3632           0 :                              GetGCCache_GCIO(hGCT));
    3633           0 :                     goto onError;
    3634             :                 }
    3635           0 :                 if ((k = _getHeaderValue_GCIO(k)) == NULL)
    3636             :                 {
    3637           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3638             :                              "Invalid Name found : '%s'.\n",
    3639           0 :                              GetGCCache_GCIO(hGCT));
    3640           0 :                     goto onError;
    3641             :                 }
    3642           0 :                 strncpy(n, k, kItemSize_GCIO - 1);
    3643           0 :                 n[kItemSize_GCIO - 1] = '\0';
    3644             :             }
    3645           0 :             else if ((k = strstr(GetGCCache_GCIO(hGCT), kConfigID_GCIO)) !=
    3646             :                      NULL)
    3647             :             {
    3648           0 :                 if (id != UNDEFINEDID_GCIO)
    3649             :                 {
    3650           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3651             :                              "Duplicate ID found : '%s'.\n",
    3652           0 :                              GetGCCache_GCIO(hGCT));
    3653           0 :                     goto onError;
    3654             :                 }
    3655           0 :                 if ((k = _getHeaderValue_GCIO(k)) == NULL)
    3656             :                 {
    3657           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3658             :                              "Invalid ID found : '%s'.\n",
    3659           0 :                              GetGCCache_GCIO(hGCT));
    3660           0 :                     goto onError;
    3661             :                 }
    3662           0 :                 if (sscanf(k, "%ld", &id) != 1)
    3663             :                 {
    3664           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3665             :                              "Invalid ID found : '%s'.\n",
    3666           0 :                              GetGCCache_GCIO(hGCT));
    3667           0 :                     goto onError;
    3668             :                 }
    3669             :             }
    3670           0 :             else if ((k = strstr(GetGCCache_GCIO(hGCT), kConfigKind_GCIO)) !=
    3671             :                      NULL)
    3672             :             {
    3673           0 :                 if (knd != vUnknownItemType_GCIO)
    3674             :                 {
    3675           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3676             :                              "Duplicate Kind found : '%s'.\n",
    3677           0 :                              GetGCCache_GCIO(hGCT));
    3678           0 :                     goto onError;
    3679             :                 }
    3680           0 :                 if ((k = _getHeaderValue_GCIO(k)) == NULL)
    3681             :                 {
    3682           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3683             :                              "Invalid Kind found : '%s'.\n",
    3684           0 :                              GetGCCache_GCIO(hGCT));
    3685           0 :                     goto onError;
    3686             :                 }
    3687           0 :                 if ((knd = str2GCTypeKind_GCIO(k)) == vUnknownItemType_GCIO)
    3688             :                 {
    3689           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3690             :                              "Not supported Kind found : '%s'.\n",
    3691           0 :                              GetGCCache_GCIO(hGCT));
    3692           0 :                     goto onError;
    3693             :                 }
    3694             :             }
    3695           0 :             else if ((k = strstr(GetGCCache_GCIO(hGCT), kConfigExtra_GCIO)) !=
    3696           0 :                          NULL ||
    3697           0 :                      (k = strstr(GetGCCache_GCIO(hGCT),
    3698             :                                  kConfigExtraText_GCIO)) != NULL)
    3699             :             {
    3700           0 :                 if (x[0] != '\0')
    3701             :                 {
    3702           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3703             :                              "Duplicate Extra information found : '%s'.\n",
    3704           0 :                              GetGCCache_GCIO(hGCT));
    3705           0 :                     goto onError;
    3706             :                 }
    3707           0 :                 if ((k = _getHeaderValue_GCIO(k)) == NULL)
    3708             :                 {
    3709           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3710             :                              "Invalid extra information found : '%s'.\n",
    3711           0 :                              GetGCCache_GCIO(hGCT));
    3712           0 :                     goto onError;
    3713             :                 }
    3714           0 :                 strncpy(x, k, kExtraSize_GCIO - 1);
    3715           0 :                 x[kExtraSize_GCIO - 1] = '\0';
    3716             :             }
    3717           0 :             else if ((k = strstr(GetGCCache_GCIO(hGCT), kConfigList_GCIO)) !=
    3718             :                      NULL)
    3719             :             {
    3720           0 :                 if (e[0] != '\0')
    3721             :                 {
    3722           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3723             :                              "Duplicate List found : '%s'.\n",
    3724           0 :                              GetGCCache_GCIO(hGCT));
    3725           0 :                     goto onError;
    3726             :                 }
    3727           0 :                 if ((k = _getHeaderValue_GCIO(k)) == NULL)
    3728             :                 {
    3729           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3730             :                              "Invalid List found : '%s'.\n",
    3731           0 :                              GetGCCache_GCIO(hGCT));
    3732           0 :                     goto onError;
    3733             :                 }
    3734           0 :                 strncpy(e, k, kExtraSize_GCIO - 1);
    3735           0 :                 e[kExtraSize_GCIO - 1] = '\0';
    3736             :             }
    3737             :             else
    3738             :             { /* Skipping ... */
    3739             :             }
    3740             : 
    3741           0 :             continue;
    3742             :         }
    3743           0 :     onError:
    3744           0 :         return OGRERR_CORRUPT_DATA;
    3745             :     }
    3746           0 :     if (bEOF != 1)
    3747             :     {
    3748           0 :         CPLError(CE_Failure, CPLE_AppDefined,
    3749             :                  "Geoconcept config field end block %s not found.\n",
    3750             :                  kConfigEndField_GCIO);
    3751           0 :         return OGRERR_CORRUPT_DATA;
    3752             :     }
    3753             : 
    3754           0 :     return OGRERR_NONE;
    3755             : } /* _readConfigFieldSubType_GCIO */
    3756             : 
    3757             : /* -------------------------------------------------------------------- */
    3758           0 : static OGRErr GCIOAPI_CALL _readConfigSubTypeType_GCIO(GCExportFileH *hGCT,
    3759             :                                                        GCType *theClass)
    3760             : {
    3761             :     int eost, res;
    3762             :     char *k;
    3763           0 :     char n[kItemSize_GCIO] = {0};
    3764             :     long id;
    3765             :     GCTypeKind knd;
    3766             :     GCDim sys;
    3767             :     GCSubType *theSubType;
    3768             : 
    3769           0 :     eost = 0;
    3770           0 :     n[0] = '\0';
    3771           0 :     id = UNDEFINEDID_GCIO;
    3772           0 :     knd = vUnknownItemType_GCIO;
    3773           0 :     sys = v2D_GCIO;
    3774           0 :     theSubType = NULL;
    3775           0 :     while (_get_GCIO(hGCT) != (vsi_l_offset)EOF)
    3776             :     {
    3777           0 :         if ((enum _tIO_MetadataType_GCIO)GetGCWhatIs_GCIO(hGCT) ==
    3778             :             vComType_GCIO)
    3779             :         {
    3780           0 :             continue;
    3781             :         }
    3782             :         /* coverity[mixed_enums] */ /* FIXME ? */
    3783           0 :         if ((enum _tIO_MetadataType_GCIO)GetGCWhatIs_GCIO(hGCT) == vHeader_GCIO)
    3784             :         {
    3785           0 :             if (strstr(GetGCCache_GCIO(hGCT), kConfigEndSubType_GCIO) != NULL)
    3786             :             {
    3787           0 :                 eost = 1;
    3788           0 :                 break;
    3789             :             }
    3790           0 :             res = OGRERR_NONE;
    3791           0 :             if ((k = strstr(GetGCCache_GCIO(hGCT), kConfigName_GCIO)) != NULL)
    3792             :             {
    3793           0 :                 if (n[0] != '\0')
    3794             :                 {
    3795           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3796             :                              "Duplicate Name found : '%s'.\n",
    3797           0 :                              GetGCCache_GCIO(hGCT));
    3798           0 :                     goto onError;
    3799             :                 }
    3800           0 :                 if ((k = _getHeaderValue_GCIO(k)) == NULL)
    3801             :                 {
    3802           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3803             :                              "Invalid Name found : '%s'.\n",
    3804           0 :                              GetGCCache_GCIO(hGCT));
    3805           0 :                     goto onError;
    3806             :                 }
    3807           0 :                 strncpy(n, k, kItemSize_GCIO - 1);
    3808           0 :                 n[kItemSize_GCIO - 1] = '\0';
    3809             :             }
    3810           0 :             else if ((k = strstr(GetGCCache_GCIO(hGCT), kConfigID_GCIO)) !=
    3811             :                      NULL)
    3812             :             {
    3813           0 :                 if (id != UNDEFINEDID_GCIO)
    3814             :                 {
    3815           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3816             :                              "Duplicate ID found : '%s'.\n",
    3817           0 :                              GetGCCache_GCIO(hGCT));
    3818           0 :                     goto onError;
    3819             :                 }
    3820           0 :                 if ((k = _getHeaderValue_GCIO(k)) == NULL)
    3821             :                 {
    3822           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3823             :                              "Invalid ID found : '%s'.\n",
    3824           0 :                              GetGCCache_GCIO(hGCT));
    3825           0 :                     goto onError;
    3826             :                 }
    3827           0 :                 if (sscanf(k, "%ld", &id) != 1)
    3828             :                 {
    3829           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3830             :                              "Invalid ID found : '%s'.\n",
    3831           0 :                              GetGCCache_GCIO(hGCT));
    3832           0 :                     goto onError;
    3833             :                 }
    3834             :             }
    3835           0 :             else if ((k = strstr(GetGCCache_GCIO(hGCT), kConfigKind_GCIO)) !=
    3836             :                      NULL)
    3837             :             {
    3838           0 :                 if (knd != vUnknownItemType_GCIO)
    3839             :                 {
    3840           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3841             :                              "Duplicate Kind found : '%s'.\n",
    3842           0 :                              GetGCCache_GCIO(hGCT));
    3843           0 :                     goto onError;
    3844             :                 }
    3845           0 :                 if ((k = _getHeaderValue_GCIO(k)) == NULL)
    3846             :                 {
    3847           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3848             :                              "Invalid Kind found : '%s'.\n",
    3849           0 :                              GetGCCache_GCIO(hGCT));
    3850           0 :                     goto onError;
    3851             :                 }
    3852           0 :                 if ((knd = str2GCTypeKind_GCIO(k)) == vUnknownItemType_GCIO)
    3853             :                 {
    3854           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3855             :                              "Not supported Kind found : '%s'.\n",
    3856           0 :                              GetGCCache_GCIO(hGCT));
    3857           0 :                     goto onError;
    3858             :                 }
    3859             :             }
    3860           0 :             else if ((k = strstr(GetGCCache_GCIO(hGCT), kConfig3D_GCIO)) !=
    3861             :                      NULL)
    3862             :             {
    3863           0 :                 if (sys != vUnknown3D_GCIO && sys != v2D_GCIO)
    3864             :                 {
    3865           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3866             :                              "Duplicate Dimension found : '%s'.\n",
    3867           0 :                              GetGCCache_GCIO(hGCT));
    3868           0 :                     goto onError;
    3869             :                 }
    3870           0 :                 if ((k = _getHeaderValue_GCIO(k)) == NULL)
    3871             :                 {
    3872           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3873             :                              "Invalid Dimension found : '%s'.\n",
    3874           0 :                              GetGCCache_GCIO(hGCT));
    3875           0 :                     goto onError;
    3876             :                 }
    3877           0 :                 if ((sys = str2GCDim(k)) == vUnknown3D_GCIO)
    3878             :                 {
    3879           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3880             :                              "Not supported Dimension found : '%s'.\n",
    3881           0 :                              GetGCCache_GCIO(hGCT));
    3882           0 :                     goto onError;
    3883             :                 }
    3884             :             }
    3885           0 :             else if (strstr(GetGCCache_GCIO(hGCT), kConfigBeginField_GCIO) !=
    3886             :                      NULL)
    3887             :             {
    3888           0 :                 if (theSubType == NULL)
    3889             :                 {
    3890           0 :                     if (n[0] == '\0' || id == UNDEFINEDID_GCIO ||
    3891           0 :                         knd == vUnknownItemType_GCIO || sys == vUnknown3D_GCIO)
    3892             :                     {
    3893           0 :                         CPLError(CE_Failure, CPLE_AppDefined, "Missing %s.\n",
    3894           0 :                                  n[0] == '\0'                   ? "Name"
    3895           0 :                                  : id == UNDEFINEDID_GCIO       ? "ID"
    3896           0 :                                  : knd == vUnknownItemType_GCIO ? "Kind"
    3897           0 :                                                                 : "3D");
    3898           0 :                         goto onError;
    3899             :                     }
    3900           0 :                     if ((theSubType =
    3901           0 :                              AddSubType_GCIO(hGCT, GetTypeName_GCIO(theClass),
    3902             :                                              n, id, knd, sys)) == NULL)
    3903             :                     {
    3904           0 :                         goto onError;
    3905             :                     }
    3906             :                 }
    3907           0 :                 res = _readConfigFieldSubType_GCIO(hGCT, theClass, theSubType);
    3908             :             }
    3909             :             else
    3910             :             { /* Skipping ... */
    3911           0 :                 res = OGRERR_NONE;
    3912             :             }
    3913           0 :             if (res != OGRERR_NONE)
    3914             :             {
    3915           0 :                 goto onError;
    3916             :             }
    3917           0 :             continue;
    3918             :         }
    3919           0 :     onError:
    3920           0 :         if (theSubType)
    3921             :         {
    3922           0 :             _dropSubType_GCIO(&theSubType);
    3923             :         }
    3924           0 :         return OGRERR_CORRUPT_DATA;
    3925             :     }
    3926           0 :     if (eost != 1)
    3927             :     {
    3928           0 :         if (theSubType)
    3929             :         {
    3930           0 :             _dropSubType_GCIO(&theSubType);
    3931             :         }
    3932           0 :         CPLError(CE_Failure, CPLE_AppDefined,
    3933             :                  "Geoconcept config subtype end block %s not found.\n",
    3934             :                  kConfigEndSubType_GCIO);
    3935           0 :         return OGRERR_CORRUPT_DATA;
    3936             :     }
    3937             : 
    3938           0 :     return OGRERR_NONE;
    3939             : } /* _readConfigSubTypeType_GCIO */
    3940             : 
    3941             : /* -------------------------------------------------------------------- */
    3942           0 : static OGRErr GCIOAPI_CALL _readConfigType_GCIO(GCExportFileH *hGCT)
    3943             : {
    3944             :     int eot, res;
    3945             :     char *k;
    3946           0 :     char n[kItemSize_GCIO] = {0};
    3947             :     long id;
    3948             :     GCType *theClass;
    3949             : 
    3950           0 :     eot = 0;
    3951           0 :     n[0] = '\0';
    3952           0 :     id = UNDEFINEDID_GCIO;
    3953           0 :     theClass = NULL;
    3954           0 :     while (_get_GCIO(hGCT) != (vsi_l_offset)EOF)
    3955             :     {
    3956           0 :         if ((enum _tIO_MetadataType_GCIO)GetGCWhatIs_GCIO(hGCT) ==
    3957             :             vComType_GCIO)
    3958             :         {
    3959           0 :             continue;
    3960             :         }
    3961             :         /* coverity[mixed_enums] */ /* FIXME ? */
    3962           0 :         if ((enum _tIO_MetadataType_GCIO)GetGCWhatIs_GCIO(hGCT) == vHeader_GCIO)
    3963             :         {
    3964           0 :             if (strstr(GetGCCache_GCIO(hGCT), kConfigEndType_GCIO) != NULL)
    3965             :             {
    3966           0 :                 eot = 1;
    3967           0 :                 break;
    3968             :             }
    3969           0 :             res = OGRERR_NONE;
    3970           0 :             if ((k = strstr(GetGCCache_GCIO(hGCT), kConfigName_GCIO)) != NULL)
    3971             :             {
    3972           0 :                 if (n[0] != '\0')
    3973             :                 {
    3974           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3975             :                              "Duplicate Name found : '%s'.\n",
    3976           0 :                              GetGCCache_GCIO(hGCT));
    3977           0 :                     goto onError;
    3978             :                 }
    3979           0 :                 if ((k = _getHeaderValue_GCIO(k)) == NULL)
    3980             :                 {
    3981           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3982             :                              "Invalid Name found : '%s'.\n",
    3983           0 :                              GetGCCache_GCIO(hGCT));
    3984           0 :                     goto onError;
    3985             :                 }
    3986           0 :                 strncpy(n, k, kItemSize_GCIO - 1);
    3987           0 :                 n[kItemSize_GCIO - 1] = '\0';
    3988             :             }
    3989           0 :             else if ((k = strstr(GetGCCache_GCIO(hGCT), kConfigID_GCIO)) !=
    3990             :                      NULL)
    3991             :             {
    3992           0 :                 if (id != UNDEFINEDID_GCIO)
    3993             :                 {
    3994           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    3995             :                              "Duplicate ID found : '%s'.\n",
    3996           0 :                              GetGCCache_GCIO(hGCT));
    3997           0 :                     goto onError;
    3998             :                 }
    3999           0 :                 if ((k = _getHeaderValue_GCIO(k)) == NULL)
    4000             :                 {
    4001           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    4002             :                              "Invalid ID found : '%s'.\n",
    4003           0 :                              GetGCCache_GCIO(hGCT));
    4004           0 :                     goto onError;
    4005             :                 }
    4006           0 :                 if (sscanf(k, "%ld", &id) != 1)
    4007             :                 {
    4008           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    4009             :                              "Not supported ID found : '%s'.\n",
    4010           0 :                              GetGCCache_GCIO(hGCT));
    4011           0 :                     goto onError;
    4012             :                 }
    4013             :             }
    4014           0 :             else if (strstr(GetGCCache_GCIO(hGCT), kConfigBeginSubType_GCIO) !=
    4015             :                      NULL)
    4016             :             {
    4017           0 :                 if (theClass == NULL)
    4018             :                 {
    4019           0 :                     if (n[0] == '\0' || id == UNDEFINEDID_GCIO ||
    4020           0 :                         (theClass = AddType_GCIO(hGCT, n, id)) == NULL)
    4021             :                     {
    4022           0 :                         goto onError;
    4023             :                     }
    4024             :                 }
    4025           0 :                 res = _readConfigSubTypeType_GCIO(hGCT, theClass);
    4026             :             }
    4027           0 :             else if (strstr(GetGCCache_GCIO(hGCT), kConfigBeginField_GCIO) !=
    4028             :                      NULL)
    4029             :             {
    4030           0 :                 if (theClass == NULL)
    4031             :                 {
    4032           0 :                     if (n[0] == '\0' || id == UNDEFINEDID_GCIO ||
    4033           0 :                         (theClass = AddType_GCIO(hGCT, n, id)) == NULL)
    4034             :                     {
    4035           0 :                         goto onError;
    4036             :                     }
    4037             :                 }
    4038           0 :                 res = _readConfigFieldType_GCIO(hGCT, theClass);
    4039             :             }
    4040             :             else
    4041             :             { /* Skipping ... */
    4042           0 :                 res = OGRERR_NONE;
    4043             :             }
    4044           0 :             if (res != OGRERR_NONE)
    4045             :             {
    4046           0 :                 goto onError;
    4047             :             }
    4048           0 :             continue;
    4049             :         }
    4050           0 :     onError:
    4051           0 :         if (theClass)
    4052             :         {
    4053           0 :             _dropType_GCIO(hGCT, &theClass);
    4054             :         }
    4055           0 :         return OGRERR_CORRUPT_DATA;
    4056             :     }
    4057           0 :     if (eot != 1)
    4058             :     {
    4059           0 :         if (theClass)
    4060             :         {
    4061           0 :             _dropType_GCIO(hGCT, &theClass);
    4062             :         }
    4063           0 :         CPLError(CE_Failure, CPLE_AppDefined,
    4064             :                  "Geoconcept config type end block %s not found.\n",
    4065             :                  kConfigEndType_GCIO);
    4066           0 :         return OGRERR_CORRUPT_DATA;
    4067             :     }
    4068             : 
    4069           0 :     return OGRERR_NONE;
    4070             : } /* _readConfigType_GCIO */
    4071             : 
    4072             : /* -------------------------------------------------------------------- */
    4073           0 : static OGRErr GCIOAPI_CALL _readConfigMap_GCIO(GCExportFileH *hGCT)
    4074             : {
    4075             :     int eom;
    4076             :     char *k;
    4077             : 
    4078           0 :     eom = 0;
    4079           0 :     while (_get_GCIO(hGCT) != (vsi_l_offset)EOF)
    4080             :     {
    4081           0 :         if ((enum _tIO_MetadataType_GCIO)GetGCWhatIs_GCIO(hGCT) ==
    4082             :             vComType_GCIO)
    4083             :         {
    4084           0 :             continue;
    4085             :         }
    4086             :         /* coverity[mixed_enums] */ /* FIXME ? */
    4087           0 :         if ((enum _tIO_MetadataType_GCIO)GetGCWhatIs_GCIO(hGCT) == vHeader_GCIO)
    4088             :         {
    4089           0 :             if (strstr(GetGCCache_GCIO(hGCT), kConfigEndMap_GCIO) != NULL)
    4090             :             {
    4091           0 :                 eom = 1;
    4092           0 :                 break;
    4093             :             }
    4094             : 
    4095           0 :             if ((k = strstr(GetGCCache_GCIO(hGCT), kConfigUnit_GCIO)) != NULL &&
    4096           0 :                 strstr(GetGCCache_GCIO(hGCT), kConfigZUnit_GCIO) == NULL)
    4097             :             {
    4098           0 :                 if ((k = _getHeaderValue_GCIO(k)) == NULL)
    4099             :                 {
    4100           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    4101             :                              "Invalid Unit found : '%s'.\n",
    4102           0 :                              GetGCCache_GCIO(hGCT));
    4103           0 :                     goto onError;
    4104             :                 }
    4105           0 :                 SetMetaUnit_GCIO(GetGCMeta_GCIO(hGCT), k);
    4106             :             }
    4107           0 :             else if ((k = strstr(GetGCCache_GCIO(hGCT),
    4108           0 :                                  kConfigPrecision_GCIO)) != NULL &&
    4109           0 :                      strstr(GetGCCache_GCIO(hGCT), kConfigZPrecision_GCIO) ==
    4110             :                          NULL)
    4111             :             {
    4112             :                 double r;
    4113           0 :                 if ((k = _getHeaderValue_GCIO(k)) == NULL)
    4114             :                 {
    4115           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    4116             :                              "Invalid Precision found : '%s'.\n",
    4117           0 :                              GetGCCache_GCIO(hGCT));
    4118           0 :                     goto onError;
    4119             :                 }
    4120           0 :                 if (CPLsscanf(k, "%lf", &r) != 1)
    4121             :                 {
    4122           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    4123             :                              "Invalid Precision found : '%s'.\n",
    4124           0 :                              GetGCCache_GCIO(hGCT));
    4125           0 :                     goto onError;
    4126             :                 }
    4127           0 :                 SetMetaResolution_GCIO(GetGCMeta_GCIO(hGCT), r);
    4128             :             }
    4129             :             else
    4130             :             { /* Skipping ... */
    4131             :             }
    4132             : 
    4133           0 :             continue;
    4134             :         }
    4135           0 :     onError:
    4136           0 :         return OGRERR_CORRUPT_DATA;
    4137             :     }
    4138           0 :     if (eom != 1)
    4139             :     {
    4140           0 :         CPLError(CE_Failure, CPLE_AppDefined,
    4141             :                  "Geoconcept config map end block %s not found.\n",
    4142             :                  kConfigEndMap_GCIO);
    4143           0 :         return OGRERR_CORRUPT_DATA;
    4144             :     }
    4145             : 
    4146           0 :     return OGRERR_NONE;
    4147             : } /* _readConfigMap_GCIO */
    4148             : 
    4149             : /* -------------------------------------------------------------------- */
    4150           0 : GCExportFileMetadata GCIOAPI_CALL1(*) ReadConfig_GCIO(GCExportFileH *hGCT)
    4151             : {
    4152             :     int eoc, res, it, nt;
    4153             :     int i, n, il, nl, ll;
    4154             :     int is, ns;
    4155             :     char l[kExtraSize_GCIO];
    4156             :     const char *v;
    4157             :     GCField *theField;
    4158             :     GCSubType *theSubType;
    4159             :     GCType *theClass;
    4160             :     CPLList *e, *es, *et;
    4161             :     GCExportFileMetadata *Meta;
    4162             : 
    4163           0 :     eoc = 0;
    4164           0 :     if (_get_GCIO(hGCT) == (vsi_l_offset)EOF)
    4165             :     {
    4166           0 :         return NULL;
    4167             :     }
    4168           0 :     if ((enum _tIO_MetadataType_GCIO)GetGCWhatIs_GCIO(hGCT) != vHeader_GCIO &&
    4169           0 :         strstr(GetGCCache_GCIO(hGCT), kConfigBeginConfig_GCIO) == NULL)
    4170             :     {
    4171           0 :         CPLError(CE_Failure, CPLE_AppDefined,
    4172             :                  "Geoconcept config begin block %s not found.\n",
    4173             :                  kConfigBeginConfig_GCIO);
    4174           0 :         return NULL;
    4175             :     }
    4176           0 :     SetGCMeta_GCIO(hGCT, CreateHeader_GCIO());
    4177           0 :     if ((Meta = GetGCMeta_GCIO(hGCT)) == NULL)
    4178             :     {
    4179           0 :         return NULL;
    4180             :     }
    4181           0 :     while (_get_GCIO(hGCT) != (vsi_l_offset)EOF)
    4182             :     {
    4183           0 :         if ((enum _tIO_MetadataType_GCIO)GetGCWhatIs_GCIO(hGCT) ==
    4184             :             vComType_GCIO)
    4185             :         {
    4186           0 :             continue;
    4187             :         }
    4188             :         /* coverity[mixed_enums] */ /* FIXME ? */
    4189           0 :         if ((enum _tIO_MetadataType_GCIO)GetGCWhatIs_GCIO(hGCT) == vHeader_GCIO)
    4190             :         {
    4191           0 :             if (strstr(GetGCCache_GCIO(hGCT), kConfigEndConfig_GCIO) != NULL)
    4192             :             {
    4193           0 :                 eoc = 1;
    4194           0 :                 break;
    4195             :             }
    4196             : 
    4197           0 :             if (strstr(GetGCCache_GCIO(hGCT), kConfigBeginMap_GCIO) != NULL)
    4198             :             {
    4199           0 :                 res = _readConfigMap_GCIO(hGCT);
    4200             :             }
    4201           0 :             else if (strstr(GetGCCache_GCIO(hGCT), kConfigBeginType_GCIO) !=
    4202             :                      NULL)
    4203             :             {
    4204           0 :                 res = _readConfigType_GCIO(hGCT);
    4205             :             }
    4206           0 :             else if (strstr(GetGCCache_GCIO(hGCT), kConfigBeginField_GCIO) !=
    4207             :                      NULL)
    4208             :             {
    4209           0 :                 res = _readConfigField_GCIO(hGCT);
    4210             :             }
    4211             :             else
    4212             :             { /* Skipping : Version, Origin, ... */
    4213           0 :                 res = OGRERR_NONE;
    4214             :             }
    4215           0 :             if (res != OGRERR_NONE)
    4216             :             {
    4217           0 :                 goto onError;
    4218             :             }
    4219           0 :             continue;
    4220             :         }
    4221           0 :     onError:
    4222           0 :         DestroyHeader_GCIO(&(GetGCMeta_GCIO(hGCT)));
    4223           0 :         CPLError(CE_Failure, CPLE_AppDefined,
    4224             :                  "Geoconcept config syntax error at line %ld.\n",
    4225             :                  GetGCCurrentLinenum_GCIO(hGCT));
    4226           0 :         return NULL;
    4227             :     }
    4228           0 :     if (eoc != 1)
    4229             :     {
    4230           0 :         DestroyHeader_GCIO(&(GetGCMeta_GCIO(hGCT)));
    4231           0 :         CPLError(CE_Failure, CPLE_AppDefined,
    4232             :                  "Geoconcept config end block %s not found.\n",
    4233             :                  kConfigEndConfig_GCIO);
    4234           0 :         return NULL;
    4235             :     }
    4236             : 
    4237           0 :     if ((nt = CPLListCount(GetMetaTypes_GCIO(Meta))) == 0)
    4238             :     {
    4239           0 :         DestroyHeader_GCIO(&(GetGCMeta_GCIO(hGCT)));
    4240           0 :         CPLError(CE_Failure, CPLE_AppDefined, "No types found.\n");
    4241           0 :         return NULL;
    4242             :     }
    4243             :     /* for each general fields add it on top of types' fields list          */
    4244           0 :     if (GetMetaFields_GCIO(Meta))
    4245             :     {
    4246           0 :         if ((n = CPLListCount(GetMetaFields_GCIO(Meta))) > 0)
    4247             :         {
    4248           0 :             for (i = n - 1; i >= 0; i--)
    4249             :             {
    4250           0 :                 if ((e = CPLListGet(GetMetaFields_GCIO(Meta), i)))
    4251             :                 {
    4252           0 :                     if ((theField = (GCField *)CPLListGetData(e)))
    4253             :                     {
    4254           0 :                         l[0] = '\0';
    4255           0 :                         ll = 0;
    4256           0 :                         if ((nl = CSLCount(GetFieldList_GCIO(theField))) > 0)
    4257             :                         {
    4258           0 :                             for (il = 0; il < nl; il++)
    4259             :                             {
    4260           0 :                                 v = CSLGetField(GetFieldList_GCIO(theField),
    4261             :                                                 il);
    4262           0 :                                 snprintf(l + ll, kExtraSize_GCIO - ll - 1,
    4263             :                                          "%s;", v);
    4264           0 :                                 l[kExtraSize_GCIO - 1] = '\0';
    4265           0 :                                 ll += (int)strlen(v);
    4266             :                             }
    4267             :                         }
    4268           0 :                         for (it = 0; it < nt; it++)
    4269             :                         {
    4270           0 :                             if ((et = CPLListGet(GetMetaTypes_GCIO(Meta), it)))
    4271             :                             {
    4272           0 :                                 if ((theClass = (GCType *)CPLListGetData(et)))
    4273             :                                 {
    4274           0 :                                     if (AddTypeField_GCIO(
    4275           0 :                                             hGCT, GetTypeName_GCIO(theClass), 0,
    4276           0 :                                             GetFieldName_GCIO(theField),
    4277           0 :                                             GetFieldID_GCIO(theField),
    4278           0 :                                             GetFieldKind_GCIO(theField),
    4279           0 :                                             GetFieldExtra_GCIO(theField),
    4280             :                                             l) == NULL)
    4281             :                                     {
    4282           0 :                                         DestroyHeader_GCIO(
    4283             :                                             &(GetGCMeta_GCIO(hGCT)));
    4284           0 :                                         return NULL;
    4285             :                                     }
    4286             :                                 }
    4287             :                             }
    4288             :                         }
    4289             :                     }
    4290             :                 }
    4291             :             }
    4292           0 :             for (i = n - 1; i >= 0; i--)
    4293             :             {
    4294           0 :                 if ((e = CPLListGet(GetMetaFields_GCIO(Meta), i)))
    4295             :                 {
    4296           0 :                     if ((theField = (GCField *)CPLListGetData(e)))
    4297             :                     {
    4298           0 :                         _DestroyField_GCIO(&theField);
    4299             :                     }
    4300             :                 }
    4301             :             }
    4302             :         }
    4303           0 :         CPLListDestroy(GetMetaFields_GCIO(Meta));
    4304           0 :         SetMetaFields_GCIO(Meta, NULL);
    4305             :     }
    4306             : 
    4307             :     /* for each field of types add it on top of types' subtypes field list */
    4308           0 :     for (it = 0; it < nt; it++)
    4309             :     {
    4310           0 :         if ((et = CPLListGet(GetMetaTypes_GCIO(Meta), it)))
    4311             :         {
    4312           0 :             if ((theClass = (GCType *)CPLListGetData(et)))
    4313             :             {
    4314           0 :                 if ((ns = CPLListCount(GetTypeSubtypes_GCIO(theClass))) == 0)
    4315             :                 {
    4316           0 :                     CPLError(CE_Failure, CPLE_AppDefined,
    4317             :                              "No subtypes found for type %s.\n",
    4318             :                              GetTypeName_GCIO(theClass));
    4319           0 :                     DestroyHeader_GCIO(&(GetGCMeta_GCIO(hGCT)));
    4320           0 :                     return NULL;
    4321             :                 }
    4322           0 :                 for (is = 0; is < ns; is++)
    4323             :                 {
    4324           0 :                     if ((es = CPLListGet(GetTypeSubtypes_GCIO(theClass), is)))
    4325             :                     {
    4326           0 :                         if ((theSubType = (GCSubType *)CPLListGetData(es)))
    4327             :                         {
    4328           0 :                             if (_findFieldByName_GCIO(
    4329             :                                     GetTypeFields_GCIO(theClass),
    4330           0 :                                     kNbFields_GCIO) == -1 &&
    4331           0 :                                 _findFieldByName_GCIO(
    4332             :                                     GetSubTypeFields_GCIO(theSubType),
    4333             :                                     kNbFields_GCIO) == -1)
    4334             :                             {
    4335           0 :                                 if (AddSubTypeField_GCIO(
    4336           0 :                                         hGCT, GetTypeName_GCIO(theClass),
    4337           0 :                                         GetSubTypeName_GCIO(theSubType), 0,
    4338             :                                         kNbFields_GCIO, -9999L, vIntFld_GCIO,
    4339             :                                         NULL, NULL) == NULL)
    4340             :                                 {
    4341           0 :                                     DestroyHeader_GCIO(&(GetGCMeta_GCIO(hGCT)));
    4342           0 :                                     return NULL;
    4343             :                                 }
    4344             :                             }
    4345           0 :                             if ((n = CPLListCount(
    4346           0 :                                      GetTypeFields_GCIO(theClass))) > 0)
    4347             :                             {
    4348           0 :                                 for (i = n - 1; i >= 0; i--)
    4349             :                                 {
    4350           0 :                                     if ((e = CPLListGet(
    4351             :                                              GetTypeFields_GCIO(theClass), i)))
    4352             :                                     {
    4353           0 :                                         if ((theField =
    4354           0 :                                                  (GCField *)CPLListGetData(e)))
    4355             :                                         {
    4356           0 :                                             l[0] = '\0';
    4357           0 :                                             ll = 0;
    4358           0 :                                             if ((nl =
    4359           0 :                                                      CSLCount(GetFieldList_GCIO(
    4360             :                                                          theField))) > 0)
    4361             :                                             {
    4362           0 :                                                 for (il = 0; il < nl; il++)
    4363             :                                                 {
    4364           0 :                                                     v = CSLGetField(
    4365           0 :                                                         GetFieldList_GCIO(
    4366             :                                                             theField),
    4367             :                                                         il);
    4368           0 :                                                     snprintf(l + ll,
    4369             :                                                              kExtraSize_GCIO -
    4370           0 :                                                                  ll - 1,
    4371             :                                                              "%s;", v);
    4372           0 :                                                     l[kExtraSize_GCIO - 1] =
    4373             :                                                         '\0';
    4374           0 :                                                     ll += (int)strlen(v);
    4375             :                                                 }
    4376             :                                             }
    4377           0 :                                             if (AddSubTypeField_GCIO(
    4378             :                                                     hGCT,
    4379           0 :                                                     GetTypeName_GCIO(theClass),
    4380           0 :                                                     GetSubTypeName_GCIO(
    4381             :                                                         theSubType),
    4382             :                                                     0,
    4383           0 :                                                     GetFieldName_GCIO(theField),
    4384           0 :                                                     GetFieldID_GCIO(theField),
    4385           0 :                                                     GetFieldKind_GCIO(theField),
    4386           0 :                                                     GetFieldExtra_GCIO(
    4387             :                                                         theField),
    4388             :                                                     l) == NULL)
    4389             :                                             {
    4390           0 :                                                 DestroyHeader_GCIO(
    4391             :                                                     &(GetGCMeta_GCIO(hGCT)));
    4392           0 :                                                 return NULL;
    4393             :                                             }
    4394             :                                         }
    4395             :                                     }
    4396             :                                 }
    4397             :                             }
    4398             :                         }
    4399             :                     }
    4400             :                 }
    4401           0 :                 if ((n = CPLListCount(GetTypeFields_GCIO(theClass))) > 0)
    4402             :                 {
    4403           0 :                     for (i = n - 1; i >= 0; i--)
    4404             :                     {
    4405           0 :                         if ((e = CPLListGet(GetTypeFields_GCIO(theClass), i)))
    4406             :                         {
    4407           0 :                             if ((theField = (GCField *)CPLListGetData(e)))
    4408             :                             {
    4409           0 :                                 _DestroyField_GCIO(&theField);
    4410             :                             }
    4411             :                         }
    4412             :                     }
    4413             :                 }
    4414           0 :                 CPLListDestroy(GetTypeFields_GCIO(theClass));
    4415           0 :                 SetTypeFields_GCIO(theClass, NULL);
    4416             :             }
    4417             :         }
    4418             :     }
    4419             : 
    4420             :     /* let's reorder sub-types fields : */
    4421           0 :     for (it = 0; it < nt; it++)
    4422             :     {
    4423           0 :         if ((et = CPLListGet(GetMetaTypes_GCIO(Meta), it)))
    4424             :         {
    4425           0 :             if ((theClass = (GCType *)CPLListGetData(et)))
    4426             :             {
    4427           0 :                 ns = CPLListCount(GetTypeSubtypes_GCIO(theClass));
    4428           0 :                 for (is = 0; is < ns; is++)
    4429             :                 {
    4430           0 :                     if ((es = CPLListGet(GetTypeSubtypes_GCIO(theClass), is)))
    4431             :                     {
    4432           0 :                         if ((theSubType = (GCSubType *)CPLListGetData(es)))
    4433             :                         {
    4434           0 :                             CPLList *orderedFields = NULL;
    4435           0 :                             if ((n = CPLListCount(
    4436           0 :                                      GetSubTypeFields_GCIO(theSubType))) > 0)
    4437             :                             {
    4438           0 :                                 if ((i = _findFieldByName_GCIO(
    4439             :                                          GetSubTypeFields_GCIO(theSubType),
    4440             :                                          kIdentifier_GCIO)) != -1)
    4441             :                                 {
    4442           0 :                                     e = CPLListGet(
    4443             :                                         GetSubTypeFields_GCIO(theSubType), i);
    4444           0 :                                     if (!(orderedFields = CPLListAppend(
    4445             :                                               orderedFields,
    4446             :                                               (GCField *)CPLListGetData(e))))
    4447             :                                     {
    4448           0 :                                         CPLError(
    4449             :                                             CE_Failure, CPLE_OutOfMemory,
    4450             :                                             "failed to arrange Geoconcept "
    4451             :                                             "subtype '%s.%s' fields list.\n",
    4452             :                                             GetTypeName_GCIO(theClass),
    4453             :                                             GetSubTypeName_GCIO(theSubType));
    4454           0 :                                         DestroyHeader_GCIO(
    4455             :                                             &(GetGCMeta_GCIO(hGCT)));
    4456           0 :                                         return NULL;
    4457             :                                     }
    4458             :                                 }
    4459           0 :                                 if ((i = _findFieldByName_GCIO(
    4460             :                                          GetSubTypeFields_GCIO(theSubType),
    4461             :                                          kClass_GCIO)) != -1)
    4462             :                                 {
    4463           0 :                                     e = CPLListGet(
    4464             :                                         GetSubTypeFields_GCIO(theSubType), i);
    4465           0 :                                     if (!(orderedFields = CPLListAppend(
    4466             :                                               orderedFields,
    4467             :                                               (GCField *)CPLListGetData(e))))
    4468             :                                     {
    4469           0 :                                         CPLError(
    4470             :                                             CE_Failure, CPLE_OutOfMemory,
    4471             :                                             "failed to arrange Geoconcept "
    4472             :                                             "subtype '%s.%s' fields list.\n",
    4473             :                                             GetTypeName_GCIO(theClass),
    4474             :                                             GetSubTypeName_GCIO(theSubType));
    4475           0 :                                         DestroyHeader_GCIO(
    4476             :                                             &(GetGCMeta_GCIO(hGCT)));
    4477           0 :                                         return NULL;
    4478             :                                     }
    4479             :                                 }
    4480           0 :                                 if ((i = _findFieldByName_GCIO(
    4481             :                                          GetSubTypeFields_GCIO(theSubType),
    4482             :                                          kSubclass_GCIO)) != -1)
    4483             :                                 {
    4484           0 :                                     e = CPLListGet(
    4485             :                                         GetSubTypeFields_GCIO(theSubType), i);
    4486           0 :                                     if (!(orderedFields = CPLListAppend(
    4487             :                                               orderedFields,
    4488             :                                               (GCField *)CPLListGetData(e))))
    4489             :                                     {
    4490           0 :                                         CPLError(
    4491             :                                             CE_Failure, CPLE_OutOfMemory,
    4492             :                                             "failed to arrange Geoconcept "
    4493             :                                             "subtype '%s.%s' fields list.\n",
    4494             :                                             GetTypeName_GCIO(theClass),
    4495             :                                             GetSubTypeName_GCIO(theSubType));
    4496           0 :                                         DestroyHeader_GCIO(
    4497             :                                             &(GetGCMeta_GCIO(hGCT)));
    4498           0 :                                         return NULL;
    4499             :                                     }
    4500             :                                 }
    4501           0 :                                 if ((i = _findFieldByName_GCIO(
    4502             :                                          GetSubTypeFields_GCIO(theSubType),
    4503             :                                          kName_GCIO)) != -1)
    4504             :                                 {
    4505           0 :                                     e = CPLListGet(
    4506             :                                         GetSubTypeFields_GCIO(theSubType), i);
    4507           0 :                                     if (!(orderedFields = CPLListAppend(
    4508             :                                               orderedFields,
    4509             :                                               (GCField *)CPLListGetData(e))))
    4510             :                                     {
    4511           0 :                                         CPLError(
    4512             :                                             CE_Failure, CPLE_OutOfMemory,
    4513             :                                             "failed to arrange Geoconcept "
    4514             :                                             "subtype '%s.%s' fields list.\n",
    4515             :                                             GetTypeName_GCIO(theClass),
    4516             :                                             GetSubTypeName_GCIO(theSubType));
    4517           0 :                                         DestroyHeader_GCIO(
    4518             :                                             &(GetGCMeta_GCIO(hGCT)));
    4519           0 :                                         return NULL;
    4520             :                                     }
    4521             :                                 }
    4522           0 :                                 if ((i = _findFieldByName_GCIO(
    4523             :                                          GetSubTypeFields_GCIO(theSubType),
    4524             :                                          kNbFields_GCIO)) != -1)
    4525             :                                 {
    4526           0 :                                     e = CPLListGet(
    4527             :                                         GetSubTypeFields_GCIO(theSubType), i);
    4528           0 :                                     if (!(orderedFields = CPLListAppend(
    4529             :                                               orderedFields,
    4530             :                                               (GCField *)CPLListGetData(e))))
    4531             :                                     {
    4532           0 :                                         CPLError(
    4533             :                                             CE_Failure, CPLE_OutOfMemory,
    4534             :                                             "failed to arrange Geoconcept "
    4535             :                                             "subtype '%s.%s' fields list.\n",
    4536             :                                             GetTypeName_GCIO(theClass),
    4537             :                                             GetSubTypeName_GCIO(theSubType));
    4538           0 :                                         DestroyHeader_GCIO(
    4539             :                                             &(GetGCMeta_GCIO(hGCT)));
    4540           0 :                                         return NULL;
    4541             :                                     }
    4542             :                                 }
    4543           0 :                                 for (i = 0; i < n; i++)
    4544             :                                 {
    4545           0 :                                     e = CPLListGet(
    4546             :                                         GetSubTypeFields_GCIO(theSubType), i);
    4547           0 :                                     if (!IsPrivateField_GCIO(
    4548             :                                             (GCField *)CPLListGetData(e)))
    4549             :                                     {
    4550           0 :                                         if (!(orderedFields = CPLListAppend(
    4551             :                                                   orderedFields,
    4552             :                                                   (GCField *)CPLListGetData(
    4553             :                                                       e))))
    4554             :                                         {
    4555           0 :                                             CPLError(CE_Failure,
    4556             :                                                      CPLE_OutOfMemory,
    4557             :                                                      "failed to arrange "
    4558             :                                                      "Geoconcept subtype "
    4559             :                                                      "'%s.%s' fields list.\n",
    4560             :                                                      GetTypeName_GCIO(theClass),
    4561             :                                                      GetSubTypeName_GCIO(
    4562             :                                                          theSubType));
    4563           0 :                                             DestroyHeader_GCIO(
    4564             :                                                 &(GetGCMeta_GCIO(hGCT)));
    4565           0 :                                             return NULL;
    4566             :                                         }
    4567             :                                     }
    4568             :                                 }
    4569           0 :                                 if ((i = _findFieldByName_GCIO(
    4570             :                                          GetSubTypeFields_GCIO(theSubType),
    4571             :                                          kX_GCIO)) != -1)
    4572             :                                 {
    4573           0 :                                     e = CPLListGet(
    4574             :                                         GetSubTypeFields_GCIO(theSubType), i);
    4575           0 :                                     if (!(orderedFields = CPLListAppend(
    4576             :                                               orderedFields,
    4577             :                                               (GCField *)CPLListGetData(e))))
    4578             :                                     {
    4579           0 :                                         CPLError(
    4580             :                                             CE_Failure, CPLE_OutOfMemory,
    4581             :                                             "failed to arrange Geoconcept "
    4582             :                                             "subtype '%s.%s' fields list.\n",
    4583             :                                             GetTypeName_GCIO(theClass),
    4584             :                                             GetSubTypeName_GCIO(theSubType));
    4585           0 :                                         DestroyHeader_GCIO(
    4586             :                                             &(GetGCMeta_GCIO(hGCT)));
    4587           0 :                                         return NULL;
    4588             :                                     }
    4589             :                                 }
    4590           0 :                                 if ((i = _findFieldByName_GCIO(
    4591             :                                          GetSubTypeFields_GCIO(theSubType),
    4592             :                                          kY_GCIO)) != -1)
    4593             :                                 {
    4594           0 :                                     e = CPLListGet(
    4595             :                                         GetSubTypeFields_GCIO(theSubType), i);
    4596           0 :                                     if (!(orderedFields = CPLListAppend(
    4597             :                                               orderedFields,
    4598             :                                               (GCField *)CPLListGetData(e))))
    4599             :                                     {
    4600           0 :                                         CPLError(
    4601             :                                             CE_Failure, CPLE_OutOfMemory,
    4602             :                                             "failed to arrange Geoconcept "
    4603             :                                             "subtype '%s.%s' fields list.\n",
    4604             :                                             GetTypeName_GCIO(theClass),
    4605             :                                             GetSubTypeName_GCIO(theSubType));
    4606           0 :                                         DestroyHeader_GCIO(
    4607             :                                             &(GetGCMeta_GCIO(hGCT)));
    4608           0 :                                         return NULL;
    4609             :                                     }
    4610             :                                 }
    4611           0 :                                 if ((i = _findFieldByName_GCIO(
    4612             :                                          GetSubTypeFields_GCIO(theSubType),
    4613             :                                          kXP_GCIO)) != -1)
    4614             :                                 {
    4615           0 :                                     e = CPLListGet(
    4616             :                                         GetSubTypeFields_GCIO(theSubType), i);
    4617           0 :                                     if (!(orderedFields = CPLListAppend(
    4618             :                                               orderedFields,
    4619             :                                               (GCField *)CPLListGetData(e))))
    4620             :                                     {
    4621           0 :                                         CPLError(
    4622             :                                             CE_Failure, CPLE_OutOfMemory,
    4623             :                                             "failed to arrange Geoconcept "
    4624             :                                             "subtype '%s.%s' fields list.\n",
    4625             :                                             GetTypeName_GCIO(theClass),
    4626             :                                             GetSubTypeName_GCIO(theSubType));
    4627           0 :                                         DestroyHeader_GCIO(
    4628             :                                             &(GetGCMeta_GCIO(hGCT)));
    4629           0 :                                         return NULL;
    4630             :                                     }
    4631             :                                 }
    4632           0 :                                 if ((i = _findFieldByName_GCIO(
    4633             :                                          GetSubTypeFields_GCIO(theSubType),
    4634             :                                          kYP_GCIO)) != -1)
    4635             :                                 {
    4636           0 :                                     e = CPLListGet(
    4637             :                                         GetSubTypeFields_GCIO(theSubType), i);
    4638           0 :                                     if (!(orderedFields = CPLListAppend(
    4639             :                                               orderedFields,
    4640             :                                               (GCField *)CPLListGetData(e))))
    4641             :                                     {
    4642           0 :                                         CPLError(
    4643             :                                             CE_Failure, CPLE_OutOfMemory,
    4644             :                                             "failed to arrange Geoconcept "
    4645             :                                             "subtype '%s.%s' fields list.\n",
    4646             :                                             GetTypeName_GCIO(theClass),
    4647             :                                             GetSubTypeName_GCIO(theSubType));
    4648           0 :                                         DestroyHeader_GCIO(
    4649             :                                             &(GetGCMeta_GCIO(hGCT)));
    4650           0 :                                         return NULL;
    4651             :                                     }
    4652             :                                 }
    4653           0 :                                 if ((i = _findFieldByName_GCIO(
    4654             :                                          GetSubTypeFields_GCIO(theSubType),
    4655             :                                          kGraphics_GCIO)) != -1)
    4656             :                                 {
    4657           0 :                                     e = CPLListGet(
    4658             :                                         GetSubTypeFields_GCIO(theSubType), i);
    4659           0 :                                     if (!(orderedFields = CPLListAppend(
    4660             :                                               orderedFields,
    4661             :                                               (GCField *)CPLListGetData(e))))
    4662             :                                     {
    4663           0 :                                         CPLError(
    4664             :                                             CE_Failure, CPLE_OutOfMemory,
    4665             :                                             "failed to arrange Geoconcept "
    4666             :                                             "subtype '%s.%s' fields list.\n",
    4667             :                                             GetTypeName_GCIO(theClass),
    4668             :                                             GetSubTypeName_GCIO(theSubType));
    4669           0 :                                         DestroyHeader_GCIO(
    4670             :                                             &(GetGCMeta_GCIO(hGCT)));
    4671           0 :                                         return NULL;
    4672             :                                     }
    4673             :                                 }
    4674           0 :                                 if ((i = _findFieldByName_GCIO(
    4675             :                                          GetSubTypeFields_GCIO(theSubType),
    4676             :                                          kAngle_GCIO)) != -1)
    4677             :                                 {
    4678           0 :                                     e = CPLListGet(
    4679             :                                         GetSubTypeFields_GCIO(theSubType), i);
    4680           0 :                                     if (!(orderedFields = CPLListAppend(
    4681             :                                               orderedFields,
    4682             :                                               (GCField *)CPLListGetData(e))))
    4683             :                                     {
    4684           0 :                                         CPLError(
    4685             :                                             CE_Failure, CPLE_OutOfMemory,
    4686             :                                             "failed to arrange Geoconcept "
    4687             :                                             "subtype '%s.%s' fields list.\n",
    4688             :                                             GetTypeName_GCIO(theClass),
    4689             :                                             GetSubTypeName_GCIO(theSubType));
    4690           0 :                                         DestroyHeader_GCIO(
    4691             :                                             &(GetGCMeta_GCIO(hGCT)));
    4692           0 :                                         return NULL;
    4693             :                                     }
    4694             :                                 }
    4695           0 :                                 CPLListDestroy(
    4696             :                                     GetSubTypeFields_GCIO(theSubType));
    4697           0 :                                 SetSubTypeFields_GCIO(theSubType,
    4698             :                                                       orderedFields);
    4699             :                             }
    4700             :                         }
    4701             :                     }
    4702             :                 }
    4703             :             }
    4704             :         }
    4705             :     }
    4706             : 
    4707           0 :     CPLDebug("GEOCONCEPT",
    4708             :              "Metadata = (\n"
    4709             :              "  nb Types : %d\n"
    4710             :              "  Charset : %s\n"
    4711             :              "  Delimiter : 0x%x\n"
    4712             :              "  Unit : %s\n"
    4713             :              "  Resolution : %g\n"
    4714             :              "  Quoted-Text : %s\n"
    4715             :              "  Format : %s\n"
    4716             :              "  CoordSystemID : %d; TimeZoneValue : %d\n"
    4717             :              ")",
    4718           0 :              CPLListCount(GetMetaTypes_GCIO(Meta)),
    4719             :              GCCharset2str_GCIO(GetMetaCharset_GCIO(Meta)),
    4720           0 :              GetMetaDelimiter_GCIO(Meta), GetMetaUnit_GCIO(Meta),
    4721             :              GetMetaResolution_GCIO(Meta),
    4722           0 :              GetMetaQuotedText_GCIO(Meta) ? "yes" : "no",
    4723           0 :              GetMetaFormat_GCIO(Meta) == 1 ? "relative" : "absolute",
    4724           0 :              GetMetaSysCoord_GCIO(Meta)
    4725           0 :                  ? GetSysCoordSystemID_GCSRS(GetMetaSysCoord_GCIO(Meta))
    4726             :                  : -1,
    4727           0 :              GetMetaSysCoord_GCIO(Meta)
    4728           0 :                  ? GetSysCoordTimeZone_GCSRS(GetMetaSysCoord_GCIO(Meta))
    4729             :                  : -1);
    4730             : 
    4731           0 :     return Meta;
    4732             : } /* ReadConfig_GCIO */
    4733             : 
    4734             : /* -------------------------------------------------------------------- */
    4735             : static VSILFILE GCIOAPI_CALL1(*)
    4736           1 :     _writeFieldsPragma_GCIO(GCSubType *theSubType, VSILFILE *gc, char delim)
    4737             : {
    4738             :     int nF, iF;
    4739             :     GCField *theField;
    4740             :     CPLList *e;
    4741             : 
    4742           1 :     VSIFPrintfL(
    4743             :         gc, "%s%s Class=%s;Subclass=%s;Kind=%d;Fields=", kPragma_GCIO,
    4744           1 :         kMetadataFIELDS_GCIO, GetTypeName_GCIO(GetSubTypeType_GCIO(theSubType)),
    4745           1 :         GetSubTypeName_GCIO(theSubType), (int)GetSubTypeKind_GCIO(theSubType));
    4746           1 :     if ((nF = CPLListCount(GetSubTypeFields_GCIO(theSubType))) > 0)
    4747             :     {
    4748          11 :         for (iF = 0; iF < nF; iF++)
    4749             :         {
    4750          10 :             if ((e = CPLListGet(GetSubTypeFields_GCIO(theSubType), iF)))
    4751             :             {
    4752          10 :                 if ((theField = (GCField *)CPLListGetData(e)))
    4753             :                 {
    4754          10 :                     if (iF > 0)
    4755           9 :                         VSIFPrintfL(gc, "%c", delim);
    4756          10 :                     if (IsPrivateField_GCIO(theField))
    4757             :                     {
    4758           7 :                         VSIFPrintfL(gc, "%s%s", kPrivate_GCIO,
    4759           7 :                                     GetFieldName_GCIO(theField) + 1);
    4760             :                     }
    4761             :                     else
    4762             :                     {
    4763           3 :                         VSIFPrintfL(gc, "%s%s", kPublic_GCIO,
    4764             :                                     GetFieldName_GCIO(theField));
    4765             :                     }
    4766             :                 }
    4767             :             }
    4768             :         }
    4769             :     }
    4770           1 :     VSIFPrintfL(gc, "\n");
    4771           1 :     SetSubTypeHeaderWritten_GCIO(theSubType, TRUE);
    4772             : 
    4773           1 :     return gc;
    4774             : } /* _writeFieldsPragma_GCIO */
    4775             : 
    4776             : /* -------------------------------------------------------------------- */
    4777           1 : GCExportFileH GCIOAPI_CALL1(*) WriteHeader_GCIO(GCExportFileH *H)
    4778             : {
    4779             :     GCExportFileMetadata *Meta;
    4780             :     int nT, iT, nS, iS;
    4781             :     GCSubType *theSubType;
    4782             :     GCType *theClass;
    4783             :     CPLList *e;
    4784             :     VSILFILE *gc;
    4785             : 
    4786             :     /* FIXME : howto change default values ?                              */
    4787             :     /*         there seems to be no ways in Geoconcept to change them ... */
    4788           1 :     Meta = GetGCMeta_GCIO(H);
    4789           1 :     gc = GetGCHandle_GCIO(H);
    4790           1 :     if (GetMetaVersion_GCIO(Meta))
    4791             :     {
    4792           0 :         VSIFPrintfL(gc, "%s%s %s\n", kPragma_GCIO, kMetadataVERSION_GCIO,
    4793             :                     GetMetaVersion_GCIO(Meta));
    4794             :     }
    4795           1 :     VSIFPrintfL(gc, "%s%s \"%s\"\n", kPragma_GCIO, kMetadataDELIMITER_GCIO,
    4796           1 :                 _metaDelimiter2str_GCIO(GetMetaDelimiter_GCIO(Meta)));
    4797           1 :     VSIFPrintfL(gc, "%s%s \"%s\"\n", kPragma_GCIO, kMetadataQUOTEDTEXT_GCIO,
    4798           1 :                 GetMetaQuotedText_GCIO(Meta) ? "yes" : "no");
    4799           1 :     VSIFPrintfL(gc, "%s%s %s\n", kPragma_GCIO, kMetadataCHARSET_GCIO,
    4800             :                 GCCharset2str_GCIO(GetMetaCharset_GCIO(Meta)));
    4801           1 :     if (strcmp(GetMetaUnit_GCIO(Meta), "deg") == 0 ||
    4802           1 :         strcmp(GetMetaUnit_GCIO(Meta), "deg.min") == 0 ||
    4803           1 :         strcmp(GetMetaUnit_GCIO(Meta), "rad") == 0 ||
    4804           1 :         strcmp(GetMetaUnit_GCIO(Meta), "gr") == 0)
    4805             :     {
    4806           0 :         VSIFPrintfL(gc, "%s%s Angle:%s\n", kPragma_GCIO, kMetadataUNIT_GCIO,
    4807           0 :                     GetMetaUnit_GCIO(Meta));
    4808             :     }
    4809             :     else
    4810             :     {
    4811           1 :         VSIFPrintfL(gc, "%s%s Distance:%s\n", kPragma_GCIO, kMetadataUNIT_GCIO,
    4812           1 :                     GetMetaUnit_GCIO(Meta));
    4813             :     }
    4814           1 :     VSIFPrintfL(gc, "%s%s %d\n", kPragma_GCIO, kMetadataFORMAT_GCIO,
    4815             :                 GetMetaFormat_GCIO(Meta));
    4816           1 :     if (GetMetaSysCoord_GCIO(Meta))
    4817             :     {
    4818           1 :         VSIFPrintfL(gc, "%s%s {Type: %d}", kPragma_GCIO, kMetadataSYSCOORD_GCIO,
    4819           1 :                     GetSysCoordSystemID_GCSRS(GetMetaSysCoord_GCIO(Meta)));
    4820           1 :         if (GetSysCoordTimeZone_GCSRS(GetMetaSysCoord_GCIO(Meta)) != -1)
    4821             :         {
    4822           0 :             VSIFPrintfL(gc, ";{TimeZone: %d}",
    4823           0 :                         GetSysCoordTimeZone_GCSRS(GetMetaSysCoord_GCIO(Meta)));
    4824             :         }
    4825             :     }
    4826             :     else
    4827             :     {
    4828           0 :         VSIFPrintfL(gc, "%s%s {Type: -1}", kPragma_GCIO,
    4829             :                     kMetadataSYSCOORD_GCIO);
    4830             :     }
    4831           1 :     VSIFPrintfL(gc, "\n");
    4832             : 
    4833           1 :     if ((nT = CPLListCount(GetMetaTypes_GCIO(Meta))) > 0)
    4834             :     {
    4835           2 :         for (iT = 0; iT < nT; iT++)
    4836             :         {
    4837           1 :             if ((e = CPLListGet(GetMetaTypes_GCIO(Meta), iT)))
    4838             :             {
    4839           1 :                 if ((theClass = (GCType *)CPLListGetData(e)))
    4840             :                 {
    4841           1 :                     if ((nS = CPLListCount(GetTypeSubtypes_GCIO(theClass))) > 0)
    4842             :                     {
    4843           2 :                         for (iS = 0; iS < nS; iS++)
    4844             :                         {
    4845           1 :                             if ((e = CPLListGet(GetTypeSubtypes_GCIO(theClass),
    4846             :                                                 iS)))
    4847             :                             {
    4848           1 :                                 if ((theSubType =
    4849           1 :                                          (GCSubType *)CPLListGetData(e)) &&
    4850           1 :                                     !IsSubTypeHeaderWritten_GCIO(theSubType))
    4851             :                                 {
    4852           1 :                                     if (!_writeFieldsPragma_GCIO(
    4853             :                                             theSubType, gc,
    4854           1 :                                             GetMetaDelimiter_GCIO(Meta)))
    4855             :                                     {
    4856           0 :                                         return NULL;
    4857             :                                     }
    4858             :                                 }
    4859             :                             }
    4860             :                         }
    4861             :                     }
    4862             :                 }
    4863             :             }
    4864             :         }
    4865             :     }
    4866             : 
    4867           1 :     return H;
    4868             : } /* WriteHeader_GCIO */
    4869             : 
    4870             : /* -------------------------------------------------------------------- */
    4871           9 : GCExportFileMetadata GCIOAPI_CALL1(*) ReadHeader_GCIO(GCExportFileH *hGXT)
    4872             : {
    4873             :     GCExportFileMetadata *Meta;
    4874             : 
    4875           9 :     if (_get_GCIO(hGXT) == (vsi_l_offset)EOF)
    4876             :     {
    4877           0 :         return NULL;
    4878             :     }
    4879           9 :     if ((enum _tIO_MetadataType_GCIO)GetGCWhatIs_GCIO(hGXT) != vPragma_GCIO)
    4880             :     {
    4881           1 :         CPLDebug("GEOCONCEPT",
    4882             :                  "Geoconcept export badly formatted :"
    4883             :                  "%s expected.",
    4884             :                  kPragma_GCIO);
    4885           1 :         return NULL;
    4886             :     }
    4887           8 :     SetGCMeta_GCIO(hGXT, CreateHeader_GCIO());
    4888           8 :     if ((Meta = GetGCMeta_GCIO(hGXT)) == NULL)
    4889             :     {
    4890           0 :         return NULL;
    4891             :     }
    4892           8 :     SetMetaExtent_GCIO(
    4893             :         Meta, CreateExtent_GCIO(HUGE_VAL, HUGE_VAL, -HUGE_VAL, -HUGE_VAL));
    4894          79 :     while (_get_GCIO(hGXT) != (vsi_l_offset)EOF)
    4895             :     {
    4896          71 :         if ((enum _tIO_MetadataType_GCIO)GetGCWhatIs_GCIO(hGXT) ==
    4897             :             vComType_GCIO)
    4898             :         {
    4899           0 :             continue;
    4900             :         }
    4901             :         /* coverity[mixed_enums] */ /* FIXME ? */
    4902          71 :         if ((enum _tIO_MetadataType_GCIO)GetGCWhatIs_GCIO(hGXT) == vPragma_GCIO)
    4903             :         {
    4904             :             /* try config header first ... */
    4905          48 :             if (!_parsePragma_GCIO(hGXT))
    4906             :             {
    4907           0 :                 return NULL;
    4908             :             }
    4909             :             /* in case of Memo read, we try parsing an object ... */
    4910          48 :             if (GetGCStatus_GCIO(hGXT) != vMemoStatus_GCIO)
    4911             :             {
    4912          48 :                 continue;
    4913             :             }
    4914             :         }
    4915             :         /* then object ... */
    4916          23 :         if (!_parseObject_GCIO(hGXT))
    4917             :         {
    4918           0 :             return NULL;
    4919             :         }
    4920             :     }
    4921           8 :     if (CPLListCount(GetMetaTypes_GCIO(Meta)) == 0)
    4922             :     {
    4923           0 :         DestroyHeader_GCIO(&(GetGCMeta_GCIO(hGXT)));
    4924           0 :         CPLError(CE_Failure, CPLE_AppDefined,
    4925             :                  "Geoconcept export syntax error at line %ld.\n",
    4926             :                  GetGCCurrentLinenum_GCIO(hGXT));
    4927           0 :         return NULL;
    4928             :     }
    4929             : 
    4930           8 :     Rewind_GCIO(hGXT, NULL);
    4931             : 
    4932          24 :     CPLDebug("GEOCONCEPT",
    4933             :              "Metadata = (\n"
    4934             :              "  nb Types : %d\n"
    4935             :              "  Charset : %s\n"
    4936             :              "  Delimiter : 0x%x\n"
    4937             :              "  Unit : %s\n"
    4938             :              "  Resolution : %g\n"
    4939             :              "  Quoted-Text : %s\n"
    4940             :              "  Format : %s\n"
    4941             :              "  CoordSystemID : %d; TimeZoneValue : %d\n"
    4942             :              ")",
    4943           8 :              CPLListCount(GetMetaTypes_GCIO(Meta)),
    4944             :              GCCharset2str_GCIO(GetMetaCharset_GCIO(Meta)),
    4945           8 :              GetMetaDelimiter_GCIO(Meta), GetMetaUnit_GCIO(Meta),
    4946             :              GetMetaResolution_GCIO(Meta),
    4947           8 :              GetMetaQuotedText_GCIO(Meta) ? "yes" : "no",
    4948           8 :              GetMetaFormat_GCIO(Meta) == 1 ? "relative" : "absolute",
    4949           8 :              GetMetaSysCoord_GCIO(Meta)
    4950           8 :                  ? GetSysCoordSystemID_GCSRS(GetMetaSysCoord_GCIO(Meta))
    4951             :                  : -1,
    4952           8 :              GetMetaSysCoord_GCIO(Meta)
    4953           8 :                  ? GetSysCoordTimeZone_GCSRS(GetMetaSysCoord_GCIO(Meta))
    4954             :                  : -1);
    4955             : 
    4956           8 :     return Meta;
    4957             : } /* ReadHeader_GCIO */
    4958             : 
    4959             : /* -------------------------------------------------------------------- */
    4960             : GCSubType GCIOAPI_CALL1(*)
    4961           1 :     FindFeature_GCIO(GCExportFileH *hGCT, const char *typDOTsubtypName)
    4962             : {
    4963             :     char **fe;
    4964             :     int whereClass, whereSubType;
    4965             :     GCType *theClass;
    4966             :     GCSubType *theSubType;
    4967           1 :     if (hGCT == NULL)
    4968           0 :         return NULL;
    4969           1 :     if (typDOTsubtypName == NULL)
    4970           0 :         return NULL;
    4971           2 :     if (!(fe = CSLTokenizeString2(typDOTsubtypName, ".", 0)) ||
    4972           1 :         CSLCount(fe) != 2)
    4973             :     {
    4974           0 :         CSLDestroy(fe);
    4975           0 :         return NULL;
    4976             :     }
    4977           1 :     if ((whereClass = _findTypeByName_GCIO(hGCT, fe[0])) == -1)
    4978             :     {
    4979           1 :         CSLDestroy(fe);
    4980           1 :         return NULL;
    4981             :     }
    4982           0 :     theClass = _getType_GCIO(hGCT, whereClass);
    4983           0 :     if ((whereSubType = _findSubTypeByName_GCIO(theClass, fe[1])) == -1)
    4984             :     {
    4985           0 :         CSLDestroy(fe);
    4986           0 :         return NULL;
    4987             :     }
    4988           0 :     theSubType = _getSubType_GCIO(theClass, whereSubType);
    4989           0 :     CSLDestroy(fe);
    4990           0 :     return theSubType;
    4991             : } /* FindFeature_GCIO */
    4992             : 
    4993             : /* -------------------------------------------------------------------- */
    4994           6 : int GCIOAPI_CALL FindFeatureFieldIndex_GCIO(GCSubType *theSubType,
    4995             :                                             const char *fieldName)
    4996             : {
    4997           6 :     if (theSubType == NULL)
    4998           0 :         return -1;
    4999           6 :     if (fieldName == NULL)
    5000           0 :         return -1;
    5001           6 :     return _findFieldByName_GCIO(GetSubTypeFields_GCIO(theSubType), fieldName);
    5002             : } /* FindFeatureFieldIndex_GCIO */
    5003             : 
    5004             : /* -------------------------------------------------------------------- */
    5005             : GCField GCIOAPI_CALL1(*)
    5006           3 :     FindFeatureField_GCIO(GCSubType *theSubType, const char *fieldName)
    5007             : {
    5008             :     int whereField;
    5009             :     GCField *theField;
    5010           3 :     if ((whereField = FindFeatureFieldIndex_GCIO(theSubType, fieldName)) == -1)
    5011             :     {
    5012           3 :         return NULL;
    5013             :     }
    5014           0 :     theField = _getField_GCIO(GetSubTypeFields_GCIO(theSubType), whereField);
    5015           0 :     return theField;
    5016             : } /* FindFeatureField_GCIO */
    5017             : 
    5018             : /* -------------------------------------------------------------------- */
    5019             : static char GCIOAPI_CALL1(*)
    5020          12 :     _escapeString_GCIO(CPL_UNUSED GCExportFileH *H, const char *theString)
    5021             : {
    5022             :     int l, i, o;
    5023             :     char *res;
    5024          12 :     if (!theString || (l = (int)strlen(theString)) == 0)
    5025             :     {
    5026           1 :         res = CPLStrdup(theString);
    5027           1 :         return res;
    5028             :     }
    5029          11 :     if ((res = (char *)CPLMalloc(l * 2 + 1)))
    5030             :     {
    5031          67 :         for (i = 0, o = 0; i < l; i++, o++)
    5032             :         {
    5033          56 :             switch (theString[i])
    5034             :             {
    5035           0 :                 case '\t':
    5036           0 :                     res[o] = '#';
    5037           0 :                     o++;
    5038           0 :                     res[o] = '#';
    5039           0 :                     break;
    5040           0 :                 case '\r':
    5041             :                 case '\n':
    5042           0 :                     res[o] = '@';
    5043           0 :                     break;
    5044          56 :                 default:
    5045          56 :                     res[o] = theString[i];
    5046          56 :                     break;
    5047             :             }
    5048             :         }
    5049          11 :         res[o] = '\0';
    5050             :     }
    5051          11 :     return res;
    5052             : } /* _escapeString_GCIO */
    5053             : 
    5054             : /* -------------------------------------------------------------------- */
    5055          10 : static int GCIOAPI_CALL _findNextFeatureFieldToWrite_GCIO(GCSubType *theSubType,
    5056             :                                                           int from, long id)
    5057             : {
    5058             :     GCExportFileH *H;
    5059             :     VSILFILE *h;
    5060             :     int n, i;
    5061             :     GCField *theField;
    5062             :     char *fieldName, *escapedValue, delim;
    5063             :     const char *quotes;
    5064             : 
    5065          10 :     if ((n = CountSubTypeFields_GCIO(theSubType)) == 0)
    5066             :     {
    5067           0 :         return WRITECOMPLETED_GCIO;
    5068             :     }
    5069          10 :     if (!(from < n))
    5070             :     {
    5071           2 :         return WRITECOMPLETED_GCIO;
    5072             :     }
    5073             : 
    5074           8 :     H = GetSubTypeGCHandle_GCIO(theSubType);
    5075           8 :     h = GetGCHandle_GCIO(H);
    5076             :     /* Dimension pragma for 3DM et 3D : */
    5077           8 :     if (from == 0)
    5078             :     {
    5079           2 :         if (GetSubTypeDim_GCIO(theSubType) == v3DM_GCIO)
    5080             :         {
    5081           0 :             if (VSIFPrintfL(h, "%s%s\n", kPragma_GCIO, k3DOBJECTMONO_GCIO) <= 0)
    5082             :             {
    5083           0 :                 CPLError(CE_Failure, CPLE_AppDefined, "Write failed.\n");
    5084           0 :                 return WRITEERROR_GCIO;
    5085             :             }
    5086           0 :             SetGCCurrentLinenum_GCIO(H, GetGCCurrentLinenum_GCIO(H) + 1L);
    5087             :         }
    5088           2 :         else if (GetSubTypeDim_GCIO(theSubType) == v3D_GCIO)
    5089             :         {
    5090           0 :             if (VSIFPrintfL(h, "%s%s\n", kPragma_GCIO, k3DOBJECT_GCIO) <= 0)
    5091             :             {
    5092           0 :                 CPLError(CE_Failure, CPLE_AppDefined, "Write failed.\n");
    5093           0 :                 return WRITEERROR_GCIO;
    5094             :             }
    5095           0 :             SetGCCurrentLinenum_GCIO(H, GetGCCurrentLinenum_GCIO(H) + 1L);
    5096             :         }
    5097             :     }
    5098           8 :     if (GetMetaQuotedText_GCIO(GetGCMeta_GCIO(H)))
    5099             :     {
    5100           0 :         quotes = "\"";
    5101             :     }
    5102             :     else
    5103             :     {
    5104           8 :         quotes = "";
    5105             :     }
    5106           8 :     delim = GetMetaDelimiter_GCIO(GetGCMeta_GCIO(H));
    5107             :     /* Fields are written in the same order as in the sub-type definition. */
    5108             :     /* Check for Private# fields : */
    5109          18 :     for (i = from; i < n; i++)
    5110             :     {
    5111          18 :         theField = GetSubTypeField_GCIO(theSubType, i);
    5112          18 :         if (!IsPrivateField_GCIO(theField))
    5113             :         {
    5114           6 :             return i; /* needs a call to WriteFeatureField_GCIO() for the ith
    5115             :                          field */
    5116             :         }
    5117          12 :         fieldName = GetFieldName_GCIO(theField);
    5118          12 :         if (EQUAL(fieldName, kX_GCIO) || EQUAL(fieldName, kY_GCIO) ||
    5119          10 :             EQUAL(fieldName, kXP_GCIO) || EQUAL(fieldName, kYP_GCIO) ||
    5120          10 :             EQUAL(fieldName, kGraphics_GCIO) || EQUAL(fieldName, kAngle_GCIO))
    5121             :         {
    5122           2 :             return GEOMETRYEXPECTED_GCIO; /* needs a call to
    5123             :                                              WriteFeatureGeometry_GCIO() now */
    5124             :         }
    5125          10 :         if (EQUAL(fieldName, kIdentifier_GCIO))
    5126             :         {
    5127             :             /* long integer which GeoConcept may use as a key for the object it
    5128             :              * will create. */
    5129             :             /* If set to '-1', it will be ignored. */
    5130           2 :             if (VSIFPrintfL(h, "%s%ld%s", quotes, id, quotes) <= 0)
    5131             :             {
    5132           0 :                 CPLError(CE_Failure, CPLE_AppDefined, "Write failed.\n");
    5133           0 :                 return WRITEERROR_GCIO;
    5134             :             }
    5135             :         }
    5136           8 :         else if (EQUAL(fieldName, kClass_GCIO))
    5137             :         {
    5138           2 :             if (!(escapedValue = _escapeString_GCIO(
    5139           2 :                       H, GetTypeName_GCIO(GetSubTypeType_GCIO(theSubType)))))
    5140             :             {
    5141           0 :                 return WRITEERROR_GCIO;
    5142             :             }
    5143           2 :             if (VSIFPrintfL(h, "%s%s%s", quotes, escapedValue, quotes) <= 0)
    5144             :             {
    5145           0 :                 CPLError(CE_Failure, CPLE_AppDefined, "Write failed.\n");
    5146           0 :                 CPLFree(escapedValue);
    5147           0 :                 return WRITEERROR_GCIO;
    5148             :             }
    5149           2 :             CPLFree(escapedValue);
    5150             :         }
    5151           6 :         else if (EQUAL(fieldName, kSubclass_GCIO))
    5152             :         {
    5153           2 :             if (!(escapedValue =
    5154           2 :                       _escapeString_GCIO(H, GetSubTypeName_GCIO(theSubType))))
    5155             :             {
    5156           0 :                 return WRITEERROR_GCIO;
    5157             :             }
    5158           2 :             if (VSIFPrintfL(h, "%s%s%s", quotes, escapedValue, quotes) <= 0)
    5159             :             {
    5160           0 :                 CPLError(CE_Failure, CPLE_AppDefined, "Write failed.\n");
    5161           0 :                 CPLFree(escapedValue);
    5162           0 :                 return WRITEERROR_GCIO;
    5163             :             }
    5164           2 :             CPLFree(escapedValue);
    5165             :         }
    5166           4 :         else if (EQUAL(fieldName, kName_GCIO))
    5167             :         {
    5168           2 :             if (!(escapedValue =
    5169           2 :                       _escapeString_GCIO(H, GetSubTypeName_GCIO(theSubType))))
    5170             :             {
    5171           0 :                 return WRITEERROR_GCIO;
    5172             :             }
    5173           2 :             if (VSIFPrintfL(h, "%s%s%s", quotes, escapedValue, quotes) <= 0)
    5174             :             {
    5175           0 :                 CPLError(CE_Failure, CPLE_AppDefined, "Write failed.\n");
    5176           0 :                 CPLFree(escapedValue);
    5177           0 :                 return WRITEERROR_GCIO;
    5178             :             }
    5179           2 :             CPLFree(escapedValue);
    5180             :         }
    5181           2 :         else if (EQUAL(fieldName, kNbFields_GCIO))
    5182             :         {
    5183           2 :             if (VSIFPrintfL(h, "%s%d%s", quotes,
    5184             :                             GetSubTypeNbFields_GCIO(theSubType), quotes) <= 0)
    5185             :             {
    5186           0 :                 CPLError(CE_Failure, CPLE_AppDefined, "Write failed.\n");
    5187           0 :                 return WRITEERROR_GCIO;
    5188             :             }
    5189             :         }
    5190             :         else
    5191             :         {
    5192           0 :             CPLError(CE_Failure, CPLE_NotSupported,
    5193             :                      "Writing %s field is not implemented.\n", fieldName);
    5194           0 :             return WRITEERROR_GCIO;
    5195             :         }
    5196          10 :         if (i != n - 1)
    5197             :         {
    5198          10 :             if (VSIFPrintfL(h, "%c", delim) <= 0)
    5199             :             {
    5200           0 :                 CPLError(CE_Failure, CPLE_AppDefined, "Write failed.\n");
    5201           0 :                 return WRITEERROR_GCIO;
    5202             :             }
    5203             :         }
    5204             :     }
    5205             : 
    5206           0 :     return WRITECOMPLETED_GCIO;
    5207             : } /* _findNextFeatureFieldToWrite_GCIO */
    5208             : 
    5209             : /* -------------------------------------------------------------------- */
    5210           2 : int GCIOAPI_CALL StartWritingFeature_GCIO(GCSubType *theSubType, long id)
    5211             : {
    5212           2 :     if (!IsSubTypeHeaderWritten_GCIO(theSubType))
    5213             :     {
    5214             :         GCExportFileH *H;
    5215             :         VSILFILE *h;
    5216             : 
    5217           0 :         H = GetSubTypeGCHandle_GCIO(theSubType);
    5218           0 :         h = GetGCHandle_GCIO(H);
    5219           0 :         if (!_writeFieldsPragma_GCIO(theSubType, h,
    5220           0 :                                      GetMetaDelimiter_GCIO(GetGCMeta_GCIO(H))))
    5221             :         {
    5222           0 :             CPLError(CE_Failure, CPLE_AppDefined,
    5223             :                      "Write Fields pragma failed for feature id %ld.\n", id);
    5224           0 :             return WRITEERROR_GCIO;
    5225             :         }
    5226             :     }
    5227           2 :     return _findNextFeatureFieldToWrite_GCIO(theSubType, 0, id);
    5228             : } /* StartWritingFeature_GCIO */
    5229             : 
    5230             : /* -------------------------------------------------------------------- */
    5231           2 : static int GCIOAPI_CALL _writePoint_GCIO(VSILFILE *h, const char *quotes,
    5232             :                                          char delim, double x, double y,
    5233             :                                          double z, GCDim dim, GCExtent *e,
    5234             :                                          int pCS, int hCS)
    5235             : {
    5236           2 :     SetExtentULAbscissa_GCIO(e, x);
    5237           2 :     SetExtentULOrdinate_GCIO(e, y);
    5238           2 :     SetExtentLRAbscissa_GCIO(e, x);
    5239           2 :     SetExtentLROrdinate_GCIO(e, y);
    5240           2 :     if (dim == v3DM_GCIO || dim == v3D_GCIO)
    5241             :     {
    5242           0 :         if (VSIFPrintfL(h, "%s%.*f%s%c%s%.*f%s%c%s%.*f%s", quotes, pCS, x,
    5243             :                         quotes, delim, quotes, pCS, y, quotes, delim, quotes,
    5244             :                         hCS, z, quotes) <= 0)
    5245             :         {
    5246           0 :             CPLError(CE_Failure, CPLE_AppDefined, "Write failed.\n");
    5247           0 :             return FALSE;
    5248             :         }
    5249             :     }
    5250             :     else
    5251             :     {
    5252           2 :         if (VSIFPrintfL(h, "%s%.*f%s%c%s%.*f%s", quotes, pCS, x, quotes, delim,
    5253             :                         quotes, pCS, y, quotes) <= 0)
    5254             :         {
    5255           0 :             CPLError(CE_Failure, CPLE_AppDefined, "Write failed.\n");
    5256           0 :             return FALSE;
    5257             :         }
    5258             :     }
    5259           2 :     return TRUE;
    5260             : } /* _writePoint_GCIO */
    5261             : 
    5262             : /* -------------------------------------------------------------------- */
    5263           0 : static int GCIOAPI_CALL _writeLine_GCIO(VSILFILE *h, const char *quotes,
    5264             :                                         char delim, OGRGeometryH poArc,
    5265             :                                         GCTypeKind knd, GCDim dim, int fmt,
    5266             :                                         GCExtent *e, int pCS, int hCS)
    5267             : {
    5268             :     int iP, nP;
    5269             :     double dX, dY, dZ;
    5270             :     /* 1st point */
    5271           0 :     if (!_writePoint_GCIO(h, quotes, delim, OGR_G_GetX(poArc, 0),
    5272             :                           OGR_G_GetY(poArc, 0), OGR_G_GetZ(poArc, 0), dim, e,
    5273             :                           pCS, hCS))
    5274             :     {
    5275           0 :         return FALSE;
    5276             :     }
    5277           0 :     if (VSIFPrintfL(h, "%c", delim) <= 0)
    5278             :     {
    5279           0 :         CPLError(CE_Failure, CPLE_AppDefined, "Write failed.\n");
    5280           0 :         return FALSE;
    5281             :     }
    5282           0 :     nP = OGR_G_GetPointCount(poArc);
    5283           0 :     if (knd == vLine_GCIO)
    5284             :     {
    5285             :         /* last point */
    5286           0 :         if (!_writePoint_GCIO(h, quotes, delim, OGR_G_GetX(poArc, nP - 1),
    5287             :                               OGR_G_GetY(poArc, nP - 1),
    5288             :                               OGR_G_GetZ(poArc, nP - 1), dim, e, pCS, hCS))
    5289             :         {
    5290           0 :             return FALSE;
    5291             :         }
    5292           0 :         if (VSIFPrintfL(h, "%c", delim) <= 0)
    5293             :         {
    5294           0 :             CPLError(CE_Failure, CPLE_AppDefined, "Write failed.\n");
    5295           0 :             return FALSE;
    5296             :         }
    5297             :     }
    5298             :     /* number of remaining points : */
    5299           0 :     if (VSIFPrintfL(h, "%s%d%s%c", quotes, nP - 1, quotes, delim) <= 0)
    5300             :     {
    5301           0 :         CPLError(CE_Failure, CPLE_AppDefined, "Write failed.\n");
    5302           0 :         return FALSE;
    5303             :     }
    5304             :     /* 2nd up to the last point ... */
    5305           0 :     for (iP = 1; iP < nP; iP++)
    5306             :     {
    5307           0 :         if (fmt == 1)
    5308             :         { /* relative coordinates ... */
    5309           0 :             dX = OGR_G_GetX(poArc, iP - 1) - OGR_G_GetX(poArc, iP);
    5310           0 :             dY = OGR_G_GetY(poArc, iP - 1) - OGR_G_GetY(poArc, iP);
    5311           0 :             dZ = OGR_G_GetZ(poArc, iP - 1) - OGR_G_GetZ(poArc, iP);
    5312             :         }
    5313             :         else
    5314             :         { /* absolute coordinates ... */
    5315           0 :             dX = OGR_G_GetX(poArc, iP);
    5316           0 :             dY = OGR_G_GetY(poArc, iP);
    5317           0 :             dZ = OGR_G_GetZ(poArc, iP);
    5318             :         }
    5319           0 :         if (!_writePoint_GCIO(h, quotes, delim, dX, dY, dZ, dim, e, pCS, hCS))
    5320             :         {
    5321           0 :             return FALSE;
    5322             :         }
    5323           0 :         if (iP != nP - 1)
    5324             :         {
    5325           0 :             if (VSIFPrintfL(h, "%c", delim) <= 0)
    5326             :             {
    5327           0 :                 CPLError(CE_Failure, CPLE_AppDefined, "Write failed.\n");
    5328           0 :                 return FALSE;
    5329             :             }
    5330             :         }
    5331             :     }
    5332           0 :     return TRUE;
    5333             : } /* _writeLine_GCIO */
    5334             : 
    5335             : /* -------------------------------------------------------------------- */
    5336           0 : static int GCIOAPI_CALL _writePolygon_GCIO(VSILFILE *h, const char *quotes,
    5337             :                                            char delim, OGRGeometryH poPoly,
    5338             :                                            GCDim dim, int fmt, GCExtent *e,
    5339             :                                            int pCS, int hCS)
    5340             : {
    5341             :     int iR, nR;
    5342             :     OGRGeometryH poRing;
    5343             :     /*
    5344             :      * X<>Y[<>Z]{Single Polygon{<>NrPolys=j[<>X<>Y[<>Z]<>Single Polygon]j}}
    5345             :      * with :
    5346             :      * Single Polygon = Nr points=k[<>PointX<>PointY[<>Z]]k...
    5347             :      */
    5348           0 :     if ((nR = OGR_G_GetGeometryCount(poPoly)) == 0)
    5349             :     {
    5350           0 :         CPLError(CE_Warning, CPLE_AppDefined,
    5351             :                  "Ignore POLYGON EMPTY in Geoconcept writer.\n");
    5352           0 :         return TRUE;
    5353             :     }
    5354           0 :     poRing = OGR_G_GetGeometryRef(poPoly, 0);
    5355           0 :     if (!_writeLine_GCIO(h, quotes, delim, poRing, vPoly_GCIO, dim, fmt, e, pCS,
    5356             :                          hCS))
    5357             :     {
    5358           0 :         return FALSE;
    5359             :     }
    5360             :     /* number of interior rings : */
    5361           0 :     if (nR > 1)
    5362             :     {
    5363           0 :         if (VSIFPrintfL(h, "%c%d%c", delim, nR - 1, delim) <= 0)
    5364             :         {
    5365           0 :             CPLError(CE_Failure, CPLE_AppDefined, "Write failed.\n");
    5366           0 :             return FALSE;
    5367             :         }
    5368           0 :         for (iR = 1; iR < nR; iR++)
    5369             :         {
    5370           0 :             poRing = OGR_G_GetGeometryRef(poPoly, iR);
    5371           0 :             if (!_writeLine_GCIO(h, quotes, delim, poRing, vPoly_GCIO, dim, fmt,
    5372             :                                  e, pCS, hCS))
    5373             :             {
    5374           0 :                 return FALSE;
    5375             :             }
    5376           0 :             if (iR != nR - 1)
    5377             :             {
    5378           0 :                 if (VSIFPrintfL(h, "%c", delim) <= 0)
    5379             :                 {
    5380           0 :                     CPLError(CE_Failure, CPLE_AppDefined, "Write failed.\n");
    5381           0 :                     return FALSE;
    5382             :                 }
    5383             :             }
    5384             :         }
    5385             :     }
    5386           0 :     return TRUE;
    5387             : } /* _writePolygon_GCIO */
    5388             : 
    5389             : /* -------------------------------------------------------------------- */
    5390           2 : int GCIOAPI_CALL WriteFeatureGeometry_GCIO(GCSubType *theSubType,
    5391             :                                            OGRGeometryH poGeom)
    5392             : {
    5393             :     GCExportFileH *H;
    5394             :     VSILFILE *h;
    5395             :     int n, i, iAn, pCS, hCS;
    5396             :     const char *quotes;
    5397             :     char delim;
    5398             : 
    5399           2 :     H = GetSubTypeGCHandle_GCIO(theSubType);
    5400           2 :     h = GetGCHandle_GCIO(H);
    5401           2 :     n = CountSubTypeFields_GCIO(theSubType);
    5402           2 :     iAn = -1;
    5403           2 :     if ((i = _findFieldByName_GCIO(GetSubTypeFields_GCIO(theSubType),
    5404             :                                    kGraphics_GCIO)) == -1)
    5405             :     {
    5406           2 :         if ((i = _findFieldByName_GCIO(GetSubTypeFields_GCIO(theSubType),
    5407             :                                        kAngle_GCIO)) == -1)
    5408             :         {
    5409           2 :             i = _findFieldByName_GCIO(GetSubTypeFields_GCIO(theSubType),
    5410             :                                       kY_GCIO);
    5411             :         }
    5412             :         else
    5413             :         {
    5414           0 :             iAn = i;
    5415             :         }
    5416             :     }
    5417             : 
    5418           2 :     if (GetMetaQuotedText_GCIO(GetGCMeta_GCIO(H)))
    5419             :     {
    5420           0 :         quotes = "\"";
    5421             :     }
    5422             :     else
    5423             :     {
    5424           2 :         quotes = "";
    5425             :     }
    5426           2 :     delim = GetMetaDelimiter_GCIO(GetGCMeta_GCIO(H));
    5427             : 
    5428           2 :     if ((pCS = GetMetaPlanarFormat_GCIO(GetGCMeta_GCIO(H))) == 0)
    5429             :     {
    5430           1 :         if (OSRIsGeographic(GetMetaSRS_GCIO(GetGCMeta_GCIO(H))))
    5431             :         {
    5432           1 :             pCS = kGeographicPlanarRadix;
    5433             :         }
    5434             :         else
    5435             :         {
    5436           0 :             pCS = kCartesianPlanarRadix;
    5437             :         }
    5438           1 :         SetMetaPlanarFormat_GCIO(GetGCMeta_GCIO(H), pCS);
    5439             :     }
    5440             : 
    5441           2 :     hCS = 0;
    5442           2 :     if (GetSubTypeDim_GCIO(theSubType) == v3D_GCIO &&
    5443           0 :         (hCS = GetMetaHeightFormat_GCIO(GetGCMeta_GCIO(H))) == 0)
    5444             :     {
    5445           0 :         hCS = kElevationRadix;
    5446           0 :         SetMetaHeightFormat_GCIO(GetGCMeta_GCIO(H), hCS);
    5447             :     }
    5448             : 
    5449           2 :     switch (wkbFlatten(OGR_G_GetGeometryType(poGeom)))
    5450             :     {
    5451           2 :         case wkbPoint:
    5452           2 :             if (!_writePoint_GCIO(h, quotes, delim, OGR_G_GetX(poGeom, 0),
    5453             :                                   OGR_G_GetY(poGeom, 0), OGR_G_GetZ(poGeom, 0),
    5454             :                                   GetSubTypeDim_GCIO(theSubType),
    5455           2 :                                   GetMetaExtent_GCIO(GetGCMeta_GCIO(H)), pCS,
    5456             :                                   hCS))
    5457             :             {
    5458           0 :                 return WRITEERROR_GCIO;
    5459             :             }
    5460           2 :             break;
    5461           0 :         case wkbLineString:
    5462           0 :             if (!_writeLine_GCIO(h, quotes, delim, poGeom, vLine_GCIO,
    5463             :                                  GetSubTypeDim_GCIO(theSubType),
    5464           0 :                                  GetMetaFormat_GCIO(GetGCMeta_GCIO(H)),
    5465           0 :                                  GetMetaExtent_GCIO(GetGCMeta_GCIO(H)), pCS,
    5466             :                                  hCS))
    5467             :             {
    5468           0 :                 return WRITEERROR_GCIO;
    5469             :             }
    5470           0 :             break;
    5471           0 :         case wkbPolygon:
    5472           0 :             if (!_writePolygon_GCIO(
    5473             :                     h, quotes, delim, poGeom, GetSubTypeDim_GCIO(theSubType),
    5474           0 :                     GetMetaFormat_GCIO(GetGCMeta_GCIO(H)),
    5475           0 :                     GetMetaExtent_GCIO(GetGCMeta_GCIO(H)), pCS, hCS))
    5476             :             {
    5477           0 :                 return WRITEERROR_GCIO;
    5478             :             }
    5479           0 :             break;
    5480           0 :         default:
    5481           0 :             CPLError(CE_Warning, CPLE_AppDefined,
    5482             :                      "Geometry type %d not supported in Geoconcept, feature "
    5483             :                      "skipped.\n",
    5484           0 :                      OGR_G_GetGeometryType(poGeom));
    5485           0 :             break;
    5486             :     }
    5487             :     /* Angle= 0 !! */
    5488           2 :     if (iAn != -1)
    5489             :     {
    5490           0 :         if (VSIFPrintfL(h, "%c%s%1d%s", delim, quotes, 0, quotes) <= 0)
    5491             :         {
    5492           0 :             CPLError(CE_Failure, CPLE_AppDefined, "Write failed.\n");
    5493           0 :             return WRITEERROR_GCIO;
    5494             :         }
    5495             :     }
    5496             :     /* if it is not the last field ... */
    5497           2 :     if (i != n - 1)
    5498             :     {
    5499           0 :         if (VSIFPrintfL(h, "%c", delim) <= 0)
    5500             :         {
    5501           0 :             CPLError(CE_Failure, CPLE_AppDefined, "Write failed.\n");
    5502           0 :             return WRITEERROR_GCIO;
    5503             :         }
    5504             :     }
    5505             : 
    5506             :     /* find out next field to write ... */
    5507           2 :     return _findNextFeatureFieldToWrite_GCIO(theSubType, i + 1, OGRNullFID);
    5508             : } /* WriteFeatureGeometry_GCIO */
    5509             : 
    5510             : /* -------------------------------------------------------------------- */
    5511           6 : int GCIOAPI_CALL WriteFeatureFieldAsString_GCIO(GCSubType *theSubType,
    5512             :                                                 int iField,
    5513             :                                                 const char *theValue)
    5514             : {
    5515             :     GCExportFileH *H;
    5516             :     VSILFILE *h;
    5517             :     int n;
    5518             :     const char *quotes;
    5519             :     char *escapedValue, delim;
    5520             :     GCField *theField;
    5521             : 
    5522           6 :     H = GetSubTypeGCHandle_GCIO(theSubType);
    5523           6 :     h = GetGCHandle_GCIO(H);
    5524           6 :     n = CountSubTypeFields_GCIO(theSubType);
    5525           6 :     if (GetMetaQuotedText_GCIO(GetGCMeta_GCIO(H)))
    5526             :     {
    5527           0 :         quotes = "\"";
    5528             :     }
    5529             :     else
    5530             :     {
    5531           6 :         quotes = "";
    5532             :     }
    5533           6 :     delim = GetMetaDelimiter_GCIO(GetGCMeta_GCIO(H));
    5534           6 :     theField = GetSubTypeField_GCIO(theSubType, iField);
    5535           6 :     if (!theField)
    5536             :     {
    5537           0 :         CPLError(CE_Failure, CPLE_NotSupported,
    5538             :                  "Attempt to write a field #%d that does not exist on feature "
    5539             :                  "%s.%s.\n",
    5540           0 :                  iField, GetTypeName_GCIO(GetSubTypeType_GCIO(theSubType)),
    5541             :                  GetSubTypeName_GCIO(theSubType));
    5542           0 :         return WRITEERROR_GCIO;
    5543             :     }
    5544           6 :     if (!(escapedValue = _escapeString_GCIO(H, theValue)))
    5545             :     {
    5546           0 :         return WRITEERROR_GCIO;
    5547             :     }
    5548           6 :     if (VSIFPrintfL(h, "%s%s%s", quotes, escapedValue, quotes) <= 0)
    5549             :     {
    5550             :         /* it is really an error if one of the parameters is not empty ... */
    5551           1 :         if (*quotes != '\0' || *escapedValue != '\0')
    5552             :         {
    5553           0 :             CPLError(CE_Failure, CPLE_AppDefined, "Write failed.\n");
    5554           0 :             CPLFree(escapedValue);
    5555           0 :             return WRITEERROR_GCIO;
    5556             :         }
    5557             :     }
    5558           6 :     if (iField != n - 1)
    5559             :     {
    5560           6 :         if (VSIFPrintfL(h, "%c", delim) <= 0)
    5561             :         {
    5562           0 :             CPLError(CE_Failure, CPLE_AppDefined, "Write failed.\n");
    5563           0 :             CPLFree(escapedValue);
    5564           0 :             return WRITEERROR_GCIO;
    5565             :         }
    5566             :     }
    5567           6 :     CPLFree(escapedValue);
    5568             : 
    5569           6 :     return _findNextFeatureFieldToWrite_GCIO(theSubType, iField + 1,
    5570             :                                              OGRNullFID);
    5571             : } /* WriteFeatureFieldAsString_GCIO */
    5572             : 
    5573             : /* -------------------------------------------------------------------- */
    5574           2 : void GCIOAPI_CALL StopWritingFeature_GCIO(GCSubType *theSubType)
    5575             : {
    5576             :     GCExportFileH *H;
    5577             : 
    5578           2 :     H = GetSubTypeGCHandle_GCIO(theSubType);
    5579           2 :     if (VSIFPrintfL(GetGCHandle_GCIO(H), "\n") <= 0)
    5580             :     {
    5581           0 :         CPLError(CE_Failure, CPLE_AppDefined, "Write failed.\n");
    5582             :     }
    5583           2 :     SetSubTypeNbFeatures_GCIO(theSubType,
    5584             :                               GetSubTypeNbFeatures_GCIO(theSubType) + 1L);
    5585           2 :     SetGCNbObjects_GCIO(H, GetGCNbObjects_GCIO(H) + 1L);
    5586           2 :     SetGCCurrentLinenum_GCIO(H, GetGCCurrentLinenum_GCIO(H) + 1L);
    5587           2 : } /* StopWritingFeature_GCIO */
    5588             : 
    5589             : /* -------------------------------------------------------------------- */
    5590          37 : OGRFeatureH GCIOAPI_CALL ReadNextFeature_GCIO(GCSubType *theSubType)
    5591             : {
    5592             :     OGRFeatureH f;
    5593             :     GCExportFileH *H;
    5594             :     GCDim d;
    5595             : 
    5596          37 :     f = NULL;
    5597          37 :     H = GetSubTypeGCHandle_GCIO(theSubType);
    5598          37 :     if (!(GetGCMeta_GCIO(H)))
    5599             :     {
    5600           0 :         return NULL;
    5601             :     }
    5602          37 :     d = vUnknown3D_GCIO;
    5603          86 :     while (_get_GCIO(H) != (vsi_l_offset)EOF)
    5604             :     {
    5605          80 :         if ((enum _tIO_MetadataType_GCIO)GetGCWhatIs_GCIO(H) == vComType_GCIO)
    5606             :         {
    5607           0 :             continue;
    5608             :         }
    5609             :         /* analyze the line according to schema : */
    5610             :         /* coverity[mixed_enums] */ /* FIXME ? */
    5611          80 :         if ((enum _tIO_MetadataType_GCIO)GetGCWhatIs_GCIO(H) == vPragma_GCIO)
    5612             :         {
    5613          49 :             if (strstr(GetGCCache_GCIO(H), k3DOBJECTMONO_GCIO))
    5614             :             {
    5615           0 :                 d = v3DM_GCIO;
    5616             :             }
    5617          49 :             else if (strstr(GetGCCache_GCIO(H), k3DOBJECT_GCIO))
    5618             :             {
    5619           0 :                 d = v3D_GCIO;
    5620             :             }
    5621          49 :             else if (strstr(GetGCCache_GCIO(H), k2DOBJECT_GCIO))
    5622             :             {
    5623           0 :                 d = v2D_GCIO;
    5624             :             }
    5625          49 :             continue;
    5626             :         }
    5627          31 :         if ((f = _buildOGRFeature_GCIO(H, &theSubType, d, NULL)))
    5628             :         {
    5629          31 :             break;
    5630             :         }
    5631           0 :         d = vUnknown3D_GCIO;
    5632             :     }
    5633             : 
    5634          37 :     return f;
    5635             : } /* ReadNextFeature_GCIO */

Generated by: LCOV version 1.14