1 : /******************************************************************************
2 : * $Id: gdalopeninfo.cpp 14752 2008-06-22 18:35:16Z warmerdam $
3 : *
4 : * Project: GDAL Core
5 : * Purpose: Implementation of GDALOpenInfo class.
6 : * Author: Frank Warmerdam, warmerdam@pobox.com
7 : *
8 : **********************************************************************
9 : * Copyright (c) 2002, Frank Warmerdam
10 : *
11 : * Permission is hereby granted, free of charge, to any person obtaining a
12 : * copy of this software and associated documentation files (the "Software"),
13 : * to deal in the Software without restriction, including without limitation
14 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 : * and/or sell copies of the Software, and to permit persons to whom the
16 : * Software is furnished to do so, subject to the following conditions:
17 : *
18 : * The above copyright notice and this permission notice shall be included
19 : * in all copies or substantial portions of the Software.
20 : *
21 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 : * DEALINGS IN THE SOFTWARE.
28 : ****************************************************************************/
29 :
30 : #include "gdal_priv.h"
31 : #include "cpl_conv.h"
32 :
33 : CPL_CVSID("$Id: gdalopeninfo.cpp 14752 2008-06-22 18:35:16Z warmerdam $");
34 :
35 : /************************************************************************/
36 : /* ==================================================================== */
37 : /* GDALOpenInfo */
38 : /* ==================================================================== */
39 : /************************************************************************/
40 :
41 : /************************************************************************/
42 : /* GDALOpenInfo() */
43 : /************************************************************************/
44 :
45 : GDALOpenInfo::GDALOpenInfo( const char * pszFilenameIn, GDALAccess eAccessIn,
46 16179 : char **papszSiblingsIn )
47 :
48 : {
49 : /* -------------------------------------------------------------------- */
50 : /* Ensure that C: is treated as C:\ so we can stat it on */
51 : /* Windows. Similar to what is done in CPLStat(). */
52 : /* -------------------------------------------------------------------- */
53 : #ifdef WIN32
54 : if( strlen(pszFilenameIn) == 2 && pszFilenameIn[1] == ':' )
55 : {
56 : char szAltPath[10];
57 :
58 : strcpy( szAltPath, pszFilenameIn );
59 : strcat( szAltPath, "\\" );
60 : pszFilename = CPLStrdup( szAltPath );
61 : }
62 : else
63 : #endif
64 16179 : pszFilename = CPLStrdup( pszFilenameIn );
65 :
66 : /* -------------------------------------------------------------------- */
67 : /* Initialize. */
68 : /* -------------------------------------------------------------------- */
69 :
70 16179 : nHeaderBytes = 0;
71 16179 : pabyHeader = NULL;
72 16179 : bIsDirectory = FALSE;
73 16179 : bStatOK = FALSE;
74 16179 : eAccess = eAccessIn;
75 16179 : fp = NULL;
76 :
77 : /* -------------------------------------------------------------------- */
78 : /* Collect information about the file. */
79 : /* -------------------------------------------------------------------- */
80 : VSIStatBufL sStat;
81 :
82 16179 : if( VSIStatL( pszFilename, &sStat ) == 0 )
83 : {
84 6399 : bStatOK = TRUE;
85 :
86 6399 : if( VSI_ISREG( sStat.st_mode ) )
87 : {
88 6353 : pabyHeader = (GByte *) CPLCalloc(1025,1);
89 :
90 6353 : fp = VSIFOpen( pszFilename, "rb" );
91 :
92 6353 : if( fp != NULL )
93 : {
94 6162 : nHeaderBytes = (int) VSIFRead( pabyHeader, 1, 1024, fp );
95 :
96 6162 : VSIRewind( fp );
97 : }
98 : /* XXX: ENOENT is used to catch the case of virtual filesystem
99 : * when we do not have a real file with such a name. Under some
100 : * circumstances EINVAL reported instead of ENOENT in Windows
101 : * (for filenames containing colon, e.g. "smth://name").
102 : * See also: #2437 */
103 191 : else if( errno == 27 /* "File to large" */
104 : || errno == ENOENT || errno == EINVAL
105 : #ifdef EOVERFLOW
106 : || errno == EOVERFLOW
107 : #else
108 : || errno == 75 /* Linux EOVERFLOW */
109 : || errno == 79 /* Solaris EOVERFLOW */
110 : #endif
111 : )
112 : {
113 191 : fp = VSIFOpenL( pszFilename, "rb" );
114 191 : if( fp != NULL )
115 : {
116 191 : nHeaderBytes = (int) VSIFReadL( pabyHeader, 1, 1024, fp );
117 191 : VSIFCloseL( fp );
118 191 : fp = NULL;
119 : }
120 : }
121 : }
122 46 : else if( VSI_ISDIR( sStat.st_mode ) )
123 46 : bIsDirectory = TRUE;
124 : }
125 :
126 : /* -------------------------------------------------------------------- */
127 : /* Capture sibling list either from passed in values, or by */
128 : /* scanning for them. */
129 : /* -------------------------------------------------------------------- */
130 16179 : if( papszSiblingsIn != NULL )
131 : {
132 6 : papszSiblingFiles = CSLDuplicate( papszSiblingsIn );
133 : }
134 22520 : else if( bStatOK && !bIsDirectory )
135 : {
136 6347 : if( CSLTestBoolean(
137 : CPLGetConfigOption( "GDAL_DISABLE_READDIR_ON_OPEN", "NO" )) )
138 : {
139 : /* skip reading the directory */
140 0 : papszSiblingFiles = NULL;
141 : }
142 : else
143 : {
144 6347 : CPLString osDir = CPLGetDirname( pszFilename );
145 6347 : papszSiblingFiles = VSIReadDir( osDir );
146 : }
147 : }
148 : else
149 9826 : papszSiblingFiles = NULL;
150 16179 : }
151 :
152 : /************************************************************************/
153 : /* ~GDALOpenInfo() */
154 : /************************************************************************/
155 :
156 16179 : GDALOpenInfo::~GDALOpenInfo()
157 :
158 : {
159 16179 : VSIFree( pabyHeader );
160 16179 : CPLFree( pszFilename );
161 :
162 16179 : if( fp != NULL )
163 5755 : VSIFClose( fp );
164 16179 : CSLDestroy( papszSiblingFiles );
165 16179 : }
166 :
|