LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/geoconcept - geoconcept.c (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 2318 933 40.3 %
Date: 2012-04-28 Functions: 84 62 73.8 %

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

Generated by: LCOV version 1.7