text: /******************************************************************************
   *
   * Project:  OpenGIS Simple Features Reference Implementation
   * Purpose:  Implement importFromDict() method to read a WKT SRS from a
   *           coordinate system dictionary in a simple text format.
   * Author:   Frank Warmerdam, warmerdam@pobox.com
   *
   ******************************************************************************
   * Copyright (c) 2004, Frank Warmerdam
   *
   * Permission is hereby granted, free of charge, to any person obtaining a
   * copy of this software and associated documentation files (the "Software"),
   * to deal in the Software without restriction, including without limitation
   * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   * and/or sell copies of the Software, and to permit persons to whom the
   * Software is furnished to do so, subject to the following conditions:
   *
   * The above copyright notice and this permission notice shall be included
   * in all copies or substantial portions of the Software.
   *
   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   * DEALINGS IN THE SOFTWARE.
   ****************************************************************************/
  
  #include "cpl_port.h"
  #include "ogr_spatialref.h"
  
  #include <cstring>
  
  #include "cpl_conv.h"
  #include "cpl_error.h"
  #include "cpl_string.h"
  #include "cpl_vsi.h"
  #include "ogr_core.h"
  #include "ogr_srs_api.h"
  
  CPL_CVSID("$Id: ogr_srs_dict.cpp 8e5eeb35bf76390e3134a4ea7076dab7d478ea0e 2018-11-14 22:55:13 +0100 Even Rouault $")
  
  /************************************************************************/
  /*                           importFromDict()                           */
  /************************************************************************/
  
  /**
   * Read SRS from WKT dictionary.
   *
   * This method will attempt to find the indicated coordinate system identity
   * in the indicated dictionary file.  If found, the WKT representation is
   * imported and used to initialize this OGRSpatialReference.
   *
   * More complete information on the format of the dictionary files can
   * be found in the epsg.wkt file in the GDAL data tree.  The dictionary
   * files are searched for in the "GDAL" domain using CPLFindFile().  Normally
   * this results in searching /usr/local/share/gdal or somewhere similar.
   *
   * This method is the same as the C function OSRImportFromDict().
   *
   * @param pszDictFile the name of the dictionary file to load.
   *
   * @param pszCode the code to lookup in the dictionary.
   *
   * @return OGRERR_NONE on success, or OGRERR_SRS_UNSUPPORTED if the code isn't
   * found, and OGRERR_SRS_FAILURE if something more dramatic goes wrong.
   */
  
  OGRErr OGRSpatialReference::importFromDict( const char *pszDictFile,
                                              const char *pszCode )
  
  {
      CPLString osWKT(lookupInDict(pszDictFile, pszCode));
      if( osWKT.empty() )
          return OGRERR_UNSUPPORTED_SRS;
  
      OGRErr eErr = importFromWkt( osWKT );
      if( eErr == OGRERR_NONE && strstr(pszDictFile, "esri_") == nullptr )
      {
          morphFromESRI();
      }
  
      return eErr;
  }
  
  /************************************************************************/
  /*                          lookupInDict()                              */
  /************************************************************************/
  
  CPLString OGRSpatialReference::lookupInDict( const char *pszDictFile,
                                               const char *pszCode )
  
  {
  /* -------------------------------------------------------------------- */
  /*      Find and open file.                                             */
  /* -------------------------------------------------------------------- */
      CPLString osDictFile(pszDictFile);
      const char *pszFilename = CPLFindFile( "gdal", pszDictFile );
      if( pszFilename == nullptr )
          return CPLString();
  
      VSILFILE *fp = VSIFOpenL( pszFilename, "rb" );
      if( fp == nullptr )
          return CPLString();
  
  /* -------------------------------------------------------------------- */
  /*      Process lines.                                                  */
  /* -------------------------------------------------------------------- */
      CPLString osWKT;
      const char *pszLine = nullptr;
  
      while( (pszLine = CPLReadLineL(fp)) != nullptr )
  
      {
          if( pszLine[0] == '#' )
              continue;
  
          if( STARTS_WITH_CI(pszLine, "include ") )
          {
              osWKT = lookupInDict( pszLine + 8, pszCode );
              if( !osWKT.empty() )
                  break;
              continue;
          }
  
          if( strstr(pszLine, ",") == nullptr )
              continue;
  
          if( EQUALN(pszLine, pszCode, strlen(pszCode))
              && pszLine[strlen(pszCode)] == ',' )
          {
              osWKT = pszLine + strlen(pszCode)+1;
              break;
          }
      }
  
  /* -------------------------------------------------------------------- */
  /*      Cleanup                                                         */
  /* -------------------------------------------------------------------- */
      VSIFCloseL( fp );
  
      return osWKT;
  }
  
  /************************************************************************/
  /*                         OSRImportFromDict()                          */
  /************************************************************************/
  
  /**
   * Read SRS from WKT dictionary.
   *
   * This method will attempt to find the indicated coordinate system identity
   * in the indicated dictionary file.  If found, the WKT representation is
   * imported and used to initialize this OGRSpatialReference.
   *
   * More complete information on the format of the dictionary files can
   * be found in the epsg.wkt file in the GDAL data tree.  The dictionary
   * files are searched for in the "GDAL" domain using CPLFindFile().  Normally
   * this results in searching /usr/local/share/gdal or somewhere similar.
   *
   * This method is the same as the C++ method
   * OGRSpatialReference::importFromDict().
   *
   * @param hSRS spatial reference system handle.
   *
   * @param pszDictFile the name of the dictionary file to load.
   *
   * @param pszCode the code to lookup in the dictionary.
   *
   * @return OGRERR_NONE on success, or OGRERR_SRS_UNSUPPORTED if the code isn't
   * found, and OGRERR_SRS_FAILURE if something more dramatic goes wrong.
   */
  
  OGRErr OSRImportFromDict( OGRSpatialReferenceH hSRS,
                            const char *pszDictFile,
                            const char *pszCode )
  
  {
      VALIDATE_POINTER1( hSRS, "OSRImportFromDict", OGRERR_FAILURE );
  
      return reinterpret_cast<OGRSpatialReference *>(hSRS)->
          importFromDict( pszDictFile, pszCode );
  }
  