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

Generated by: LCOV version 1.14