LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/geoconcept - geoconcept.c (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 2319 929 40.1 %
Date: 2010-01-09 Functions: 85 62 72.9 %

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

Generated by: LCOV version 1.7