?? ogrsfdriverregistrar.cpp
字號:
/******************************************************************************
* $Id: ogrsfdriverregistrar.cpp 10646 2007-01-18 02:38:10Z warmerdam $
*
* Project: OpenGIS Simple Features Reference Implementation
* Purpose: The OGRSFDriverRegistrar class implementation.
* Author: Frank Warmerdam, warmerdam@pobox.com
*
******************************************************************************
* Copyright (c) 1999, Les Technologies SoftMap Inc.
*
* 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 "ogrsf_frmts.h"
#include "ogr_api.h"
#include "ogr_p.h"
#include "cpl_multiproc.h"
CPL_CVSID("$Id: ogrsfdriverregistrar.cpp 10646 2007-01-18 02:38:10Z warmerdam $");
static OGRSFDriverRegistrar *poRegistrar = NULL;
static char *pszUpdatableINST_DATA =
"__INST_DATA_TARGET: ";
/************************************************************************/
/* OGRSFDriverRegistrar */
/************************************************************************/
OGRSFDriverRegistrar::OGRSFDriverRegistrar()
{
CPLAssert( poRegistrar == NULL );
nDrivers = 0;
papoDrivers = NULL;
nOpenDSCount = 0;
papszOpenDSRawName = NULL;
papoOpenDS = NULL;
papoOpenDSDriver = NULL;
/* -------------------------------------------------------------------- */
/* We want to push a location to search for data files */
/* supporting GDAL/OGR such as EPSG csv files, S-57 definition */
/* files, and so forth. The static pszUpdateableINST_DATA */
/* string can be updated within the shared library or */
/* executable during an install to point installed data */
/* directory. If it isn't burned in here then we use the */
/* INST_DATA macro (setup at configure time) if */
/* available. Otherwise we don't push anything and we hope */
/* other mechanisms such as environment variables will have */
/* been employed. */
/* -------------------------------------------------------------------- */
if( CPLGetConfigOption( "GDAL_DATA", NULL ) != NULL )
{
CPLPushFinderLocation( CPLGetConfigOption( "GDAL_DATA", NULL ) );
}
else if( pszUpdatableINST_DATA[19] != ' ' )
{
CPLPushFinderLocation( pszUpdatableINST_DATA + 19 );
}
else
{
#ifdef INST_DATA
CPLPushFinderLocation( INST_DATA );
#endif
}
}
/************************************************************************/
/* ~OGRSFDriverRegistrar() */
/************************************************************************/
OGRSFDriverRegistrar::~OGRSFDriverRegistrar()
{
for( int i = 0; i < nDrivers; i++ )
{
delete papoDrivers[i];
}
CPLFree( papoDrivers );
papoDrivers = NULL;
poRegistrar = NULL;
}
/************************************************************************/
/* OGRCleanupAll() */
/************************************************************************/
void OGRCleanupAll()
{
if( poRegistrar != NULL )
delete poRegistrar;
OSRCleanup();
CPLFinderClean();
VSICleanupFileManager();
CPLFreeConfig();
CPLCleanupTLS();
}
/************************************************************************/
/* GetRegistrar() */
/************************************************************************/
OGRSFDriverRegistrar *OGRSFDriverRegistrar::GetRegistrar()
{
if( poRegistrar == NULL )
poRegistrar = new OGRSFDriverRegistrar();
return poRegistrar;
}
/************************************************************************/
/* Open() */
/************************************************************************/
OGRDataSource *OGRSFDriverRegistrar::Open( const char * pszName,
int bUpdate,
OGRSFDriver ** ppoDriver )
{
OGRDataSource *poDS;
if( ppoDriver != NULL )
*ppoDriver = NULL;
GetRegistrar();
CPLErrorReset();
for( int iDriver = 0; iDriver < poRegistrar->nDrivers; iDriver++ )
{
poDS = poRegistrar->papoDrivers[iDriver]->Open( pszName, bUpdate );
if( poDS != NULL )
{
if( ppoDriver != NULL )
*ppoDriver = poRegistrar->papoDrivers[iDriver];
poDS->Reference();
if( poDS->GetDriver() == NULL )
poDS->m_poDriver = poRegistrar->papoDrivers[iDriver];
CPLDebug( "OGR", "OGROpen(%s/%p) succeeded as %s.",
pszName, poDS, poDS->GetDriver()->GetName() );
return poDS;
}
if( CPLGetLastErrorType() == CE_Failure )
return NULL;
}
CPLDebug( "OGR", "OGROpen(%s) failed.", pszName );
return NULL;
}
/************************************************************************/
/* OGROpen() */
/************************************************************************/
OGRDataSourceH OGROpen( const char *pszName, int bUpdate,
OGRSFDriverH *pahDriverList )
{
if (poRegistrar)
return poRegistrar->Open( pszName, bUpdate,
(OGRSFDriver **) pahDriverList );
return NULL;
}
/************************************************************************/
/* OpenShared() */
/************************************************************************/
OGRDataSource *
OGRSFDriverRegistrar::OpenShared( const char * pszName, int bUpdate,
OGRSFDriver ** ppoDriver )
{
OGRDataSource *poDS;
if( ppoDriver != NULL )
*ppoDriver = NULL;
CPLErrorReset();
/* -------------------------------------------------------------------- */
/* First try finding an existing open dataset matching exactly */
/* on the original datasource raw name used to open the */
/* datasource. */
/* */
/* NOTE: It is an error, but currently we ignore the bUpdate, */
/* and return whatever is open even if it is read-only and the */
/* application requested update access. */
/* -------------------------------------------------------------------- */
int iDS;
for( iDS = 0; iDS < nOpenDSCount; iDS++ )
{
poDS = papoOpenDS[iDS];
if( strcmp( pszName, papszOpenDSRawName[iDS]) == 0 )
{
poDS->Reference();
if( ppoDriver != NULL )
*ppoDriver = papoOpenDSDriver[iDS];
return poDS;
}
}
/* -------------------------------------------------------------------- */
/* If that doesn't match, try matching on the name returned by */
/* the datasource itself. */
/* -------------------------------------------------------------------- */
for( iDS = 0; iDS < nOpenDSCount; iDS++ )
{
poDS = papoOpenDS[iDS];
if( strcmp( pszName, poDS->GetName()) == 0 )
{
poDS->Reference();
if( ppoDriver != NULL )
*ppoDriver = papoOpenDSDriver[iDS];
return poDS;
}
}
/* -------------------------------------------------------------------- */
/* We don't have the datasource. Open it normally. */
/* -------------------------------------------------------------------- */
OGRSFDriver *poTempDriver = NULL;
poDS = Open( pszName, bUpdate, &poTempDriver );
if( poDS == NULL )
return poDS;
/* -------------------------------------------------------------------- */
/* We don't have this datasource already. Grow our list to */
/* hold the new datasource. */
/* -------------------------------------------------------------------- */
papszOpenDSRawName = (char **)
CPLRealloc( papszOpenDSRawName, sizeof(char*) * (nOpenDSCount+1) );
papoOpenDS = (OGRDataSource **)
CPLRealloc( papoOpenDS, sizeof(char*) * (nOpenDSCount+1) );
papoOpenDSDriver = (OGRSFDriver **)
CPLRealloc( papoOpenDSDriver, sizeof(char*) * (nOpenDSCount+1) );
papszOpenDSRawName[nOpenDSCount] = CPLStrdup( pszName );
papoOpenDS[nOpenDSCount] = poDS;
papoOpenDSDriver[nOpenDSCount] = poTempDriver;
nOpenDSCount++;
if( ppoDriver != NULL )
*ppoDriver = poTempDriver;
return poDS;
}
/************************************************************************/
/* OGROpenShared() */
/************************************************************************/
OGRDataSourceH OGROpenShared( const char *pszName, int bUpdate,
OGRSFDriverH *pahDriverList )
{
OGRSFDriverRegistrar::GetRegistrar();
return poRegistrar->OpenShared( pszName, bUpdate,
(OGRSFDriver **) pahDriverList );
}
/************************************************************************/
/* ReleaseDataSource() */
/************************************************************************/
OGRErr OGRSFDriverRegistrar::ReleaseDataSource( OGRDataSource * poDS )
{
int iDS;
for( iDS = 0; iDS < nOpenDSCount; iDS++ )
{
if( poDS == papoOpenDS[iDS] )
break;
}
if( iDS == nOpenDSCount )
{
CPLDebug( "OGR",
"ReleaseDataSource(%s/%p) on unshared datasource!\n"
"Deleting directly.",
poDS->GetName(), poDS );
delete poDS;
return OGRERR_FAILURE;
}
if( poDS->GetRefCount() > 0 )
poDS->Dereference();
if( poDS->GetRefCount() > 0 )
{
CPLDebug( "OGR",
"ReleaseDataSource(%s/%p) ... just dereferencing.",
poDS->GetName(), poDS );
return OGRERR_NONE;
}
if( poDS->GetSummaryRefCount() > 0 )
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -