Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: OpenGIS Simple Features Reference Implementation
4 : * Purpose: Implements OGRGeoconceptDriver class.
5 : * Author: Didier Richard, didier.richard@ign.fr
6 : * Language: C++
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2007, Geoconcept and IGN
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 "cpl_conv.h"
31 : #include "cpl_string.h"
32 : #include "ogrgeoconceptdatasource.h"
33 : #include "ogrgeoconceptdriver.h"
34 :
35 : /************************************************************************/
36 : /* ~OGRGeoconceptDriver() */
37 : /************************************************************************/
38 :
39 2288 : OGRGeoconceptDriver::~OGRGeoconceptDriver()
40 : {
41 2288 : }
42 :
43 : /************************************************************************/
44 : /* GetName() */
45 : /************************************************************************/
46 :
47 3937 : const char *OGRGeoconceptDriver::GetName()
48 :
49 : {
50 3937 : return "Geoconcept";
51 : }
52 :
53 : /************************************************************************/
54 : /* Open() */
55 : /************************************************************************/
56 :
57 22957 : OGRDataSource *OGRGeoconceptDriver::Open(const char *pszFilename, int bUpdate)
58 :
59 : {
60 : #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
61 : /* -------------------------------------------------------------------- */
62 : /* We will only consider .gxt and .txt files. */
63 : /* -------------------------------------------------------------------- */
64 22957 : const char *pszExtension = CPLGetExtension(pszFilename);
65 22957 : if (!EQUAL(pszExtension, "gxt") && !EQUAL(pszExtension, "txt"))
66 : {
67 22944 : return nullptr;
68 : }
69 : #endif
70 :
71 13 : OGRGeoconceptDataSource *poDS = new OGRGeoconceptDataSource();
72 :
73 13 : if (!poDS->Open(pszFilename, true, CPL_TO_BOOL(bUpdate)))
74 : {
75 5 : delete poDS;
76 5 : return nullptr;
77 : }
78 8 : return poDS;
79 : }
80 :
81 : /************************************************************************/
82 : /* CreateDataSource() */
83 : /* */
84 : /* Options (-dsco) : */
85 : /* EXTENSION=GXT|TXT (default GXT) */
86 : /************************************************************************/
87 :
88 18 : OGRDataSource *OGRGeoconceptDriver::CreateDataSource(const char *pszName,
89 : char **papszOptions)
90 :
91 : {
92 : VSIStatBufL sStat;
93 : /* int bSingleNewFile = FALSE; */
94 :
95 18 : if (pszName == nullptr || strlen(pszName) == 0)
96 : {
97 0 : CPLError(CE_Failure, CPLE_AppDefined,
98 : "Invalid datasource name (null or empty)");
99 0 : return nullptr;
100 : }
101 :
102 : /* -------------------------------------------------------------------- */
103 : /* Is the target a valid existing directory? */
104 : /* -------------------------------------------------------------------- */
105 18 : if (VSIStatL(pszName, &sStat) == 0)
106 : {
107 0 : if (!VSI_ISDIR(sStat.st_mode))
108 : {
109 0 : CPLError(CE_Failure, CPLE_AppDefined,
110 : "%s is not a valid existing directory.", pszName);
111 0 : return nullptr;
112 : }
113 : }
114 :
115 : /* -------------------------------------------------------------------- */
116 : /* Does it end with the extension .gxt indicating the user likely */
117 : /* wants to create a single file set? */
118 : /* -------------------------------------------------------------------- */
119 35 : else if (EQUAL(CPLGetExtension(pszName), "gxt") ||
120 17 : EQUAL(CPLGetExtension(pszName), "txt"))
121 : {
122 : /* bSingleNewFile = TRUE; */
123 : }
124 :
125 : /* -------------------------------------------------------------------- */
126 : /* Return a new OGRDataSource() */
127 : /* -------------------------------------------------------------------- */
128 18 : OGRGeoconceptDataSource *poDS = new OGRGeoconceptDataSource();
129 18 : if (!poDS->Create(pszName, papszOptions))
130 : {
131 1 : delete poDS;
132 1 : return nullptr;
133 : }
134 17 : return poDS;
135 : }
136 :
137 : /************************************************************************/
138 : /* DeleteDataSource() */
139 : /************************************************************************/
140 :
141 16 : OGRErr OGRGeoconceptDriver::DeleteDataSource(const char *pszDataSource)
142 :
143 : {
144 : VSIStatBufL sStatBuf;
145 : static const char *const apszExtensions[] = {"gxt", "txt", "gct",
146 : "gcm", "gcr", nullptr};
147 :
148 16 : if (VSIStatL(pszDataSource, &sStatBuf) != 0)
149 : {
150 0 : CPLError(CE_Failure, CPLE_AppDefined,
151 : "%s does not appear to be a file or directory.",
152 : pszDataSource);
153 :
154 0 : return OGRERR_FAILURE;
155 : }
156 :
157 16 : if (VSI_ISREG(sStatBuf.st_mode) &&
158 0 : (EQUAL(CPLGetExtension(pszDataSource), "gxt") ||
159 0 : EQUAL(CPLGetExtension(pszDataSource), "txt")))
160 : {
161 0 : for (int iExt = 0; apszExtensions[iExt] != nullptr; iExt++)
162 : {
163 : const char *pszFile =
164 0 : CPLResetExtension(pszDataSource, apszExtensions[iExt]);
165 0 : if (VSIStatL(pszFile, &sStatBuf) == 0)
166 0 : VSIUnlink(pszFile);
167 : }
168 : }
169 16 : else if (VSI_ISDIR(sStatBuf.st_mode))
170 : {
171 16 : char **papszDirEntries = VSIReadDir(pszDataSource);
172 :
173 32 : for (int iFile = 0;
174 32 : papszDirEntries != nullptr && papszDirEntries[iFile] != nullptr;
175 : iFile++)
176 : {
177 16 : if (CSLFindString(const_cast<char **>(apszExtensions),
178 32 : CPLGetExtension(papszDirEntries[iFile])) != -1)
179 : {
180 16 : VSIUnlink(CPLFormFilename(pszDataSource, papszDirEntries[iFile],
181 : nullptr));
182 : }
183 : }
184 :
185 16 : CSLDestroy(papszDirEntries);
186 :
187 16 : VSIRmdir(pszDataSource);
188 : }
189 :
190 16 : return OGRERR_NONE;
191 : }
192 :
193 : /************************************************************************/
194 : /* TestCapability() */
195 : /************************************************************************/
196 :
197 2428 : int OGRGeoconceptDriver::TestCapability(const char *pszCap)
198 :
199 : {
200 2428 : if (EQUAL(pszCap, ODrCCreateDataSource))
201 1214 : return TRUE;
202 :
203 1214 : if (EQUAL(pszCap, ODrCDeleteDataSource))
204 1214 : return TRUE;
205 :
206 0 : return FALSE;
207 : }
208 :
209 : /************************************************************************/
210 : /* RegisterOGRGeoconcept() */
211 : /************************************************************************/
212 :
213 1509 : void RegisterOGRGeoconcept()
214 :
215 : {
216 1509 : OGRSFDriver *poDriver = new OGRGeoconceptDriver;
217 1509 : poDriver->SetMetadataItem(GDAL_DCAP_VECTOR, "YES");
218 1509 : poDriver->SetMetadataItem(GDAL_DCAP_CREATE_LAYER, "YES");
219 1509 : poDriver->SetMetadataItem(GDAL_DCAP_CREATE_FIELD, "YES");
220 1509 : poDriver->SetMetadataItem(GDAL_DMD_EXTENSIONS, "gxt txt");
221 1509 : poDriver->SetMetadataItem(GDAL_DCAP_Z_GEOMETRIES, "YES");
222 :
223 1509 : poDriver->SetMetadataItem(
224 : GDAL_DMD_CREATIONOPTIONLIST,
225 : "<CreationOptionList>"
226 : " <Option name='EXTENSION' type='string-select' "
227 : "description='indicates the "
228 : "GeoConcept export file extension. TXT was used by earlier releases of "
229 : "GeoConcept. GXT is currently used.' default='GXT'>"
230 : " <Value>GXT</Value>"
231 : " <Value>TXT</Value>"
232 : " </Option>"
233 : " <Option name='CONFIG' type='string' description='path to the GCT "
234 : "file that "
235 : "describes the GeoConcept types definitions.'/>"
236 1509 : "</CreationOptionList>");
237 :
238 1509 : poDriver->SetMetadataItem(GDAL_DS_LAYER_CREATIONOPTIONLIST,
239 : "<LayerCreationOptionList>"
240 : " <Option name='FEATURETYPE' type='string' "
241 : "description='TYPE.SUBTYPE : "
242 : "defines the feature to be created. The TYPE "
243 : "corresponds to one of the Name "
244 : "found in the GCT file for a type section. The "
245 : "SUBTYPE corresponds to one of "
246 : "the Name found in the GCT file for a sub-type "
247 : "section within the previous "
248 : "type section'/>"
249 1509 : "</LayerCreationOptionList>");
250 1509 : poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES");
251 1509 : poDriver->SetMetadataItem(GDAL_DMD_SUPPORTED_SQL_DIALECTS, "OGRSQL SQLITE");
252 :
253 1509 : OGRSFDriverRegistrar::GetRegistrar()->RegisterDriver(poDriver);
254 1509 : }
|