LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/geoconcept - geoconcept.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 1112 2586 43.0 %
Date: 2025-01-18 12:42:00 Functions: 62 83 74.7 %

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

Generated by: LCOV version 1.14