LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/filegdb - FGdbUtils.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 182 132 72.5 %
Date: 2012-12-26 Functions: 18 15 83.3 %

       1                 : /******************************************************************************
       2                 : * $Id: FGdbUtils.cpp 23984 2012-02-15 05:19:25Z rcoup $
       3                 : *
       4                 : * Project:  OpenGIS Simple Features Reference Implementation
       5                 : * Purpose:  Different utility functions used in FileGDB OGR driver.
       6                 : * Author:   Ragi Yaser Burhum, ragi@burhum.com
       7                 : *           Paul Ramsey, pramsey at cleverelephant.ca
       8                 : *
       9                 : ******************************************************************************
      10                 : * Copyright (c) 2010, Ragi Yaser Burhum
      11                 : * Copyright (c) 2011, Paul Ramsey <pramsey at cleverelephant.ca>
      12                 : *
      13                 : * Permission is hereby granted, free of charge, to any person obtaining a
      14                 : * copy of this software and associated documentation files (the "Software"),
      15                 : * to deal in the Software without restriction, including without limitation
      16                 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      17                 : * and/or sell copies of the Software, and to permit persons to whom the
      18                 : * Software is furnished to do so, subject to the following conditions:
      19                 : *
      20                 : * The above copyright notice and this permission notice shall be included
      21                 : * in all copies or substantial portions of the Software.
      22                 : *
      23                 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      24                 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      25                 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      26                 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      27                 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      28                 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      29                 : * DEALINGS IN THE SOFTWARE.
      30                 : ****************************************************************************/
      31                 : 
      32                 : #include "FGdbUtils.h"
      33                 : #include <algorithm>
      34                 : 
      35                 : #include "ogr_api.h"
      36                 : #include "ogrpgeogeometry.h"
      37                 : 
      38                 : CPL_CVSID("$Id: FGdbUtils.cpp 23984 2012-02-15 05:19:25Z rcoup $");
      39                 : 
      40                 : using std::string;
      41                 : 
      42                 : /*************************************************************************/
      43                 : /*                          StringToWString()                            */
      44                 : /*************************************************************************/
      45                 : 
      46            2927 : std::wstring StringToWString(const std::string& utf8string)
      47                 : {
      48            2927 :     wchar_t* pszUTF16 = CPLRecodeToWChar( utf8string.c_str(), CPL_ENC_UTF8, CPL_ENC_UCS2);
      49            2927 :     std::wstring utf16string = pszUTF16;
      50            2927 :     CPLFree(pszUTF16);
      51               0 :     return utf16string;
      52                 : }
      53                 : 
      54                 : /*************************************************************************/
      55                 : /*                          WStringToString()                            */
      56                 : /*************************************************************************/
      57                 : 
      58           12312 : std::string WStringToString(const std::wstring& utf16string)
      59                 : {
      60           12312 :     char* pszUTF8 = CPLRecodeFromWChar( utf16string.c_str(), CPL_ENC_UCS2, CPL_ENC_UTF8 );
      61           12312 :     std::string utf8string = pszUTF8;
      62           12312 :     CPLFree(pszUTF8);
      63               0 :     return utf8string; 
      64                 : }
      65                 : 
      66                 : /*************************************************************************/
      67                 : /*                                GDBErr()                               */
      68                 : /*************************************************************************/
      69                 : 
      70               5 : bool GDBErr(long int hr, std::string desc)
      71                 : {
      72               5 :     std::wstring fgdb_error_desc_w;
      73                 :     fgdbError er;
      74               5 :     er = FileGDBAPI::ErrorInfo::GetErrorDescription(hr, fgdb_error_desc_w);
      75               5 :     if ( er == S_OK )
      76                 :     {
      77               5 :         std::string fgdb_error_desc = WStringToString(fgdb_error_desc_w);
      78                 :         CPLError( CE_Failure, CPLE_AppDefined,
      79               5 :                   "Error: %s (%s)", desc.c_str(), fgdb_error_desc.c_str());
      80                 :     }
      81                 :     else
      82                 :     {
      83                 :         CPLError( CE_Failure, CPLE_AppDefined,
      84               0 :                   "Error (%ld): %s", hr, desc.c_str());
      85                 :     }
      86                 :     // FIXME? EvenR: not sure if ClearErrors() is really necessary, but as it, it causes crashes in case of
      87                 :     // repeated errors
      88                 :     //FileGDBAPI::ErrorInfo::ClearErrors();
      89                 : 
      90               5 :     return false;
      91                 : }
      92                 : 
      93                 : /*************************************************************************/
      94                 : /*                            GDBDebug()                                 */
      95                 : /*************************************************************************/
      96                 : 
      97               0 : bool GDBDebug(long int hr, std::string desc)
      98                 : {
      99               0 :     std::wstring fgdb_error_desc_w;
     100                 :     fgdbError er;
     101               0 :     er = FileGDBAPI::ErrorInfo::GetErrorDescription(hr, fgdb_error_desc_w);
     102               0 :     if ( er == S_OK )
     103                 :     {
     104               0 :         std::string fgdb_error_desc = WStringToString(fgdb_error_desc_w);
     105               0 :         CPLDebug("FGDB", "%s (%s)", desc.c_str(), fgdb_error_desc.c_str());
     106                 :     }
     107                 :     else
     108                 :     {
     109               0 :         CPLDebug("FGDB", "%s", desc.c_str());
     110                 :     }
     111                 :     // FIXME? EvenR: not sure if ClearErrors() is really necessary, but as it, it causes crashes in case of
     112                 :     // repeated errors
     113                 :     //FileGDBAPI::ErrorInfo::ClearErrors();
     114                 : 
     115               0 :     return false;
     116                 : }
     117                 : 
     118                 : /*************************************************************************/
     119                 : /*                            GDBToOGRGeometry()                         */
     120                 : /*************************************************************************/
     121                 : 
     122             170 : bool GDBToOGRGeometry(string geoType, bool hasZ, OGRwkbGeometryType* pOut)
     123                 : {
     124             170 :     if (geoType == "esriGeometryPoint")
     125                 :     {
     126              46 :         *pOut = hasZ? wkbPoint25D : wkbPoint;
     127                 :     }
     128             124 :     else if (geoType == "esriGeometryMultipoint")
     129                 :     {
     130              20 :         *pOut = hasZ? wkbMultiPoint25D : wkbMultiPoint;
     131                 :     }
     132             104 :     else if (geoType == "esriGeometryLine")
     133                 :     {
     134               0 :         *pOut = hasZ? wkbLineString25D : wkbLineString;
     135                 :     }
     136             104 :     else if (geoType == "esriGeometryPolyline")
     137                 :     {
     138              40 :         *pOut = hasZ? wkbMultiLineString25D : wkbMultiLineString;
     139                 :     }
     140              64 :     else if (geoType == "esriGeometryPolygon" ||
     141                 :             geoType == "esriGeometryMultiPatch")
     142                 :     {
     143              64 :         *pOut = hasZ? wkbMultiPolygon25D : wkbMultiPolygon; // no mapping to single polygon
     144                 :     }
     145                 :     else
     146                 :     {
     147                 :         CPLError( CE_Failure, CPLE_AppDefined,
     148               0 :                 "Cannot map esriGeometryType(%s) to OGRwkbGeometryType", geoType.c_str());
     149               0 :         return false;
     150                 :     }
     151                 : 
     152             170 :     return true;
     153                 : }
     154                 : 
     155                 : /*************************************************************************/
     156                 : /*                            OGRGeometryToGDB()                         */
     157                 : /*************************************************************************/
     158                 : 
     159              36 : bool OGRGeometryToGDB(OGRwkbGeometryType ogrType, std::string *gdbType, bool *hasZ)
     160                 : {
     161              36 :     switch (ogrType)
     162                 :     {
     163                 :         /* 3D forms */
     164                 :         case wkbPoint25D:
     165                 :         {
     166               1 :             *gdbType = "esriGeometryPoint";
     167               1 :             *hasZ = true;
     168               1 :             break;
     169                 :         }
     170                 : 
     171                 :         case wkbMultiPoint25D:
     172                 :         {
     173               1 :             *gdbType = "esriGeometryMultipoint";
     174               1 :             *hasZ = true;
     175               1 :             break;
     176                 :         }
     177                 : 
     178                 :         case wkbLineString25D:
     179                 :         case wkbMultiLineString25D:
     180                 :         {
     181               2 :             *gdbType = "esriGeometryPolyline";
     182               2 :             *hasZ = true;
     183               2 :             break;
     184                 :         }
     185                 : 
     186                 :         case wkbPolygon25D:
     187                 :         case wkbMultiPolygon25D:
     188                 :         {
     189               2 :             *gdbType = "esriGeometryPolygon";
     190               2 :             *hasZ = true;
     191               2 :             break;
     192                 :         }
     193                 : 
     194                 :         /* 2D forms */
     195                 :         case wkbPoint:
     196                 :         {
     197              22 :             *gdbType = "esriGeometryPoint";
     198              22 :             *hasZ = false;
     199              22 :             break;
     200                 :         }
     201                 : 
     202                 :         case wkbMultiPoint:
     203                 :         {
     204               1 :             *gdbType = "esriGeometryMultipoint";
     205               1 :             *hasZ = false;
     206               1 :             break;
     207                 :         }
     208                 : 
     209                 :         case wkbLineString:
     210                 :         case wkbMultiLineString:
     211                 :         {
     212               2 :             *gdbType = "esriGeometryPolyline";
     213               2 :             *hasZ = false;
     214               2 :             break;
     215                 :         }
     216                 : 
     217                 :         case wkbPolygon:
     218                 :         case wkbMultiPolygon:
     219                 :         {
     220               5 :             *gdbType = "esriGeometryPolygon";
     221               5 :             *hasZ = false;
     222               5 :             break;
     223                 :         }
     224                 :         
     225                 :         default:
     226                 :         {
     227                 :             CPLError( CE_Failure, CPLE_AppDefined, "Cannot map OGRwkbGeometryType (%s) to ESRI type",
     228               0 :                       OGRGeometryTypeToName(ogrType));
     229               0 :             return false;
     230                 :         }
     231                 :     }
     232              36 :     return true;
     233                 : }
     234                 : 
     235                 : /*************************************************************************/
     236                 : /*                            GDBToOGRFieldType()                        */
     237                 : /*************************************************************************/
     238                 : 
     239                 : // We could make this function far more robust by doing automatic coertion of types,
     240                 : // and/or skipping fields we do not know. But our purposes this works fine
     241             568 : bool GDBToOGRFieldType(std::string gdbType, OGRFieldType* pOut)
     242                 : {
     243                 :     /*
     244                 :     ESRI types
     245                 :     esriFieldTypeSmallInteger = 0,
     246                 :     esriFieldTypeInteger = 1,
     247                 :     esriFieldTypeSingle = 2,
     248                 :     esriFieldTypeDouble = 3,
     249                 :     esriFieldTypeString = 4,
     250                 :     esriFieldTypeDate = 5,
     251                 :     esriFieldTypeOID = 6,
     252                 :     esriFieldTypeGeometry = 7,
     253                 :     esriFieldTypeBlob = 8,
     254                 :     esriFieldTypeRaster = 9,
     255                 :     esriFieldTypeGUID = 10,
     256                 :     esriFieldTypeGlobalID = 11,
     257                 :     esriFieldTypeXML = 12
     258                 :     */
     259                 : 
     260                 :     //OGR Types
     261                 : 
     262                 :     //            Desc                                 Name                GDB->OGR Mapped By Us?
     263                 :     /** Simple 32bit integer *///                   OFTInteger = 0,             YES
     264                 :     /** List of 32bit integers *///                 OFTIntegerList = 1,         NO
     265                 :     /** Double Precision floating point *///        OFTReal = 2,                YES
     266                 :     /** List of doubles *///                        OFTRealList = 3,            NO
     267                 :     /** String of ASCII chars *///                  OFTString = 4,              YES
     268                 :     /** Array of strings *///                       OFTStringList = 5,          NO
     269                 :     /** deprecated *///                             OFTWideString = 6,          NO
     270                 :     /** deprecated *///                             OFTWideStringList = 7,      NO
     271                 :     /** Raw Binary data *///                        OFTBinary = 8,              YES
     272                 :     /** Date *///                                   OFTDate = 9,                NO
     273                 :     /** Time *///                                   OFTTime = 10,               NO
     274                 :     /** Date and Time *///                          OFTDateTime = 11            YES
     275                 : 
     276             568 :     if (gdbType == "esriFieldTypeSmallInteger" ||
     277                 :         gdbType == "esriFieldTypeInteger")
     278                 :     {
     279             274 :         *pOut = OFTInteger;
     280             274 :         return true;
     281                 :     }
     282             294 :     else if (gdbType == "esriFieldTypeSingle" ||
     283                 :         gdbType == "esriFieldTypeDouble")
     284                 :     {
     285             145 :         *pOut = OFTReal;
     286             145 :         return true;
     287                 :     }
     288             149 :     else if (gdbType == "esriFieldTypeGUID" ||
     289                 :         gdbType == "esriFieldTypeGlobalID" ||
     290                 :         gdbType == "esriFieldTypeXML" ||
     291                 :         gdbType == "esriFieldTypeString")
     292                 :     {
     293             145 :         *pOut = OFTString;
     294             145 :         return true;
     295                 :     }
     296               4 :     else if (gdbType == "esriFieldTypeDate")
     297                 :     {
     298               2 :         *pOut = OFTDateTime;
     299               2 :         return true;
     300                 :     }
     301               2 :     else if (gdbType == "esriFieldTypeBlob")
     302                 :     {
     303               2 :         *pOut = OFTBinary;
     304               2 :         return true;
     305                 :     }
     306                 :     else
     307                 :     {
     308                 :         /* Intentionally fail at these
     309                 :         esriFieldTypeOID
     310                 :         esriFieldTypeGeometry
     311                 :         esriFieldTypeRaster
     312                 :         */
     313               0 :         CPLError( CE_Warning, CPLE_AppDefined, "%s", ("Cannot map field " + gdbType).c_str());
     314                 : 
     315               0 :         return false;
     316                 :     }
     317                 : }
     318                 : 
     319                 : /*************************************************************************/
     320                 : /*                            OGRToGDBFieldType()                        */
     321                 : /*************************************************************************/
     322                 : 
     323              73 : bool OGRToGDBFieldType(OGRFieldType ogrType, std::string* gdbType)
     324                 : {
     325              73 :     switch(ogrType)
     326                 :     {
     327                 :         case OFTInteger:
     328                 :         {
     329              37 :             *gdbType = "esriFieldTypeInteger";
     330              37 :             break;
     331                 :         }
     332                 :         case OFTReal:
     333                 :         {
     334              17 :             *gdbType = "esriFieldTypeDouble";
     335              17 :             break;
     336                 :         }
     337                 :         case OFTString:
     338                 :         {
     339              19 :             *gdbType = "esriFieldTypeString";
     340              19 :             break;
     341                 :         }
     342                 :         case OFTBinary:
     343                 :         {
     344               0 :             *gdbType = "esriFieldTypeBlob";
     345               0 :             break;
     346                 :         }
     347                 :         case OFTDate:
     348                 :         case OFTDateTime:
     349                 :         {
     350               0 :             *gdbType = "esriFieldTypeDate";
     351               0 :             break;
     352                 :         }
     353                 :         default:
     354                 :         {
     355                 :             CPLError( CE_Warning, CPLE_AppDefined,
     356                 :                       "Cannot map OGR field type (%s)",
     357               0 :                       OGR_GetFieldTypeName(ogrType) );
     358               0 :             return false;
     359                 :         }
     360                 :     }
     361                 : 
     362              73 :     return true;
     363                 : }
     364                 : 
     365                 : /*************************************************************************/
     366                 : /*                       GDBFieldTypeToWidthPrecision()                  */
     367                 : /*************************************************************************/
     368                 : 
     369              70 : bool GDBFieldTypeToWidthPrecision(std::string &gdbType, int *width, int *precision)
     370                 : {
     371              70 :     *precision = 0;
     372                 : 
     373              70 :     if(gdbType == "esriFieldTypeSmallInteger" )
     374                 :     {
     375               0 :         *width = 2;
     376                 :     }
     377              70 :     else if(gdbType == "esriFieldTypeInteger" )
     378                 :     {
     379              37 :         *width = 12;
     380                 :     }
     381              33 :     else if(gdbType == "esriFieldTypeSingle" )
     382                 :     {
     383               0 :         *width = 12;
     384               0 :         *precision = 5;
     385                 :     }
     386              33 :     else if(gdbType == "esriFieldTypeDouble" )
     387                 :     {
     388              15 :         *width = 24;
     389              15 :         *precision = 15;
     390                 :     }
     391              18 :     else if(gdbType == "esriFieldTypeString" )
     392                 :     {
     393              18 :         *width = 2147483647;
     394                 :     }
     395               0 :     else if(gdbType == "esriFieldTypeDate" )
     396                 :     {
     397               0 :         *width = 32;
     398                 :     }
     399               0 :     else if(gdbType == "esriFieldTypeOID" )
     400                 :     {
     401               0 :         *width = 15;
     402                 :     }
     403                 :     else
     404                 :     {
     405                 :         CPLError( CE_Warning, CPLE_AppDefined,
     406               0 :                   "Cannot map ESRI field type (%s)", gdbType.c_str());
     407               0 :         return false;
     408                 :     }
     409                 : 
     410              70 :     return true;
     411                 : }
     412                 : 
     413                 : /*************************************************************************/
     414                 : /*                       GDBFieldTypeToWidthPrecision()                  */
     415                 : /*************************************************************************/
     416                 : 
     417             801 : bool GDBGeometryToOGRGeometry(bool forceMulti, FileGDBAPI::ShapeBuffer* pGdbGeometry,
     418                 :                               OGRSpatialReference* pOGRSR, OGRGeometry** ppOutGeometry)
     419                 : {
     420                 : 
     421             801 :     OGRGeometry* pOGRGeometry = NULL;
     422                 : 
     423                 :     OGRErr eErr = OGRCreateFromShapeBin( pGdbGeometry->shapeBuffer,
     424                 :                                 &pOGRGeometry,
     425             801 :                                 pGdbGeometry->inUseLength);
     426                 : 
     427                 :     //OGRErr eErr = OGRGeometryFactory::createFromWkb(pGdbGeometry->shapeBuffer, pOGRSR, &pOGRGeometry, pGdbGeometry->inUseLength );
     428                 : 
     429             801 :     if (eErr != OGRERR_NONE)
     430                 :     {
     431               0 :         CPLError( CE_Failure, CPLE_AppDefined, "Failed attempting to import GDB WKB Geometry. OGRGeometryFactory err:%d", eErr);
     432               0 :         return false;
     433                 :     }
     434                 : 
     435             801 :     if( pOGRGeometry != NULL )
     436                 :     {
     437                 :         // force geometries to multi if requested
     438                 : 
     439                 :         // If it is a polygon, force to MultiPolygon since we always produce multipolygons
     440             801 :         if (wkbFlatten(pOGRGeometry->getGeometryType()) == wkbPolygon)
     441                 :         {
     442             332 :             pOGRGeometry = OGRGeometryFactory::forceToMultiPolygon(pOGRGeometry);
     443                 :         }
     444             469 :         else if (forceMulti)
     445                 :         {
     446             348 :             if (wkbFlatten(pOGRGeometry->getGeometryType()) == wkbLineString)
     447                 :             {
     448             232 :                 pOGRGeometry = OGRGeometryFactory::forceToMultiLineString(pOGRGeometry);
     449                 :             }
     450             116 :             else if (wkbFlatten(pOGRGeometry->getGeometryType()) == wkbPoint)
     451                 :             {
     452               0 :                 pOGRGeometry = OGRGeometryFactory::forceToMultiPoint(pOGRGeometry);
     453                 :             }
     454                 :         }
     455                 : 
     456             801 :         if (pOGRGeometry)
     457             801 :             pOGRGeometry->assignSpatialReference( pOGRSR );
     458                 :     }
     459                 : 
     460                 : 
     461             801 :     *ppOutGeometry = pOGRGeometry;
     462                 : 
     463             801 :     return true;
     464                 : }
     465                 : 
     466                 : /*************************************************************************/
     467                 : /*                         GDBToOGRSpatialReference()                    */
     468                 : /*************************************************************************/
     469                 : 
     470               0 : bool GDBToOGRSpatialReference(const string & wkt, OGRSpatialReference** ppSR)
     471                 : {
     472               0 :     if (wkt.size() <= 0)
     473                 :     {
     474               0 :         CPLError( CE_Warning, CPLE_AppDefined, "ESRI Spatial Reference is NULL");
     475               0 :         return false;
     476                 :     }
     477                 : 
     478               0 :     *ppSR = new OGRSpatialReference(wkt.c_str());
     479                 : 
     480               0 :     OGRErr result = (*ppSR)->morphFromESRI();
     481                 : 
     482               0 :     if (result == OGRERR_NONE)
     483                 :     {
     484               0 :         return true;
     485                 :     }
     486                 :     else
     487                 :     {
     488               0 :         delete *ppSR;
     489               0 :         *ppSR = NULL;
     490                 : 
     491                 :         CPLError( CE_Failure, CPLE_AppDefined,
     492               0 :                   "Failed morhping from ESRI Geometry: %s", wkt.c_str());
     493                 : 
     494               0 :         return false;
     495                 :     }
     496                 : }
     497                 : 
     498                 : /*************************************************************************/
     499                 : /*                           FGDB_CPLAddXMLAttribute()                   */
     500                 : /*************************************************************************/
     501                 : 
     502                 : /* Utility method for attributing nodes */
     503             862 : void FGDB_CPLAddXMLAttribute(CPLXMLNode* node, const char* attrname, const char* attrvalue)
     504                 : {
     505             862 :     if ( !node ) return;
     506             862 :     CPLCreateXMLNode( CPLCreateXMLNode( node, CXT_Attribute, attrname ), CXT_Text, attrvalue );
     507                 : }
     508                 : 
     509                 : /*************************************************************************/
     510                 : /*                          FGDBLaunderName()                            */
     511                 : /*************************************************************************/
     512                 : 
     513             111 : std::string FGDBLaunderName(const std::string name)
     514                 : {
     515             111 :     std::string newName = name;
     516                 : 
     517             111 :     if ( newName[0]>='0' && newName[0]<='9' )
     518                 :     {
     519               2 :         newName = "_" + newName;
     520                 :     }
     521                 : 
     522            1444 :     for(size_t i=0; i < newName.size(); i++)
     523                 :     {
     524            1333 :         if ( !( newName[i] == '_' ||
     525                 :               ( newName[i]>='0' && newName[i]<='9') ||
     526                 :               ( newName[i]>='a' && newName[i]<='z') || 
     527                 :               ( newName[i]>='A' && newName[i]<='Z') ))
     528                 :         {
     529              20 :             newName[i] = '_';
     530                 :         }
     531                 :     }
     532                 : 
     533               0 :     return newName;
     534                 : }
     535                 : 
     536                 : /*************************************************************************/
     537                 : /*                     FGDBEscapeUnsupportedPrefixes()                   */
     538                 : /*************************************************************************/
     539                 : 
     540              38 : std::string FGDBEscapeUnsupportedPrefixes(const std::string className)
     541                 : {
     542              38 :     std::string newName = className;
     543                 :     // From ESRI docs
     544                 :     // Feature classes starting with these strings are unsupported.
     545                 :     static const char* UNSUPPORTED_PREFIXES[] = {"sde_", "gdb_", "delta_", NULL};
     546                 : 
     547             149 :     for (int i = 0; UNSUPPORTED_PREFIXES[i] != NULL; i++)
     548                 :     {
     549             112 :         if (newName.find(UNSUPPORTED_PREFIXES[i]) == 0)
     550                 :         {
     551               1 :             newName = "_" + newName;
     552               1 :             break;
     553                 :         }
     554                 :     }
     555                 : 
     556               0 :     return newName;
     557                 : }
     558                 : 
     559                 : /*************************************************************************/
     560                 : /*                        FGDBEscapeReservedKeywords()                   */
     561                 : /*************************************************************************/
     562                 : 
     563             111 : std::string FGDBEscapeReservedKeywords(const std::string name)
     564                 : {
     565             111 :     std::string newName = name;
     566             111 :     std::string upperName = name;
     567             111 :     std::transform(upperName.begin(), upperName.end(), upperName.begin(), ::toupper);
     568                 : 
     569                 :     // From ESRI docs
     570                 :     static const char* RESERVED_WORDS[] = {FGDB_OID_NAME, "ADD", "ALTER", "AND", "AS", "ASC", "BETWEEN",
     571                 :                                     "BY", "COLUMN", "CREATE", "DATE", "DELETE", "DESC",
     572                 :                                     "DROP", "EXISTS", "FOR", "FROM", "IN", "INSERT", "INTO",
     573                 :                                     "IS", "LIKE", "NOT", "NULL", "OR", "ORDER", "SELECT",
     574                 :                                     "SET", "TABLE", "UPDATE", "VALUES", "WHERE", NULL};
     575                 : 
     576                 :     // Append an underscore to any FGDB reserved words used as field names
     577                 :     // This is the same behaviour ArcCatalog follows.
     578            3631 :     for (int i = 0; RESERVED_WORDS[i] != NULL; i++)
     579                 :     {
     580            3522 :         const char* w = RESERVED_WORDS[i];
     581            3522 :         if (upperName == w)
     582                 :         {
     583               2 :             newName += '_';
     584               2 :             break;
     585                 :         }
     586                 :     }
     587                 : 
     588             111 :     return newName;
     589            2139 : }

Generated by: LCOV version 1.7