Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members   Related Pages  

gdalopen.cpp

00001 /******************************************************************************
00002  * $Id: gdalopen_cpp-source.html,v 1.13 2002/12/21 19:13:13 warmerda Exp $
00003  *
00004  * Project:  GDAL Core
00005  * Purpose:  Implementation of GDALOpen(), GDALOpenShared(), GDALOpenInfo and
00006  *           related services.
00007  * Author:   Frank Warmerdam, warmerdam@pobox.com
00008  *
00009  **********************************************************************
00010  * Copyright (c) 2002, Frank Warmerdam
00011  *
00012  * Permission is hereby granted, free of charge, to any person obtaining a
00013  * copy of this software and associated documentation files (the "Software"),
00014  * to deal in the Software without restriction, including without limitation
00015  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00016  * and/or sell copies of the Software, and to permit persons to whom the
00017  * Software is furnished to do so, subject to the following conditions:
00018  *
00019  * The above copyright notice and this permission notice shall be included
00020  * in all copies or substantial portions of the Software.
00021  *
00022  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00023  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00024  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
00025  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00026  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00027  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00028  * DEALINGS IN THE SOFTWARE.
00029  ******************************************************************************
00030  *
00031  * $Log: gdalopen_cpp-source.html,v $
00031  * Revision 1.13  2002/12/21 19:13:13  warmerda
00031  * updated
00031  *
00032  * Revision 1.17  2002/07/09 20:33:12  warmerda
00033  * expand tabs
00034  *
00035  * Revision 1.16  2002/06/19 18:20:21  warmerda
00036  * use VSIStatL() so it works on large files, dont keep stat in openinfo.
00037  *
00038  * Revision 1.15  2002/06/15 00:07:23  aubin
00039  * mods to enable 64bit file i/o
00040  *
00041  * Revision 1.14  2002/06/12 21:13:27  warmerda
00042  * use metadata based driver info
00043  *
00044  * Revision 1.13  2002/05/28 18:56:22  warmerda
00045  * added shared dataset concept
00046  *
00047  * Revision 1.12  2001/12/12 17:21:21  warmerda
00048  * Use CPLStat instead of VSIStat().
00049  *
00050  * Revision 1.11  2001/08/20 13:40:28  warmerda
00051  * modified message on failure to open if not a file
00052  *
00053  * Revision 1.10  2001/07/18 04:04:30  warmerda
00054  * added CPL_CVSID
00055  *
00056  * Revision 1.9  2001/01/03 05:32:20  warmerda
00057  * avoid depending on VSIStatBuf file size for 2GB issues
00058  *
00059  * Revision 1.8  2000/04/21 21:55:53  warmerda
00060  * set filename as description of GDALDatasets.
00061  *
00062  * Revision 1.7  2000/01/10 15:43:06  warmerda
00063  * Fixed debug statement.
00064  *
00065  * Revision 1.6  2000/01/10 15:31:02  warmerda
00066  * Added debug statement in GDALOpen.
00067  *
00068  * Revision 1.5  1999/11/11 21:59:07  warmerda
00069  * added GetDriver() for datasets
00070  *
00071  * Revision 1.4  1999/10/01 14:44:02  warmerda
00072  * added documentation
00073  *
00074  * Revision 1.3  1999/04/21 04:00:34  warmerda
00075  * Initialize fp to NULL.
00076  *
00077  * Revision 1.2  1998/12/31 18:52:45  warmerda
00078  * Use CPL memory functions (they are safe), and fixed up header reading.
00079  *
00080  * Revision 1.1  1998/12/03 18:31:45  warmerda
00081  * New
00082  *
00083  */
00084 
00085 #include "gdal_priv.h"
00086 #include "cpl_conv.h"
00087 
00088 CPL_CVSID("$Id: gdalopen_cpp-source.html,v 1.13 2002/12/21 19:13:13 warmerda Exp $");
00089 
00090 /************************************************************************/
00091 /* ==================================================================== */
00092 /*                             GDALOpenInfo                             */
00093 /* ==================================================================== */
00094 /************************************************************************/
00095 
00096 /************************************************************************/
00097 /*                            GDALOpenInfo()                            */
00098 /************************************************************************/
00099 
00100 GDALOpenInfo::GDALOpenInfo( const char * pszFilenameIn, GDALAccess eAccessIn )
00101 
00102 {
00103 /* -------------------------------------------------------------------- */
00104 /*      Ensure that C: is treated as C:\ so we can stat it on           */
00105 /*      Windows.  Similar to what is done in CPLStat().                 */
00106 /* -------------------------------------------------------------------- */
00107 #ifdef WIN32
00108     if( strlen(pszFilenameIn) == 2 && pszFilenameIn[1] == ':' )
00109     {
00110         char    szAltPath[10];
00111         
00112         strcpy( szAltPath, pszFilenameIn );
00113         strcat( szAltPath, "\\" );
00114         pszFilename = CPLStrdup( szAltPath );
00115     }
00116     else
00117 #endif
00118         pszFilename = CPLStrdup( pszFilenameIn );
00119 
00120 /* -------------------------------------------------------------------- */
00121 /*      Initialize.                                                     */
00122 /* -------------------------------------------------------------------- */
00123 
00124     nHeaderBytes = 0;
00125     pabyHeader = NULL;
00126     bIsDirectory = FALSE;
00127     bStatOK = FALSE;
00128     eAccess = eAccessIn;
00129     fp = NULL;
00130     
00131 /* -------------------------------------------------------------------- */
00132 /*      Collect information about the file.                             */
00133 /* -------------------------------------------------------------------- */
00134     VSIStatBufL  sStat;
00135 
00136     if( VSIStatL( pszFilename, &sStat ) == 0 )
00137     {
00138         bStatOK = TRUE;
00139 
00140         if( VSI_ISREG( sStat.st_mode ) )
00141         {
00142             pabyHeader = (GByte *) CPLCalloc(1025,1);
00143 
00144             fp = VSIFOpen( pszFilename, "rb" );
00145 
00146             if( fp != NULL )
00147             {
00148                 nHeaderBytes = VSIFRead( pabyHeader, 1, 1024, fp );
00149 
00150                 VSIRewind( fp );
00151             }
00152         }
00153         else if( VSI_ISDIR( sStat.st_mode ) )
00154             bIsDirectory = TRUE;
00155     }
00156 }
00157 
00158 /************************************************************************/
00159 /*                           ~GDALOpenInfo()                            */
00160 /************************************************************************/
00161 
00162 GDALOpenInfo::~GDALOpenInfo()
00163 
00164 {
00165     VSIFree( pabyHeader );
00166     CPLFree( pszFilename );
00167 
00168     if( fp != NULL )
00169         VSIFClose( fp );
00170 }
00171 
00172 /************************************************************************/
00173 /*                              GDALOpen()                              */
00174 /************************************************************************/
00175 
00193 GDALDatasetH GDALOpen( const char * pszFilename, GDALAccess eAccess )
00194 
00195 {
00196     int         iDriver;
00197     GDALDriverManager *poDM = GetGDALDriverManager();
00198     GDALOpenInfo oOpenInfo( pszFilename, eAccess );
00199 
00200     CPLErrorReset();
00201     
00202     for( iDriver = 0; iDriver < poDM->GetDriverCount(); iDriver++ )
00203     {
00204         GDALDriver      *poDriver = poDM->GetDriver( iDriver );
00205         GDALDataset     *poDS;
00206 
00207         poDS = poDriver->pfnOpen( &oOpenInfo );
00208         if( poDS != NULL )
00209         {
00210             poDS->SetDescription( pszFilename );
00211 
00212             if( poDS->poDriver == NULL )
00213                 poDS->poDriver = poDriver;
00214 
00215             
00216             CPLDebug( "GDAL", "GDALOpen(%s) succeeds as %s.\n",
00217                       pszFilename, poDriver->GetDescription() );
00218 
00219             return (GDALDatasetH) poDS;
00220         }
00221 
00222         if( CPLGetLastErrorNo() != 0 )
00223             return NULL;
00224     }
00225 
00226     if( oOpenInfo.bStatOK )
00227         CPLError( CE_Failure, CPLE_OpenFailed,
00228                   "`%s' not recognised as a supported file format.\n",
00229                   pszFilename );
00230     else
00231         CPLError( CE_Failure, CPLE_OpenFailed,
00232                   "`%s' does not exist in the file system,\n"
00233                   "and is not recognised as a supported dataset name.\n",
00234                   pszFilename );
00235               
00236     return NULL;
00237 }
00238 
00239 /************************************************************************/
00240 /*                           GDALOpenShared()                           */
00241 /************************************************************************/
00242 
00264 GDALDatasetH GDALOpenShared( const char *pszFilename, GDALAccess eAccess )
00265 
00266 {
00267 /* -------------------------------------------------------------------- */
00268 /*      First scan the existing list to see if it could already         */
00269 /*      contain the requested dataset.                                  */
00270 /* -------------------------------------------------------------------- */
00271     int         i, nSharedDatasetCount;
00272     GDALDataset **papoSharedDatasets 
00273                         = GDALDataset::GetOpenDatasets(&nSharedDatasetCount);
00274     
00275     for( i = 0; i < nSharedDatasetCount; i++ )
00276     {
00277         if( strcmp(pszFilename,papoSharedDatasets[i]->GetDescription()) == 0 
00278             && (eAccess == GA_ReadOnly 
00279                 || papoSharedDatasets[i]->GetAccess() == eAccess ) )
00280             
00281         {
00282             papoSharedDatasets[i]->Reference();
00283             return papoSharedDatasets[i];
00284         }
00285     }
00286 
00287 /* -------------------------------------------------------------------- */
00288 /*      Try opening the the requested dataset.                          */
00289 /* -------------------------------------------------------------------- */
00290     GDALDataset *poDataset;
00291 
00292     poDataset = (GDALDataset *) GDALOpen( pszFilename, eAccess );
00293     if( poDataset != NULL )
00294         poDataset->MarkAsShared();
00295     
00296     return (GDALDatasetH) poDataset;
00297 }
00298 
00299 /************************************************************************/
00300 /*                             GDALClose()                              */
00301 /************************************************************************/
00302 
00303 void GDALClose( GDALDatasetH hDS )
00304 
00305 {
00306     GDALDataset *poDS = (GDALDataset *) hDS;
00307     int         i, nSharedDatasetCount;
00308     GDALDataset **papoSharedDatasets 
00309                         = GDALDataset::GetOpenDatasets(&nSharedDatasetCount);
00310 
00311 /* -------------------------------------------------------------------- */
00312 /*      If this file is in the shared dataset list then dereference     */
00313 /*      it, and only delete/remote it if the reference count has        */
00314 /*      dropped to zero.                                                */
00315 /* -------------------------------------------------------------------- */
00316     for( i = 0; i < nSharedDatasetCount; i++ )
00317     {
00318         if( papoSharedDatasets[i] == poDS )
00319         {
00320             if( poDS->Dereference() > 0 )
00321                 return;
00322 
00323             delete poDS;
00324             return;
00325         }
00326     }
00327 
00328 /* -------------------------------------------------------------------- */
00329 /*      This is not shared dataset, so directly delete it.              */
00330 /* -------------------------------------------------------------------- */
00331     delete poDS;
00332 }
00333 
00334 /************************************************************************/
00335 /*                        GDALDumpOpenDataset()                         */
00336 /************************************************************************/
00337 
00338 int GDALDumpOpenDatasets( FILE *fp )
00339    
00340 {
00341     int         i, nSharedDatasetCount;
00342     GDALDataset **papoSharedDatasets 
00343                         = GDALDataset::GetOpenDatasets(&nSharedDatasetCount);
00344 
00345     if( nSharedDatasetCount > 0 )
00346         VSIFPrintf( fp, "Open GDAL Datasets:\n" );
00347     
00348     for( i = 0; i < nSharedDatasetCount; i++ )
00349     {
00350         const char *pszDriverName;
00351         GDALDataset *poDS = papoSharedDatasets[i];
00352         
00353         if( poDS->GetDriver() == NULL )
00354             pszDriverName = "DriverIsNULL";
00355         else
00356             pszDriverName = poDS->GetDriver()->GetDescription();
00357 
00358         poDS->Reference();
00359         VSIFPrintf( fp, "  %d %c %-6s %dx%dx%d %s\n", 
00360                     poDS->Dereference(), 
00361                     poDS->GetShared() ? 'S' : 'N',
00362                     pszDriverName, 
00363                     poDS->GetRasterXSize(),
00364                     poDS->GetRasterYSize(),
00365                     poDS->GetRasterCount(),
00366                     poDS->GetDescription() );
00367     }
00368     
00369     return nSharedDatasetCount;
00370 }

Generated at Sat Dec 21 14:01:59 2002 for GDAL by doxygen1.2.3-20001105 written by Dimitri van Heesch, © 1997-2000