1 : /******************************************************************************
2 : * $Id: s57filecollector.cpp 10645 2007-01-18 02:22:39Z warmerdam $
3 : *
4 : * Project: S-57 Translator
5 : * Purpose: Implements S57FileCollector() function. This function collects
6 : * a list of S-57 data files based on the contents of a directory,
7 : * catalog file, or direct reference to an S-57 file.
8 : * Author: Frank Warmerdam, warmerdam@pobox.com
9 : *
10 : ******************************************************************************
11 : * Copyright (c) 1999, Frank Warmerdam
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 "s57.h"
33 : #include "cpl_conv.h"
34 : #include "cpl_string.h"
35 :
36 : CPL_CVSID("$Id: s57filecollector.cpp 10645 2007-01-18 02:22:39Z warmerdam $");
37 :
38 : /************************************************************************/
39 : /* S57FileCollector() */
40 : /************************************************************************/
41 :
42 0 : char **S57FileCollector( const char *pszDataset )
43 :
44 : {
45 : VSIStatBuf sStatBuf;
46 0 : char **papszRetList = NULL;
47 :
48 : /* -------------------------------------------------------------------- */
49 : /* Stat the dataset, and fail if it isn't a file or directory. */
50 : /* -------------------------------------------------------------------- */
51 0 : if( CPLStat( pszDataset, &sStatBuf ) )
52 : {
53 : CPLError( CE_Failure, CPLE_AppDefined,
54 : "No S-57 files found, %s\nisn't a directory or a file.\n",
55 0 : pszDataset );
56 :
57 0 : return NULL;
58 : }
59 :
60 : /* -------------------------------------------------------------------- */
61 : /* We handle directories by scanning for all S-57 data files in */
62 : /* them, but not for catalogs. */
63 : /* -------------------------------------------------------------------- */
64 0 : if( VSI_ISDIR(sStatBuf.st_mode) )
65 : {
66 0 : char **papszDirFiles = CPLReadDir( pszDataset );
67 : int iFile;
68 0 : DDFModule oModule;
69 :
70 0 : for( iFile = 0;
71 0 : papszDirFiles != NULL && papszDirFiles[iFile] != NULL;
72 : iFile++ )
73 : {
74 : char *pszFullFile;
75 :
76 : pszFullFile = CPLStrdup(
77 0 : CPLFormFilename( pszDataset, papszDirFiles[iFile], NULL ) );
78 :
79 : // Add to list if it is an S-57 _data_ file.
80 0 : if( VSIStat( pszFullFile, &sStatBuf ) == 0
81 : && VSI_ISREG( sStatBuf.st_mode )
82 : && oModule.Open( pszFullFile, TRUE ) )
83 : {
84 0 : if( oModule.FindFieldDefn("DSID") != NULL )
85 0 : papszRetList = CSLAddString( papszRetList, pszFullFile );
86 : }
87 :
88 0 : CPLFree( pszFullFile );
89 : }
90 :
91 0 : return papszRetList;
92 : }
93 :
94 : /* -------------------------------------------------------------------- */
95 : /* If this is a regular file, but not a catalog just return it. */
96 : /* Note that the caller may still open it and fail. */
97 : /* -------------------------------------------------------------------- */
98 0 : DDFModule oModule;
99 : DDFRecord *poRecord;
100 :
101 0 : if( !oModule.Open(pszDataset) )
102 : {
103 : CPLError( CE_Failure, CPLE_AppDefined,
104 : "The file %s isn't an S-57 data file, or catalog.\n",
105 0 : pszDataset );
106 :
107 0 : return NULL;
108 : }
109 :
110 0 : poRecord = oModule.ReadRecord();
111 0 : if( poRecord == NULL )
112 0 : return NULL;
113 :
114 0 : if( poRecord->FindField( "CATD" ) == NULL
115 : || oModule.FindFieldDefn("CATD")->FindSubfieldDefn( "IMPL" ) == NULL )
116 : {
117 0 : papszRetList = CSLAddString( papszRetList, pszDataset );
118 0 : return papszRetList;
119 : }
120 :
121 :
122 : /* -------------------------------------------------------------------- */
123 : /* We presumably have a catalog. It contains paths to files */
124 : /* that generally lack the ENC_ROOT component. Try to find the */
125 : /* correct name for the ENC_ROOT directory if available and */
126 : /* build a base path for our purposes. */
127 : /* -------------------------------------------------------------------- */
128 0 : char *pszCatDir = CPLStrdup( CPLGetPath( pszDataset ) );
129 0 : char *pszRootDir = NULL;
130 :
131 0 : if( CPLStat( CPLFormFilename(pszCatDir,"ENC_ROOT",NULL), &sStatBuf ) == 0
132 : && VSI_ISDIR(sStatBuf.st_mode) )
133 : {
134 0 : pszRootDir = CPLStrdup(CPLFormFilename( pszCatDir, "ENC_ROOT", NULL ));
135 : }
136 0 : else if( CPLStat( CPLFormFilename( pszCatDir, "enc_root", NULL ),
137 : &sStatBuf ) == 0 && VSI_ISDIR(sStatBuf.st_mode) )
138 : {
139 0 : pszRootDir = CPLStrdup(CPLFormFilename( pszCatDir, "enc_root", NULL ));
140 : }
141 :
142 0 : if( pszRootDir )
143 : CPLDebug( "S57", "Found root directory to be %s.",
144 0 : pszRootDir );
145 :
146 : /* -------------------------------------------------------------------- */
147 : /* We have a catalog. Scan it for data files, those with an */
148 : /* IMPL of BIN. Shouldn't there be a better way of testing */
149 : /* whether a file is a data file or another catalog file? */
150 : /* -------------------------------------------------------------------- */
151 0 : for( ; poRecord != NULL; poRecord = oModule.ReadRecord() )
152 : {
153 0 : if( poRecord->FindField( "CATD" ) != NULL
154 : && EQUAL(poRecord->GetStringSubfield("CATD",0,"IMPL",0),"BIN") )
155 : {
156 : const char *pszFile, *pszWholePath;
157 :
158 0 : pszFile = poRecord->GetStringSubfield("CATD",0,"FILE",0);
159 :
160 : // Often there is an extra ENC_ROOT in the path, try finding
161 : // this file.
162 :
163 0 : pszWholePath = CPLFormFilename( pszCatDir, pszFile, NULL );
164 0 : if( CPLStat( pszWholePath, &sStatBuf ) != 0
165 : && pszRootDir != NULL )
166 : {
167 0 : pszWholePath = CPLFormFilename( pszRootDir, pszFile, NULL );
168 : }
169 :
170 0 : if( CPLStat( pszWholePath, &sStatBuf ) != 0 )
171 : {
172 : CPLError( CE_Warning, CPLE_OpenFailed,
173 : "Can't find file %s from catalog %s.",
174 0 : pszFile, pszDataset );
175 0 : continue;
176 : }
177 :
178 0 : papszRetList = CSLAddString( papszRetList, pszWholePath );
179 0 : CPLDebug( "S57", "Got path %s from CATALOG.", pszWholePath );
180 : }
181 : }
182 :
183 0 : CPLFree( pszCatDir );
184 0 : CPLFree( pszRootDir );
185 :
186 0 : return papszRetList;
187 : }
188 :
|